diff --git a/include/server/IServerSocket.h b/include/server/IServerSocket.h new file mode 100644 index 0000000..a91225d --- /dev/null +++ b/include/server/IServerSocket.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +namespace td { +namespace server { + +class IServerSocket { + public: + utils::Signal OnConnect; + utils::Signal OnDisconnect; + utils::Signal OnReceive; + + virtual void Send(PlayerID, const protocol::PacketBase&) = 0; + + IServerSocket() {} + virtual ~IServerSocket() {} + + private: + PlayerIds m_Ids; + + protected: + void OnConnectPeer(PeerID a_PeerId); + void OnDisconnectPeer(PeerID a_PeerId); + void OnReceivePeer(PeerID a_PeerId, const protocol::PacketBase& a_Packet); +}; + +} // namespace server +} // namespace td diff --git a/include/server/IServerState.h b/include/server/IServerState.h new file mode 100644 index 0000000..8e8626d --- /dev/null +++ b/include/server/IServerState.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace td { +namespace server { + +class Server; + +class IServerState { + protected: + void SendPacket(PlayerID a_Id, const protocol::PacketBase& a_Packet); + void SetNewState(const std::shared_ptr& a_NewState); + + public: + virtual void HandlePacket(PlayerID a_Id, const protocol::PacketBase& a_Packet) = 0; + virtual void Update(float a_Delta) = 0; + virtual void OnPlayerJoin(PlayerID a_Id) = 0; + virtual void OnPlayerLeave(PlayerID a_Id) = 0; + + IServerState(IServerSocket& a_Server); + virtual ~IServerState() {} + + private: + IServerSocket& m_Socket; + Server* m_Server; + + void SetServer(Server* a_Server) { + m_Server = a_Server; + } + + friend class Server; +}; + +} // namespace server +} // namespace td diff --git a/include/server/PlayerIds.h b/include/server/PlayerIds.h new file mode 100644 index 0000000..6166a26 --- /dev/null +++ b/include/server/PlayerIds.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +namespace td { +namespace server { + +class PlayerIds { + private: + std::map m_PeerToPlayer; + std::map m_PlayerToPeer; + PlayerID m_NextId; + + public: + PlayerIds() : m_NextId(0) {} + ~PlayerIds() {} + + void AddConnection(PeerID a_PeerId) { + m_PeerToPlayer.emplace(a_PeerId, m_NextId); + m_PlayerToPeer.emplace(m_NextId, a_PeerId); + m_NextId++; + } + + PlayerID GetPlayerId(PeerID a_PeerId) const { + return m_PeerToPlayer.at(a_PeerId); + } + + PeerID GetPeerId(PlayerID a_PlayerId) const { + return m_PlayerToPeer.at(a_PlayerId); + } + + void RemovePeer(PeerID a_PeerId) { + PlayerID playerId = GetPlayerId(a_PeerId); + m_PeerToPlayer.erase(a_PeerId); + m_PlayerToPeer.erase(playerId); + } +}; + +} // namespace server +} // namespace td diff --git a/include/server/Server.h b/include/server/Server.h new file mode 100644 index 0000000..79c0ecf --- /dev/null +++ b/include/server/Server.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +namespace td { +namespace server { + +class Server { + private: + std::shared_ptr m_State; + std::unique_ptr m_Socket; + + public: + Server(std::unique_ptr&& a_Socket) : m_Socket(std::move(a_Socket)) {} + + void Update(float a_Delta) { + m_State->Update(a_Delta); + } + + void UpdateState(const std::shared_ptr& a_State) { + m_State = a_State; + m_State->SetServer(this); + } + +}; + +} // namespace server +} // namespace td diff --git a/src/server/IServerSocket.cpp b/src/server/IServerSocket.cpp new file mode 100644 index 0000000..3fabde5 --- /dev/null +++ b/src/server/IServerSocket.cpp @@ -0,0 +1,21 @@ +#include + +namespace td { +namespace server { + +void IServerSocket::OnConnectPeer(PeerID a_PeerId) { + m_Ids.AddConnection(a_PeerId); + OnConnect(m_Ids.GetPlayerId(a_PeerId)); +} + +void IServerSocket::OnDisconnectPeer(PeerID a_PeerId) { + OnDisconnect(m_Ids.GetPlayerId(a_PeerId)); + m_Ids.RemovePeer(a_PeerId); +} + +void IServerSocket::OnReceivePeer(PeerID a_PeerId, const protocol::PacketBase& a_Packet) { + OnReceive(m_Ids.GetPlayerId(a_PeerId), a_Packet); +} + +} // namespace server +} // namespace td diff --git a/src/server/IServerState.cpp b/src/server/IServerState.cpp new file mode 100644 index 0000000..fe5accb --- /dev/null +++ b/src/server/IServerState.cpp @@ -0,0 +1,29 @@ +#include +#include + +namespace td { +namespace server { + +IServerState::IServerState(IServerSocket& a_Socket) : m_Socket(a_Socket) { + // TODO: don't do it like this + m_Socket.OnConnect.Connect([this](PlayerID a_Player){ + OnPlayerJoin(a_Player); + }); + m_Socket.OnDisconnect.Connect([this](PlayerID a_Player){ + OnPlayerLeave(a_Player); + }); + m_Socket.OnReceive.Connect([this](PlayerID a_Player, const protocol::PacketBase& a_Packet){ + HandlePacket(a_Player, a_Packet); + }); +} + +void IServerState::SendPacket(PlayerID a_Id, const protocol::PacketBase& a_Packet) { + m_Socket.Send(a_Id, a_Packet); +} + +void IServerState::SetNewState(const std::shared_ptr& a_NewState) { + m_Server->UpdateState(a_NewState); +} + +} // namespace server +} // namespace td diff --git a/src/server/Server.cpp b/src/server/Server.cpp new file mode 100644 index 0000000..b648900 --- /dev/null +++ b/src/server/Server.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file