From f84c996a523510129f056081c575a6789b1430a7 Mon Sep 17 00:00:00 2001 From: dean11 Date: Thu, 20 Feb 2014 16:52:36 +0100 Subject: [PATCH 1/4] GameLogic - Added disconnect messages and reuse of players --- Code/Game/GameLogic/DynamicObject.cpp | 45 +++++++++++++++++-- Code/Game/GameLogic/DynamicObject.h | 8 ++++ Code/Game/GameLogic/Game.cpp | 11 +++++ Code/Game/GameLogic/Game.h | 4 +- Code/Game/GameLogic/GameAPI.h | 3 ++ Code/Game/GameLogic/Game_PlayerData.cpp | 8 ++++ Code/Game/GameLogic/Player.cpp | 5 +++ Code/Game/GameLogic/Player.h | 2 + Code/Game/GameProtocols/ObjectProtocols.h | 21 ++++----- .../GameProtocols/ProtocolIdentificationID.h | 1 - Code/Game/GameServer/GameClient.h | 1 + .../GameServer/Implementation/GameClient.cpp | 13 +++++- .../Implementation/GameSession_Gameplay.cpp | 35 ++++++++++----- .../Implementation/GameSession_General.cpp | 2 +- 14 files changed, 129 insertions(+), 30 deletions(-) diff --git a/Code/Game/GameLogic/DynamicObject.cpp b/Code/Game/GameLogic/DynamicObject.cpp index 6df5bef0..e6d9ff49 100644 --- a/Code/Game/GameLogic/DynamicObject.cpp +++ b/Code/Game/GameLogic/DynamicObject.cpp @@ -2,37 +2,76 @@ #include "CollisionManager.h" using namespace GameLogic; +using namespace Oyster::Math; DynamicObject::DynamicObject() :Object() { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) :Object(rigidBody, EventOnCollision, type, objectID) { this->extraDamageOnCollision = extraDamageOnCollision; + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) :Object(rigidBody, EventOnCollision, type, objectID) { this->extraDamageOnCollision = extraDamageOnCollision; + this->isReleased = false; + this->isActive = true; } DynamicObject::~DynamicObject(void) { +} + +void DynamicObject::ReleaseDynamicObject() +{ + //TODO: Inactivate the physics object + if(this->isReleased) return; + + this->isReleased = true; + this->isActive = false; + this->lookDirection = Float3::null; + this->forwardDirection = Float3::null; + this->scale = Float3::null; + this->extraDamageOnCollision = 0; + +} +bool DynamicObject::IsReleased() +{ + return this->isReleased; +} +bool DynamicObject::IsActive() +{ + return this->isActive; +} +void DynamicObject::Inactivate() +{ + this->isActive = false; +} +void DynamicObject::Activate() +{ + this->isActive = true; + this->isReleased = false; } \ No newline at end of file diff --git a/Code/Game/GameLogic/DynamicObject.h b/Code/Game/GameLogic/DynamicObject.h index 2d5fa617..8a32e849 100644 --- a/Code/Game/GameLogic/DynamicObject.h +++ b/Code/Game/GameLogic/DynamicObject.h @@ -22,7 +22,15 @@ namespace GameLogic ~DynamicObject(void); + void ReleaseDynamicObject(); + bool IsReleased(); + bool IsActive(); + void Inactivate(); + void Activate(); + private: + bool isActive; + bool isReleased; }; diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index 8dd7ffa6..c599fecf 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -67,6 +67,17 @@ void Game::GetAllPlayerPositions() const Game::PlayerData* Game::CreatePlayer() { + //Se if there is a free player somewhere in our list + for (unsigned int i = 0; i < this->players.Size(); i++) + { + if(this->players[i] && this->players[i]->player->IsReleased()) + { + //We give the body to someone else + this->players[i]->player->Activate(); + return this->players[i]; + } + } + // Find a free space in array or insert at end int insert = InsertObject(this->players, (PlayerData*)0); int freeID = 0; diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index 5ab19ba2..8d34a154 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -43,8 +43,8 @@ namespace GameLogic void Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right) override; void TurnLeft(Oyster::Math3D::Float deltaLeftRadians ) override; ObjectSpecialType GetObjectType() const override; - - + void Inactivate() override; + void Release() override; Player *player; }; diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index 66cf5ea2..a501a0d9 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -106,6 +106,9 @@ namespace GameLogic * @return The current player state ********************************************************/ virtual PLAYER_STATE GetState() const = 0; + + virtual void Inactivate() = 0; + virtual void Release() = 0; }; class ILevelData :public IObjectData diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 045da742..1f675f6a 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -93,4 +93,12 @@ void Game::PlayerData::Rotate(const Oyster::Math3D::Float3& lookDir, const Oyste void Game::PlayerData::TurnLeft(Oyster::Math3D::Float deltaLeftRadians ) { this->player->TurnLeft(deltaLeftRadians); +} +void Game::PlayerData::Inactivate() +{ + this->player->Inactivate(); +} +void Game::PlayerData::Release() +{ + this->player->ReleaseDynamicObject(); } \ No newline at end of file diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 5b855785..02e8510c 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -293,6 +293,11 @@ bool Player::IsIdle() return (this->playerState == PLAYER_STATE::PLAYER_STATE_IDLE); } +void Player::Inactivate() +{ + //this-> +} + Oyster::Math::Float3 Player::GetPosition() const { return (Oyster::Math::Float3) this->rigidBody->GetState().centerPos; diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 13c6e300..3ddd7f9a 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -63,6 +63,8 @@ namespace GameLogic bool IsJumping(); bool IsIdle(); + void Inactivate(); + Oyster::Math::Float3 GetPosition() const; Oyster::Math::Float3 GetLookDir() const; Oyster::Math::Float4x4 GetOrientation() const; diff --git a/Code/Game/GameProtocols/ObjectProtocols.h b/Code/Game/GameProtocols/ObjectProtocols.h index cae7c7f5..22f8213e 100644 --- a/Code/Game/GameProtocols/ObjectProtocols.h +++ b/Code/Game/GameProtocols/ObjectProtocols.h @@ -292,6 +292,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; + //#define protocol_Gameplay_ObjectEnabled 356 struct Protocol_ObjectPositionRotation :public Oyster::Network::CustomProtocolObject { short object_ID; @@ -366,7 +367,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectEnabled 356 + //#define protocol_Gameplay_ObjectEnabled 357 struct Protocol_ObjectEnable :public Oyster::Network::CustomProtocolObject { int objectID; @@ -399,7 +400,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectDisabled 357 + //#define protocol_Gameplay_ObjectDisabled 358 struct Protocol_ObjectDisable :public Oyster::Network::CustomProtocolObject { int objectID; @@ -439,7 +440,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectCreate 358 + //#define protocol_Gameplay_ObjectCreate 359 struct Protocol_ObjectCreate :public Oyster::Network::CustomProtocolObject { //ObjectType type; //ie player, box or whatever @@ -543,7 +544,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectCreatePlayer 359 + //#define protocol_Gameplay_ObjectCreatePlayer 360 struct Protocol_ObjectCreatePlayer :public Oyster::Network::CustomProtocolObject { /*1*/ int object_ID; @@ -673,7 +674,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectJoinTeam 360 + //#define protocol_Gameplay_ObjectJoinTeam 361 struct Protocol_ObjectJoinTeam :public Oyster::Network::CustomProtocolObject { int objectID; @@ -713,7 +714,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectLeaveTeam 361 + //#define protocol_Gameplay_ObjectLeaveTeam 362 struct Protocol_ObjectLeaveTeam :public Oyster::Network::CustomProtocolObject { int objectID; @@ -745,7 +746,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectWeaponCooldown 362 + //#define protocol_Gameplay_ObjectWeaponCooldown 363 struct Protocol_ObjectWeaponCooldown :public Oyster::Network::CustomProtocolObject { float seconds; @@ -777,7 +778,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectWeaponEnergy 363 + //#define protocol_Gameplay_ObjectWeaponEnergy 364 struct Protocol_ObjectWeaponEnergy :public Oyster::Network::CustomProtocolObject { float energy; @@ -809,7 +810,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectRespawn 364 + //#define protocol_Gameplay_ObjectRespawn 365 struct Protocol_ObjectRespawn :public Oyster::Network::CustomProtocolObject { float position[3]; @@ -852,7 +853,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectDie 365 + //#define protocol_Gameplay_ObjectDie 366 struct Protocol_ObjectDie :public Oyster::Network::CustomProtocolObject { int objectID; diff --git a/Code/Game/GameProtocols/ProtocolIdentificationID.h b/Code/Game/GameProtocols/ProtocolIdentificationID.h index cb630012..79235e2f 100644 --- a/Code/Game/GameProtocols/ProtocolIdentificationID.h +++ b/Code/Game/GameProtocols/ProtocolIdentificationID.h @@ -69,7 +69,6 @@ #define protocol_Gameplay_ObjectWeaponEnergy 364 #define protocol_Gameplay_ObjectRespawn 365 #define protocol_Gameplay_ObjectDie 366 -//Disconnect #define protocol_Gameplay_ObjectDisconnectPlayer 367 #define protocol_GameplayMAX 399 diff --git a/Code/Game/GameServer/GameClient.h b/Code/Game/GameServer/GameClient.h index 497e6c2e..aace26c7 100644 --- a/Code/Game/GameServer/GameClient.h +++ b/Code/Game/GameServer/GameClient.h @@ -55,6 +55,7 @@ namespace DanBias GameLogic::IPlayerData* ReleasePlayer(); Oyster::Network::NetClient ReleaseClient(); + bool IsInvalid(); void Invalidate(); int IncrementFailedProtocol(); void ResetFailedProtocolCount(); diff --git a/Code/Game/GameServer/Implementation/GameClient.cpp b/Code/Game/GameServer/Implementation/GameClient.cpp index 3293a383..e8e78ab0 100644 --- a/Code/Game/GameServer/Implementation/GameClient.cpp +++ b/Code/Game/GameServer/Implementation/GameClient.cpp @@ -25,12 +25,15 @@ GameClient::GameClient(Utility::DynamicMemory::SmartPointerclient = 0; - this->player = 0; + if(this->player) + this->player->Inactivate(); + this->isReady = false; this->character = L"crate_colonists.dan"; this->alias = L"Unknown"; this->secondsSinceLastResponse = 0.0f; + this->client = 0; + this->player = 0; } void GameClient::SetPlayer(GameLogic::IPlayerData* player) @@ -58,8 +61,14 @@ void GameClient::SetState(ClientState state) this->state = state; } +bool GameClient::IsInvalid() +{ + return this->isInvalid; +} void GameClient::Invalidate() { + this->player->Release(); + this->player = 0; this->isInvalid = true; this->isReady = false; this->state = ClientState_Invalid; diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 0c52dfff..737ef1c9 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -62,24 +62,30 @@ using namespace DanBias; { case NetworkClient::ClientEventArgs::EventType_Disconnect: { - //Send disconnect message to all the other players so the player can be removed from the client. - Protocol_ObjectDisconnectPlayer dp(cl->GetClient()->GetID()); - for(int i = 0; i < this->gClients.Size(); i++) - { - if(this->gClients[i] && this->gClients[i] != cl) - { - this->gClients[i]->GetClient()->Send(dp); - } - } printf("\t(%i : %s) - EventType_Disconnect\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); + Protocol_ObjectDisconnectPlayer prot(this->gClients[temp]->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if(i != temp && this->gClients[i]) this->gClients[i]->GetClient()->Send(prot); + } + this->gClients[temp]->Invalidate(); } break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve: break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend: + { if(this->gClients[temp]->IncrementFailedProtocol() >= 5/*client->threshold*/) + { + Protocol_ObjectDisconnectPlayer prot(this->gClients[temp]->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if(i != temp && this->gClients[i]) this->gClients[i]->GetClient()->Send(prot); + } this->gClients[temp]->Invalidate(); + } + } break; case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved: this->ParseProtocol(e.args.data.protocol, cl); @@ -267,10 +273,17 @@ using namespace DanBias; switch (p.status) { case GameLogic::Protocol_General_Status::States_disconected: + { printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID()); - //TODO: Tell other clients - //Protocol_ + + Protocol_ObjectDisconnectPlayer prot(c->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if( this->gClients[i] && c->GetClient()->GetID() != this->gClients[i]->GetClient()->GetID() ) this->gClients[i]->GetClient()->Send(prot); + } + c->Invalidate(); this->Detach(c->GetClient()->GetID()); + } break; case GameLogic::Protocol_General_Status::States_idle: diff --git a/Code/Game/GameServer/Implementation/GameSession_General.cpp b/Code/Game/GameServer/Implementation/GameSession_General.cpp index 30eabed2..45143e42 100644 --- a/Code/Game/GameServer/Implementation/GameSession_General.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_General.cpp @@ -214,7 +214,7 @@ bool GameSession::Join(gClient gameClient) { for (unsigned int i = 0; i < this->gClients.Size(); i++) { - if(this->gClients[i]) + if(this->gClients[i] && !this->gClients[i]->IsInvalid()) { IPlayerData* temp = this->gClients[i]->GetPlayer(); Protocol_ObjectCreatePlayer oc( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), From 7d887d81b0b9034f479b81006a423f6c5125a7fb Mon Sep 17 00:00:00 2001 From: dean11 Date: Thu, 20 Feb 2014 16:54:24 +0100 Subject: [PATCH 2/4] GameServer - Modified one row --- .../GameServer/Implementation/GameSession_General.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Code/Game/GameServer/Implementation/GameSession_General.cpp b/Code/Game/GameServer/Implementation/GameSession_General.cpp index 30eabed2..e2106ac9 100644 --- a/Code/Game/GameServer/Implementation/GameSession_General.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_General.cpp @@ -217,11 +217,18 @@ bool GameSession::Join(gClient gameClient) if(this->gClients[i]) { IPlayerData* temp = this->gClients[i]->GetPlayer(); - Protocol_ObjectCreatePlayer oc( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), + Protocol_ObjectCreatePlayer p1( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), temp->GetID(), false, temp->GetTeamID(), Utility::String::WStringToString(this->gClients[i]->GetAlias(), std::string()), Utility::String::WStringToString(this->gClients[i]->GetCharacter(), std::string())); - nwClient->Send(oc); + nwClient->Send(p1); + + temp = playerData; + Protocol_ObjectCreatePlayer p2( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), + temp->GetID(), false, temp->GetTeamID(), + Utility::String::WStringToString(gameClient->GetAlias(), std::string()), + Utility::String::WStringToString(gameClient->GetCharacter(), std::string())); + this->gClients[i]->GetClient()->Send(p2); } } } From c718dc5a2b7d1fe1873d131f1f48691b82ee16e2 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 21 Feb 2014 09:34:09 +0100 Subject: [PATCH 3/4] Started implementing broadcasting --- .../GameClient/GameClientState/GameState.cpp | 2 +- Code/Network/NetworkAPI/NetworkServer.h | 37 ++++++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index b4aee882..4cbdf686 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -591,7 +591,7 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState case protocol_Gameplay_ObjectDie: break; /** @todo TODO: implement */ case protocol_Gameplay_ObjectDisconnectPlayer: { - //Removes + //Remove the disconnected player Protocol_ObjectDisconnectPlayer decoded(data); auto object = this->privData->dynamicObjects->find( decoded.objectID ); if( object != this->privData->dynamicObjects->end() ) diff --git a/Code/Network/NetworkAPI/NetworkServer.h b/Code/Network/NetworkAPI/NetworkServer.h index 593c3847..82693310 100644 --- a/Code/Network/NetworkAPI/NetworkServer.h +++ b/Code/Network/NetworkAPI/NetworkServer.h @@ -22,16 +22,16 @@ namespace Oyster { struct BroadcastOptions { - //bool broadcast; - //float broadcastInterval; - //std::wstring subnetToBroadcast; - //CustomNetProtocol broadcastMessage; - //BroadcastOptions() - //{ - // broadcast = true; - // broadcastInterval = 1.0f; - // subnetToBroadcast = L"192.168.0.1"; - //} + bool broadcast; + float broadcastInterval; + std::wstring subnetToBroadcast; + CustomNetProtocol broadcastMessage; + BroadcastOptions() + { + broadcast = true; + broadcastInterval = 1.0f; + subnetToBroadcast = L"192.168.0.1"; + } } broadcastOptions; struct MainOptions @@ -117,6 +117,23 @@ namespace Oyster */ int NetworkServer::GetPort(); + + + /*************************************** + Broadcast functions + ***************************************/ + //Set broadcast settings. + void SetBroadcast(CustomNetProtocol& broadcastMessage, float interval = 1.0f, bool enable = true); + + //Set broadcast settings. + void SetBroadcastMessage(CustomNetProtocol& broadcastMessage); + + //Enable/disable broadcast. + void SetBroadcast(bool enable); + + //Set interval between each broadcast message in seconds. + void SetBroadcastInterval(float interval); + private: struct PrivateData; PrivateData* privateData; From a46ba0efb55be86450e4e02efc4e8c6ecec193c9 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 21 Feb 2014 11:12:24 +0100 Subject: [PATCH 4/4] Added print out for disconnect --- Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 737ef1c9..c919c159 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -78,6 +78,7 @@ using namespace DanBias; { if(this->gClients[temp]->IncrementFailedProtocol() >= 5/*client->threshold*/) { + printf("\t(%i : %s) - EventType_Disconnect\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); Protocol_ObjectDisconnectPlayer prot(this->gClients[temp]->GetPlayer()->GetID()); for (unsigned int i = 0; i < this->gClients.Size(); i++) {