summaryrefslogtreecommitdiffstats
path: root/source/Server.h
blob: 176c82a40601813059e3f4e9d93d5fb2423c45a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

// cServer.h

// Interfaces to the cServer object representing the network server





#pragma once

#include "OSSupport/SocketThreads.h"
#include "OSSupport/ListenThread.h"
#include "CryptoPP/rsa.h"
#include "CryptoPP/randpool.h"
#include "RCONServer.h"





// fwd:
class cPlayer;
class cClientHandle;
class cIniFile;
class cCommandOutputCallback ;

typedef std::list<cClientHandle *> cClientHandleList;





class cServer										// tolua_export
	: public cListenThread::cCallback
{													// tolua_export
public:												// tolua_export
	bool InitServer(cIniFile & a_SettingsIni);

	// tolua_begin
	
	const AString & GetDescription(void) const {return m_Description; }

	// Player counts:
	int  GetMaxPlayers(void) const {return m_MaxPlayers; }
	int  GetNumPlayers(void) const { return m_NumPlayers; }
	void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; }
	
	void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL);

	// tolua_end

	bool Start(void);

	bool Command(cClientHandle & a_Client, AString & a_Cmd);
	
	/// Executes the console command, sends output through the specified callback
	void ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output);

	/// Binds the built-in console commands with the plugin manager
	static void BindBuiltInConsoleCommands(void);
	
	void Shutdown(void);

	void SendMessage(const AString & a_Message, cPlayer * a_Player = NULL, bool a_bExclude = false );  // tolua_export
	
	void KickUser(int a_ClientID, const AString & a_Reason);
	void AuthenticateUser(int a_ClientID);  // Called by cAuthenticator to auth the specified user

	const AString & GetServerID(void) const { return m_ServerID; }  // tolua_export
	
	void ClientDestroying(const cClientHandle * a_Client);  // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client
	
	void NotifyClientWrite(const cClientHandle * a_Client);  // Notifies m_SocketThreads that client has something to be written
	
	void WriteToClient(const cClientHandle * a_Client, const AString & a_Data);  // Queues outgoing data for the client through m_SocketThreads
	
	void QueueClientClose(const cClientHandle * a_Client);  // Queues the clienthandle to close when all its outgoing data is sent
	
	void RemoveClient(const cClientHandle * a_Client);  // Removes the clienthandle from m_SocketThreads
	
	CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
	CryptoPP::RSA::PublicKey  & GetPublicKey (void) { return m_PublicKey; }
	
private:

	friend class cRoot; // so cRoot can create and destroy cServer
	
	/// When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap)
	class cNotifyWriteThread :
		public cIsThread
	{
		typedef cIsThread super;
		
		cEvent    m_Event;  // Set when m_Clients gets appended
		cServer * m_Server;

		cCriticalSection  m_CS;
		cClientHandleList m_Clients;
		
		virtual void Execute(void);
		
	public:	
	
		cNotifyWriteThread(void);
		~cNotifyWriteThread();
	
		bool Start(cServer * a_Server);
		
		void NotifyClientWrite(const cClientHandle * a_Client);
	} ;
	
	/// The server tick thread takes care of the players who aren't yet spawned in a world
	class cTickThread :
		public cIsThread
	{
		typedef cIsThread super;
		
	public:
		cTickThread(cServer & a_Server);
		
	protected:
		cServer & m_Server;
		
		// cIsThread overrides:
		virtual void Execute(void) override;
	} ;
	
	
	cNotifyWriteThread m_NotifyWriteThread;
	
	cListenThread m_ListenThreadIPv4;
	cListenThread m_ListenThreadIPv6;
	
	cCriticalSection  m_CSClients;  // Locks client list
	cClientHandleList m_Clients;    // Clients that are connected to the server
	
	cSocketThreads m_SocketThreads;
	
	int m_ClientViewDistance;  // The default view distance for clients; settable in Settings.ini

	bool m_bIsConnected; // true - connected false - not connected

	bool m_bRestarting;
	
	CryptoPP::RSA::PrivateKey m_PrivateKey;
	CryptoPP::RSA::PublicKey  m_PublicKey;
	
	cRCONServer m_RCONServer;
	
	AString m_Description;
	int m_MaxPlayers;
	int m_NumPlayers;
	
	cTickThread m_TickThread;
	cEvent m_RestartEvent;
	
	/// The server ID used for client authentication
	AString m_ServerID;
	

	cServer(void);

	/// Loads, or generates, if missing, RSA keys for protocol encryption
	void PrepareKeys(void);
	
	bool Tick(float a_Dt);

	// cListenThread::cCallback overrides:
	virtual void OnConnectionAccepted(cSocket & a_Socket) override;
}; // tolua_export