aboutsummaryrefslogtreecommitdiff
path: root/src/query.cc
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-07-02 13:28:45 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-07-02 13:28:45 -0300
commite782274ade8d7307e157a997d6ac3bcaa4130024 (patch)
tree7999cc2737817db3e4c22bf94236ade6d5dd0d95 /src/query.cc
parentaaf198773fd8e041b0976cc0682e83f8acf394d0 (diff)
downloadgame-e782274ade8d7307e157a997d6ac3bcaa4130024.tar.gz
game-e782274ade8d7307e157a997d6ac3bcaa4130024.zip
`query.cc`
Diffstat (limited to 'src/query.cc')
-rw-r--r--src/query.cc1352
1 files changed, 1352 insertions, 0 deletions
diff --git a/src/query.cc b/src/query.cc
index a31b9b0..5da269d 100644
--- a/src/query.cc
+++ b/src/query.cc
@@ -20,6 +20,8 @@ void SetQueryManagerLoginData(int Type, const char *Data){
}
}
+// TQueryManagerConnection
+// =============================================================================
// TODO(fusion): An initializer list executes in the same order fields are
// declared. This initialization should work as long as `BufferSize` is the
// first field declared in `TQueryManagerConnection`, which it is.
@@ -373,6 +375,8 @@ int TQueryManagerConnection::executeQuery(int Timeout, bool AutoReconnect){
return QUERY_FAILED;
}
+ this->ReadBuffer.Size = ResponseSize;
+ this->ReadBuffer.Position = 0;
int Status = this->getByte();
if(Status == QUERY_FAILED){
error("TQueryManagerConnection::executeQuery: Anfrage fehlgeschlagen.\n");
@@ -381,3 +385,1351 @@ int TQueryManagerConnection::executeQuery(int Timeout, bool AutoReconnect){
return Status;
}
}
+
+int TQueryManagerConnection::checkAccountPassword(uint32 AccountID,
+ const char *Password, const char *IPAddress){
+ this->prepareQuery(10);
+ this->sendQuad(AccountID);
+ this->sendString(Password);
+ this->sendString(IPAddress);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 4){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::checkAccountPassword: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::loginAdmin(uint32 AccountID, bool PrivateWorld,
+ int *NumberOfCharacters, char (*Characters)[30], char (*Worlds)[30],
+ uint8 (*IPAddresses)[4], uint16 *Ports, uint16 *PremiumDaysLeft){
+ this->prepareQuery(12);
+ this->sendQuad(AccountID);
+ this->sendFlag(PrivateWorld);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NumberOfCharacters = this->getByte();
+ for(int i = 0; i < *NumberOfCharacters; i += 1){
+ this->getString(Characters[i], 30);
+ this->getString(Worlds[i], 30);
+ this->getBytes(IPAddresses[i], 4);
+ Ports[i] = this->getWord();
+ }
+ *PremiumDaysLeft = this->getWord();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode == 1){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::loginAdmin: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::loadWorldConfig(int *WorldType, int *RebootTime,
+ int *IPAddress, int *Port, int *MaxPlayers, int *PremiumPlayerBuffer,
+ int *MaxNewbies, int *PremiumNewbieBuffer){
+ this->prepareQuery(53);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *WorldType = this->getByte();
+ *RebootTime = (int)this->getByte() * 60;
+ IPAddress[0] = this->getByte();
+ IPAddress[1] = this->getByte();
+ IPAddress[2] = this->getByte();
+ IPAddress[3] = this->getByte();
+ *Port = this->getWord();
+ *MaxPlayers = this->getWord();
+ *PremiumPlayerBuffer = this->getWord();
+ *MaxNewbies = this->getWord();
+ *PremiumNewbieBuffer = this->getWord();
+ }
+ return Result;
+}
+
+static int GetRightByName(const char *RightName){
+ int Result = -1;
+ if(strcmp(RightName, "PREMIUM_ACCOUNT") == 0){
+ Result = PREMIUM_ACCOUNT;
+ }else if(strcmp(RightName, "NOTATION") == 0){
+ Result = NOTATION;
+ }else if(strcmp(RightName, "NAMELOCK") == 0){
+ Result = NAMELOCK;
+ }else if(strcmp(RightName, "STATEMENT_REPORT") == 0){
+ Result = STATEMENT_REPORT;
+ }else if(strcmp(RightName, "BANISHMENT") == 0){
+ Result = BANISHMENT;
+ }else if(strcmp(RightName, "FINAL_WARNING") == 0){
+ Result = FINAL_WARNING;
+ }else if(strcmp(RightName, "IP_BANISHMENT") == 0){
+ Result = IP_BANISHMENT;
+ }else if(strcmp(RightName, "KICK") == 0){
+ Result = KICK;
+ }else if(strcmp(RightName, "HOME_TELEPORT") == 0){
+ Result = HOME_TELEPORT;
+ }else if(strcmp(RightName, "GAMEMASTER_BROADCAST") == 0){
+ Result = GAMEMASTER_BROADCAST;
+ }else if(strcmp(RightName, "ANONYMOUS_BROADCAST") == 0){
+ Result = ANONYMOUS_BROADCAST;
+ }else if(strcmp(RightName, "NO_BANISHMENT") == 0){
+ Result = NO_BANISHMENT;
+ }else if(strcmp(RightName, "ALLOW_MULTICLIENT") == 0){
+ Result = ALLOW_MULTICLIENT;
+ }else if(strcmp(RightName, "LOG_COMMUNICATION") == 0){
+ Result = LOG_COMMUNICATION;
+ }else if(strcmp(RightName, "READ_GAMEMASTER_CHANNEL") == 0){
+ Result = READ_GAMEMASTER_CHANNEL;
+ }else if(strcmp(RightName, "READ_TUTOR_CHANNEL") == 0){
+ Result = READ_TUTOR_CHANNEL;
+ }else if(strcmp(RightName, "HIGHLIGHT_HELP_CHANNEL") == 0){
+ Result = HIGHLIGHT_HELP_CHANNEL;
+ }else if(strcmp(RightName, "SEND_BUGREPORTS") == 0){
+ Result = SEND_BUGREPORTS;
+ }else if(strcmp(RightName, "NAME_INSULTING") == 0){
+ Result = NAME_INSULTING;
+ }else if(strcmp(RightName, "NAME_SENTENCE") == 0){
+ Result = NAME_SENTENCE;
+ }else if(strcmp(RightName, "NAME_NONSENSICAL_LETTERS") == 0){
+ Result = NAME_NONSENSICAL_LETTERS;
+ }else if(strcmp(RightName, "NAME_BADLY_FORMATTED") == 0){
+ Result = NAME_BADLY_FORMATTED;
+ }else if(strcmp(RightName, "NAME_NO_PERSON") == 0){
+ Result = NAME_NO_PERSON;
+ }else if(strcmp(RightName, "NAME_CELEBRITY") == 0){
+ Result = NAME_CELEBRITY;
+ }else if(strcmp(RightName, "NAME_COUNTRY") == 0){
+ Result = NAME_COUNTRY;
+ }else if(strcmp(RightName, "NAME_FAKE_IDENTITY") == 0){
+ Result = NAME_FAKE_IDENTITY;
+ }else if(strcmp(RightName, "NAME_FAKE_POSITION") == 0){
+ Result = NAME_FAKE_POSITION;
+ }else if(strcmp(RightName, "STATEMENT_INSULTING") == 0){
+ Result = STATEMENT_INSULTING;
+ }else if(strcmp(RightName, "STATEMENT_SPAMMING") == 0){
+ Result = STATEMENT_SPAMMING;
+ }else if(strcmp(RightName, "STATEMENT_ADVERT_OFFTOPIC") == 0){
+ Result = STATEMENT_ADVERT_OFFTOPIC;
+ }else if(strcmp(RightName, "STATEMENT_ADVERT_MONEY") == 0){
+ Result = STATEMENT_ADVERT_MONEY;
+ }else if(strcmp(RightName, "STATEMENT_NON_ENGLISH") == 0){
+ Result = STATEMENT_NON_ENGLISH;
+ }else if(strcmp(RightName, "STATEMENT_CHANNEL_OFFTOPIC") == 0){
+ Result = STATEMENT_CHANNEL_OFFTOPIC;
+ }else if(strcmp(RightName, "STATEMENT_VIOLATION_INCITING") == 0){
+ Result = STATEMENT_VIOLATION_INCITING;
+ }else if(strcmp(RightName, "CHEATING_BUG_ABUSE") == 0){
+ Result = CHEATING_BUG_ABUSE;
+ }else if(strcmp(RightName, "CHEATING_GAME_WEAKNESS") == 0){
+ Result = CHEATING_GAME_WEAKNESS;
+ }else if(strcmp(RightName, "CHEATING_MACRO_USE") == 0){
+ Result = CHEATING_MACRO_USE;
+ }else if(strcmp(RightName, "CHEATING_MODIFIED_CLIENT") == 0){
+ Result = CHEATING_MODIFIED_CLIENT;
+ }else if(strcmp(RightName, "CHEATING_HACKING") == 0){
+ Result = CHEATING_HACKING;
+ }else if(strcmp(RightName, "CHEATING_MULTI_CLIENT") == 0){
+ Result = CHEATING_MULTI_CLIENT;
+ }else if(strcmp(RightName, "CHEATING_ACCOUNT_TRADING") == 0){
+ Result = CHEATING_ACCOUNT_TRADING;
+ }else if(strcmp(RightName, "CHEATING_ACCOUNT_SHARING") == 0){
+ Result = CHEATING_ACCOUNT_SHARING;
+ }else if(strcmp(RightName, "GAMEMASTER_THREATENING") == 0){
+ Result = GAMEMASTER_THREATENING;
+ }else if(strcmp(RightName, "GAMEMASTER_PRETENDING") == 0){
+ Result = GAMEMASTER_PRETENDING;
+ }else if(strcmp(RightName, "GAMEMASTER_INFLUENCE") == 0){
+ Result = GAMEMASTER_INFLUENCE;
+ }else if(strcmp(RightName, "GAMEMASTER_FALSE_REPORTS") == 0){
+ Result = GAMEMASTER_FALSE_REPORTS;
+ }else if(strcmp(RightName, "KILLING_EXCESSIVE_UNJUSTIFIED") == 0){
+ Result = KILLING_EXCESSIVE_UNJUSTIFIED;
+ }else if(strcmp(RightName, "DESTRUCTIVE_BEHAVIOUR") == 0){
+ Result = DESTRUCTIVE_BEHAVIOUR;
+ }else if(strcmp(RightName, "SPOILING_AUCTION") == 0){
+ Result = SPOILING_AUCTION;
+ }else if(strcmp(RightName, "INVALID_PAYMENT") == 0){
+ Result = INVALID_PAYMENT;
+ }else if(strcmp(RightName, "TELEPORT_TO_CHARACTER") == 0){
+ Result = TELEPORT_TO_CHARACTER;
+ }else if(strcmp(RightName, "TELEPORT_TO_MARK") == 0){
+ Result = TELEPORT_TO_MARK;
+ }else if(strcmp(RightName, "TELEPORT_VERTICAL") == 0){
+ Result = TELEPORT_VERTICAL;
+ }else if(strcmp(RightName, "TELEPORT_TO_COORDINATE") == 0){
+ Result = TELEPORT_TO_COORDINATE;
+ }else if(strcmp(RightName, "LEVITATE") == 0){
+ Result = LEVITATE;
+ }else if(strcmp(RightName, "SPECIAL_MOVEUSE") == 0){
+ Result = SPECIAL_MOVEUSE;
+ }else if(strcmp(RightName, "MODIFY_GOSTRENGTH") == 0){
+ Result = MODIFY_GOSTRENGTH;
+ }else if(strcmp(RightName, "SHOW_COORDINATE") == 0){
+ Result = SHOW_COORDINATE;
+ }else if(strcmp(RightName, "RETRIEVE") == 0){
+ Result = RETRIEVE;
+ }else if(strcmp(RightName, "ENTER_HOUSES") == 0){
+ Result = ENTER_HOUSES;
+ }else if(strcmp(RightName, "OPEN_NAMEDOORS") == 0){
+ // TODO(fusion): The actual name was "OPEN_NAMEDDOORS" but could be a typo?
+ // Either way, it doesn't make that much of a difference since there is no
+ // actual query manager outside the ones we might build ourselves.
+ Result = OPEN_NAMEDOORS;
+ }else if(strcmp(RightName, "INVULNERABLE") == 0){
+ Result = INVULNERABLE;
+ }else if(strcmp(RightName, "UNLIMITED_MANA") == 0){
+ Result = UNLIMITED_MANA;
+ }else if(strcmp(RightName, "KEEP_INVENTORY") == 0){
+ Result = KEEP_INVENTORY;
+ }else if(strcmp(RightName, "ALL_SPELLS") == 0){
+ Result = ALL_SPELLS;
+ }else if(strcmp(RightName, "UNLIMITED_CAPACITY") == 0){
+ Result = UNLIMITED_CAPACITY;
+ }else if(strcmp(RightName, "ZERO_CAPACITY") == 0){
+ Result = ZERO_CAPACITY;
+ }else if(strcmp(RightName, "ATTACK_EVERYWHERE") == 0){
+ Result = ATTACK_EVERYWHERE;
+ }else if(strcmp(RightName, "NO_ATTACK") == 0){
+ Result = NO_ATTACK;
+ }else if(strcmp(RightName, "NO_RUNES") == 0){
+ Result = NO_RUNES;
+ }else if(strcmp(RightName, "NO_LOGOUT_BLOCK") == 0){
+ Result = NO_LOGOUT_BLOCK;
+ }else if(strcmp(RightName, "GAMEMASTER_OUTFIT") == 0){
+ Result = GAMEMASTER_OUTFIT;
+ }else if(strcmp(RightName, "ILLUMINATE") == 0){
+ Result = ILLUMINATE;
+ }else if(strcmp(RightName, "CHANGE_PROFESSION") == 0){
+ Result = CHANGE_PROFESSION;
+ }else if(strcmp(RightName, "IGNORED_BY_MONSTERS") == 0){
+ Result = IGNORED_BY_MONSTERS;
+ }else if(strcmp(RightName, "SHOW_KEYHOLE_NUMBERS") == 0){
+ Result = SHOW_KEYHOLE_NUMBERS;
+ }else if(strcmp(RightName, "CREATE_OBJECTS") == 0){
+ Result = CREATE_OBJECTS;
+ }else if(strcmp(RightName, "CREATE_MONEY") == 0){
+ Result = CREATE_MONEY;
+ }else if(strcmp(RightName, "CREATE_MONSTERS") == 0){
+ Result = CREATE_MONSTERS;
+ }else if(strcmp(RightName, "CHANGE_SKILLS") == 0){
+ Result = CHANGE_SKILLS;
+ }else if(strcmp(RightName, "CLEANUP_FIELDS") == 0){
+ Result = CLEANUP_FIELDS;
+ }else if(strcmp(RightName, "NO_STATISTICS") == 0){
+ Result = NO_STATISTICS;
+ }
+ return Result;
+}
+
+// NOTE(fusion): These seem to be related to forums and an admin panel.
+static bool IsAdministrativeRight(const char *RightName){
+ return strcmp(RightName, "CLEAR_CHARACTER_INFO") == 0
+ || strcmp(RightName, "CLEAR_GUILDS") == 0
+ || strcmp(RightName, "DELETE_GUILDS") == 0
+ || strcmp(RightName, "BOARD_REPORT") == 0
+ || strcmp(RightName, "BOARD_MODERATION") == 0
+ || strcmp(RightName, "BOARD_ANONYMOUS_EDIT") == 0
+ || strcmp(RightName, "BOARD_PRECONFIRMED") == 0
+ || strcmp(RightName, "KEEP_ACCOUNT") == 0
+ || strcmp(RightName, "INVITED") == 0
+ || strcmp(RightName, "CIPWATCH_ADMIN") == 0
+ || strcmp(RightName, "CIPWATCH_USER") == 0
+ || strcmp(RightName, "CREATECHAR_GAMEMASTER") == 0
+ || strcmp(RightName, "CREATECHAR_GOD") == 0
+ || strcmp(RightName, "CREATECHAR_TEST") == 0
+ || strcmp(RightName, "VIEW_ACCOUNT") == 0
+ || strcmp(RightName, "VIEW_GAMEMASTER_RECORD") == 0
+ || strcmp(RightName, "VIEW_CRIMINAL_RECORD") == 0
+ || strcmp(RightName, "VIEW_LOG_FILES") == 0
+ || strcmp(RightName, "MODIFY_BANISHMENT") == 0
+ || strcmp(RightName, "APPOINT_CIP") == 0
+ || strcmp(RightName, "APPOINT_SGM") == 0
+ || strcmp(RightName, "APPOINT_JGM") == 0
+ || strcmp(RightName, "APPOINT_SENATOR") == 0
+ || strcmp(RightName, "SET_ACCOUNT_RIGHTS") == 0
+ || strcmp(RightName, "SET_CHARACTER_RIGHTS") == 0
+ || strcmp(RightName, "SET_ACCOUNTGROUP_RIGHTS") == 0
+ || strcmp(RightName, "SET_CHARACTERGROUP_RIGHTS") == 0
+ || strcmp(RightName, "KEEP_CHARACTER") == 0
+ || strcmp(RightName, "EXTRA_CHARACTER") == 0;
+}
+
+// NOTE(fusion): `PlayerName` is an input and output parameter. It will contain
+// the correct player name with upper and lower case letters if the operation is
+// successful.
+int TQueryManagerConnection::loginGame(uint32 AccountID, char *PlayerName,
+ const char *Password, const char *IPAddress, bool PrivateWorld,
+ bool PremiumAccountRequired, bool GamemasterRequired, uint32 *CharacterID,
+ int *Sex, char *Guild, char *Rank, char *Title, int *NumberOfBuddies,
+ uint32 *BuddyIDs, char (*BuddyNames)[30], uint8 *Rights,
+ bool *PremiumAccountActivated){
+ this->prepareQuery(20);
+ this->sendQuad(AccountID);
+ this->sendString(PlayerName);
+ this->sendString(Password);
+ this->sendString(IPAddress);
+ this->sendFlag(PrivateWorld);
+ this->sendFlag(PremiumAccountRequired);
+ this->sendFlag(GamemasterRequired);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *CharacterID = this->getQuad();
+ this->getString(PlayerName, 30);
+ *Sex = this->getByte();
+ this->getString(Guild, 30);
+ this->getString(Rank, 30);
+ this->getString(Title, 30);
+ *NumberOfBuddies = this->getByte();
+
+ int SkipBuddies = 0;
+ if(*NumberOfBuddies > 100){ // MAX_BUDDIES
+ error("TQueryManagerConnection::loginGame: zu viele Buddys (%d) für %s.\n",
+ *NumberOfBuddies, PlayerName);
+ SkipBuddies = *NumberOfBuddies - 100;
+ *NumberOfBuddies = 100;
+ }
+
+ for(int i = 0; i < *NumberOfBuddies; i += 1){
+ BuddyIDs[i] = this->getQuad();
+ this->getString(BuddyNames[i], 30);
+ }
+
+ if(SkipBuddies > 0){
+ char BuddyName[30];
+ for(int i = 0; i < SkipBuddies; i += 1){
+ this->getQuad();
+ this->getString(BuddyName, 30);
+ }
+ }
+
+ int NumberOfRights = this->getByte();
+ for(int i = 0; i < NumberOfRights; i += 1){
+ char RightName[30];
+ this->getString(RightName, 30);
+ int Right = GetRightByName(RightName);
+ if(Right != -1){
+ SetBit(Rights, Right);
+ }else if(!IsAdministrativeRight(RightName)){
+ error("TQueryManagerConnection::loginGame: Unbekanntes Recht %s.\n", RightName);
+ }
+ }
+
+ *PremiumAccountActivated = this->getFlag();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 15){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::loginGame: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::logoutGame(uint32 CharacterID, int Level, const char *Profession,
+ const char *Residence, time_t LastLoginTime, int TutorActivities){
+ this->prepareQuery(21);
+ this->sendQuad(CharacterID);
+ this->sendWord(Level);
+ this->sendString(Profession);
+ this->sendString(Residence);
+ this->sendQuad((uint32)LastLoginTime);
+ this->sendWord((uint16)TutorActivities);
+ int Status = this->executeQuery(120, true);
+ return (Status == QUERY_OK ? 0 : -1);
+}
+
+int TQueryManagerConnection::setNotation(uint32 GamemasterID, const char *PlayerName,
+ const char *IPAddress, const char *Reason, const char *Comment, uint32 *BanishmentID){
+ this->prepareQuery(26);
+ this->sendQuad(GamemasterID);
+ this->sendString(PlayerName);
+ this->sendString(IPAddress);
+ this->sendString(Reason);
+ this->sendString(Comment);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *BanishmentID = this->getQuad();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 2){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::setNotation: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::setNotation: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::setNamelock(uint32 GamemasterID, const char *PlayerName,
+ const char *IPAddress, const char *Reason, const char *Comment){
+ this->prepareQuery(23);
+ this->sendQuad(GamemasterID);
+ this->sendString(PlayerName);
+ this->sendString(IPAddress);
+ this->sendString(Reason);
+ this->sendString(Comment);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 4){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::setNamelock: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else if(Status != QUERY_OK){
+ error("TQueryManagerConnection::setNamelock: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::banishAccount(uint32 GamemasterID, const char *PlayerName,
+ const char *IPAddress, const char *Reason, const char *Comment, bool *FinalWarning,
+ int *Days, uint32 *BanishmentID){
+ this->prepareQuery(25);
+ this->sendQuad(GamemasterID);
+ this->sendString(PlayerName);
+ this->sendString(IPAddress);
+ this->sendString(Reason);
+ this->sendString(Comment);
+ this->sendFlag(*FinalWarning);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *BanishmentID = this->getQuad();
+ *Days = this->getByte();
+ *FinalWarning = this->getFlag();
+ if(*Days == 0xFF){
+ *Days = -1;
+ }
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 3){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::banishAccount: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::banishAccount: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::reportStatement(uint32 ReporterID, const char *PlayerName,
+ const char *Reason, const char *Comment, uint32 BanishmentID, uint32 StatementID,
+ int NumberOfStatements, uint32 *StatementIDs, int *TimeStamps, uint32 *CharacterIDs,
+ const char (*Channels)[30], const char (*Texts)[256]){
+ this->prepareQuery(27);
+ this->sendQuad(ReporterID);
+ this->sendString(PlayerName);
+ this->sendString(Reason);
+ this->sendString(Comment);
+ this->sendQuad(BanishmentID);
+ this->sendQuad(StatementID);
+
+ int NonZeroStatements = 0;
+ for(int i = 0; i < NumberOfStatements; i += 1){
+ if(StatementIDs[i] != 0){
+ NonZeroStatements += 1;
+ }
+ }
+
+ this->sendQuad((uint32)NonZeroStatements);
+ for(int i = 0; i < NumberOfStatements; i += 1){
+ if(StatementIDs[i] != 0){
+ this->sendQuad(StatementIDs[i]);
+ this->sendQuad((uint32)TimeStamps[i]);
+ this->sendQuad(CharacterIDs[i]);
+ this->sendString(Channels[i]);
+ this->sendString(Texts[i]);
+ }
+ }
+
+ int Status = this->executeQuery(180, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 2){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::reportStatement: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else if(Status != QUERY_OK){
+ error("TQueryManagerConnection::reportStatement: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::banishIPAddress(uint32 GamemasterID, const char *PlayerName,
+ const char *IPAddress, const char *Reason, const char *Comment){
+ this->prepareQuery(28);
+ this->sendQuad(GamemasterID);
+ this->sendString(PlayerName);
+ this->sendString(IPAddress);
+ this->sendString(Reason);
+ this->sendString(Comment);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 2){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::banishIPAddress: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else if(Status != QUERY_OK){
+ error("TQueryManagerConnection::banishIPAddress: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::logCharacterDeath(uint32 CharacterID, int Level,
+ uint32 Offender, const char *Remark, bool Unjustified, time_t Time){
+ this->prepareQuery(29);
+ this->sendQuad(CharacterID);
+ this->sendWord((uint16)Level);
+ this->sendQuad(Offender);
+ this->sendString(Remark);
+ this->sendFlag(Unjustified);
+ this->sendQuad((uint32)Time);
+ int Status = this->executeQuery(90, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::logCharacterDeath: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::addBuddy(uint32 AccountID, uint32 Buddy){
+ this->prepareQuery(30);
+ this->sendQuad(AccountID);
+ this->sendQuad(Buddy);
+ int Status = this->executeQuery(90, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::addBuddy: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::removeBuddy(uint32 AccountID, uint32 Buddy){
+ this->prepareQuery(31);
+ this->sendQuad(AccountID);
+ this->sendQuad(Buddy);
+ int Status = this->executeQuery(90, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::removeBuddy: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::decrementIsOnline(uint32 CharacterID){
+ this->prepareQuery(32);
+ this->sendQuad(CharacterID);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::decrementIsOnline: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::finishAuctions(int *NumberOfAuctions, uint16 *HouseIDs,
+ uint32 *CharacterIDs, char (*CharacterNames)[30], int *Bids){
+ this->prepareQuery(33);
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfAuctions = *NumberOfAuctions;
+ *NumberOfAuctions = this->getWord();
+ if(*NumberOfAuctions > MaxNumberOfAuctions){
+ error("TQueryManagerConnection::finishAuctions: zu viele Auktionen (%d>%d).\n",
+ *NumberOfAuctions, MaxNumberOfAuctions);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfAuctions; i += 1){
+ HouseIDs[i] = this->getWord();
+ CharacterIDs[i] = this->getQuad();
+ this->getString(CharacterNames[i], 30);
+ Bids[i] = (int)this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::finishAuctions: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::excludeFromAuctions(uint32 CharacterID, bool Banish){
+ this->prepareQuery(51);
+ this->sendQuad(CharacterID);
+ this->sendFlag(Banish);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::excludeFromAuctions: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::transferHouses(int *NumberOfTransfers, uint16 *HouseIDs,
+ uint32 *NewOwnerIDs, char (*NewOwnerNames)[30], int *Prices){
+ this->prepareQuery(35);
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfTransfers = *NumberOfTransfers;
+ *NumberOfTransfers = this->getWord();
+ if(*NumberOfTransfers > MaxNumberOfTransfers){
+ error("TQueryManagerConnection::transferHouses: zu viele Transfers (%d>%d).\n",
+ *NumberOfTransfers, MaxNumberOfTransfers);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfTransfers; i += 1){
+ HouseIDs[i] = this->getWord();
+ NewOwnerIDs[i] = this->getQuad();
+ this->getString(NewOwnerNames[i], 30);
+ Prices[i] = (int)this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::transferHouses: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::cancelHouseTransfer(uint16 HouseID){
+ this->prepareQuery(52);
+ this->sendWord(HouseID);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::cancelHouseTransfer: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::evictFreeAccounts(int *NumberOfEvictions,
+ uint16 *HouseIDs, uint32 *OwnerIDs){
+ this->prepareQuery(36);
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfEvictions = *NumberOfEvictions;
+ *NumberOfEvictions = this->getWord();
+ if(*NumberOfEvictions > MaxNumberOfEvictions){
+ error("TQueryManagerConnection::evictFreeAccounts: zu viele Räumungen (%d>%d).\n",
+ *NumberOfEvictions, MaxNumberOfEvictions);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfEvictions; i += 1){
+ HouseIDs[i] = this->getWord();
+ OwnerIDs[i] = this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::evictFreeAccounts: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::evictDeletedCharacters(int *NumberOfEvictions, uint16 *HouseIDs){
+ this->prepareQuery(37);
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfEvictions = *NumberOfEvictions;
+ *NumberOfEvictions = this->getWord();
+ if(*NumberOfEvictions > MaxNumberOfEvictions){
+ error("TQueryManagerConnection::evictDeletedCharacters: zu viele Räumungen (%d>%d).\n",
+ *NumberOfEvictions, MaxNumberOfEvictions);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfEvictions; i += 1){
+ HouseIDs[i] = this->getWord();
+ }
+ }else{
+ error("TQueryManagerConnection::evictDeletedCharacters: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::evictExGuildleaders(int NumberOfGuildhouses,
+ int *NumberOfEvictions, uint16 *HouseIDs, uint32 *Guildleaders){
+ this->prepareQuery(38);
+
+ this->sendWord((uint16)NumberOfGuildhouses);
+ for(int i = 0; i < NumberOfGuildhouses; i += 1){
+ this->sendWord(HouseIDs[i]);
+ this->sendQuad(Guildleaders[i]);
+ }
+
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NumberOfEvictions = this->getWord();
+ for(int i = 0; i < *NumberOfEvictions; i += 1){
+ HouseIDs[i] = this->getWord();
+ }
+ }else{
+ error("TQueryManagerConnection::evictExGuildleaders: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::insertHouseOwner(uint16 HouseID, uint32 OwnerID, int PaidUntil){
+ this->prepareQuery(39);
+ this->sendWord(HouseID);
+ this->sendQuad(OwnerID);
+ this->sendQuad((uint32)PaidUntil);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::insertHouseOwner: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::updateHouseOwner(uint16 HouseID, uint32 OwnerID, int PaidUntil){
+ this->prepareQuery(40);
+ this->sendWord(HouseID);
+ this->sendQuad(OwnerID);
+ this->sendQuad((uint32)PaidUntil);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::updateHouseOwner: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::deleteHouseOwner(uint16 HouseID){
+ this->prepareQuery(41);
+ this->sendWord(HouseID);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::deleteHouseOwner: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getHouseOwners(int *NumberOfOwners, uint16 *HouseIDs,
+ uint32 *OwnerIDs, char (*OwnerNames)[30], int *PaidUntils){
+ this->prepareQuery(42);
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfOwners = *NumberOfOwners;
+ *NumberOfOwners = this->getWord();
+ if(*NumberOfOwners > MaxNumberOfOwners){
+ error("TQueryManagerConnection::getHouseOwners: zu viele Häuser (%d>%d).\n",
+ *NumberOfOwners, MaxNumberOfOwners);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfOwners; i += 1){
+ HouseIDs[i] = this->getWord();
+ OwnerIDs[i] = this->getQuad();
+ this->getString(OwnerNames[i], 30);
+ PaidUntils[i] = (int)this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::getHouseOwners: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getAuctions(int *NumberOfAuctions, uint16 *HouseIDs){
+ this->prepareQuery(43);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ int MaxNumberOfAuctions = *NumberOfAuctions;
+ *NumberOfAuctions = this->getWord();
+ if(*NumberOfAuctions > MaxNumberOfAuctions){
+ error("TQueryManagerConnection::getAuctions: zu viele Auktionen (%d>%d).\n",
+ *NumberOfAuctions, MaxNumberOfAuctions);
+ return -1;
+ }
+
+ for(int i = 0; i < *NumberOfAuctions; i += 1){
+ HouseIDs[i] = this->getWord();
+ }
+ }else{
+ error("TQueryManagerConnection::getAuctions: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::startAuction(uint16 HouseID){
+ this->prepareQuery(44);
+ this->sendWord(HouseID);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::startAuction: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::insertHouses(int NumberOfHouses, uint16 *HouseIDs,
+ const char **Names, int *Rents, const char **Descriptions, int *Sizes,
+ int *PositionsX,int *PositionsY,int *PositionsZ, char (*Towns)[30],
+ bool *Guildhouses){
+ this->prepareQuery(45);
+
+ this->sendWord(NumberOfHouses);
+ for(int i = 0; i < NumberOfHouses; i += 1){
+ this->sendWord(HouseIDs[i]);
+ this->sendString(Names[i]);
+ this->sendQuad((int)Rents[i]);
+ this->sendString(Descriptions[i]);
+ this->sendWord((uint16)Sizes[i]);
+ this->sendWord((uint16)PositionsX[i]);
+ this->sendWord((uint16)PositionsY[i]);
+ this->sendByte((uint8)PositionsZ[i]);
+ this->sendString(Towns[i]);
+ this->sendFlag(Guildhouses[i]);
+ }
+
+ int Status = this->executeQuery(60, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::insertHouses: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::clearIsOnline(int *NumberOfAffectedPlayers){
+ this->prepareQuery(46);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NumberOfAffectedPlayers = this->getWord();
+ }else{
+ error("TQueryManagerConnection::clearIsOnline: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::createPlayerlist(int NumberOfPlayers, const char **Names,
+ int *Levels, const char (*Professions)[30], bool *NewRecord){
+ this->prepareQuery(47);
+
+ if(NumberOfPlayers >= 0){
+ this->sendWord((uint16)NumberOfPlayers);
+ for(int i = 0; i < NumberOfPlayers; i += 1){
+ this->sendString(Names[i]);
+ this->sendWord((uint16)Levels[i]);
+ this->sendString(Professions[i]);
+ }
+ }else{
+ this->sendWord(0xFFFF);
+ }
+
+ int Status = this->executeQuery(240, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NewRecord = this->getFlag();
+ }else{
+ error("TQueryManagerConnection::createPlayerlist: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::logKilledCreatures(int NumberOfRaces, const char **Names,
+ int *KilledPlayers,int *KilledCreatures){
+ this->prepareQuery(48);
+
+ this->sendWord((uint16)NumberOfRaces);
+ for(int i = 0; i < NumberOfRaces; i += 1){
+ this->sendString(Names[i]);
+ this->sendQuad((uint32)KilledPlayers[i]);
+ this->sendQuad((uint32)KilledCreatures[i]);
+ }
+
+ int Status = this->executeQuery(240, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::logKilledCreatures: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::loadPlayers(uint32 MinimumCharacterID, int *NumberOfPlayers,
+ char (*Names)[30], uint32 *CharacterIDs){
+ this->prepareQuery(50);
+ this->sendQuad(MinimumCharacterID);
+ int Status = this->executeQuery(900, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ // TODO(fusion): This is called to fill the player index in `InitPlayerIndex`
+ // but there is no explicit parameter that limits how many results are returned
+ // which could be a problem.
+ *NumberOfPlayers = (int)this->getQuad();
+ for(int i = 0; i < *NumberOfPlayers; i += 1){
+ this->getString(Names[i], 30);
+ CharacterIDs[i] = this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::loadPlayers: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getKeptCharacters(uint32 MinimumCharacterID,
+ int *NumberOfPlayers, uint32 *CharacterIDs){
+ this->prepareQuery(200);
+ this->sendQuad(MinimumCharacterID);
+ int Status = this->executeQuery(1800, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ // TODO(fusion): Same as `loadPlayers`.
+ *NumberOfPlayers = (int)this->getQuad();
+ for(int i = 0; i < *NumberOfPlayers; i += 1){
+ CharacterIDs[i] = this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::getKeptCharacters: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getDeletedCharacters(uint32 MinimumCharacterID,
+ int *NumberOfPlayers, uint32 *CharacterIDs){
+ this->prepareQuery(201);
+ this->sendQuad(MinimumCharacterID);
+ int Status = this->executeQuery(900, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ // TODO(fusion): Same as `loadPlayers`.
+ *NumberOfPlayers = (int)this->getQuad();
+ for(int i = 0; i < *NumberOfPlayers; i += 1){
+ CharacterIDs[i] = this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::getKeptCharacters: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::deleteOldCharacter(uint32 CharacterID){
+ this->prepareQuery(202);
+ this->sendQuad(CharacterID);
+ int Status = this->executeQuery(30, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::deleteOldCharacter: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getHiddenCharacters(uint32 MinimumCharacterID,
+ int *NumberOfPlayers, uint32 *CharacterIDs){
+ this->prepareQuery(203);
+ this->sendQuad(MinimumCharacterID);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ // TODO(fusion): Same as `loadPlayers`.
+ *NumberOfPlayers = (int)this->getQuad();
+ for(int i = 0; i < *NumberOfPlayers; i += 1){
+ CharacterIDs[i] = this->getQuad();
+ }
+ }else{
+ error("TQueryManagerConnection::getHiddenCharacters: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::createHighscores(int NumberOfPlayers, uint32 *CharacterIDs,
+ int *ExpPoints, int *ExpLevel, int *Fist, int *Club, int *Axe,
+ int *Sword, int *Distance, int *Shielding, int *Magic, int *Fishing){
+ this->prepareQuery(204);
+
+ this->sendQuad((uint32)NumberOfPlayers);
+ for(int i = 0; i < NumberOfPlayers; i += 1){
+ this->sendQuad(CharacterIDs[i]);
+ this->sendQuad((uint32)ExpPoints[i]);
+ this->sendWord((uint16)ExpLevel[i]);
+ this->sendWord((uint16)Fist[i]);
+ this->sendWord((uint16)Club[i]);
+ this->sendWord((uint16)Axe[i]);
+ this->sendWord((uint16)Sword[i]);
+ this->sendWord((uint16)Distance[i]);
+ this->sendWord((uint16)Shielding[i]);
+ this->sendWord((uint16)Magic[i]);
+ this->sendWord((uint16)Fishing[i]);
+ }
+
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::createHighscores: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::createCensus(void){
+ this->prepareQuery(205);
+ int Status = this->executeQuery(600, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::createCensus: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::createKillStatistics(void){
+ this->prepareQuery(206);
+ int Status = this->executeQuery(300, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status != QUERY_OK){
+ error("TQueryManagerConnection::createKillStatistics: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getPlayersOnline(int *NumberOfWorlds, char (*Names)[30], uint16 *Players){
+ this->prepareQuery(207);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NumberOfWorlds = this->getByte();
+ for(int i = 0; i < *NumberOfWorlds; i += 1){
+ this->getString(Names[i], 30);
+ Players[i] = this->getWord();
+ }
+ }else{
+ error("TQueryManagerConnection::getPlayersOnline: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getWorlds(int *NumberOfWorlds, char (*Names)[30]){
+ this->prepareQuery(208);
+ int Status = this->executeQuery(120, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *NumberOfWorlds = this->getByte();
+ for(int i = 0; i < *NumberOfWorlds; i += 1){
+ this->getString(Names[i], 30);
+ }
+ }else{
+ error("TQueryManagerConnection::getWorlds: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::getServerLoad(const char *World, int Period, int *Data){
+ this->prepareQuery(209);
+ this->sendString(World);
+ this->sendByte((uint8)Period);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ // TODO(fusion): Another hardcoded constant?
+ for(int i = 0; i < 600; i += 0){
+ Data[i] = this->getWord();
+ if(Data[i] == 0xFFFF){
+ Data[i] = -1;
+ }
+ }
+ }else{
+ error("TQueryManagerConnection::getServerLoad: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::insertPaymentDataOld(uint32 PurchaseNr, uint32 ReferenceNr,
+ const char *FirstName, const char *LastName, const char *Company,
+ const char *Street, const char *Zip, const char *City, const char *Country,
+ const char *State, const char *Phone, const char *Fax, const char *EMail,
+ const char *PaymentMethod, uint32 ProductID, const char *Registrant,
+ uint32 AccountID, uint32 *PaymentID){
+ this->prepareQuery(210);
+ this->sendQuad(PurchaseNr);
+ this->sendQuad(ReferenceNr);
+ this->sendString(FirstName);
+ this->sendString(LastName);
+ this->sendString(Company);
+ this->sendString(Street);
+ this->sendString(Zip);
+ this->sendString(City);
+ this->sendString(Country);
+ this->sendString(State);
+ this->sendString(Phone);
+ this->sendString(Fax);
+ this->sendString(EMail);
+ this->sendString(PaymentMethod);
+ this->sendQuad(ProductID);
+ this->sendString(Registrant);
+ this->sendQuad(AccountID);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *PaymentID = this->getQuad();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode == 1){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::insertPaymentDataOld: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::insertPaymentDataOld: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::addPaymentOld(uint32 AccountID, const char *Description,
+ uint32 PaymentID, int Days, int *ActionTaken){
+ this->prepareQuery(211);
+ this->sendQuad(AccountID);
+ this->sendString(Description);
+ this->sendQuad(PaymentID);
+ this->sendWord((uint16)Days);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *ActionTaken = this->getByte();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 2){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::addPaymentOld: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::addPaymentOld: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::cancelPaymentOld(uint32 PurchaseNr, uint32 ReferenceNr,
+ uint32 AccountID, bool *IllegalUse, char *EMailAddress){
+ this->prepareQuery(212);
+ this->sendQuad(PurchaseNr);
+ this->sendQuad(ReferenceNr);
+ this->sendQuad(AccountID);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *IllegalUse = this->getFlag();
+ this->getString(EMailAddress, 50);
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 2){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::cancelPaymentOld: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::cancelPaymentOld: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::insertPaymentDataNew(uint32 PurchaseNr, uint32 ReferenceNr,
+ const char *FirstName, const char *LastName, const char *Company,
+ const char *Street, const char *Zip, const char *City, const char *Country,
+ const char *State, const char *Phone, const char *Fax, const char *EMail,
+ const char *PaymentMethod, uint32 ProductID, const char *Registrant,
+ const char *PaymentKey, uint32 *PaymentID){
+ this->prepareQuery(213);
+ this->sendWord(PurchaseNr);
+ this->sendWord(ReferenceNr);
+ this->sendString(FirstName);
+ this->sendString(LastName);
+ this->sendString(Company);
+ this->sendString(Street);
+ this->sendString(Zip);
+ this->sendString(City);
+ this->sendString(Country);
+ this->sendString(State);
+ this->sendString(Phone);
+ this->sendString(Fax);
+ this->sendString(EMail);
+ this->sendString(PaymentMethod);
+ this->sendWord(ProductID);
+ this->sendString(Registrant);
+ this->sendString(PaymentKey);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *PaymentID = this->getQuad();
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode == 1){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::insertPaymentDataNew: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::insertPaymentDataNew: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::addPaymentNew(const char *PaymentKey, uint32 PaymentID,
+ int *ActionTaken, char *EMailReceiver){
+ this->prepareQuery(214);
+ this->sendString(PaymentKey);
+ this->sendQuad(PaymentID);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *ActionTaken = this->getByte();
+ if(*ActionTaken == 5){
+ this->getString(EMailReceiver, 100);
+ }
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode >= 1 && ErrorCode <= 3){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::addPaymentNew: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::addPaymentNew: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+int TQueryManagerConnection::cancelPaymentNew(uint32 PurchaseNr, uint32 ReferenceNr,
+ const char *PaymentKey, bool *IllegalUse, bool *Present, char *EMailAddress){
+ this->prepareQuery(215);
+ this->sendQuad(PurchaseNr);
+ this->sendQuad(ReferenceNr);
+ this->sendString(PaymentKey);
+ int Status = this->executeQuery(360, true);
+ int Result = (Status == QUERY_OK ? 0 : -1);
+ if(Status == QUERY_OK){
+ *IllegalUse = this->getFlag();
+ *Present = this->getFlag();
+ this->getString(EMailAddress, 50);
+ }else if(Status == QUERY_ERROR){
+ int ErrorCode = this->getByte();
+ if(ErrorCode == 1){
+ Result = ErrorCode;
+ }else{
+ error("TQueryManagerConnection::cancelPaymentNew: Ungültiger Fehlercode %d.\n", ErrorCode);
+ }
+ }else{
+ error("TQueryManagerConnection::cancelPaymentNew: Anfrage fehlgeschlagen.\n");
+ }
+ return Result;
+}
+
+// TQueryManagerConnectionPool
+// =============================================================================
+// TODO(fusion): Same as `TQueryManagerConnection::TQueryManagerConnection`.
+TQueryManagerConnectionPool::TQueryManagerConnectionPool(int Connections) :
+ NumberOfConnections(std::max<int>(Connections, 1)),
+ QueryManagerConnection(NULL),
+ QueryManagerConnectionFree(NULL),
+ FreeQueryManagerConnections(this->NumberOfConnections),
+ QueryManagerConnectionMutex(1)
+{
+ if(Connections <= 0){
+ error("TQueryManagerConnectionPool::TQueryManagerConnectionPool:"
+ " Ungültige Verbindungsanzahl %d.\n", Connections);
+ }
+}
+
+void TQueryManagerConnectionPool::init(void){
+ this->QueryManagerConnection = new TQueryManagerConnection[this->NumberOfConnections];
+ this->QueryManagerConnectionFree = new bool[this->NumberOfConnections];
+ for(int i = 0; i < this->NumberOfConnections; i += 1){
+ if(!this->QueryManagerConnection[i].isConnected()){
+ error("TQueryManagerConnectionPool::init: Kann nicht zum Query-Manager verbinden.\n");
+ throw "cannot connect to query manager";
+ }
+
+ this->QueryManagerConnectionFree[i] = true;
+ }
+}
+
+void TQueryManagerConnectionPool::exit(void){
+ for(int i = 0; i < this->NumberOfConnections; i += 1){
+ this->FreeQueryManagerConnections.down();
+ }
+
+ delete[] this->QueryManagerConnection;
+ delete[] this->QueryManagerConnectionFree;
+}
+
+TQueryManagerConnection *TQueryManagerConnectionPool::getConnection(void){
+ int ConnectionIndex = -1;
+ this->FreeQueryManagerConnections.down();
+ this->QueryManagerConnectionMutex.down();
+ for(int i = 0; i < this->NumberOfConnections; i += 1){
+ if(this->QueryManagerConnectionFree[i]){
+ this->QueryManagerConnectionFree[i] = false;
+ ConnectionIndex = i;
+ break;
+ }
+ }
+ this->QueryManagerConnectionMutex.up();
+
+ if(ConnectionIndex == -1){
+ error("TQueryManagerConnectionPool::getConnection: Keine freie Verbindung gefunden.\n");
+ return NULL;
+ }
+
+ return &this->QueryManagerConnection[ConnectionIndex];
+}
+
+void TQueryManagerConnectionPool::releaseConnection(TQueryManagerConnection *Connection){
+ int ConnectionIndex = -1;
+ for(int i = 0; i < this->NumberOfConnections; i += 1){
+ if(&this->QueryManagerConnection[i] == Connection){
+ ConnectionIndex = i;
+ break;
+ }
+ }
+
+ if(ConnectionIndex == -1){
+ error("TQueryManagerConnectionPool::releaseConnection: Verbindung nicht gefunden.\n");
+ return;
+ }
+
+ this->QueryManagerConnectionFree[ConnectionIndex] = true;
+ this->FreeQueryManagerConnections.up();
+}
+
+// TQueryManagerPoolConnection
+// =============================================================================
+TQueryManagerPoolConnection::TQueryManagerPoolConnection(TQueryManagerConnectionPool *Pool) :
+ QueryManagerConnectionPool(Pool),
+ QueryManagerConnection(NULL)
+{
+ if(this->QueryManagerConnectionPool == NULL){
+ error("TQueryManagerPoolConnection::TQueryManagerPoolConnection: Pool ist NULL.\n");
+ return;
+ }
+
+ this->QueryManagerConnection = this->QueryManagerConnectionPool->getConnection();
+}
+
+TQueryManagerPoolConnection::~TQueryManagerPoolConnection(void){
+ if(this->QueryManagerConnection != NULL){
+ ASSERT(this->QueryManagerConnectionPool != NULL);
+ this->QueryManagerConnectionPool->releaseConnection(this->QueryManagerConnection);
+ }
+}