diff --git a/client/client_application.cpp b/client/client_application.cpp index ecddb97..b71140f 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -119,10 +119,10 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { activeScene = new OptionsMenu(&config); break; case SceneList::LOBBYMENU: - activeScene = new LobbyMenu(&config, &network, &clientIndex); + activeScene = new LobbyMenu(&config, &network, &clientIndex, &playerIndex); break; case SceneList::INWORLD: - activeScene = new InWorld(&config, &network, &clientIndex); + activeScene = new InWorld(&config, &network, &clientIndex, &playerIndex); break; case SceneList::INCOMBAT: activeScene = new InCombat(); diff --git a/client/client_application.hpp b/client/client_application.hpp index d4b22f5..40e00b0 100644 --- a/client/client_application.hpp +++ b/client/client_application.hpp @@ -44,9 +44,11 @@ private: BaseScene* activeScene = nullptr; + //shared parameters ConfigUtility config; UDPNetworkUtility network; - int clientIndex = -1; //replace with a struct? + int clientIndex = -1; + int playerIndex = -1; }; #endif diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 37c533f..fc1bdde 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -31,10 +31,11 @@ //Public access members //------------------------- -InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex): +InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argPlayerIndex): config(*argConfig), network(*argNetwork), - clientIndex(*argClientIndex) + clientIndex(*argClientIndex), + playerIndex(*argPlayerIndex) { //setup the utility objects buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); @@ -61,23 +62,12 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet //TODO: add the tilesheet to the map system? tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15); - //create the server-side player object - //TODO: the login system needs an overhaul - SerialPacket packet; - packet.meta.type = SerialPacket::Type::PLAYER_NEW; - packet.playerInfo.clientIndex = clientIndex; - snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str()); - snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str()); - packet.playerInfo.position = {0,0}; - packet.playerInfo.motion = {0,0}; - - //send it - char buffer[PACKET_BUFFER_SIZE]; - serialize(&packet, buffer); - network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); - //request a sync + SerialPacket packet; + char buffer[PACKET_STRING_SIZE]; packet.meta.type = SerialPacket::Type::SYNCHRONIZE; + packet.clientInfo.clientIndex = clientIndex; + packet.clientInfo.playerIndex = playerIndex; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); @@ -190,28 +180,28 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { case SDLK_LEFT: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST); - SendState(); + SendPlayerUpdate(); } break; case SDLK_RIGHT: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST); - SendState(); + SendPlayerUpdate(); } break; case SDLK_UP: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH); - SendState(); + SendPlayerUpdate(); } break; case SDLK_DOWN: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH); - SendState(); + SendPlayerUpdate(); } break; } @@ -223,28 +213,28 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { case SDLK_LEFT: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST); - SendState(); + SendPlayerUpdate(); } break; case SDLK_RIGHT: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST); - SendState(); + SendPlayerUpdate(); } break; case SDLK_UP: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH); - SendState(); + SendPlayerUpdate(); } break; case SDLK_DOWN: if (localCharacter) { localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH); - SendState(); + SendPlayerUpdate(); } break; } @@ -259,18 +249,18 @@ void InWorld::HandlePacket(SerialPacket packet) { case SerialPacket::Type::DISCONNECT: HandleDisconnect(packet); break; + case SerialPacket::Type::REGION_CONTENT: + HandleRegionContent(packet); + break; + case SerialPacket::Type::PLAYER_UPDATE: + HandlePlayerUpdate(packet); + break; case SerialPacket::Type::PLAYER_NEW: HandlePlayerNew(packet); break; case SerialPacket::Type::PLAYER_DELETE: HandlePlayerDelete(packet); break; - case SerialPacket::Type::PLAYER_UPDATE: - HandlePlayerUpdate(packet); - break; - case SerialPacket::Type::REGION_CONTENT: - HandleRegionContent(packet); - break; //handle errors default: throw(std::runtime_error("Unknown SerialPacket::Type encountered")); @@ -281,23 +271,48 @@ void InWorld::HandlePacket(SerialPacket packet) { void InWorld::HandleDisconnect(SerialPacket packet) { network.Unbind(Channels::SERVER); clientIndex = -1; + playerIndex = -1; SetNextScene(SceneList::MAINMENU); } +void InWorld::HandleRegionContent(SerialPacket packet) { + //replace existing regions + //TODO: account for map index + if (regionPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) { + regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y); + } + regionPager.PushRegion(packet.regionInfo.region); + packet.regionInfo.region = nullptr; +} + +void InWorld::HandlePlayerUpdate(SerialPacket packet) { + if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) { + throw(std::runtime_error("Cannot update nen-existant players")); + } + + //update only if the message didn't originate from here + if (packet.playerInfo.clientIndex != clientIndex) { + playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); + playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion); + } + playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); +} + void InWorld::HandlePlayerNew(SerialPacket packet) { if (playerCharacters.find(packet.playerInfo.playerIndex) != playerCharacters.end()) { throw(std::runtime_error("Cannot create duplicate players")); } + //TODO: set the handle playerCharacters[packet.playerInfo.playerIndex].GetSprite()->LoadSurface(config["dir.sprites"] + packet.playerInfo.avatar, 4, 4); playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion); playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); //catch this client's player object - if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) { - playerIndex = packet.playerInfo.playerIndex; + if (packet.playerInfo.playerIndex == playerIndex && !localCharacter) { localCharacter = &playerCharacters[playerIndex]; + //setup the camera camera.width = GetScreen()->w; camera.height = GetScreen()->h; @@ -315,40 +330,17 @@ void InWorld::HandlePlayerDelete(SerialPacket packet) { playerCharacters.erase(packet.playerInfo.playerIndex); //catch this client's player object - if (packet.playerInfo.clientIndex == clientIndex) { + if (packet.playerInfo.playerIndex == playerIndex) { playerIndex = -1; localCharacter = nullptr; } } -void InWorld::HandlePlayerUpdate(SerialPacket packet) { - if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) { - HandlePlayerNew(packet); - return; - } - - //update only if the message didn't originate from here - if (packet.playerInfo.clientIndex != clientIndex) { - playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); - playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion); - } - playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); -} - -void InWorld::HandleRegionContent(SerialPacket packet) { - //replace existing regions - if (regionPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) { - regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y); - } - regionPager.PushRegion(packet.regionInfo.region); - packet.regionInfo.region = nullptr; -} - //------------------------- //Server control //------------------------- -void InWorld::SendState() { +void InWorld::SendPlayerUpdate() { SerialPacket packet; char buffer[PACKET_BUFFER_SIZE]; @@ -369,7 +361,7 @@ void InWorld::RequestDisconnect() { //send a disconnect request packet.meta.type = SerialPacket::Type::DISCONNECT; - packet.clientInfo.index = clientIndex; + packet.clientInfo.clientIndex = clientIndex; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); } @@ -380,17 +372,18 @@ void InWorld::RequestShutDown() { //send a shutdown request packet.meta.type = SerialPacket::Type::SHUTDOWN; - packet.clientInfo.index = clientIndex; + packet.clientInfo.clientIndex = clientIndex; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); } -void InWorld::RequestRegion(int x, int y) { +void InWorld::RequestRegion(int mapIndex, int x, int y) { SerialPacket packet; char buffer[PACKET_BUFFER_SIZE]; //pack the region's data packet.meta.type = SerialPacket::Type::REGION_REQUEST; + packet.regionInfo.mapIndex = mapIndex; packet.regionInfo.x = x; packet.regionInfo.y = y; serialize(&packet, buffer); @@ -430,7 +423,7 @@ void InWorld::UpdateMap() { for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { if (!regionPager.FindRegion(i, j)) { - RequestRegion(i, j); + RequestRegion(0, i, j); } } } diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index bb0cc5c..00dcfa2 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -52,7 +52,7 @@ class InWorld : public BaseScene { public: //Public access members - InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const); + InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const); ~InWorld(); protected: @@ -80,19 +80,19 @@ protected: void HandleRegionContent(SerialPacket); //Server control - void SendState(); + void SendPlayerUpdate(); void RequestDisconnect(); void RequestShutDown(); - void RequestRegion(int x, int y); + void RequestRegion(int mapIndex, int x, int y); //utilities void UpdateMap(); - //globals + //shared parameters ConfigUtility& config; - FrameRate fps; UDPNetworkUtility& network; int& clientIndex; + int& playerIndex; //graphics Image buttonImage; @@ -111,11 +111,11 @@ protected: int width = 0, height = 0; int marginX = 0, marginY = 0; } camera; + FrameRate fps; //game std::map playerCharacters; PlayerCharacter* localCharacter = nullptr; - int playerIndex = -1; }; #endif diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index 1000af4..d6900da 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -30,10 +30,11 @@ //Public access members //------------------------- -LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex): +LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argPlayerIndex): config(*argConfig), network(*argNetwork), - clientIndex(*argClientIndex) + clientIndex(*argClientIndex), + playerIndex(*argPlayerIndex) { //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); @@ -155,13 +156,17 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { } else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) { - //TODO: The player login information should be collected by the lobby screen //the vars SerialPacket packet; char buffer[PACKET_BUFFER_SIZE]; - //join the selected server + //pack the packet packet.meta.type = SerialPacket::Type::JOIN_REQUEST; + strncpy(packet.clientInfo.player, config["client.player"].c_str(), PACKET_STRING_SIZE); + strncpy(packet.clientInfo.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE); + strncpy(packet.clientInfo.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE); + + //join the selected server serialize(&packet, buffer); network.Send(&selection->address, buffer, PACKET_BUFFER_SIZE); selection = nullptr; @@ -203,20 +208,20 @@ void LobbyMenu::HandlePacket(SerialPacket packet) { //extract the data ServerInformation server; server.address = packet.meta.srcAddress; + server.networkVersion = packet.serverInfo.networkVersion; server.name = packet.serverInfo.name; server.playerCount = packet.serverInfo.playerCount; //NOTE: Check compatibility here - server.compatible = packet.serverInfo.regionWidth == REGION_WIDTH && - packet.serverInfo.regionHeight == REGION_HEIGHT && - packet.serverInfo.regionDepth == REGION_DEPTH; + server.compatible = server.networkVersion == NETWORK_VERSION; //push serverInfo.push_back(server); } break; case SerialPacket::Type::JOIN_RESPONSE: - clientIndex = packet.clientInfo.index; + clientIndex = packet.clientInfo.clientIndex; + playerIndex = packet.clientInfo.playerIndex; network.Bind(&packet.meta.srcAddress, Channels::SERVER); SetNextScene(SceneList::INWORLD); break; diff --git a/client/scenes/lobby_menu.hpp b/client/scenes/lobby_menu.hpp index 53808bb..4273400 100644 --- a/client/scenes/lobby_menu.hpp +++ b/client/scenes/lobby_menu.hpp @@ -28,9 +28,6 @@ #include "button.hpp" #include "config_utility.hpp" -//map -#include "region.hpp" - //network #include "udp_network_utility.hpp" #include "serial_packet.hpp" @@ -45,7 +42,7 @@ class LobbyMenu : public BaseScene { public: //Public access members - LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const); + LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const, int* const); ~LobbyMenu(); protected: @@ -64,10 +61,11 @@ protected: void HandlePacket(SerialPacket); - //global + //shared parameters ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; + int& playerIndex; //members Image image; @@ -79,7 +77,7 @@ protected: //server list struct ServerInformation { IPaddress address; - //TODO: version info + int networkVersion; std::string name; int playerCount; bool compatible; diff --git a/client/scenes/main_menu.hpp b/client/scenes/main_menu.hpp index 5aba53d..9c06a0d 100644 --- a/client/scenes/main_menu.hpp +++ b/client/scenes/main_menu.hpp @@ -49,7 +49,7 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //globals + //shared parameters ConfigUtility& config; //members diff --git a/client/scenes/options_menu.hpp b/client/scenes/options_menu.hpp index 6e99965..bc05e1f 100644 --- a/client/scenes/options_menu.hpp +++ b/client/scenes/options_menu.hpp @@ -49,7 +49,7 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //globals + //shared parameters ConfigUtility& config; //members diff --git a/client/scenes/splash_screen.hpp b/client/scenes/splash_screen.hpp index f332cbe..f24a1c6 100644 --- a/client/scenes/splash_screen.hpp +++ b/client/scenes/splash_screen.hpp @@ -40,7 +40,7 @@ protected: void Update(double delta); void Render(SDL_Surface* const); - //globals + //shared parameters ConfigUtility& config; //members diff --git a/common/network/serial.cpp b/common/network/serial.cpp index c6ca226..6f2f069 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -97,6 +97,10 @@ void serializePlayer(SerialPacket* packet, char* buffer) { SERIALIZE(buffer, &packet->playerInfo.clientIndex, sizeof(int)); SERIALIZE(buffer, &packet->playerInfo.playerIndex, sizeof(int)); + //texts + SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); + SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); + //vectors SERIALIZE(buffer, &packet->playerInfo.position.x, sizeof(double)); SERIALIZE(buffer, &packet->playerInfo.position.y, sizeof(double)); @@ -176,6 +180,10 @@ void deserializePlayer(SerialPacket* packet, char* buffer) { DESERIALIZE(buffer, &packet->playerInfo.clientIndex, sizeof(int)); DESERIALIZE(buffer, &packet->playerInfo.playerIndex, sizeof(int)); + //texts + DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); + DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); + //vectors DESERIALIZE(buffer, &packet->playerInfo.position.x, sizeof(double)); DESERIALIZE(buffer, &packet->playerInfo.position.y, sizeof(double)); diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index af897d6..ff4fb8c 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -108,6 +108,8 @@ union SerialPacket { Metadata meta; int clientIndex; int playerIndex; + char handle[PACKET_STRING_SIZE]; + char avatar[PACKET_STRING_SIZE]; Vector2 position; Vector2 motion; }playerInfo; diff --git a/rsc/config.cfg b/rsc/config.cfg index 0b5fec0..37fbd5e 100644 --- a/rsc/config.cfg +++ b/rsc/config.cfg @@ -23,7 +23,8 @@ map.pager.height = 20 map.pager.depth = 3 #player options -player.handle = username -player.avatar = elliot2.bmp +client.player = Kayne Ruse +client.handle = Ratstail91 +client.avatar = elliot2.bmp #debugging