0ad/source/network/Server.h
2006-08-26 20:25:37 +00:00

149 lines
4.1 KiB
C++

#ifndef _Network_NetServer_H
#define _Network_NetServer_H
#include "Session.h"
#include "ps/GameAttributes.h"
#include "simulation/TurnManager.h"
#include "ps/scripting/JSMap.h"
#include "simulation/ScriptObject.h"
class CGame;
enum ENetServerState
{
// 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
NSS_PreBind,
// 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.
NSS_PreGame,
// In-Game state: the one with all the killing ;-)
NSS_InGame,
// The game is over and someone has won. Players might linger to chat or
// download the replay log.
NSS_PostGame
};
class CNetServerSession;
class CNetServer:
protected CServerSocket,
protected CTurnManager,
public CJSObject<CNetServer>
{
private:
typedef std::map<int, CNetServerSession *> SessionMap;
/*
Every connected session is in m_Sessions as soon as the Handshake and
Authentication stages are complete.
*/
SessionMap m_Sessions;
CJSMap<SessionMap> m_JSI_Sessions;
/*
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;
ENetServerState m_ServerState;
CGame *m_pGame;
CGameAttributes *m_pGameAttributes;
uint m_MaxObservers;
int m_LastSessionID;
CPlayer *m_pServerPlayer;
CStrW m_Password;
CStrW m_ServerPlayerName;
CStrW m_ServerName;
CStrW m_WelcomeMessage;
int m_Port;
CScriptObject m_OnChat;
CScriptObject m_OnClientConnect;
CScriptObject m_OnClientDisconnect;
static CGameAttributes::UpdateCallback AttributeUpdate;
static CPlayer::UpdateCallback PlayerAttributeUpdate;
static PlayerSlotAssignmentCB PlayerSlotAssignmentCallback;
void FillSetGameConfig(CSetGameConfig *pMsg);
void FillSetPlayerConfig(CSetPlayerConfig *pMsg, CPlayer *pPlayer);
static CNetMessage *CreatePlayerSlotAssignmentMessage(CPlayerSlot *slot);
// JS Interface Methods
bool JSI_Open(JSContext *cx, uintN argc, jsval *argv);
static void ScriptingInit();
protected:
friend class CNetServerSession;
// Assign a session ID to the session. Do this just before calling AddSession
void AssignSessionID(CNetServerSession *pSession);
// Add the session. This will be called after the session passes the
// handshake and authentication stages. AssignSessionID should've been called
// on the session prior to calling this method.
void AddSession(CNetServerSession *pSession);
// Remove the session from the server
void RemoveSession(CNetServerSession *pSession);
// Queue a command coming in from the wire. The command has been validated
// by the caller.
void QueueIncomingCommand(CNetMessage *pMsg);
// Call the JS callback for incoming events
void OnChat(const CStrW& from, const CStrW& message);
void OnClientConnect(CNetServerSession *pSession);
void OnClientDisconnect(CNetServerSession *pSession);
// 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(CGame *pGame, CGameAttributes *pGameAttribs);
virtual ~CNetServer();
static void GetDefaultListenAddress(CSocketAddress &address);
PS_RESULT Bind(const CSocketAddress &address);
inline void SetPassword(const CStr& password)
{ m_Password=password; }
inline const CStrW& GetServerPlayerName()
{ return m_ServerPlayerName; }
inline ENetServerState GetServerState()
{ return m_ServerState; }
int StartGame();
void Broadcast(CNetMessage *);
};
extern CNetServer *g_NetServer;
#endif // _Network_NetServer_H