The server builds using the new packet types; incomplete

Most of this was achieved by dummying out calls in HandlePacket(), so the
server's actual logic is incomplete.
This commit is contained in:
Kayne Ruse
2014-11-09 23:15:09 +11:00
parent 3b9df46510
commit a1c20959fe
6 changed files with 193 additions and 105 deletions
+23 -16
View File
@@ -27,6 +27,7 @@
* valid data, but it will still be carried in that packet's format. * valid data, but it will still be carried in that packet's format.
*/ */
//TODO: This needs to be smoothed out
enum class SerialPacketType { enum class SerialPacketType {
//default: there is something wrong //default: there is something wrong
NONE = 0, NONE = 0,
@@ -57,6 +58,14 @@ enum class SerialPacketType {
DISCONNECT_REQUEST, DISCONNECT_REQUEST,
DISCONNECT_FORCED, DISCONNECT_FORCED,
//load the account
LOGIN_REQUEST,
LOGIN_RESPONSE,
//unload the account
LOGOUT_REQUEST,
LOGOUT_RESPONSE,
//shut down the server //shut down the server
SHUTDOWN_REQUEST, SHUTDOWN_REQUEST,
@@ -66,7 +75,7 @@ enum class SerialPacketType {
//------------------------- //-------------------------
//map data //map data
REGION_REQUEST, REGION_REQUEST, //NOTE: technically a query
REGION_CONTENT, REGION_CONTENT,
//------------------------- //-------------------------
@@ -78,25 +87,23 @@ enum class SerialPacketType {
// statistics // statistics
//------------------------- //-------------------------
//all stats
CHARACTER_STATS_REQUEST,
CHARACTER_STATS_RESPONSE,
//character management //character management
//NOTE: The server sends create & delete messages to the clients, but the clients... don't? CHARACTER_CREATE,
CHARACTER_CREATE CHARACTER_DELETE,
CHARACTER_DELETE CHARACTER_LOAD,
CHARACTER_LOAD CHARACTER_UNLOAD,
CHARACTER_UNLOAD
//find out info from the server //find out info from the server
CHARACTER_QUERY_EXISTS QUERY_CHARACTER_EXISTS,
CHARACTER_QUERY_LOCATION QUERY_CHARACTER_STATS,
QUERY_CHARACTER_LOCATION,
//set the info in the server //set the info in the server
CHARACTER_SET_ROOM CHARACTER_SET_ROOM,
CHARACTER_SET_ORIGIN CHARACTER_SET_ORIGIN,
CHARACTER_SET_MOTION CHARACTER_SET_MOTION,
//TODO: enemy management
//------------------------- //-------------------------
//TextPacket //TextPacket
@@ -107,9 +114,9 @@ enum class SerialPacketType {
TEXT_BROADCAST, TEXT_BROADCAST,
//rejection/error messages //rejection/error messages
SHUTDOWN_REJECTION,
JOIN_REJECTION, JOIN_REJECTION,
CHARACTER_REJECTION, CHARACTER_REJECTION,
SHUTDOWN_REJECTION,
//------------------------- //-------------------------
//not used //not used
+35 -17
View File
@@ -54,26 +54,35 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
break; break;
case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE: case SerialPacketType::DISCONNECT_REQUEST:
case SerialPacketType::DISCONNECT: case SerialPacketType::DISCONNECT_FORCED:
case SerialPacketType::SHUTDOWN: case SerialPacketType::LOGIN_REQUEST:
case SerialPacketType::LOGIN_RESPONSE:
case SerialPacketType::LOGOUT_REQUEST:
case SerialPacketType::LOGOUT_RESPONSE:
case SerialPacketType::SHUTDOWN_REQUEST:
serializeClient(buffer, static_cast<ClientPacket*>(packet)); serializeClient(buffer, static_cast<ClientPacket*>(packet));
break; break;
case SerialPacketType::REGION_REQUEST: case SerialPacketType::REGION_REQUEST:
case SerialPacketType::REGION_CONTENT: case SerialPacketType::REGION_CONTENT:
serializeRegion(buffer, static_cast<RegionPacket*>(packet)); serializeRegion(buffer, static_cast<RegionPacket*>(packet));
break; break;
case SerialPacketType::CHARACTER_NEW: case SerialPacketType::CHARACTER_CREATE:
case SerialPacketType::CHARACTER_DELETE: case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_LOAD:
case SerialPacketType::CHARACTER_STATS_REQUEST: case SerialPacketType::CHARACTER_UNLOAD:
case SerialPacketType::CHARACTER_STATS_RESPONSE: case SerialPacketType::QUERY_CHARACTER_EXISTS:
case SerialPacketType::QUERY_CHARACTER_STATS:
case SerialPacketType::QUERY_CHARACTER_LOCATION:
case SerialPacketType::CHARACTER_SET_ROOM:
case SerialPacketType::CHARACTER_SET_ORIGIN:
case SerialPacketType::CHARACTER_SET_MOTION:
serializeCharacter(buffer, static_cast<CharacterPacket*>(packet)); serializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
break; break;
case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::TEXT_BROADCAST:
case SerialPacketType::JOIN_REJECTION: case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
serializeText(buffer, static_cast<TextPacket*>(packet)); serializeText(buffer, static_cast<TextPacket*>(packet));
break; break;
} }
@@ -84,7 +93,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
SerialPacketType type; SerialPacketType type;
memcpy(&type, buffer, sizeof(SerialPacketType)); memcpy(&type, buffer, sizeof(SerialPacketType));
switch(type) { switch(packet->type) {
case SerialPacketType::PING: case SerialPacketType::PING:
case SerialPacketType::PONG: case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST: case SerialPacketType::BROADCAST_REQUEST:
@@ -93,26 +102,35 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
break; break;
case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE: case SerialPacketType::DISCONNECT_REQUEST:
case SerialPacketType::DISCONNECT: case SerialPacketType::DISCONNECT_FORCED:
case SerialPacketType::SHUTDOWN: case SerialPacketType::LOGIN_REQUEST:
case SerialPacketType::LOGIN_RESPONSE:
case SerialPacketType::LOGOUT_REQUEST:
case SerialPacketType::LOGOUT_RESPONSE:
case SerialPacketType::SHUTDOWN_REQUEST:
deserializeClient(buffer, static_cast<ClientPacket*>(packet)); deserializeClient(buffer, static_cast<ClientPacket*>(packet));
break; break;
case SerialPacketType::REGION_REQUEST: case SerialPacketType::REGION_REQUEST:
case SerialPacketType::REGION_CONTENT: case SerialPacketType::REGION_CONTENT:
deserializeRegion(buffer, static_cast<RegionPacket*>(packet)); deserializeRegion(buffer, static_cast<RegionPacket*>(packet));
break; break;
case SerialPacketType::CHARACTER_NEW: case SerialPacketType::CHARACTER_CREATE:
case SerialPacketType::CHARACTER_DELETE: case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_LOAD:
case SerialPacketType::CHARACTER_STATS_REQUEST: case SerialPacketType::CHARACTER_UNLOAD:
case SerialPacketType::CHARACTER_STATS_RESPONSE: case SerialPacketType::QUERY_CHARACTER_EXISTS:
case SerialPacketType::QUERY_CHARACTER_STATS:
case SerialPacketType::QUERY_CHARACTER_LOCATION:
case SerialPacketType::CHARACTER_SET_ROOM:
case SerialPacketType::CHARACTER_SET_ORIGIN:
case SerialPacketType::CHARACTER_SET_MOTION:
deserializeCharacter(buffer, static_cast<CharacterPacket*>(packet)); deserializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
break; break;
case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::TEXT_BROADCAST:
case SerialPacketType::JOIN_REJECTION: case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::SHUTDOWN_REJECTION:
deserializeText(buffer, static_cast<TextPacket*>(packet)); deserializeText(buffer, static_cast<TextPacket*>(packet));
break; break;
} }
+1 -1
View File
@@ -40,7 +40,7 @@ static const luaL_Reg libs[] = {
{nullptr, nullptr} {nullptr, nullptr}
}; };
int openMapSystemAPI(lua_State* L) { int openRoomSystemAPI(lua_State* L) {
//create the table //create the table
luaL_newlibtable(L, libs); luaL_newlibtable(L, libs);
+11
View File
@@ -98,6 +98,17 @@ private:
sqlite3* database = nullptr; sqlite3* database = nullptr;
lua_State* luaState = nullptr; lua_State* luaState = nullptr;
//ugly references; I hate this
AccountManager& accountMgr = AccountManager::GetSingleton();
CharacterManager& characterMgr = CharacterManager::GetSingleton();
ClientManager& clientMgr = ClientManager::GetSingleton();
DoorManager& doorMgr = DoorManager::GetSingleton();
MonsterManager& monsterMgr = MonsterManager::GetSingleton();
RoomManager& roomMgr = RoomManager::GetSingleton();
ConfigUtility& config = ConfigUtility::GetSingleton();
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
//misc //misc
bool running = true; bool running = true;
}; };
+90 -40
View File
@@ -43,7 +43,6 @@ void ServerApplication::Init(int argc, char* argv[]) {
std::cout << "Beginning " << argv[0] << std::endl; std::cout << "Beginning " << argv[0] << std::endl;
//load the config settings //load the config settings
ConfigUtility& config = ConfigUtility::GetSingleton();
config.Load("rsc/config.cfg", argc, argv); config.Load("rsc/config.cfg", argc, argv);
//------------------------- //-------------------------
@@ -60,7 +59,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
if (SDLNet_Init()) { if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net")); throw(std::runtime_error("Failed to initialize SDL_net"));
} }
UDPNetworkUtility::GetSingleton().Open(config.Int("server.port")); network.Open(config.Int("server.port"));
std::cout << "Initialized SDL_net" << std::endl; std::cout << "Initialized SDL_net" << std::endl;
//Init SQL //Init SQL
@@ -102,10 +101,10 @@ void ServerApplication::Init(int argc, char* argv[]) {
//------------------------- //-------------------------
//set the hooks //set the hooks
AccountManager::GetSingleton().SetDatabase(database); accountMgr.SetDatabase(database);
CharacterManager::GetSingleton().SetDatabase(database); characterMgr.SetDatabase(database);
RoomManager::GetSingleton().SetLuaState(luaState); roomMgr.SetLuaState(luaState);
std::cout << "Internal managers initialized" << std::endl; std::cout << "Internal managers initialized" << std::endl;
@@ -173,9 +172,23 @@ void ServerApplication::Proc() {
//... //...
//Check connections //Check connections
int disconnected = ClientManager::GetSingleton().CheckConnections(); int disconnected = clientMgr.CheckConnections();
if (disconnected != -1) { if (disconnected != -1) {
//TODO: clean up after this disconnection //find and unload the accounts associated with this client
accountMgr.UnloadIf([&](std::pair<const int, AccountData> account) -> bool {
if (account.second.GetClientIndex() == disconnected) {
//find and unload the characters associated with this account
characterMgr.UnloadIf([&](std::pair<const int, CharacterData> character) -> bool {
if (character.second.GetOwner() == account.first) {
PumpCharacterUnload(character.first);
return true;
}
return false;
});
return true;
}
return false;
});
} }
//give the computer a break //give the computer a break
@@ -187,16 +200,20 @@ void ServerApplication::Proc() {
void ServerApplication::Quit() { void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl; std::cout << "Shutting down" << std::endl;
//TODO: save the server state
//close the managers //close the managers
ClientManager::GetSingleton().UnloadAll(); accountMgr.UnloadAll();
AccountManager::GetSingleton().UnloadAll(); characterMgr.UnloadAll();
CharacterManager::GetSingleton().UnloadAll(); clientMgr.UnloadAll();
RoomManager::GetSingleton().UnloadAll(); doorMgr.UnloadAll();
monsterMgr.UnloadAll();
roomMgr.UnloadAll();
//APIs //APIs
lua_close(luaState); lua_close(luaState);
sqlite3_close_v2(database); sqlite3_close_v2(database);
UDPNetworkUtility::GetSingleton().Close(); network.Close();
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit(); SDL_Quit();
@@ -213,60 +230,93 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
case SerialPacketType::PING: { case SerialPacketType::PING: {
ServerPacket newPacket; ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG; newPacket.type = SerialPacketType::PONG;
UDPNetworkUtility::GetSingleton().SendTo(argPacket->srcAddress, &newPacket); network.SendTo(argPacket->srcAddress, &newPacket);
} }
break; break;
case SerialPacketType::PONG: case SerialPacketType::PONG:
ClientManager::GetSingleton().HandlePong(static_cast<ServerPacket*>(argPacket)); clientMgr.HandlePong(static_cast<ServerPacket*>(argPacket));
break; break;
//connections //client connections
case SerialPacketType::BROADCAST_REQUEST: case SerialPacketType::BROADCAST_REQUEST:
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket)); // HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
break; break;
case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_REQUEST:
HandleJoinRequest(static_cast<ClientPacket*>(argPacket)); // HandleJoinRequest(static_cast<ClientPacket*>(argPacket));
break; break;
case SerialPacketType::DISCONNECT: case SerialPacketType::LOGIN_REQUEST:
HandleDisconnect(static_cast<ClientPacket*>(argPacket)); // HandleLoginRequest(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::SHUTDOWN:
HandleShutdown(static_cast<ClientPacket*>(argPacket));
break; break;
//map management //client disconnections
case SerialPacketType::DISCONNECT_REQUEST:
// HandleDisconnectRequest(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::DISCONNECT_FORCED:
// HandleDisconnectForced(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::LOGOUT_REQUEST:
// HandleLogoutRequest(static_cast<ClientPacket*>(argPacket));
break;
//server commands
case SerialPacketType::SHUTDOWN_REQUEST:
// HandleShutdownRequest(static_cast<ClientPacket*>(argPacket));
break;
//data management & queries
case SerialPacketType::REGION_REQUEST: case SerialPacketType::REGION_REQUEST:
HandleRegionRequest(static_cast<RegionPacket*>(argPacket)); // HandleRegionRequest(static_cast<RegionPacket*>(argPacket));
break;
case SerialPacketType::QUERY_CHARACTER_EXISTS:
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
break;
case SerialPacketType::QUERY_CHARACTER_STATS:
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
break;
case SerialPacketType::QUERY_CHARACTER_LOCATION:
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
break;
case SerialPacketType::TEXT_BROADCAST:
// HandleCharacterStatsRequest(static_cast<RegionPacket*>(argPacket));
break; break;
//combat management
//TODO: combat management
//character management //character management
case SerialPacketType::CHARACTER_NEW: case SerialPacketType::CHARACTER_CREATE:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket)); // HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
break; break;
case SerialPacketType::CHARACTER_DELETE: case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket)); // HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break; break;
case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_LOAD:
case SerialPacketType::CHARACTER_STATS_REQUEST: // HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket)); break;
case SerialPacketType::CHARACTER_UNLOAD:
// HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break;
//character movement
case SerialPacketType::CHARACTER_SET_ROOM:
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_SET_ORIGIN:
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_SET_MOTION:
// HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break; break;
//enemy management //enemy management
//TODO: enemy management //TODO: enemy management
//mismanagement //TODO: text
case SerialPacketType::SYNCHRONIZE:
HandleSynchronize(static_cast<ClientPacket*>(argPacket));
break;
//handle errors //handle errors
default: { default: {
std::string msg = "Unknown SerialPacketType encountered in the server: "; std::ostringstream msg;
msg += to_string_custom(static_cast<int>(argPacket->type)); msg << "Unknown SerialPacketType encountered in the server: ";
throw(std::runtime_error(msg)); msg << to_string_custom(static_cast<int>(argPacket->type));
throw(std::runtime_error(msg.str()));
} }
break; break;
} }
+33 -31
View File
@@ -23,6 +23,7 @@
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <sstream>
//------------------------- //-------------------------
//basic connections //basic connections
@@ -43,18 +44,24 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
//SET: connections //SET: connections
void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
//register the client
int clientIndex = clientMgr.Create(argPacket->srcAddress);
//load the user account //load the user account
//TODO: handle passwords //TODO: handle passwords
int accountIndex = accountMgr.Load(argPacket->username, clientIndex); int accountIndex = accountMgr.Load(argPacket->username, clientIndex);
//Cannot load //Cannot load
if (accountIndex < 0) { if (accountIndex < 0) {
std::ostringstream msg;
msg << "Account already loaded: " << argPacket->username;
TextPacket newPacket; TextPacket newPacket;
newPacket.type = SerialPacketType::JOIN_REJECTION; newPacket.type = SerialPacketType::JOIN_REJECTION;
std::string msg = std::string() + "Account already loaded: " + argPacket->username;
memset(newPacket.name, 0, PACKET_STRING_SIZE); memset(newPacket.name, 0, PACKET_STRING_SIZE);
strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE); //BUG: If the name is too long this would truncate it strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket)); network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
clientMgr.Unload(clientIndex);
return; return;
} }
@@ -66,13 +73,8 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket)); network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
//register the client
ClientData newClient;
newClient.SetAddress(argPacket->srcAddress);
clientMap[clientIndex++] = newClient;
//finished this routine //finished this routine
std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; std::cout << "New connection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
} }
//SET: connections //SET: connections
@@ -90,7 +92,7 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) {
//forward to the specified client //forward to the specified client
network.SendTo( network.SendTo(
clientMap[ accountMgr.Get(argPacket->accountIndex)->GetClientIndex() ].GetAddress(), clientMgr.Get(accountMgr.Get(argPacket->accountIndex)->GetClientIndex())->GetAddress(),
static_cast<SerialPacket*>(argPacket) static_cast<SerialPacket*>(argPacket)
); );
@@ -105,11 +107,11 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) {
}); });
//erase the in-memory stuff //erase the in-memory stuff
clientMap.erase(accountMgr.Get(argPacket->accountIndex)->GetClientIndex()); clientMgr.Unload(accountMgr.Get(argPacket->accountIndex)->GetClientIndex());
accountMgr.Unload(argPacket->accountIndex); accountMgr.Unload(argPacket->accountIndex);
//finished this routine //finished this routine
std::cout << "Disconnection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; std::cout << "Disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
} }
//SET: connections //SET: connections
@@ -127,7 +129,7 @@ void ServerApplication::HandleShutdown(ClientPacket* const argPacket) {
//disconnect all clients //disconnect all clients
ClientPacket newPacket; ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT; newPacket.type = SerialPacketType::DISCONNECT_FORCED;
PumpPacket(&newPacket); PumpPacket(&newPacket);
//finished this routine //finished this routine
@@ -166,27 +168,27 @@ void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
//cannot load or create //cannot load or create
if (characterIndex < 0) { if (characterIndex < 0) {
//build the error message //build the error message
std::string msg; std::ostringstream msg;
if (characterIndex == -1) { if (characterIndex == -1) {
msg += "Character already loaded: "; msg << "Character already loaded: ";
} }
else if (characterIndex == -2) { else if (characterIndex == -2) {
msg += "Character already exists: "; msg << "Character already exists: ";
} }
msg += argPacket->handle; msg << argPacket->handle;
//create, fill and send the packet //create, fill and send the packet
TextPacket newPacket; TextPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_REJECTION; newPacket.type = SerialPacketType::CHARACTER_REJECTION;
memset(newPacket.name, 0, PACKET_STRING_SIZE); memset(newPacket.name, 0, PACKET_STRING_SIZE);
strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE); strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket)); network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
return; return;
} }
//send this new character to all clients //send this new character to all clients
CharacterPacket newPacket; CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW; newPacket.type = SerialPacketType::CHARACTER_CREATE;
CopyCharacterToPacket(&newPacket, characterIndex); CopyCharacterToPacket(&newPacket, characterIndex);
PumpPacket(&newPacket); PumpPacket(&newPacket);
} }
@@ -255,15 +257,15 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//NOTE: I quite dislike this function //NOTE: I quite dislike this function
//send all of the server's data to this client //send all of the server's data to this client
ClientData& client = clientMap[argPacket->clientIndex]; ClientData* client = clientMgr.Get(argPacket->clientIndex);
//send all characters //send all characters
CharacterPacket newPacket; CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_UPDATE; newPacket.type = SerialPacketType::CHARACTER_SET_ORIGIN;
for (auto& it : *characterMgr.GetContainer()) { for (auto& it : *characterMgr.GetContainer()) {
CopyCharacterToPacket(&newPacket, it.first); CopyCharacterToPacket(&newPacket, it.first);
network.SendTo(client.GetAddress(), static_cast<SerialPacket*>(&newPacket)); network.SendTo(client->GetAddress(), static_cast<SerialPacket*>(&newPacket));
} }
//TODO: more in HandleSynchronize() //TODO: more in HandleSynchronize()
@@ -278,6 +280,11 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
//NOTE: This assumes each player has only one account and character at a time //NOTE: This assumes each player has only one account and character at a time
//TODO: handle multiple characters (bots, etc.) //TODO: handle multiple characters (bots, etc.)
//send a disconnection message just in case
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT_FORCED;
network.SendTo(clientMgr.Get(clientIndex)->GetAddress(), &newPacket);
//find the account //find the account
int accountIndex = -1; int accountIndex = -1;
for (auto& it : *accountMgr.GetContainer()) { for (auto& it : *accountMgr.GetContainer()) {
@@ -296,15 +303,10 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
} }
} }
//send a disconnection message just in case
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT;
network.SendTo(clientMap[clientIndex].GetAddress(), &newPacket);
//clean up this mess //clean up this mess
characterMgr.Unload(characterIndex); characterMgr.Unload(characterIndex);
accountMgr.Unload(accountIndex); accountMgr.Unload(accountIndex);
clientMap.erase(clientIndex); clientMgr.Unload(clientIndex);
PumpCharacterUnload(characterIndex); PumpCharacterUnload(characterIndex);
@@ -313,7 +315,7 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
std::cerr << "\tClient: " << clientIndex << std::endl; std::cerr << "\tClient: " << clientIndex << std::endl;
std::cerr << "\tAccount: " << accountIndex << std::endl; std::cerr << "\tAccount: " << accountIndex << std::endl;
std::cerr << "\tCharacter: " << characterIndex << std::endl; std::cerr << "\tCharacter: " << characterIndex << std::endl;
std::cout << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; std::cout << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl;
} }
//SET: utility //SET: utility
@@ -321,12 +323,12 @@ void ServerApplication::CleanupLostConnection(int clientIndex) {
//SET: utility //SET: utility
void ServerApplication::PumpPacket(SerialPacket* const argPacket) { void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
for (auto& it : clientMap) { for (auto& it : *clientMgr.GetContainer()) {
network.SendTo(it.second.GetAddress(), argPacket); network.SendTo(it.second.GetAddress(), argPacket);
} }
} }
//SET: utility //SET: utility/delete
void ServerApplication::PumpCharacterUnload(int uid) { void ServerApplication::PumpCharacterUnload(int uid) {
//delete the client-side character(s) //delete the client-side character(s)
//NOTE: This is a strange function //NOTE: This is a strange function
@@ -336,7 +338,7 @@ void ServerApplication::PumpCharacterUnload(int uid) {
PumpPacket(static_cast<SerialPacket*>(&newPacket)); PumpPacket(static_cast<SerialPacket*>(&newPacket));
} }
//SET: utility //SET: utility/delete
void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
CharacterData* character = characterMgr.Get(characterIndex); CharacterData* character = characterMgr.Get(characterIndex);
if (!character) { if (!character) {