Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
NetGame.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: NetGame.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Network Game Manager class
13 */
14 
15 #include "MemDebug.h"
16 #include "NetGame.h"
17 #include "NetGameClient.h"
18 #include "NetGameServer.h"
19 #include "NetClientConfig.h"
20 #include "NetServerConfig.h"
21 #include "NetPlayer.h"
22 
23 #include "NetMsg.h"
24 #include "NetData.h"
25 #include "NetLayer.h"
26 
27 #include "Player.h"
28 #include "Ship.h"
29 #include "ShipDesign.h"
30 #include "Sim.h"
31 #include "Element.h"
32 #include "HUDView.h"
33 
34 #include "NetHost.h"
35 #include "Game.h"
36 #include "Light.h"
37 
38 // +--------------------------------------------------------------------+
39 
40 const int MAX_NET_FPS = 20;
41 const int MIN_NET_FRAME = 1000 / MAX_NET_FPS;
42 
43 const DWORD SHIP_ID_START = 0x0010;
44 const DWORD SHOT_ID_START = 0x0400;
45 
46 static NetGame* netgame = 0;
47 
48 static DWORD ship_id_key = SHIP_ID_START;
49 static DWORD shot_id_key = SHOT_ID_START;
50 
51 static long start_time = 0;
52 
53 // +--------------------------------------------------------------------+
54 
56 : objid(0), netid(0), link(0), local_player(0), last_send_time(0), active(true)
57 {
58  netgame = this;
59  sim = Sim::GetSim();
60 
61  ship_id_key = SHIP_ID_START;
62  shot_id_key = SHOT_ID_START;
63 
64  if (sim)
66 
67  Player* player = Player::GetCurrentPlayer();
68  if (player) {
69  player_name = player->Name();
70  player_pass = player->Password();
71  }
72 
73  start_time = NetLayer::GetUTC();
74 }
75 
77 {
78  netgame = 0;
79  local_player = 0;
80  players.destroy();
81 
82  if (link) {
83  double delta = fabs((double)(NetLayer::GetUTC() - start_time));
84  double bandwidth = 10.0 * (link->GetBytesSent() + link->GetBytesRecv()) / delta;
85  double recvrate = link->GetPacketsRecv() / delta;
86 
87  Print("NetGame Stats\n-------------\n");
88  Print(" packets sent %d\n", link->GetPacketsSent());
89  Print(" packets recv %d\n", link->GetPacketsRecv());
90  Print(" bytes sent %d\n", link->GetBytesSent());
91  Print(" bytes recv %d\n", link->GetBytesRecv());
92  Print(" retries %d\n", link->GetRetries());
93  Print(" drops %d\n", link->GetDrops());
94  Print(" avg lag %d msec\n", link->GetLag());
95  Print(" time %d sec\n", (int) delta);
96  Print(" bandwidth %d bps\n", (int) bandwidth);
97  Print(" packet rate %d pps in\n\n", (int) recvrate);
98 
99  delete link;
100  }
101 }
102 
103 // +--------------------------------------------------------------------+
104 
105 NetGame*
107 {
108  if (!netgame) {
110  netgame = new(__FILE__,__LINE__) NetGameServer;
111 
112  else if (NetClientConfig::GetInstance() && NetClientConfig::GetInstance()->GetSelectedServer())
113  netgame = new(__FILE__,__LINE__) NetGameClient;
114  }
115 
116  return netgame;
117 }
118 
119 NetGame*
121 {
122  return netgame;
123 }
124 
125 DWORD
127 {
128  if (local_player)
129  return local_player->GetObjID();
130 
131  return 0;
132 }
133 
134 DWORD
136 {
137  if (type == SHIP) {
138  if (ship_id_key >= SHOT_ID_START)
139  ship_id_key = SHIP_ID_START;
140 
141  return ship_id_key++;
142  }
143 
144  else if (type == SHOT) {
145  if (shot_id_key >= 0xFFFE)
146  shot_id_key = SHOT_ID_START;
147 
148  return shot_id_key++;
149  }
150 
151  return 0;
152 }
153 
154 // +--------------------------------------------------------------------+
155 
156 void
158 {
159  Send();
160  Recv();
161 }
162 
163 void
165 {
166  NetMsg* msg = link->GetMessage();
167 
168  while (msg) {
169  if (active) {
170  // For Debug Convenience:
171  // NetPlayer* player = FindPlayerByNetID(msg->NetID());
172 
173  switch (msg->Type()) {
174  case NET_JOIN_REQUEST: DoJoinRequest(msg); break;
175  case NET_JOIN_ANNOUNCE: DoJoinAnnounce(msg); break;
176  case NET_QUIT_REQUEST: DoQuitRequest(msg); break;
177  case NET_QUIT_ANNOUNCE: DoQuitAnnounce(msg); break;
178  case NET_GAME_OVER: DoGameOver(msg); break;
179  case NET_DISCONNECT: DoDisconnect(msg); break;
180 
181  case NET_OBJ_LOC: DoObjLoc(msg); break;
182  case NET_OBJ_DAMAGE: DoObjDamage(msg); break;
183  case NET_OBJ_KILL: DoObjKill(msg); break;
184  case NET_OBJ_SPAWN: DoObjSpawn(msg); break;
185  case NET_OBJ_HYPER: DoObjHyper(msg); break;
186  case NET_OBJ_TARGET: DoObjTarget(msg); break;
187  case NET_OBJ_EMCON: DoObjEmcon(msg); break;
188  case NET_SYS_DAMAGE: DoSysDamage(msg); break;
189  case NET_SYS_STATUS: DoSysStatus(msg); break;
190 
191  case NET_ELEM_CREATE: DoElemCreate(msg); break;
192  case NET_ELEM_REQUEST: DoElemRequest(msg); break;
193  case NET_SHIP_LAUNCH: DoShipLaunch(msg); break;
194  case NET_NAV_DATA: DoNavData(msg); break;
195  case NET_NAV_DELETE: DoNavDelete(msg); break;
196 
197  case NET_WEP_TRIGGER: DoWepTrigger(msg); break;
198  case NET_WEP_RELEASE: DoWepRelease(msg); break;
199  case NET_WEP_DESTROY: DoWepDestroy(msg); break;
200 
201  case NET_COMM_MESSAGE: DoCommMsg(msg); break;
202  case NET_CHAT_MESSAGE: DoChatMsg(msg); break;
203  case NET_SELF_DESTRUCT: DoSelfDestruct(msg); break;
204  }
205  }
206 
207  delete msg;
208  msg = link->GetMessage();
209  }
210 }
211 
212 // +--------------------------------------------------------------------+
213 
214 void
216 {
217 }
218 
219 int
221 {
222  if (netgame) {
223  int num_players = netgame->players.size();
224 
225  if (netgame->local_player)
226  num_players++;
227 
228  return num_players;
229  }
230 
231  return 0;
232 }
233 
234 NetPlayer*
235 NetGame::FindPlayerByName(const char* name)
236 {
237  for (int i = 0; i < players.size(); i++) {
238  NetPlayer* p = players[i];
239 
240  if (!strcmp(p->Name(), name))
241  return p;
242  }
243 
244  return 0;
245 }
246 
247 NetPlayer*
249 {
250  for (int i = 0; i < players.size(); i++) {
251  NetPlayer* p = players[i];
252 
253  if (p->GetNetID() == netid)
254  return p;
255  }
256 
257  return 0;
258 }
259 
260 NetPlayer*
262 {
263  for (int i = 0; i < players.size(); i++) {
264  NetPlayer* p = players[i];
265 
266  if (p->GetObjID() == objid)
267  return p;
268  }
269 
270  return 0;
271 }
272 
273 Ship*
275 {
276  if (sim)
277  return sim->FindShipByObjID(objid);
278 
279  return 0;
280 }
281 
282 Shot*
284 {
285  if (sim)
286  return sim->FindShotByObjID(objid);
287 
288  return 0;
289 }
290 
291 NetPeer*
293 {
294  if (player && link) {
295  return link->FindPeer(player->GetNetID());
296  }
297 
298  return 0;
299 }
300 
301 // +--------------------------------------------------------------------+
302 
303 void
304 NetGame::Respawn(DWORD objid, Ship* spawn)
305 {
306 }
307 
308 // +--------------------------------------------------------------------+
309 
310 bool
312 {
313  return netgame != 0;
314 }
315 
316 bool
318 {
319  if (netgame)
320  return netgame->IsClient();
321  return false;
322 }
323 
324 bool
326 {
327  if (netgame)
328  return netgame->IsServer();
329  return false;
330 }