Rearranged the server-side object hierarchy (read more)

This has been a long-running problem for days, but I've finally
implemented a correctly working hierarchy between the ClientData,
AccountData and CharacterData objects:

CharacterData -> AccountData -> ClientData

There doesn't seem to be any issues with it right now, touch wood.
This commit is contained in:
Kayne Ruse
2014-05-13 02:09:00 +10:00
parent 01244005e9
commit eeb2400e79
7 changed files with 42 additions and 35 deletions
-1
View File
@@ -31,7 +31,6 @@ struct AccountData {
bool whiteListed = true; bool whiteListed = true;
int clientIndex; int clientIndex;
int characterIndex;
}; };
#endif #endif
+4 -5
View File
@@ -38,7 +38,7 @@ static const char* DELETE_USER_ACCOUNT = "DELETE FROM UserAccounts WHERE uid = ?
//Define the methods //Define the methods
//------------------------- //-------------------------
int ServerApplication::CreateUserAccount(std::string username, int clientIndex, int characterIndex) { int ServerApplication::CreateUserAccount(std::string username, int clientIndex) {
//create this user account, failing if it exists, leave this account in memory //create this user account, failing if it exists, leave this account in memory
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
@@ -62,10 +62,10 @@ int ServerApplication::CreateUserAccount(std::string username, int clientIndex,
sqlite3_finalize(statement); sqlite3_finalize(statement);
//load this account into memory //load this account into memory
return LoadUserAccount(username, clientIndex, characterIndex); return LoadUserAccount(username, clientIndex);
} }
int ServerApplication::LoadUserAccount(std::string username, int clientIndex, int characterIndex) { int ServerApplication::LoadUserAccount(std::string username, int clientIndex) {
//load this user account, failing if it is in memory, creating it if it doesn't exist //load this user account, failing if it is in memory, creating it if it doesn't exist
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
@@ -99,7 +99,6 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex, in
newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.blackListed = sqlite3_column_int(statement, 2);
newAccount.whiteListed = sqlite3_column_int(statement, 3); newAccount.whiteListed = sqlite3_column_int(statement, 3);
newAccount.clientIndex = clientIndex; newAccount.clientIndex = clientIndex;
newAccount.characterIndex = characterIndex;
//finish the routine //finish the routine
sqlite3_finalize(statement); sqlite3_finalize(statement);
@@ -110,7 +109,7 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex, in
if (ret == SQLITE_DONE) { if (ret == SQLITE_DONE) {
//create the non-existant account instead //create the non-existant account instead
return CreateUserAccount(username, clientIndex, characterIndex); return CreateUserAccount(username, clientIndex);
} }
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) ));
-3
View File
@@ -54,9 +54,6 @@ struct CharacterData {
float accuracy = 0.0; float accuracy = 0.0;
float evasion = 0.0; float evasion = 0.0;
float luck = 0.0; float luck = 0.0;
//uid
static int uidCounter;
}; };
#endif #endif
+1
View File
@@ -110,6 +110,7 @@ int ServerApplication::LoadCharacter(int owner, std::string handle, std::string
CharacterData& newChar = characterMap[uid]; CharacterData& newChar = characterMap[uid];
//metadata //metadata
newChar.owner = owner;
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2)); newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3)); newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
//Don't cache the birth //Don't cache the birth
+2 -2
View File
@@ -77,8 +77,8 @@ private:
void PumpPacket(SerialPacket); void PumpPacket(SerialPacket);
//Account management //Account management
int CreateUserAccount(std::string username, int clientIndex, int characterIndex); int CreateUserAccount(std::string username, int clientIndex);
int LoadUserAccount(std::string username, int clientIndex, int characterIndex); int LoadUserAccount(std::string username, int clientIndex);
int SaveUserAccount(int uid); int SaveUserAccount(int uid);
void UnloadUserAccount(int uid); void UnloadUserAccount(int uid);
void DeleteUserAccount(int uid); void DeleteUserAccount(int uid);
+35 -23
View File
@@ -42,29 +42,32 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
} }
void ServerApplication::HandleJoinRequest(SerialPacket packet) { void ServerApplication::HandleJoinRequest(SerialPacket packet) {
//create the new client
ClientData newClient;
newClient.address = packet.meta.srcAddress;
//load the user account //load the user account
int accountIndex = LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter, CharacterData::uidCounter); int accountIndex = LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter);
if (accountIndex < 0) { if (accountIndex < 0) {
//TODO: send rejection packet //TODO: send rejection packet
std::cerr << "Error: Account already loaded: " << accountIndex << std::endl; std::cerr << "Error: Account already loaded: " << accountIndex << std::endl;
return; return;
} }
//create the new client //load the new character
ClientData newClient; int characterIndex = LoadCharacter(accountIndex, packet.clientInfo.handle, packet.clientInfo.avatar);
newClient.address = packet.meta.srcAddress; if (characterIndex < 0) {
//TODO: send rejection packet
//TODO: move this into the character management code std::cerr << "Error: Character already loaded: " << characterIndex << std::endl;
//create the new character UnloadUserAccount(accountIndex);
CharacterData newCharacter; return;
newCharacter.handle = packet.clientInfo.handle; }
newCharacter.avatar = packet.clientInfo.avatar;
//send the client their info //send the client their info
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE; packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
packet.clientInfo.clientIndex = ClientData::uidCounter; packet.clientInfo.clientIndex = ClientData::uidCounter;
packet.clientInfo.accountIndex = accountIndex; packet.clientInfo.accountIndex = accountIndex;
packet.clientInfo.characterIndex = CharacterData::uidCounter; packet.clientInfo.characterIndex = characterIndex;
//bounce this packet //bounce this packet
char buffer[PACKET_BUFFER_SIZE]; char buffer[PACKET_BUFFER_SIZE];
@@ -73,17 +76,16 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) {
//send the new character to all clients //send the new character to all clients
packet.meta.type = SerialPacket::Type::CHARACTER_NEW; packet.meta.type = SerialPacket::Type::CHARACTER_NEW;
packet.characterInfo.characterIndex = CharacterData::uidCounter; packet.characterInfo.characterIndex = characterIndex;
strncpy(packet.characterInfo.handle, newCharacter.handle.c_str(), PACKET_STRING_SIZE); strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE);
strncpy(packet.characterInfo.avatar, newCharacter.avatar.c_str(), PACKET_STRING_SIZE); strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE);
packet.characterInfo.position = newCharacter.position; packet.characterInfo.position = characterMap[characterIndex].position;
packet.characterInfo.motion = newCharacter.motion; packet.characterInfo.motion = characterMap[characterIndex].motion;
PumpPacket(packet); PumpPacket(packet);
//TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?) //TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?)
//finished this routine //finished this routine
clientMap[ClientData::uidCounter++] = newClient; clientMap[ClientData::uidCounter++] = newClient;
characterMap[CharacterData::uidCounter++] = newCharacter;
std::cout << "Connect, total: " << clientMap.size() << std::endl; std::cout << "Connect, total: " << clientMap.size() << std::endl;
} }
@@ -111,26 +113,36 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) {
void ServerApplication::HandleDisconnect(SerialPacket packet) { void ServerApplication::HandleDisconnect(SerialPacket packet) {
//TODO: authenticate who is disconnecting/kicking //TODO: authenticate who is disconnecting/kicking
//TODO: define the difference between unloading and deletng a character //TODO: define the difference between unloading and deleting a character
//forward to the specified client //forward to the specified client
char buffer[PACKET_BUFFER_SIZE]; char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer); serialize(&packet, buffer);
network.Send(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, buffer, PACKET_BUFFER_SIZE); network.Send(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, buffer, PACKET_BUFFER_SIZE);
//delete the client side character //delete the server- and client-side character(s)
SerialPacket delPacket; SerialPacket delPacket;
delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE;
delPacket.characterInfo.characterIndex = accountMap[packet.clientInfo.accountIndex].characterIndex;
PumpPacket(delPacket); for (std::map<int, CharacterData>::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) {
if (it->second.owner == packet.clientInfo.accountIndex) {
delPacket.characterInfo.characterIndex = it->first;
PumpPacket(delPacket);
SaveCharacter(it->first);
it = characterMap.erase(it); //efficient
continue;
}
else {
++it;
}
}
//erase the in-memory stuff //erase the in-memory stuff
clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex); clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex);
characterMap.erase(accountMap[packet.clientInfo.accountIndex].characterIndex);
UnloadUserAccount(packet.clientInfo.accountIndex); UnloadUserAccount(packet.clientInfo.accountIndex);
//finished this routine //finished this routine
std::cout << "Disconnect, total: " << accountMap.size() << std::endl; std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
} }
void ServerApplication::HandleShutdown(SerialPacket packet) { void ServerApplication::HandleShutdown(SerialPacket packet) {
-1
View File
@@ -32,7 +32,6 @@
//------------------------- //-------------------------
int ClientData::uidCounter = 0; int ClientData::uidCounter = 0;
int CharacterData::uidCounter = 0;
//------------------------- //-------------------------
//Define the public members //Define the public members