-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathCServer.h
291 lines (236 loc) · 8.92 KB
/
CServer.h
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/////////////////////////////////////////
//
// OpenLieroX
//
// code under LGPL, based on JasonBs work,
// enhanced by Dark Charlie and Albert Zeyer
//
//
/////////////////////////////////////////
// Server class
// Created 28/6/02
// Jason Boettcher
#ifndef __CSERVER_H__
#define __CSERVER_H__
#include <string>
#include "Networking.h"
#include "SmartPointer.h"
#include "CBonus.h"
#include "CShootList.h"
#include "HTTP.h"
#include "Timer.h"
#include "CBanList.h"
#include "game/GameMode.h"
class CWorm;
class CServerConnection;
class CMap;
struct Version;
class CGameMode;
struct WormJoinInfo;
class FlagInfo;
struct weapon_t;
enum {
MAX_CHALLENGES = 1024,
MAX_SERVER_SOCKETS = 4, // = max UDP masterservers
};
// Challenge structure
class challenge_t { public:
NetworkAddr Address;
AbsTime fTime;
int iNum;
std::string sClientVersion;
};
// Client leaving reasons
enum {
CLL_QUIT=0,
CLL_TIMEOUT,
CLL_KICK,
CLL_BAN
};
class GameServer {
public:
GameServer();
~GameServer();
public:
// Handles information about a client connecting using NAT traversal
struct NatConnection {
SmartPointer<NetworkSocket> tTraverseSocket;
SmartPointer<NetworkSocket> tConnectHereSocket;
NetworkAddr tAddress;
AbsTime fLastUsed;
bool bClientConnected;
NatConnection() : bClientConnected(false) { tTraverseSocket = new NetworkSocket(); tConnectHereSocket = new NetworkSocket(); }
};
private:
// Attributes
// Clients
CServerConnection *cClients; // TODO: use std::list or vector
// Bonuses
CBonus cBonuses[MAX_BONUSES]; // TODO: use std::list or vector
// Map
FlagInfo* m_flagInfo;
// Simulation
int lastClientSendData;
bool recheckGame;
AbsTime fLastBonusTime;
int iLastVictim; // TODO: what is this good for
// Network
SmartPointer<NetworkSocket> tSockets[MAX_SERVER_SOCKETS];
int nPort;
typedef std::list< SmartPointer<NatConnection> > NatConnList;
NatConnList tNatClients;
challenge_t tChallenges[MAX_CHALLENGES]; // TODO: use std::list or vector
CShootList cShootList;
CHttp tHttp;
CHttp tHttp2;
bool bLocalClientConnected;
int iSuicidesInPacket;
CBanList cBanList;
AbsTime fLastUpdateSent;
bool bServerRegistered;
AbsTime fLastRegister;
std::string sCurrentUrl;
std::list<std::string>::iterator tCurrentMasterServer;
std::list<std::string> tMasterServers;
AbsTime fRegisterUdpTime;
std::vector<std::string> tUdpMasterServers;
int iFirstUdpMasterServerNotRespondingCount;
AbsTime fWeaponSelectionTime;
int iWeaponSelectionTime_Warning;
std::string sExternalIP;
bool m_clientsNeedLobbyUpdate;
AbsTime m_clientsNeedLobbyUpdateTime;
std::string netError;
friend class CServerNetEngine;
friend class CServerNetEngineBeta7;
friend class CServerNetEngineBeta9;
public:
// Methods
void Clear();
void ResetSockets();
void SetSocketWithEvents(bool v);
int StartServer();
void Shutdown();
void notifyLog(const std::string& msg);
// Game
void Frame();
int PrepareGame(std::string* errMsg = NULL);
void BeginMatch(CServerConnection* cl = NULL); // if NULL, begin match for everybody; or only for cl
void GameOver();
void SpawnWorm(CWorm *Worm, const std::string& reason, CVec * _pos = NULL, CServerConnection * client = NULL);
void SimulateGame();
void SpawnBonus();
void WormShoot(CWorm *w);
void WormShootEnd(CWorm* w, const weapon_t* weapon);
void RecheckGame();
void gotoLobby();
// Network
bool ReadPackets();
void SendPackets(bool sendPendingOnly = false);
bool ReadPacketsFromSocket(const SmartPointer<NetworkSocket>& sock);
int getPort() { return nPort; }
bool checkBandwidth(CServerConnection *cl);
static bool checkUploadBandwidth(float fCurUploadRate); // used by client/server to check upload
static float getMaxUploadBandwidth();
void ObtainExternalIP();
void ProcessGetExternalIP();
void RegisterServer();
void RegisterServerUdp();
void ProcessRegister();
void CheckRegister();
bool DeRegisterServer();
void DeRegisterServerUdp();
bool ProcessDeRegister();
void CheckTimeouts();
void CheckWeaponSelectionTime();
void DropClient(CServerConnection *cl, int reason, const std::string& sReason, bool showReason = true);
CWorm* AddWorm(const WormJoinInfo& wormInfo, CServerConnection* cl);
void PrepareWorm(CWorm* worm);
void RemoveClient(CServerConnection *cl, const std::string& reason);
void RemoveClientWorms(CServerConnection* cl, const std::set<CWorm*>& worms, const std::string& reason);
void RemoveAllClientWorms(CServerConnection* cl, const std::string& reason);
void kickWorm(int wormID, const std::string& sReason, bool showReason = true);
void kickWorm(const std::string& szWormName, const std::string& sReason, bool showReason = true);
void banWorm(int wormID, const std::string& sReason, bool showReason = true);
void banWorm(const std::string& szWormName, const std::string& sReason, bool showReason = true);
void muteWorm(int wormID);
void muteWorm(const std::string& szWormName);
void unmuteWorm(int wormID);
void unmuteWorm(const std::string& szWormName);
void authorizeWorm(int wormID);
void killWorm(int victimID, int killerID, int suicidesCount = 0); // suicidesCount is ignored if victimID != killerID
void cloneWeaponsToAllWorms(CWorm* worm);
void CheckReadyClient();
void CheckForFillWithBots();
float GetDownload();
float GetUpload(float timeRange = 2.0f);
void checkVersionCompatibilities(bool dropOut);
bool checkVersionCompatibility(CServerConnection* cl, bool dropOut, bool makeMsg = true, std::string* msg = NULL);
bool isVersionCompatible(const Version& ver, std::string* incompReason = NULL);
bool clientsConnected_less(const Version& ver); // true if clients < ver are connected
// Sending
void SendGlobalPacket(CBytestream *bs); // TODO: move this to CServerNetEngine
void SendGlobalPacket(CBytestream* bs, const Version& minVersion);
void SendGlobalText(const std::string& text, int type);
void SendWormsOut(const std::list<byte>& ids);
void SendDisconnect();
void SendWormLobbyUpdate(CServerConnection* receiver = NULL, CServerConnection *target = NULL); // if NULL, to everybody, or only to cl. If target is NULL send info about all worms
void UpdateGameLobby();
void UpdateWorms();
void UpdateWorm(CWorm* w);
#ifdef FUZZY_ERROR_TESTING
void SendRandomPacket();
#endif
void SendFiles();
void SendEmptyWeaponsOnRespawn( CWorm * Worm );
bool SendUpdate();
void SendGameStateUpdates();
void SendWeapons(CServerConnection* cl = NULL, CWorm* w = NULL); // if NULL, send globally, else only to that client
void SendWormTagged(CWorm *w);
void SendTeamScoreUpdate();
void SendPlaySound(const std::string& name);
void SetWormSpeedFactor(int wormID, float f);
void SetWormCanUseNinja(int wormID, bool b);
void SetWormDamageFactor(int wormID, float f);
void SetWormShieldFactor(int wormID, float f);
void SetWormCanAirJump(int wormID, bool b);
bool CanWormHandleClientSideRespawn(CWorm* w);
// Connectionless packets only here
void ParseConnectionlessPacket(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs, const std::string& ip);
void ParseGetChallenge(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs);
void ParseConnect(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs);
void ParsePing(const SmartPointer<NetworkSocket>& tSocket);
void ParseTime(const SmartPointer<NetworkSocket>& tSocket);
void ParseQuery(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs, const std::string& ip);
void ParseGetInfo(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bsHeader = NULL);
void ParseWantsJoin(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs, const std::string& ip);
void ParseTraverse(const SmartPointer<NetworkSocket>& tSocket, CBytestream *bs, const std::string& ip);
void ParseServerRegistered(const SmartPointer<NetworkSocket>& tSocket);
// Variables
FlagInfo* flagInfo() const { return m_flagInfo; }
CBanList *getBanList() { return &cBanList; }
CServerConnection *getClient(int iWormID);
CHttp *getHttp() { return &tHttp; }
CServerConnection* getClients() { return cClients; }
CServerConnection* localClientConnection();
CServerConnection* firstNonlocalClientConnection();
bool isServerRunning() const { return cClients != NULL; }
int getNumBots() const;
int getLastBot() const;
int getFirstEmptyTeam() const; // -1 if there is no empty team; only possible teams by gamemode
bool isTeamEmpty(int t) const;
int getTeamWormNum(int t) const;
bool allWormsHaveFullLives() const;
int getAliveWormCount() const;
int getAliveTeamCount() const;
CWorm *getFirstAliveWorm() const;
void setWeaponRestFile(const std::string& fn);
void setDefaultWeaponRestFile();
bool serverChoosesWeapons();
bool serverAllowsConnectDuringGame();
void DumpGameState(CmdLineIntf* caller);
void DumpConnections();
};
extern GameServer *cServer;
void SyncServerAndClient();
#endif // __CSERVER_H__