From d55dfb90e44333a25832faafb2af817aa8976f51 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 26 Apr 2014 01:05:31 +1000 Subject: [PATCH] Worked the new protocol into the client (read more) I've added the handle and avatar fields back into the PlayerInfo section in the network code, because I need to be able to load a specific file when a new player is created. This wasn't forseen, but it's fine. i'm leaving the fields in ClientInfo as well, because LobbyMenu is using them to login to the server. PlayerIndex is now a shared parameter. I've shifted some code around in InWorld, however the overall logic is the same. This build (as well as the last) does not compile. --- client/client_application.cpp | 4 +- client/client_application.hpp | 4 +- client/scenes/in_world.cpp | 117 +++++++++++++++---------------- client/scenes/in_world.hpp | 12 ++-- client/scenes/lobby_menu.cpp | 21 +++--- client/scenes/lobby_menu.hpp | 10 ++- client/scenes/main_menu.hpp | 2 +- client/scenes/options_menu.hpp | 2 +- client/scenes/splash_screen.hpp | 2 +- common/network/serial.cpp | 8 +++ common/network/serial_packet.hpp | 2 + rsc/config.cfg | 5 +- 12 files changed, 99 insertions(+), 90 deletions(-) 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