2004-08-16 17:19:17 +02:00
|
|
|
#ifndef _Network_NetServer_H
|
|
|
|
#define _Network_NetServer_H
|
|
|
|
|
|
|
|
#include "Network/Session.h"
|
|
|
|
#include "Game.h"
|
|
|
|
#include "TurnManager.h"
|
|
|
|
|
|
|
|
class CNetServer;
|
|
|
|
class CPlayer;
|
|
|
|
|
|
|
|
class CNetServerSession: public CNetSession
|
|
|
|
{
|
|
|
|
CNetServer *m_pServer;
|
|
|
|
CPlayer *m_pPlayer;
|
|
|
|
bool m_IsObserver;
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~CNetServerSession();
|
|
|
|
|
|
|
|
inline CNetServerSession(CNetServer *pServer, CSocketInternal *pInt, MessageHandler *pMsgHandler=HandshakeHandler):
|
|
|
|
CNetSession(pInt, pMsgHandler),
|
|
|
|
m_pServer(pServer)
|
|
|
|
{}
|
|
|
|
|
|
|
|
inline bool IsObserver()
|
|
|
|
{ return m_IsObserver; }
|
|
|
|
|
|
|
|
// Called by server when starting the game, after sending NMT_StartGame to
|
|
|
|
// all connected clients.
|
|
|
|
void StartGame();
|
|
|
|
|
2004-09-21 16:40:43 +02:00
|
|
|
static MessageHandler BaseHandler;
|
2004-08-16 17:19:17 +02:00
|
|
|
static MessageHandler HandshakeHandler;
|
|
|
|
static MessageHandler AuthenticateHandler;
|
|
|
|
static MessageHandler PreGameHandler;
|
|
|
|
static MessageHandler ObserverHandler;
|
|
|
|
static MessageHandler ChatHandler;
|
|
|
|
static MessageHandler InGameHandler;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ENetServerState
|
|
|
|
{
|
2004-09-21 16:40:43 +02:00
|
|
|
// We haven't opened the port yet, we're just setting some stuff up.
|
|
|
|
// This is probably equivalent to the first "Start Network Game" screen
|
2004-08-16 17:19:17 +02:00
|
|
|
NSS_PreBind,
|
2004-09-21 16:40:43 +02:00
|
|
|
// The server is open and accepting connections. This is the screen where
|
|
|
|
// rules are set up by the operator and where players join and select civs
|
|
|
|
// and stuff.
|
2004-08-16 17:19:17 +02:00
|
|
|
NSS_PreGame,
|
|
|
|
NSS_InGame,
|
2004-09-21 16:40:43 +02:00
|
|
|
// The game is over and someone has won. Players might linger to chat or
|
|
|
|
// download the replay log.
|
2004-08-16 17:19:17 +02:00
|
|
|
NSS_PostGame
|
|
|
|
};
|
|
|
|
|
|
|
|
class CNetServerAttributes: public CAttributeMap
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CNetServerAttributes();
|
|
|
|
};
|
|
|
|
|
|
|
|
class CNetServer: protected CServerSocket, protected CTurnManager
|
|
|
|
{
|
|
|
|
private:
|
2004-09-21 16:40:43 +02:00
|
|
|
/*
|
|
|
|
Every connected session is in m_Sessions as soon as the Handshake and
|
|
|
|
Authentication stages are complete.
|
|
|
|
*/
|
2004-08-16 17:19:17 +02:00
|
|
|
std::vector <CNetServerSession *> m_Sessions;
|
2004-09-21 16:40:43 +02:00
|
|
|
/*
|
|
|
|
All sessions currently associated with a player. Subset of m_Sessions.
|
|
|
|
*/
|
2004-08-16 17:19:17 +02:00
|
|
|
std::vector <CNetServerSession *> m_PlayerSessions;
|
2004-09-21 16:40:43 +02:00
|
|
|
/*
|
|
|
|
All sessions that have observer status (observer as in watcher - simple
|
|
|
|
chatters don't have an entry here, only in m_Sessions).
|
|
|
|
Sessions are added here after they have successfully requested observer
|
|
|
|
status.
|
|
|
|
*/
|
|
|
|
std::vector <CNetServerSession *> m_Observers;
|
|
|
|
|
2004-08-16 17:19:17 +02:00
|
|
|
uint m_NumPlayers;
|
2004-09-21 16:40:43 +02:00
|
|
|
uint m_MaxObservers;
|
2004-08-16 17:19:17 +02:00
|
|
|
|
|
|
|
ENetServerState m_ServerState;
|
|
|
|
|
|
|
|
CGame *m_pGame;
|
|
|
|
CGameAttributes *m_pGameAttributes;
|
|
|
|
CNetServerAttributes *m_pServerAttributes;
|
|
|
|
|
|
|
|
CStr m_Password;
|
|
|
|
CStrW m_ServerPlayerName;
|
|
|
|
|
|
|
|
static CAttributeMap::UpdateCallback AttributeUpdate;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
friend class CNetServerSession;
|
|
|
|
|
|
|
|
// Try to add the session as a newly connected player. If that is not
|
|
|
|
// possible, make the session an observer.
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
// true. The session has been allocated a player slot
|
|
|
|
// false: All player slots busy, the session should be made an observer
|
|
|
|
bool AddNewPlayer(CNetServerSession *pSession);
|
|
|
|
|
2004-09-21 16:40:43 +02:00
|
|
|
// Remove the session from all the relevant lists.
|
|
|
|
// NOTE: Currently unsafe to call for observers or players
|
|
|
|
void RemoveSession(CNetServerSession *pSession);
|
|
|
|
|
2004-08-16 17:19:17 +02:00
|
|
|
// Queue a command coming in from the wire. The command has been validated
|
|
|
|
// by the caller.
|
|
|
|
void QueueIncomingCommand(CNetMessage *pMsg);
|
|
|
|
|
|
|
|
// OVERRIDES FROM CServerSocket
|
|
|
|
virtual void OnAccept(const CSocketAddress &);
|
|
|
|
|
|
|
|
// OVERRIDES FROM CTurnManager
|
|
|
|
virtual void NewTurn();
|
|
|
|
virtual void QueueLocalCommand(CNetMessage *pMsg);
|
|
|
|
|
|
|
|
// OVERRIDABLES
|
|
|
|
// Will only be called from the Network Thread, by the OnAccept handler
|
|
|
|
virtual CNetServerSession *CreateSession(CSocketInternal *pInt);
|
|
|
|
|
|
|
|
// Ask the server if the session is allowed to start observing.
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
// true if the session should be made an observer
|
|
|
|
// false otherwise
|
|
|
|
virtual bool AllowObserver(CNetServerSession *pSession);
|
|
|
|
|
|
|
|
public:
|
|
|
|
CNetServer(CNetServerAttributes *pServerAttribs, CGame *pGame, CGameAttributes *pGameAttribs);
|
|
|
|
|
|
|
|
static void GetDefaultListenAddress(CSocketAddress &address);
|
|
|
|
PS_RESULT Bind(const CSocketAddress &address);
|
|
|
|
|
|
|
|
inline void SetPassword(CStr password)
|
|
|
|
{ m_Password=password; }
|
|
|
|
|
|
|
|
inline CStrW GetServerPlayerName()
|
|
|
|
{ return m_ServerPlayerName; }
|
|
|
|
|
|
|
|
inline ENetServerState GetServerState()
|
|
|
|
{ return m_ServerState; }
|
|
|
|
|
|
|
|
int StartGame();
|
|
|
|
|
|
|
|
// Synchronized, safe to call from any thread
|
|
|
|
void Broadcast(CNetMessage *);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern CNetServer *g_NetServer;
|
|
|
|
extern CNetServerAttributes g_NetServerAttributes;
|
|
|
|
|
|
|
|
#endif // _Network_NetServer_H
|