From 1d436aa1c307e578f1df29df6fb46a669c03ed14 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sat, 23 Aug 2025 12:54:48 +0200 Subject: [PATCH] add bots --- include/client/Client.h | 13 ++++- include/client/IClientSocket.h | 1 + include/client/socket/FakeSocket.h | 1 + include/td/display/state/DebugWorldState.h | 7 ++- include/td/render/Renderer.h | 7 ++- .../td/render/renderer/PlayerListRenderer.h | 7 +++ src/client/Client.cpp | 10 +++- src/client/socket/FakeSocket.cpp | 4 ++ src/client/state/LoggingState.cpp | 1 + src/server/PlayerManager.cpp | 4 +- src/td/display/state/DebugWorldState.cpp | 47 +++++++++++++------ src/td/render/renderer/PlayerListRenderer.cpp | 15 +++++- 12 files changed, 93 insertions(+), 24 deletions(-) diff --git a/include/client/Client.h b/include/client/Client.h index a400fde..622011e 100644 --- a/include/client/Client.h +++ b/include/client/Client.h @@ -3,27 +3,38 @@ #include #include #include +#include namespace td { namespace client { class ClientState; +class LoggingState; class Client : public StateMachine { private: std::shared_ptr m_Socket; PlayerManager m_Players; + std::optional m_Id; public: - Client(const std::shared_ptr& a_Socket, const std::string& a_PlayerName); + Client(const std::shared_ptr& a_Socket); + ~Client(); void SendPacket(const protocol::PacketBase& a_Packet); + void Disconnect(); + const PlayerManager& GetPlayers() const { return m_Players; } + const std::optional GetId() const { + return m_Id; + } + friend class ClientState; + friend class LoggingState; }; } // namespace client diff --git a/include/client/IClientSocket.h b/include/client/IClientSocket.h index c4d8c65..1ad1894 100644 --- a/include/client/IClientSocket.h +++ b/include/client/IClientSocket.h @@ -14,6 +14,7 @@ class IClientSocket { utils::Signal OnReceive; virtual void Send(const protocol::PacketBase& a_Packet) = 0; + virtual void Disconnect() = 0; IClientSocket() {} virtual ~IClientSocket() {} diff --git a/include/client/socket/FakeSocket.h b/include/client/socket/FakeSocket.h index 0440708..ed17eb4 100644 --- a/include/client/socket/FakeSocket.h +++ b/include/client/socket/FakeSocket.h @@ -27,6 +27,7 @@ class FakeSocket : public IClientSocket { void ReceiveFromFakePeer(PeerID a_Peer, const protocol::PacketBase& a_Packet); virtual void Send(const protocol::PacketBase& a_Packet) override; + virtual void Disconnect() override; }; } // namespace client diff --git a/include/td/display/state/DebugWorldState.h b/include/td/display/state/DebugWorldState.h index e639851..a8aae95 100644 --- a/include/td/display/state/DebugWorldState.h +++ b/include/td/display/state/DebugWorldState.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace td { @@ -13,11 +14,13 @@ class DebugWorldState : public DisplayState { private: render::RenderPipeline m_Renderer; render::Camera m_Camera; - std::unique_ptr m_Client; - std::unique_ptr m_Client2; std::unique_ptr m_Server; + std::unique_ptr m_Client; client::GameState* m_ClientState; + std::vector> m_FakeClients; + std::shared_ptr m_ServerSocket; + public: DebugWorldState(Display& a_Display); ~DebugWorldState(); diff --git a/include/td/render/Renderer.h b/include/td/render/Renderer.h index 5ff36c6..3bb5e64 100644 --- a/include/td/render/Renderer.h +++ b/include/td/render/Renderer.h @@ -42,8 +42,11 @@ class RenderPipeline { virtual ~RenderPipeline() {} template - void AddRenderer(Args&&... args) { - m_Renderers.push_back(std::make_unique(args...)); + T& AddRenderer(Args&&... args) { + auto ptr = std::make_unique(args...); + auto rawPtr = ptr.get(); + m_Renderers.push_back(std::move(ptr)); + return *rawPtr; } void Clear() { diff --git a/include/td/render/renderer/PlayerListRenderer.h b/include/td/render/renderer/PlayerListRenderer.h index 226dff1..6f01055 100644 --- a/include/td/render/renderer/PlayerListRenderer.h +++ b/include/td/render/renderer/PlayerListRenderer.h @@ -6,10 +6,17 @@ namespace td { namespace render { +/** + * \brief This is a debug class + */ class PlayerListRenderer : public BasicRenderer { private: const client::PlayerManager& m_Players; public: + utils::Signal<> OnPlayerCreate; + // utils::Signal<> OnRequestPOV; + utils::Signal OnPlayerKick; + virtual void Render(float a_Lerp) override; PlayerListRenderer(const client::PlayerManager& a_Players); diff --git a/src/client/Client.cpp b/src/client/Client.cpp index a843f60..bad7c24 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -5,13 +5,21 @@ namespace td { namespace client { -Client::Client(const std::shared_ptr& a_Socket, const std::string& a_PlayerName) : m_Socket(a_Socket), m_Players(a_Socket) { +Client::Client(const std::shared_ptr& a_Socket) : m_Socket(a_Socket), m_Players(a_Socket) { // ChangeState(a_PlayerName); } +Client::~Client() { + Disconnect(); +} + void Client::SendPacket(const protocol::PacketBase& a_Packet) { m_Socket->Send(a_Packet); } +void Client::Disconnect() { + m_Socket->Disconnect(); +} + } // namespace client } // namespace td diff --git a/src/client/socket/FakeSocket.cpp b/src/client/socket/FakeSocket.cpp index 66e6ba9..dea2544 100644 --- a/src/client/socket/FakeSocket.cpp +++ b/src/client/socket/FakeSocket.cpp @@ -15,5 +15,9 @@ std::shared_ptr FakeSocket::Connect(const std::shared_ptrDisconnectFakePeer(m_PeerId); +} + } // namespace client } // namespace td diff --git a/src/client/state/LoggingState.cpp b/src/client/state/LoggingState.cpp index 9fccb79..3b57aa6 100644 --- a/src/client/state/LoggingState.cpp +++ b/src/client/state/LoggingState.cpp @@ -19,6 +19,7 @@ void LoggingState::Handle(const protocol::packets::PlayerJoinPacket& a_Packet) { } void LoggingState::Handle(const protocol::packets::LoggingSuccessPacket& a_Packet) { + m_StateMachine.m_Id = a_Packet->m_PlayerId; ChangeState(); } diff --git a/src/server/PlayerManager.cpp b/src/server/PlayerManager.cpp index ae273c0..78a32c2 100644 --- a/src/server/PlayerManager.cpp +++ b/src/server/PlayerManager.cpp @@ -36,14 +36,13 @@ void PlayerManager::ConnectionHandler::Handle(const protocol::packets::Disconnec PlayerManager::PlayerManager(const std::shared_ptr& a_Socket) : m_Socket(a_Socket) { a_Socket->RegisterHandler([this](PlayerID a_PlayerId) { return std::make_unique(*this, a_PlayerId); }); - a_Socket->OnPlayerDisconnect.Connect(std::bind(&PlayerManager::RemovePlayer, this, std::placeholders::_1)); + a_Socket->OnPlayerDisconnect.Connect(std::bind(&PlayerManager::Disconnect, this, std::placeholders::_1)); } void PlayerManager::Disconnect(PlayerID a_Player) { if (!m_Players.contains(a_Player)) return; std::cout << "[Server] " << +a_Player << " wants to disconnect !\n"; - m_Socket->Disconnect(a_Player); m_Socket->Broadcast(protocol::packets::PlayerLeavePacket(a_Player)); m_Players.erase(a_Player); } @@ -51,6 +50,7 @@ void PlayerManager::Disconnect(PlayerID a_Player) { PlayerManager::~PlayerManager() {} void PlayerManager::RemovePlayer(PlayerID a_Player) { + m_Socket->Disconnect(a_Player); Disconnect(a_Player); } diff --git a/src/td/display/state/DebugWorldState.cpp b/src/td/display/state/DebugWorldState.cpp index d0cd5ad..7baab80 100644 --- a/src/td/display/state/DebugWorldState.cpp +++ b/src/td/display/state/DebugWorldState.cpp @@ -26,12 +26,12 @@ namespace td { DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) { // server - auto serverFakeSocket = std::make_shared(); - m_Server = std::make_unique(serverFakeSocket); + m_ServerSocket = std::make_shared(); + m_Server = std::make_unique(m_ServerSocket); // client - auto clientFakeSocket = client::FakeSocket::Connect(serverFakeSocket); - m_Client = std::make_unique(clientFakeSocket, "Player0"); + auto clientFakeSocket = client::FakeSocket::Connect(m_ServerSocket); + m_Client = std::make_unique(clientFakeSocket); // TODO: make it better m_Client->OnStateChange.Connect([this](client::Client::State& a_State) { @@ -41,7 +41,24 @@ DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) { m_Renderer.AddRenderer(m_Camera, clientWorld); m_Renderer.AddRenderer(m_Camera, clientWorld); m_Renderer.AddRenderer(m_Camera, clientWorld); - m_Renderer.AddRenderer(m_Client->GetPlayers()); + + auto& list = m_Renderer.AddRenderer(m_Client->GetPlayers()); + + list.OnPlayerCreate.Connect([this]() { + auto newSocket = client::FakeSocket::Connect(m_ServerSocket); + auto newClient = std::make_unique(newSocket); + newClient->ChangeState("Bot"); + m_FakeClients.push_back(std::move(newClient)); + }); + + list.OnPlayerKick.Connect([this](PlayerID a_Player) { + auto it = std::find_if(m_FakeClients.begin(), m_FakeClients.end(), [a_Player](auto& clientPtr){ + if (!clientPtr->GetId().has_value()) + return false; + return clientPtr->GetId().value() == a_Player; + }); + m_FakeClients.erase(it); + }); // update state m_ClientState = gameState; @@ -50,11 +67,6 @@ DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) { m_Client->ChangeState("Player0"); - // client2 - auto clientFakeSocket2 = client::FakeSocket::Connect(serverFakeSocket); - m_Client2 = std::make_unique(clientFakeSocket2, "Player1"); - m_Client2->ChangeState("Player1"); - // camera m_Camera.SetCamPos({77, 7, 13}); m_Camera.UpdatePerspective(m_StateMachine.GetAspectRatio()); @@ -73,10 +85,17 @@ void DebugWorldState::OnAspectRatioChange(float a_Ratio) { void DebugWorldState::OnKeyDown(SDL_Keycode a_Key) { // temporary tests - if (a_Key == SDLK_A) { - m_Client->SendPacket(td::protocol::packets::SpawnTroopPacket(td::EntityType::Zombie, 1)); - } else if (a_Key == SDLK_Z) { - m_Client->SendPacket(td::protocol::packets::PlaceTowerPacket(td::TowerType::Archer, td::TowerCoords(77, 13))); + switch (a_Key) { + case SDLK_A: + m_Client->SendPacket(td::protocol::packets::SpawnTroopPacket(td::EntityType::Zombie, 1)); + break; + + case SDLK_Z: + m_Client->SendPacket(td::protocol::packets::PlaceTowerPacket(td::TowerType::Archer, td::TowerCoords(77, 13))); + break; + + default: + break; } } diff --git a/src/td/render/renderer/PlayerListRenderer.cpp b/src/td/render/renderer/PlayerListRenderer.cpp index fc317ce..79ce219 100644 --- a/src/td/render/renderer/PlayerListRenderer.cpp +++ b/src/td/render/renderer/PlayerListRenderer.cpp @@ -1,18 +1,29 @@ #include #include - -#include +#include namespace td { namespace render { void PlayerListRenderer::Render(float a_Lerp) { ImGui::Begin("Players"); + if (ImGui::Button("Add player")) { + OnPlayerCreate(); + } + std::optional kick; for (const auto& [id, player] : m_Players) { + ImGui::PushID(id); ImGui::Text("[%i] %s", id, player.m_PlayerName.c_str()); + ImGui::SameLine(); + if (ImGui::Button("Kick")){ + kick = id; + } + ImGui::PopID(); } ImGui::End(); + if (kick.has_value()) + OnPlayerKick(*kick); } PlayerListRenderer::PlayerListRenderer(const client::PlayerManager& a_Players) : m_Players(a_Players) {}