|
You last visited: Today at 04:26
Advertisement
Struct/MAP in struct speichern?
Discussion on Struct/MAP in struct speichern? within the C/C++ forum part of the Coders Den category.
09/10/2013, 22:40
|
#1
|
elite*gold: 4
Join Date: Mar 2010
Posts: 3,148
Received Thanks: 1,535
|
Struct/MAP in struct speichern?
Ich versuche momentan in einer Struct den datentyp map zu speichern, aber sobald ich es in der struct in der headerdatei mit reinpacke stirbt das Programm beim start.
sieht ca so aus
Code:
struct EventGift
{
DWORD dwID;
int nCount;
int nPercentage;
};
struct EventMonster
{
DWORD dwID;
int nInerval;
int nPercentage;
map<DWORD,EventGift> m_aEventGift;
};
class AutoEvent
{
public:
map<DWORD, EventMonster> m_aEventMonster;
AutoEvent();
~AutoEvent();
void ReadInc();
void Process();
};
kommentiere ich map<DWORD,EventGIft> m_aEventGift; aus stürzt es nicht mehr ab, nur kann ich so nicht meine werte speichern.
|
|
|
09/10/2013, 22:58
|
#2
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Das ist nicht der für den Absturz relevante Teil. Mit dem Debugger wirst du den Fehler sicher besser eingrenzen können. Wenn es nicht zu viel ist, kannst du auch den gesamten Quelltext zur Fehlersuche bereitstellen.
Wozu brauchst du eigentlich std::map? Reicht std::vector nicht aus?
|
|
|
09/11/2013, 06:28
|
#3
|
elite*gold: 50
Join Date: Mar 2010
Posts: 1,373
Received Thanks: 521
|
Ich weiß nicht, ob das der Fehler ist oder nur beim Einfügen in deinen Beitrag passiert ist, aber in der Klasse AutoEvent wird m_aEventMonster nicht richtig deklariert, also die Typen für das Tenplate sind nicht in den <>-Klammern.
|
|
|
09/11/2013, 07:19
|
#4
|
elite*gold: 0
Join Date: Jan 2009
Posts: 1,160
Received Thanks: 232
|
Quote:
map<DWORD, EventMonster, m_aEventMonster;
|
Du hast anscheiennd ein , mit einem > verwechselt.
|
|
|
09/11/2013, 21:06
|
#5
|
elite*gold: 4
Join Date: Mar 2010
Posts: 3,148
Received Thanks: 1,535
|
Quote:
Originally Posted by Delinquenz
Du hast anscheiennd ein , mit einem > verwechselt.
|
ja in der Source ist es richtig, war gerade nur so schnell freihand getippt.
Ich habe map anstatt vector gewählt, da die ID's nicht von 1-10 z.b. gehen, sondern z.b. 22, 105, 160
so kann ich besser auf den einzelnen Datensatz zugreifen.
Quote:
Originally Posted by Tasiro
Das ist nicht der für den Absturz relevante Teil. Mit dem Debugger wirst du den Fehler sicher besser eingrenzen können. Wenn es nicht zu viel ist, kannst du auch den gesamten Quelltext zur Fehlersuche bereitstellen.
Wozu brauchst du eigentlich std::map? Reicht std::vector nicht aus?
|
Debugger sagt einfach Programm beendet mit Code -5
sobald ich aber diesen teil in der Header auskommentiere läuft alles.
Also MUSS es daran liegen, da ich es in der CPP noch garnicht behandele
|
|
|
09/11/2013, 21:20
|
#6
|
elite*gold: 0
Join Date: Feb 2013
Posts: 1,137
Received Thanks: 869
|
Quote:
Debugger sagt einfach Programm beendet mit Code -5
|
Dann debugge mal richtig, so mit steppen, breaken, tanzen und so.
Oder zeig mal deinen kompletten Code her.
|
|
|
09/11/2013, 21:41
|
#7
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Quote:
Originally Posted by Jopsi332
Ich habe map anstatt vector gewählt, da die ID's nicht von 1-10 z.b. gehen, sondern z.b. 22, 105, 160
so kann ich besser auf den einzelnen Datensatz zugreifen.
|
Reicht es nicht, über die einzelnen Datensätze auf deren IDs zuzugreifen? Wozu brauchst du eigentlich eine ID?
Quote:
Originally Posted by Jopsi332
Debugger sagt einfach Programm beendet mit Code -5
|
F5 drücken ist noch kein Debuggen...
Quote:
Originally Posted by Schlüsselbein
zeig mal deinen kompletten Code her.
|
|
|
|
09/11/2013, 22:37
|
#8
|
elite*gold: 4
Join Date: Mar 2010
Posts: 3,148
Received Thanks: 1,535
|
Quote:
Originally Posted by Tasiro
Reicht es nicht, über die einzelnen Datensätze auf deren IDs zuzugreifen? Wozu brauchst du eigentlich eine ID?
F5 drücken ist noch kein Debuggen...
|
Ich starte das programm und dann mach ich den reiter debug->attach->und geh auf das programm
Code:
.h
#pragma once
struct EventGift
{
DWORD dwID;
int nCount;
int nPercentage;
};
typedef struct EventMonster
{
DWORD dwID;
int nInterval;
int nPercentage;
//vector<D3DXVECTOR3> position;
map<DWORD,EventGift> m_aEventGift;
CTimer m_Interval;
EventMonster()
{
dwID = 0;
nInterval = 0;
nPercentage = 0;
m_aEventGift.clear();
}
}m_aEventMonster, *paEventMonster;
class CAutoEvent
{
public:
map<DWORD,EventMonster> m_aEventMonster;
CAutoEvent();
virtual ~CAutoEvent();
void ReadInc();
void Process();
};
Code:
.cpp
#include "stdafx.h"
#ifdef __AUTO_EVENT
CAutoEvent::CAutoEvent()
{
//ZeroMemory(&m_aEventMonster,sizeof(m_aEventMonster));
}
CAutoEvent::~CAutoEvent()
{
}
void CAutoEvent::ReadInc()
{
CScanner script;
if( script.Load( "AutoEvent.inc" ) == FALSE )
{
Error("Could not load AutoEvent.inc!");
return ;
}
EventMonster pEventMonster;
ZeroMemory(&pEventMonster, sizeof(pEventMonster));
script.GetToken();
while( script.tok != FINISHED )
{
if(script.Token == _T("EventMonster"))
{
script.GetToken();
while(script.Token != _T( "}" ))
{
pEventMonster.dwID = script.GetNumber();
script.GetToken();//{
while(script.Token != _T( "}" ))
{
if(script.Token == _T("Intervall"))
{
script.GetToken();//=
pEventMonster.nInterval = script.GetNumber();
}
else if(script.Token == _T("percentage"))
{
script.GetToken();//=
pEventMonster.nPercentage = script.GetNumber();
}
else if(script.Token == _T("Gift"))
{
EventGift pEventGift;
ZeroMemory(&pEventGift,sizeof(pEventGift));
script.GetToken();
while(script.Token != _T("}"))
{
if(script.Token == _T("SetGift"))
{
BOOL bSkip = FALSE;
script.GetToken();//(
pEventGift.dwID = script.GetNumber();
script.GetToken();//,
pEventGift.nCount = script.GetNumber();
script.GetToken();//,
pEventGift.nPercentage = script.GetNumber();
script.GetToken();//)
ItemProp * pItemProp = prj.GetItemProp(pEventGift.dwID);
if(!pItemProp)
{
Error("Error AutoEvent ID [Monster %i] Item[%i]",pEventMonster.dwID,pEventGift.dwID);
bSkip = TRUE;
}
map<DWORD,EventGift>::iterator it = pEventMonster.m_aEventGift.find( pEventGift.dwID );
if( it != pEventMonster.m_aEventGift.end() )
{}
else
{
Error("Error AutoEvent Duplicatet ItemGift[Monster %i] [ID %i]",pEventMonster.dwID,pEventGift.dwID);
bSkip = TRUE;
}
if(!bSkip)
pEventMonster.m_aEventGift.insert(make_pair(pEventGift.dwID,pEventGift));
}
script.GetToken();
}
script.GetToken();
continue;
}
else if(script.Token == _T("Positions"))
{
script.GetToken();
while(script.Token!=_T("}"))
{
if(script.Token == _T("SetPosition"))
{
script.GetToken();//(
D3DXVECTOR3 vPos;
vPos.x = script.GetNumber();
script.GetToken();//,
vPos.y = script.GetNumber();
script.GetToken();//,
vPos.z = script.GetNumber();
script.GetToken();//)
//pEventMonster.position.push_back(vPos);
}
script.GetToken();
}
script.GetToken();
continue;
}
script.GetToken();
}
//m_aEventMonster.insert(make_pair(pEventMonster.dwID, pEventMonster));
pEventMonster.dwID = script.GetNumber(); // ID;
}
script.GetToken();
}
script.GetToken();
}
}
void CAutoEvent::Process()
{
}
CAutoEvent g_AutoEvent;
#endif
|
|
|
09/11/2013, 23:04
|
#9
|
elite*gold: 0
Join Date: Feb 2013
Posts: 1,137
Received Thanks: 869
|
Breakpoints sagen dir was?
|
|
|
09/11/2013, 23:12
|
#10
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
Quote:
ZeroMemory(&pEventMonster, sizeof(pEventMonster));
|
Da haben wir es doch. Was fällt dir ein, das einfach zu 0en?
std::map hat einen Standardkonstruktur, das Objekt ist nie uninitialisiert - das ist der Vorteil von objektorientierter Programmierung. Du hast doch selbst einen Standardkonstruktor für EventMonster definiert, also wozu diese Zeile?
Durch das 0en des Speichers beschädigst du evtl. den internen Zustand (ich weiß nichts Genaueres über die Implementation von map).
Btw. ist dir bewusst, wofür das Präfix "p" normalerweise verwendet wird? Deine EventMonster Variable ist kein Zeiger, also wozu das p?
Code:
typedef struct EventMonster
{
//...
}m_aEventMonster, *paEventMonster;
Ich bin mir nicht so ganz sicher, ob du weißt, was du da tust.
|
|
|
09/12/2013, 07:13
|
#11
|
elite*gold: 0
Join Date: Jan 2009
Posts: 1,160
Received Thanks: 232
|
Mal machste ein Struct mit typedef, mal ohne. Du definierst den vermeintlichen Klassenmember (m_aEventMonster) einfach mal global und definierst ihn lokal neu innerhalb der Klasse. Sicher, dass das nicht das Ergebnis von c&p ist?
|
|
|
09/12/2013, 16:34
|
#12
|
elite*gold: 4
Join Date: Mar 2010
Posts: 3,148
Received Thanks: 1,535
|
Oh scheiße, das mit typedef und global definiert war nur um was zu testen ._.
Code:
.h
#pragma once
struct EventGift
{
DWORD dwID;
int nCount;
int nPercentage;
};
struct EventMonster
{
DWORD dwID;
int nInterval;
int nPercentage;
//vector<D3DXVECTOR3> position;
map<DWORD,EventGift> m_aEventGift;
CTimer m_Interval;
};
class CAutoEvent
{
public:
map<DWORD,EventMonster> m_aEventMonster;
CAutoEvent();
virtual ~CAutoEvent();
void ReadInc();
void Process();
};
das mit dem "p" weiß ich, hab ich gewählt um es besser auseinander zu halten von der KlassenVariable und die die ich in der Funktion nutze.
|
|
|
09/13/2013, 02:13
|
#13
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Code:
.cpp
#include "stdafx.h"
Du solltest deine Projekteinstellungen ändern. Entweder C/C++ - Vorkompilierte Header - Vorkompilierte Header nicht verwenden oder C/C++ - Erweitert - Erzwungene Includedateien auf stdafx.h setzen.
In der stdafx.h sollten nur Headerdateien inkludiert werden, die sich nicht ändern werden, generell sollte diese Datei möglichst nicht ohne Grund genutzt werden, da durch deren Verwendung die Kompilierzeit unnötig steigen kann: alle Dateien müssen erneut übersetzt werden, wenn du in einer in stdafx.h inkludierten Datei etwas änderst.
Code:
class CAutoEvent
{
public:
map<DWORD,EventMonster> m_aEventMonster;
CAutoEvent();
virtual ~CAutoEvent();
void ReadInc();
void Process();
};
Du brauchst virtuelle Destruktoren nur bei virtuellen Methoden (Variablen sollten ein Implementierungsdetail sein). Und wenn der Destruktor als einziges virtuell ist, gibt es keinen Grund, Zeiger oder Referenzen auf CAutoEvents zu erstellen, welche tatsächlich Objekte abgeleiteter Klassen beinhalten. Damit ist ein virtueller Destruktor nicht notwendig.
Code:
CAutoEvent g_AutoEvent;
Du verwendest globale Objekte. Warum?
Code:
#ifdef __AUTO_EVENT
__AUTO_EVENT ist ein für den Compiler reservierter Bezeichner, genau wie jeder andere Bezeichner mit zwei Unterstrichen oder einem führenden Unterstrich und einem darauf folgenden Großbuchstaben, oder einem Bezeichner mit einem führendem Unterstrich im globalen Namensraum. Visual Studio darf dir also deine Festplatte formatieren.
Davon abgesehen verstehe ich nicht, wieso du das brauchst. Wenn ich raten müsste, würde ich auf die stdafx.h tippen...
Code:
CScanner script;
if( script.Load( "AutoEvent.inc" ) == FALSE )
CGibt ces cdenn ckeinen cpassenden CKonstruktor cfür CScanner? Und eine Methode wie .good (und möglicherweise noch eine implizite Konvertierung zu bool)?
Mit true, false, TRUE und FALSE sollte nicht verglichen werden. Statt if (b == true) kannst du auch einfach if (b) schreiben, und statt if (b == false) entsprechend if (! b).
Code:
Error("Could not load AutoEvent.inc!");
Ist das... eine globale Funktion? Warum nicht std::cerr oder ein anderes Stream-Objekt?
Code:
void CAutoEvent::ReadInc()
{
// ein über 100 Zeilen langes Ungetüm
}
Was du in CAutoEvent::ReadInc machen möchtest, nennt sich Syntaxanalyse. Diese wird (normalerweise) von einem Parser durchgeführt, welcher seine Token (normalerweise) von einem Lexer (lexikalischen Scanner) erhält. Ein Parser kann z. B. so aussehen (hier ohne Lexer, mit explizitem Syntaxbaum und mit wenig Templateargumenten - kein node<T>):
Code:
#include <iostream>
#include <string>
#include <memory> // std::unique_ptr<T>
#include <functional> // std::plus, ...
#include <cctype> // std::isdigit
#include <limits> // std:numeric_limits<T>
// Basisklasse aller Knoten
class node {
public:
// vielleicht muss eine erbende Klasse selbst aufräumen
virtual ~ node ();
// berechnet den Wert des Knotens; rein virtuell
virtual double eval () const = 0;
};
node :: ~ node () {}
// Warum nicht mal eine rein virtuelle Funktion definieren?
double node :: eval () const {
throw std::exception ("pure virtual function node::eval called");
}
// eine Klasse für Zahlen
class number : public node {
private:
double value;
public:
number (double value);
double eval () const override;
};
number :: number (double value)
: value (value) {}
double number :: eval () const {
return this->value;
}
// mit variadischen Templates ließe sich das einmal für jede beliebige Anzahl
// von Kindern machen, die werden aber erst ab VS2013 unterstützt
// Klassentemplate für unäre Knoten
template <typename unary_function>
class unary_node : public node {
private:
// das Kind
std::unique_ptr <node> child;
// die eigentliche Berechnungsfunktion
unary_function function;
public:
unary_node (std::unique_ptr <node> && child, unary_function function = unary_function ());
double eval () const override;
};
template <typename unary_function>
unary_node <unary_function> :: unary_node (std::unique_ptr <node> && child, unary_function function)
: child (std::move (child)), function (function) {}
template <typename unary_function>
double unary_node <unary_function> :: eval () const {
return this->function (this->child->eval ());
}
// Klassentemplate für binäre Knoten
template <typename binary_function>
class binary_node : public node {
private:
// linkes und rechtes Kind
std::unique_ptr <node> left;
std::unique_ptr <node> right;
// die eigentliche Berechnungsfunktion
binary_function function;
public:
binary_node (std::unique_ptr <node> && left, std::unique_ptr <node> && right, binary_function function = binary_function ());
double eval () const override;
};
template <typename binary_function>
binary_node <binary_function> :: binary_node (std::unique_ptr <node> && left, std::unique_ptr <node> && right, binary_function function)
: left (std::move (left)), right (std::move (right)), function (function) {}
template <typename binary_function>
double binary_node <binary_function> :: eval () const {
return this->function (this->left->eval (), this->right->eval ());
}
// ist so einfacher als mit selbst geschriebenen Klassen
typedef unary_node <std::negate <double>> negation;
typedef binary_node <std::plus <double>> addition;
typedef binary_node <std::minus <double>> subtraction;
typedef binary_node <std::multiplies <double>> multiplication;
typedef binary_node <std::divides <double>> division;
/* Grammatik
expression
Ausdruck -> Ausdruck + Term
Ausdruck -> Ausdruck - Term
Ausdruck -> Term
term
Term -> Term * Faktor
Term -> Term / Faktor
Term -> Faktor
factor
Faktor -> + Faktor
Faktor -> - Faktor
Faktor -> ( Ausdruck )
Faktor -> Zahl
number
Zahl -> Ziffer+
*/
// der Parser, ein Klassentemplate
template <typename input_iterator> // z. B. char*
// ent-auskommentieren, sobald es von IntelliSense vollständig unterstützt wird:
class parser //final
{
private:
input_iterator begin;
input_iterator end;
// die tatsächlichen Parse-Funktionen
std::unique_ptr <node> parse_expression ();
std::unique_ptr <node> parse_term ();
std::unique_ptr <node> parse_factor ();
std::unique_ptr <node> parse_unsigned_factor ();
std::unique_ptr <node> parse_number ();
// entfernt die Vorzeichen und gibt die Anzahl der Minus-Vorzeichen zurück
size_t parse_signs ();
public:
parser (input_iterator begin, input_iterator end);
// zum Parsen
std::unique_ptr <node> parse ();
};
template <typename input_iterator>
parser <input_iterator> :: parser (input_iterator begin, input_iterator end)
: begin (begin), end (end) {}
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse () {
return this->parse_expression ();
}
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse_expression () {
std::unique_ptr <node> term = this->parse_term ();
while (this->begin != this->end) {
if (* this->begin == '+') {
++this->begin;
// Gibt es da vielleicht eine einfachere Variante?
term.reset (new addition (std::unique_ptr <node> (std::move (term)), this->parse_term ()));
} else if (* this->begin == '-') {
++this->begin;
term.reset (new subtraction (std::unique_ptr <node> (term.release ()), this->parse_term ()));
} else
break;
}
return term;
}
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse_term () {
std::unique_ptr <node> factor = this->parse_factor ();
while (this->begin != this->end) {
if (* this->begin == '*') {
++this->begin;
factor.reset (new multiplication (std::unique_ptr <node> (factor.release ()), this->parse_factor ()));
} else if (* this->begin == '/') {
++this->begin;
factor.reset (new division (std::unique_ptr <node> (factor.release ()), this->parse_factor ()));
} else
break;
}
return factor;
}
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse_factor () {
if (this->begin == this->end)
throw std::exception ("syntax error, factor expected");
// vertraue dem Compiler, optimieren zu können
if (this->parse_signs () % 2 == 1)
return std::unique_ptr <node> (new negation (this->parse_unsigned_factor ()));
return this->parse_unsigned_factor ();
}
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse_unsigned_factor () {
if (this->begin == this->end)
throw std::exception ("syntax error, unsigned factor expected");
if (* this->begin == '(') {
++this->begin;
auto expression = this->parse_expression ();
if (this->begin == this->end)
throw std::exception ("syntax error, missing ')'");
if (* this->begin != ')')
throw std::exception ("syntax error, ')' expected");
++this->begin;
return expression;
}
return this->parse_number ();
}
// nur natürliche Zahlen werden interpretiert
template <typename input_iterator>
std::unique_ptr <node> parser <input_iterator> :: parse_number () {
if (this->begin == this->end || ! std::isdigit (* this->begin))
throw std::exception ("syntax error, number expected");
double value = 0;
do {
value *= 10;
value += * this->begin++ - '0';
} while (this->begin != this->end && std::isdigit (* this->begin));
return std::unique_ptr <node> (new number (value));
}
template <typename input_iterator>
size_t parser <input_iterator> :: parse_signs () {
size_t count = 0;
while (true) {
if (this->begin == this->end)
throw std::exception ("syntax error, token expected");
if (* this->begin == '+')
++this->begin;
else if (* this->begin == '-') {
++count;
++this->begin;
} else
break;
}
return count;
}
// und jetzt die Funktion, die die Verwendung so schön einfach macht:
template <typename input_iterator>
std::unique_ptr <node> parse (input_iterator begin, input_iterator end) {
return parser <input_iterator> (begin, end).parse ();
}
int main () {
std::string expression;
std::cout << "expression: ";
std::cin >> expression;
try {
auto ast = parse (expression.cbegin (), expression.cend ());
double value = ast->eval ();
std::cout << "value: " << value << '\n';
} catch (std::exception ex) {
std::cout << ex.what () << '\n';
}
// damit cin.get() nicht sofort zurückkehrt
std::cin.ignore (std::numeric_limits <std::streamsize>::max (), '\n');
std::cin.get ();
}
|
|
|
09/13/2013, 02:56
|
#14
|
elite*gold: 0
Join Date: Dec 2012
Posts: 255
Received Thanks: 110
|
Quote:
Code:
throw std::exception ("pure virtual function node::eval called");
|
Den Hinweis mit pure virtual function call bekommst du ohnehin. Da wird abort aufgerufen, zumindest in der VS implementation. Sehr schönes Beispiel!
|
|
|
09/13/2013, 16:42
|
#15
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Quote:
Originally Posted by Master674b
Den Hinweis mit pure virtual function call bekommst du ohnehin. Da wird abort aufgerufen, zumindest in der VS implementation.
|
Und es ist undefiniertes Verhalten. Aber da die Funktion sowieso nie aufgerufen werden sollte und es auch nicht mehr als ein Beispiel ist, und der Aufruf einer rein virtuellen Funktion tatsächlich bestraft werden sollte, ist das in Ordnung. Auch ist mir die Fehlermeldung "pure virtual function call" ein wenig zu... unspezifisch, falls sie mir irgendwann irgendwo als Fehler gemeldet werden sollte.
|
|
|
|
|
Similar Threads
|
[help] new, delete, struct
01/23/2013 - C/C++ - 9 Replies
Well, i have a structure, input and output functions, to get some data, now i would like to make the following:
-the user inputs a number (for which i need a dynamic memory reservation)
-and that number declares how many times the input should loop)
so for example the use puts in 4; it will run the input function 4 times he can tpye in stuff for 4 different companyes or w/e ... same with the output
Here is waht i ahev for now:
|
Struct Allokieren ?
12/08/2012 - C/C++ - 11 Replies
Hallo,
Ich arbeite mich gerade durch das Buch C++ A - Z und bin gerade bei den Structuren, so
jetzt habe ich mir als beispiel ein kleines (Telefon Buch) gemacht ganz simpel (Vorname, Nachname, Geschlecht, Nummer)
Code
#include "stdafx.h"
using namespace std;
|
struct and classes
08/03/2012 - CO2 Programming - 6 Replies
took about 50 pages reading about difference between structs and classes , so i thought it's good idea to sum up this for whoever want to get it with a spoon , feel free to correct or add information
at struct cannot have instance field initializers in structs
struct time
{
private int x = 5; // compile-time error
}
Structs cannot contain explicit parameterless constructors
struct time
{
|
[c++] struct
08/25/2011 - C/C++ - 2 Replies
Kann closed werden. sry
|
Packet Struct's
05/02/2009 - Kal Online - 30 Replies
Mir war langweilig hier nen beispiel wie ihr wie ich finde alles bischen besser aussehn lassen könnt :P
struct PacketsSend
{
DWORD VersionCheck;
DWORD Login;
DWORD Ping;
DWORD Skill;
DWORD Chat;
|
All times are GMT +2. The time now is 04:26.
|
|