1
0
forked from 0ad/0ad
0ad/source/network/Server.h
janwas c0ed950657 had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).

it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.

after several hours, the code now requires fewer casts and less
guesswork.

other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.

This was SVN commit r5942.
2008-05-11 18:48:32 +00:00

154 lines
4.2 KiB
C++

#ifndef INCLUDED_NETWORK_SERVER
#define INCLUDED_NETWORK_SERVER
#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;
size_t 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);
// Synchronization object for batches
CMutex m_Mutex;
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 bool NewTurnReady();
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 *);
static void ScriptingInit();
};
extern CNetServer *g_NetServer;
#endif // INCLUDED_NETWORK_SERVER