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:
@@ -31,7 +31,6 @@ struct AccountData {
|
|||||||
bool whiteListed = true;
|
bool whiteListed = true;
|
||||||
|
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
int characterIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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) ));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
int ClientData::uidCounter = 0;
|
int ClientData::uidCounter = 0;
|
||||||
int CharacterData::uidCounter = 0;
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Define the public members
|
//Define the public members
|
||||||
|
|||||||
Reference in New Issue
Block a user