From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_net_game_server_8cpp_source.html | 1311 ++++++++++++++++++++ 1 file changed, 1311 insertions(+) create mode 100644 Doc/doxygen/html/_net_game_server_8cpp_source.html (limited to 'Doc/doxygen/html/_net_game_server_8cpp_source.html') diff --git a/Doc/doxygen/html/_net_game_server_8cpp_source.html b/Doc/doxygen/html/_net_game_server_8cpp_source.html new file mode 100644 index 0000000..58268dc --- /dev/null +++ b/Doc/doxygen/html/_net_game_server_8cpp_source.html @@ -0,0 +1,1311 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/NetGameServer.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
NetGameServer.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 5.0
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2007. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: NetGameServer.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Server-Side Network Game Manager class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "NetGameServer.h"
+
17 #include "NetServerConfig.h"
+
18 #include "NetLobbyServer.h"
+
19 #include "NetPlayer.h"
+
20 #include "NetUser.h"
+
21 #include "NetMsg.h"
+
22 #include "NetData.h"
+
23 #include "StarServer.h"
+
24 #include "Ship.h"
+
25 #include "ShipDesign.h"
+
26 #include "Shield.h"
+
27 #include "Sim.h"
+
28 #include "SimEvent.h"
+
29 #include "Element.h"
+
30 #include "HUDView.h"
+
31 #include "RadioMessage.h"
+
32 #include "RadioView.h"
+
33 #include "Instruction.h"
+
34 #include "Hangar.h"
+
35 #include "FlightDeck.h"
+
36 #include "Mission.h"
+
37 
+
38 #include "NetLayer.h"
+
39 #include "NetHost.h"
+
40 #include "NetPeer.h"
+
41 #include "NetUtil.h"
+
42 #include "Game.h"
+
43 #include "Light.h"
+
44 
+
45 // +--------------------------------------------------------------------+
+
46 
+
47 const int MAX_NET_FPS = 20;
+
48 const int MIN_NET_FRAME = 1000 / MAX_NET_FPS;
+
49 
+
50 // +--------------------------------------------------------------------+
+
51 
+ +
53 {
+
54  Print("Constructing NetGameServer\n");
+
55 
+
56  WORD server_port = 11101;
+
57 
+ +
59  server_port = NetServerConfig::GetInstance()->GetGamePort();
+
60 
+
61  NetAddr server(NetHost().Address().IPAddr(), server_port);
+
62 
+
63  link = new(__FILE__,__LINE__) NetLink(server);
+
64 
+
65  ListIter<SimRegion> rgn_iter = sim->GetRegions();
+
66  while (++rgn_iter) {
+
67  SimRegion* rgn = rgn_iter.value();
+
68 
+
69  ListIter<Ship> iter = rgn->Ships();
+
70  while (++iter) {
+
71  Ship* s = iter.value();
+
72  s->SetObjID(GetNextObjID());
+
73  Observe(s);
+
74  ships.append(s);
+
75  }
+
76  }
+
77 
+
78  if (local_player) {
+ + +
81  }
+
82 }
+
83 
+ +
85 {
+ +
87  while (++player) {
+
88  NetPlayer* p = player.value();
+
89 
+
90  if (p->GetShip())
+
91  p->GetShip()->SetRespawnCount(0);
+
92 
+ +
94  }
+
95 
+
96  Sleep(500);
+
97 
+
98  ListIter<Ship> iter = ships;
+
99  while (++iter) {
+
100  Ship* s = iter.value();
+
101  s->SetRespawnCount(0);
+
102  }
+
103 
+
104  zombies.destroy();
+
105  ships.clear();
+
106 }
+
107 
+
108 // +--------------------------------------------------------------------+
+
109 
+
110 void
+ +
112 {
+ +
114  CheckSessions();
+
115 
+
116  ListIter<SimRegion> rgn_iter = sim->GetRegions();
+
117  while (++rgn_iter) {
+
118  SimRegion* rgn = rgn_iter.value();
+
119 
+
120  ListIter<Ship> iter = rgn->Ships();
+
121  while (++iter) {
+
122  Ship* s = iter.value();
+
123 
+
124  if (s->GetObjID() == 0) {
+
125  s->SetObjID(GetNextObjID());
+
126  Observe(s);
+
127  ships.append(s);
+
128 
+
129  NetJoinAnnounce join_ann;
+
130  join_ann.SetShip(s);
+
131  join_ann.SetName("Server A.I. Ship");
+
132  SendData(&join_ann);
+
133  }
+
134  }
+
135  }
+
136 
+
137 
+
138  static DWORD time_mark = 0;
+
139 
+
140  if (!time_mark) time_mark = Game::RealTime();
+
141  else if (Game::RealTime() - time_mark > 60000) {
+
142  time_mark = Game::RealTime();
+
143 
+
144  if (link && players.size() > 0) {
+
145  Print("Server Stats\n-------------\n");
+
146  Print(" packets sent %d\n", link->GetPacketsSent());
+
147  Print(" packets recv %d\n", link->GetPacketsRecv());
+
148  Print(" bytes sent %d\n", link->GetBytesSent());
+
149  Print(" bytes recv %d\n", link->GetBytesRecv());
+
150  Print(" retries %d\n", link->GetRetries());
+
151  Print(" drops %d\n", link->GetDrops());
+
152  Print(" avg lag %d msec\n", link->GetLag());
+
153  }
+
154  }
+
155 }
+
156 
+
157 void
+ +
159 {
+
160  if (!link)
+
161  return;
+
162 
+ +
164  while (++iter) {
+
165  NetPlayer* player = iter.value();
+
166  NetPeer* peer = link->FindPeer(player->GetNetID());
+
167 
+
168  if (peer && (NetLayer::GetUTC() - peer->LastReceiveTime()) > NET_DISCONNECT_TIME) {
+
169  // announce drop:
+
170  NetPlayer* zombie = iter.removeItem();
+
171  HUDView::Message(Game::GetText("NetGameServer.remote-discon").data(), zombie->Name());
+
172 
+
173  // tell everyone else:
+
174  NetQuitAnnounce quit_ann;
+
175  quit_ann.SetObjID(zombie->GetObjID());
+
176  quit_ann.SetDisconnected(true);
+
177  SendData(&quit_ann);
+
178 
+
179  // return remote ship to ship pool:
+
180  Ship* s = zombie->GetShip();
+
181  if (s) {
+
182  Observe(s);
+
183  ships.append(s);
+
184  s->SetNetworkControl(0);
+
185  zombie->SetShip(0);
+
186 
+
187  NetJoinAnnounce join_ann;
+
188  join_ann.SetShip(s);
+
189  join_ann.SetName("Server A.I. Ship");
+
190  SendData(&join_ann);
+
191  }
+
192 
+
193  zombies.append(zombie);
+
194  }
+
195  }
+
196 }
+
197 
+
198 NetPlayer*
+ +
200 {
+
201  for (int i = 0; i < zombies.size(); i++) {
+
202  NetPlayer* p = zombies[i];
+
203 
+
204  if (p->GetObjID() == objid)
+
205  return p;
+
206  }
+
207 
+
208  return 0;
+
209 }
+
210 
+
211 // +--------------------------------------------------------------------+
+
212 
+
213 void
+ +
215 {
+
216  if (!msg) return;
+
217 
+
218  bool unpause = players.isEmpty();
+
219 
+
220  NetJoinRequest join_req;
+
221  if (join_req.Unpack(msg->Data())) {
+
222  HUDView::Message(Game::GetText("NetGameServer::join-request").data(), join_req.GetName(), join_req.GetElement(), join_req.GetIndex());
+
223 
+
224  DWORD nid = msg->NetID();
+
225  Text name = join_req.GetName();
+
226  Text serno = join_req.GetSerialNumber();
+
227  Text elem_name = join_req.GetElement();
+
228  int index = join_req.GetIndex();
+
229  Ship* ship = 0;
+
230  Sim* sim = Sim::GetSim();
+
231 
+
232  if (sim) {
+
233  Element* element = sim->FindElement(elem_name);
+
234 
+
235  if (element)
+
236  ship = element->GetShip(index);
+
237  }
+
238 
+
239  if (!ship) {
+
240  Print(" JOIN DENIED: could not locate ship for remote player\n");
+
241  return;
+
242  }
+
243 
+
244  if (!ship->GetObjID()) {
+
245  Print(" JOIN DENIED: remote player requested ship with objid = 0\n");
+
246  return;
+
247  }
+
248 
+ +
250 
+
251  if (lobby) {
+
252  NetUser* user = lobby->FindUserByName(name);
+
253 
+
254  if (!user)
+
255  user = lobby->FindUserByNetID(nid);
+
256 
+
257  if (!user) {
+
258  Print(" JOIN DENIED: remote player '%s' not found in lobby\n", name.data());
+
259  return;
+
260  }
+
261 
+
262  else if (!user->IsAuthOK()) {
+
263  Print(" JOIN DENIED: remote player '%s' not authenticated\n", name.data());
+
264  return;
+
265  }
+
266  }
+
267 
+
268  NetPlayer* remote_player = FindPlayerByNetID(nid);
+
269  if (remote_player && remote_player->GetShip() != ship) {
+
270  Print(" disconnecting remote player from ship '%s'\n", ship->Name());
+
271  players.remove(remote_player);
+
272  delete remote_player;
+
273  remote_player = 0;
+
274  }
+
275 
+
276  if (!remote_player) {
+
277  Ignore(ship);
+
278  ships.remove(ship);
+
279 
+
280  remote_player = new(__FILE__,__LINE__) NetPlayer(nid);
+
281  remote_player->SetName(name);
+
282  remote_player->SetSerialNumber(serno);
+
283  remote_player->SetObjID(ship->GetObjID());
+
284  remote_player->SetShip(ship);
+
285 
+
286  HUDView::Message(Game::GetText("NetGameServer::join-announce").data());
+
287  Print("remote player name = %s\n", name.data());
+
288  Print(" obj = %d\n", ship->GetObjID());
+
289  Print(" ship = %s\n", ship->Name());
+
290 
+
291  remote_player->SetObjID(ship->GetObjID());
+
292 
+
293  // tell the new player about the server:
+
294  if (local_player) {
+
295  NetJoinAnnounce join_ann;
+
296  join_ann.SetShip(local_player);
+
297  join_ann.SetName(player_name);
+
298  link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE);
+
299  }
+
300 
+
301  // tell the new player about the existing remote players:
+ +
303  while (++iter) {
+
304  Ship* s = iter->GetShip();
+
305 
+
306  if (s) {
+
307  NetJoinAnnounce join_ann;
+
308  join_ann.SetShip(s);
+
309  join_ann.SetName(iter->Name());
+
310  join_ann.SetObjID(iter->GetObjID());
+
311  link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE);
+
312  }
+
313  }
+
314 
+
315  // tell the new player about the A.I. controlled ships:
+
316  ListIter<Ship> ai_iter = ships;
+
317  while (++ai_iter) {
+
318  Ship* s = ai_iter.value();
+
319  if (s != local_player) {
+
320  NetJoinAnnounce join_ann;
+
321  join_ann.SetShip(s);
+
322  join_ann.SetName("Server A.I. Ship");
+
323  link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE);
+
324  }
+
325  }
+
326 
+
327  // make the new player an "existing" remote player:
+
328  players.append(remote_player);
+
329 
+
330  // tell existing players about the new player:
+
331  // NOTE, this also provides the net id to the new player!
+
332  iter.reset();
+
333  while (++iter) {
+
334  Ship* s = remote_player->GetShip();
+
335 
+
336  NetJoinAnnounce join_ann;
+
337  join_ann.SetShip(s);
+
338  join_ann.SetName(remote_player->Name());
+
339  join_ann.SetObjID(remote_player->GetObjID());
+ +
341  }
+
342 
+
343  if (unpause) {
+ +
345  if (s)
+
346  s->Pause(false);
+
347  }
+
348  }
+
349  }
+
350 }
+
351 
+
352 void
+ +
354 {
+
355  if (!msg) return;
+
356 
+
357  NetJoinAnnounce join_ann;
+
358  if (join_ann.Unpack(msg->Data())) {
+
359  Print("Server received Join Announce from '%s'\n", join_ann.GetName());
+
360  }
+
361 }
+
362 
+
363 void
+ +
365 {
+
366  if (!msg) return;
+
367 
+
368  NetPlayer* player = FindPlayerByNetID(msg->NetID());
+
369 
+
370  if (player) {
+
371  NetPlayer* zombie = players.remove(player);
+
372  HUDView::Message(Game::GetText("NetGameServer.remote-quit").data(), zombie->Name());
+
373 
+
374  // tell everyone else:
+
375  NetQuitAnnounce quit_ann;
+
376  quit_ann.SetObjID(zombie->GetObjID());
+
377  SendData(&quit_ann);
+
378 
+
379  // return remote ship to ship pool:
+
380  Ship* s = zombie->GetShip();
+
381  if (s) {
+
382  Observe(s);
+
383  ships.append(s);
+
384  s->SetNetworkControl(0);
+
385  zombie->SetShip(0);
+
386 
+
387  NetJoinAnnounce join_ann;
+
388  join_ann.SetShip(s);
+
389  join_ann.SetName("Server A.I. Ship");
+
390  SendData(&join_ann);
+
391  }
+
392 
+
393  zombies.append(zombie);
+
394  }
+
395  else {
+
396  Print("Quit Request from unknown player NetID: %08X\n", msg->NetID());
+
397  }
+
398 }
+
399 
+
400 void
+ +
402 {
+
403  if (!msg) return;
+
404  Print("Server received Quit Announce from NetID: %08x\n", msg->NetID());
+
405 }
+
406 
+
407 void
+ +
409 {
+
410  if (!msg) return;
+
411  Print("Server received Game Over from NetID: %08x\n", msg->NetID());
+
412 }
+
413 
+
414 void
+ +
416 {
+
417  if (!msg) return;
+
418  Print("Server received Disconnect from NetID: %08x\n", msg->NetID());
+
419 }
+
420 
+
421 void
+ +
423 {
+
424  if (!msg) return;
+
425 
+
426  NetObjLoc obj_loc;
+
427  obj_loc.Unpack(msg->Data());
+
428 
+
429  NetPlayer* player = FindPlayerByObjID(obj_loc.GetObjID());
+
430  if (player && player->GetShip()) {
+
431  player->DoObjLoc(&obj_loc);
+
432  }
+
433 
+
434  else {
+
435  player = FindZombieByObjID(obj_loc.GetObjID());
+
436 
+
437  if (player)
+
438  SendDisconnect(player);
+
439  }
+
440 }
+
441 
+
442 void
+ +
444 {
+
445  if (!msg) return;
+
446  Print("Server received OBJ DAMAGE from NetID: %08x (ignored)\n", msg->NetID());
+
447 }
+
448 
+
449 void
+ +
451 {
+
452  if (!msg) return;
+
453 
+
454  NetObjKill obj_kill;
+
455  obj_kill.Unpack(msg->Data());
+
456 
+
457  if (obj_kill.GetKillType() != NetObjKill::KILL_DOCK) {
+
458  Print("Server received OBJ KILL from NetID: %08x (ignored)\n", msg->NetID());
+
459  return;
+
460  }
+
461 
+
462  Ship* ship = FindShipByObjID(obj_kill.GetObjID());
+
463  if (ship) {
+
464  Ship* killer = FindShipByObjID(obj_kill.GetKillerID());
+
465  Text killer_name = Game::GetText("NetGameServer.unknown");
+
466 
+
467  if (killer)
+
468  killer_name = killer->Name();
+
469 
+
470  ShipStats* killee = ShipStats::Find(ship->Name());
+
471  if (killee)
+
472  killee->AddEvent(SimEvent::DOCK, killer_name);
+
473 
+
474  FlightDeck* deck = killer->GetFlightDeck(obj_kill.GetFlightDeck());
+
475  sim->NetDockShip(ship, killer, deck);
+
476  }
+
477 }
+
478 
+
479 void
+ +
481 {
+
482  if (!msg) return;
+
483  Print("Server received OBJ SPAWN from NetID: %08x (ignored)\n", msg->NetID());
+
484 }
+
485 
+
486 void
+ +
488 {
+
489  if (!msg) return;
+
490  Print("Server received OBJ HYPER from NetID: %d\n", msg->NetID());
+
491 
+
492  NetObjHyper obj_hyper;
+
493  obj_hyper.Unpack(msg->Data());
+
494 
+
495  NetPlayer* player = FindPlayerByObjID(obj_hyper.GetObjID());
+
496  if (player && player->GetShip()) {
+
497  if (player->DoObjHyper(&obj_hyper)) {
+
498  SendData(&obj_hyper);
+
499  }
+
500  }
+
501  else {
+
502  player = FindZombieByObjID(obj_hyper.GetObjID());
+
503 
+
504  if (player)
+
505  SendDisconnect(player);
+
506  }
+
507 }
+
508 
+
509 void
+ +
511 {
+
512  if (!msg) return;
+
513 
+
514  NetObjTarget obj_target;
+
515  obj_target.Unpack(msg->Data());
+
516 
+
517  NetPlayer* player = FindPlayerByObjID(obj_target.GetObjID());
+
518  if (player) {
+
519  player->DoObjTarget(&obj_target);
+
520  }
+
521  else {
+
522  player = FindZombieByObjID(obj_target.GetObjID());
+
523 
+
524  if (player)
+
525  SendDisconnect(player);
+
526  }
+
527 }
+
528 
+
529 void
+ +
531 {
+
532  if (!msg) return;
+
533 
+
534  NetObjEmcon obj_emcon;
+
535  obj_emcon.Unpack(msg->Data());
+
536 
+
537  NetPlayer* player = FindPlayerByObjID(obj_emcon.GetObjID());
+
538  if (player) {
+
539  player->DoObjEmcon(&obj_emcon);
+
540  }
+
541  else {
+
542  player = FindZombieByObjID(obj_emcon.GetObjID());
+
543 
+
544  if (player)
+
545  SendDisconnect(player);
+
546  }
+
547 }
+
548 
+
549 // +--------------------------------------------------------------------+
+
550 
+
551 void
+ +
553 {
+
554  if (!msg) return;
+
555 
+
556  NetSysDamage sys_damage;
+
557  sys_damage.Unpack(msg->Data());
+
558 
+
559  NetPlayer* player = FindZombieByObjID(sys_damage.GetObjID());
+
560 
+
561  if (player)
+
562  SendDisconnect(player);
+
563 }
+
564 
+
565 void
+ +
567 {
+
568  if (!msg) return;
+
569 
+
570  NetSysStatus sys_status;
+
571  sys_status.Unpack(msg->Data());
+
572 
+
573  Ship* ship = FindShipByObjID(sys_status.GetObjID());
+
574  NetPlayer* player = FindPlayerByNetID(msg->NetID());
+
575 
+
576  if (ship) {
+
577  if (!player || ship->GetObjID() != player->GetObjID()) {
+
583  return;
+
584  }
+
585 
+
586  player->DoSysStatus(&sys_status);
+
587 
+
588  // rebroadcast:
+
589  System* sys = ship->GetSystem(sys_status.GetSystem());
+
590  NetUtil::SendSysStatus(ship, sys);
+
591  }
+
592 
+
593  else {
+
594  player = FindZombieByObjID(sys_status.GetObjID());
+
595 
+
596  if (player)
+
597  SendDisconnect(player);
+
598  }
+
599 }
+
600 
+
601 // +--------------------------------------------------------------------+
+
602 
+
603 void
+ +
605 {
+
606  if (!msg) return;
+
607 
+
608  NetElemRequest elem_request;
+
609  elem_request.Unpack(msg->Data());
+
610 
+
611  Sim* sim = Sim::GetSim();
+
612  Element* elem = sim->FindElement(elem_request.GetName());
+
613 
+
614  if (elem) {
+
615  int squadron = -1;
+
616  int slots[] = { -1,-1,-1,-1 };
+
617  Ship* carrier = elem->GetCarrier();
+
618 
+
619  if (carrier && carrier->GetHangar()) {
+
620  Hangar* hangar = carrier->GetHangar();
+
621 
+
622  for (int i = 0; i < 4; i++) {
+
623  hangar->FindSquadronAndSlot(elem->GetShip(i+1), squadron, slots[i]);
+
624  }
+
625  }
+
626 
+
627  NetUtil::SendElemCreate(elem, squadron, slots, false, true);
+
628  }
+
629 }
+
630 
+
631 // +--------------------------------------------------------------------+
+
632 
+
633 void
+ +
635 {
+
636  if (!msg) return;
+
637 
+
638  NetElemCreate elem_create;
+
639  elem_create.Unpack(msg->Data());
+
640 
+
641  Sim* sim = Sim::GetSim();
+
642  Element* elem = sim->CreateElement(elem_create.GetName(),
+
643  elem_create.GetIFF(),
+
644  elem_create.GetType());
+
645 
+
646  int* load = elem_create.GetLoadout();
+
647  int* slots = elem_create.GetSlots();
+
648  int squadron = elem_create.GetSquadron();
+
649  int code = elem_create.GetObjCode();
+
650  Text target = elem_create.GetObjective();
+
651  bool alert = elem_create.GetAlert();
+
652 
+
653  elem->SetIntelLevel(elem_create.GetIntel());
+
654  elem->SetLoadout(load);
+
655 
+
656  if (code > Instruction::RTB || target.length() > 0) {
+
657  Instruction* obj = new(__FILE__,__LINE__) Instruction(code, target);
+
658  elem->AddObjective(obj);
+
659  }
+
660 
+
661  Ship* carrier = sim->FindShip(elem_create.GetCarrier());
+
662  if (carrier) {
+
663  elem->SetCarrier(carrier);
+
664 
+
665  Hangar* hangar = carrier->GetHangar();
+
666  if (hangar) {
+
667  Text squadron_name = hangar->SquadronName(squadron);
+
668  elem->SetSquadron(squadron_name);
+
669 
+
670  FlightDeck* deck = 0;
+
671  int queue = 1000;
+
672 
+
673  for (int i = 0; i < carrier->NumFlightDecks(); i++) {
+
674  FlightDeck* d = carrier->GetFlightDeck(i);
+
675 
+
676  if (d && d->IsLaunchDeck()) {
+
677  int dq = hangar->PreflightQueue(d);
+
678 
+
679  if (dq < queue) {
+
680  queue = dq;
+
681  deck = d;
+
682  }
+
683  }
+
684  }
+
685 
+
686  for (int i = 0; i < 4; i++) {
+
687  int slot = slots[i];
+
688  if (slot > -1) {
+
689  hangar->GotoAlert(squadron, slot, deck, elem, load, !alert);
+
690  }
+
691  }
+
692  }
+
693  }
+
694 
+ +
696  elem_create.GetSquadron(),
+
697  elem_create.GetSlots(),
+
698  elem_create.GetAlert());
+
699 }
+
700 
+
701 void
+ +
703 {
+
704  if (!msg) return;
+
705 
+
706  NetShipLaunch ship_launch;
+
707  ship_launch.Unpack(msg->Data());
+
708 
+
709  Sim* sim = Sim::GetSim();
+
710  int squadron = ship_launch.GetSquadron();
+
711  int slot = ship_launch.GetSlot();
+
712 
+
713  NetPlayer* player = FindPlayerByObjID(ship_launch.GetObjID());
+
714  if (player) {
+
715  Ship* carrier = player->GetShip();
+
716 
+
717  if (carrier) {
+
718  Hangar* hangar = carrier->GetHangar();
+
719 
+
720  if (hangar) {
+
721  hangar->Launch(squadron, slot);
+
722  }
+
723 
+
724  NetUtil::SendShipLaunch(carrier, squadron, slot);
+
725  }
+
726  }
+
727 }
+
728 
+
729 void
+ +
731 {
+
732  if (!msg) return;
+
733 
+
734  NetNavData nav_data;
+
735  nav_data.Unpack(msg->Data());
+
736 
+
737  Element* elem = sim->FindElement(nav_data.GetElem());
+
738 
+
739  if (elem) {
+
740  if (nav_data.IsAdd()) {
+
741  Instruction* navpt = new(__FILE__,__LINE__) Instruction(*nav_data.GetNavPoint());
+
742  Instruction* after = 0;
+
743  int index = nav_data.GetIndex();
+
744 
+
745  if (index >= 0 && index < elem->GetFlightPlan().size())
+
746  after = elem->GetFlightPlan().at(index);
+
747 
+
748  elem->AddNavPoint(navpt, after, false);
+
749  }
+
750 
+
751  else {
+
752  Instruction* navpt = nav_data.GetNavPoint();
+
753  Instruction* exist = 0;
+
754  int index = nav_data.GetIndex();
+
755 
+
756  if (navpt && index >= 0 && index < elem->GetFlightPlan().size()) {
+
757  exist = elem->GetFlightPlan().at(index);
+
758  *exist = *navpt;
+
759  }
+
760  }
+
761 
+
762  SendData(&nav_data);
+
763  }
+
764 }
+
765 
+
766 void
+ +
768 {
+
769  if (!msg) return;
+
770 
+
771  NetNavDelete nav_delete;
+
772  nav_delete.Unpack(msg->Data());
+
773 
+
774  Element* elem = sim->FindElement(nav_delete.GetElem());
+
775 
+
776  if (elem) {
+
777  int index = nav_delete.GetIndex();
+
778 
+
779  if (index < 0) {
+
780  elem->ClearFlightPlan(false);
+
781  }
+
782 
+
783  else if (index < elem->FlightPlanLength()) {
+
784  Instruction* npt = elem->GetFlightPlan().at(index);
+
785  elem->DelNavPoint(npt, false);
+
786  }
+
787 
+
788  SendData(&nav_delete);
+
789  }
+
790 }
+
791 
+
792 void
+ +
794 {
+
795  if (!msg) return;
+
796 
+
797  NetWepTrigger trigger;
+
798  trigger.Unpack(msg->Data());
+
799 
+
800  NetPlayer* player = FindPlayerByObjID(trigger.GetObjID());
+
801  if (player) {
+
802  player->DoWepTrigger(&trigger);
+
803  }
+
804  else {
+
805  player = FindZombieByObjID(trigger.GetObjID());
+
806 
+
807  if (player)
+
808  SendDisconnect(player);
+
809  }
+
810 }
+
811 
+
812 void
+ +
814 {
+
815  if (!msg) return;
+
816 
+
817  NetWepRelease release;
+
818  release.Unpack(msg->Data());
+
819 
+
820  NetPlayer* player = FindPlayerByObjID(release.GetObjID());
+
821  if (player) {
+
822  player->DoWepRelease(&release);
+
823  }
+
824  else {
+
825  player = FindZombieByObjID(release.GetObjID());
+
826 
+
827  if (player)
+
828  SendDisconnect(player);
+
829  }
+
830 
+
831  Print("WEP RELEASE on server? objid = %d\n", release.GetObjID());
+
832 }
+
833 
+
834 void
+ +
836 {
+
837 }
+
838 
+
839 void
+ +
841 {
+
842  if (!msg) return;
+
843 
+
844  NetCommMsg comm_msg;
+
845  comm_msg.Unpack(msg->Data());
+
846 
+
847  RadioMessage* radio_msg = comm_msg.GetRadioMessage();
+
848 
+
849  NetPlayer* player = FindPlayerByObjID(comm_msg.GetObjID());
+
850  if (player && radio_msg) {
+
851  player->DoCommMessage(&comm_msg);
+
852 
+
853  int channel = comm_msg.GetRadioMessage()->Channel();
+
854 
+ +
856  while (++dst) {
+
857  NetPlayer* remote_player = dst.value();
+
858  if (remote_player->GetNetID() &&
+
859  (channel == 0 || channel == remote_player->GetIFF())) {
+
860 
+
861  BYTE* data = comm_msg.Pack();
+
862  int size = comm_msg.Length();
+
863 
+
864  link->SendMessage(remote_player->GetNetID(), data, size, NetMsg::RELIABLE);
+
865  }
+
866  }
+
867  }
+
868  else {
+
869  player = FindZombieByObjID(comm_msg.GetObjID());
+
870 
+
871  if (player)
+
872  SendDisconnect(player);
+
873  }
+
874 }
+
875 
+
876 void
+ +
878 {
+
879  if (!msg) return;
+
880 
+
881  NetChatMsg chat_msg;
+
882  chat_msg.Unpack(msg->Data());
+
883 
+
884  RouteChatMsg(chat_msg);
+
885 }
+
886 
+
887 void
+ +
889 {
+
890  DWORD dst_id = chat_msg.GetDstID();
+
891 
+
892  // broadcast or team:
+
893  if (dst_id == 0xffff || dst_id <= 10) {
+
894  BYTE* data = chat_msg.Pack();
+
895  int size = chat_msg.Length();
+
896 
+ +
898  while (++dst) {
+
899  NetPlayer* remote_player = dst.value();
+
900  if (remote_player->GetNetID() && chat_msg.GetName() != remote_player->Name()) {
+
901  if (dst_id == 0xffff || dst_id == 0 || remote_player->GetIFF() == (int) dst_id-1)
+
902  link->SendMessage(remote_player->GetNetID(), data, size);
+
903  }
+
904  }
+
905 
+
906  if (local_player && (dst_id == 0xffff || dst_id == 0 || local_player->GetIFF() == (int) dst_id-1)) {
+
907  Text name = chat_msg.GetName();
+
908  if (name.length() < 1)
+
909  name = Game::GetText("NetGameServer.chat.unknown");
+
910 
+
911  // don't echo general messages from the local player.
+
912  // they are already displayed by the chat entry code
+
913  // in starshatter.cpp
+
914 
+
915  if (name != player_name)
+
916  HUDView::Message("%s> %s", name.data(), chat_msg.GetText().data());
+
917  }
+
918  }
+
919 
+
920  // direct to local player:
+
921  else if (local_player && local_player->GetObjID() == dst_id) {
+
922  Text name = chat_msg.GetName();
+
923  if (name.length() < 1)
+
924  name = Game::GetText("NetGameServer.chat.unknown");
+
925 
+
926  HUDView::Message("%s> %s", name.data(), chat_msg.GetText().data());
+
927  }
+
928 
+
929  // ship-to-ship, but not to local player:
+
930  else if (!local_player || local_player->GetObjID() != dst_id) {
+
931  NetPlayer* remote_player = FindPlayerByObjID(dst_id);
+
932  if (remote_player && remote_player->GetNetID()) {
+
933  BYTE* data = chat_msg.Pack();
+
934  int size = chat_msg.Length();
+
935  link->SendMessage(remote_player->GetNetID(), data, size);
+
936  }
+
937 
+
938  // record message in server log:
+
939  ::Print("%s> %s\n", chat_msg.GetName().data(), chat_msg.GetText().data());
+
940  }
+
941 
+
942  if (dst_id == 0xffff)
+
943  return;
+
944 
+
945  // record message in chat log:
+ +
947 
+
948  if (!lobby)
+
949  return;
+
950 
+
951  NetUser* user = lobby->FindUserByName(chat_msg.GetName());
+
952 
+
953  if (user)
+
954  lobby->AddChat(user, chat_msg.GetText(), false); // don't re-route
+
955 }
+
956 
+
957 // +--------------------------------------------------------------------+
+
958 
+
959 const char* FormatGameTime();
+
960 
+
961 void
+ +
963 {
+
964  if (!msg) return;
+
965 
+
966  NetSelfDestruct self_destruct;
+
967  self_destruct.Unpack(msg->Data());
+
968 
+
969  Ship* ship = FindShipByObjID(self_destruct.GetObjID());
+
970  NetPlayer* player = FindPlayerByNetID(msg->NetID());
+
971 
+
972  if (ship) {
+
973  if (!player || ship->GetObjID() != player->GetObjID()) {
+
974  Print("NetGameServer::DoSelfDestruct - received request for ship '%s' from wrong player %s\n",
+
975  ship->Name(), player ? player->Name() : "null");
+
976 
+
977  return;
+
978  }
+
979 
+
980  ship->InflictNetDamage(self_destruct.GetDamage());
+
981 
+
982  SendData(&self_destruct);
+
983 
+
984  int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f);
+
985 
+
986  // then delete the ship:
+
987  if (ship_destroyed) {
+ +
989  Print(" %s Self Destruct (%s)\n", ship->Name(), FormatGameTime());
+
990 
+
991  ShipStats* killee = ShipStats::Find(ship->Name());
+
992  if (killee)
+
993  killee->AddEvent(SimEvent::DESTROYED, ship->Name());
+
994 
+
995  ship->DeathSpiral();
+
996  }
+
997  }
+
998 }
+
999 
+
1000 // +--------------------------------------------------------------------+
+
1001 
+
1002 void
+ +
1004 {
+
1005  if (players.isEmpty())
+
1006  return;
+
1007 
+
1008  DWORD time = Game::GameTime();
+
1009 
+
1010  // don't flood the network...
+
1011  if (time - last_send_time < MIN_NET_FRAME)
+
1012  return;
+
1013 
+
1014  last_send_time = time;
+
1015 
+
1016  // tell the remote players where *we* are:
+
1017  if (local_player && !local_player->IsNetObserver() && objid) {
+
1018  double r, p, y;
+ +
1020 
+
1021  NetObjLoc obj_loc;
+
1022  obj_loc.SetObjID(objid);
+
1023  obj_loc.SetLocation(local_player->Location());
+
1024  obj_loc.SetVelocity(local_player->Velocity());
+
1025  obj_loc.SetOrientation(Point(r,p,y));
+
1026  obj_loc.SetThrottle(local_player->Throttle() > 10);
+
1027  obj_loc.SetAugmenter(local_player->Augmenter());
+
1028  obj_loc.SetGearDown(local_player->IsGearDown());
+
1029 
+
1030  Shield* shield = local_player->GetShield();
+
1031  if (shield)
+
1032  obj_loc.SetShield((int) shield->GetPowerLevel());
+
1033  else
+
1034  obj_loc.SetShield(0);
+
1035 
+
1036  SendData(&obj_loc);
+
1037  }
+
1038 
+
1039  // tell each remote player where all the others are:
+ +
1041  while (++src) {
+
1042  NetPlayer* player = src.value();
+
1043 
+
1044  Ship* player_ship = player->GetShip();
+
1045 
+
1046  if (player_ship) {
+
1047  double r, p, y;
+
1048  player_ship->Cam().Orientation().ComputeEulerAngles(r,p,y);
+
1049 
+
1050  NetObjLoc obj_loc;
+
1051  obj_loc.SetObjID(player->GetObjID());
+
1052  obj_loc.SetLocation(player_ship->Location());
+
1053  obj_loc.SetVelocity(player_ship->Velocity());
+
1054  obj_loc.SetOrientation(Point(r,p,y));
+
1055  obj_loc.SetThrottle(player_ship->Throttle() > 10);
+
1056  obj_loc.SetAugmenter(player_ship->Augmenter());
+
1057  obj_loc.SetGearDown(player_ship->IsGearDown());
+
1058 
+
1059  Shield* shield = player_ship->GetShield();
+
1060  if (shield)
+
1061  obj_loc.SetShield((int) shield->GetPowerLevel());
+
1062  else
+
1063  obj_loc.SetShield(0);
+
1064 
+
1065  BYTE* obj_loc_data = obj_loc.Pack();
+
1066 
+ +
1068  while (++dst) {
+
1069  NetPlayer* remote_player = dst.value();
+
1070  if (remote_player->GetNetID() && remote_player != player)
+
1071  link->SendMessage(remote_player->GetNetID(), obj_loc_data, NetObjLoc::SIZE);
+
1072  }
+
1073  }
+
1074  }
+
1075 
+
1076  // tell each remote player where all the A.I. ships are:
+
1077  ListIter<Ship> ai_iter = ships;
+
1078  while (++ai_iter) {
+
1079  Ship* s = ai_iter.value();
+
1080 
+
1081  if (s && !s->IsStatic()) {
+
1082  double r, p, y;
+
1083  s->Cam().Orientation().ComputeEulerAngles(r,p,y);
+
1084 
+
1085  NetObjLoc obj_loc;
+
1086  obj_loc.SetObjID(s->GetObjID());
+
1087  obj_loc.SetLocation(s->Location());
+
1088  obj_loc.SetVelocity(s->Velocity());
+
1089  obj_loc.SetOrientation(Point(r,p,y));
+
1090  obj_loc.SetThrottle(s->Throttle() > 10);
+
1091  obj_loc.SetAugmenter(s->Augmenter());
+
1092  obj_loc.SetGearDown(s->IsGearDown());
+
1093 
+
1094  Shield* shield = s->GetShield();
+
1095  if (shield)
+
1096  obj_loc.SetShield((int) shield->GetPowerLevel());
+
1097  else
+
1098  obj_loc.SetShield(0);
+
1099 
+
1100  SendData(&obj_loc);
+
1101  }
+
1102  }
+
1103 }
+
1104 
+
1105 // +--------------------------------------------------------------------+
+
1106 
+
1107 void
+ +
1109 {
+
1110  if (net_data) {
+
1111  BYTE* data = net_data->Pack();
+
1112  int size = net_data->Length();
+
1113  BYTE flags = 0;
+
1114  bool all = true; // include player with objid in net_data?
+
1115  DWORD oid = net_data->GetObjID();
+
1116 
+
1117  BYTE msg_type = net_data->Type();
+
1118 
+
1119  if (msg_type >= 0x10)
+
1120  flags |= NetMsg::RELIABLE;
+
1121 
+
1122  if (msg_type == NET_WEP_TRIGGER ||
+
1123  msg_type == NET_COMM_MESSAGE ||
+
1124  msg_type == NET_CHAT_MESSAGE ||
+
1125  msg_type == NET_OBJ_HYPER ||
+
1126  msg_type == NET_ELEM_CREATE ||
+
1127  msg_type == NET_NAV_DATA ||
+
1128  msg_type == NET_NAV_DELETE) {
+
1129  all = false;
+
1130  }
+
1131 
+ +
1133  while (++dst) {
+
1134  NetPlayer* remote_player = dst.value();
+
1135  if (remote_player->GetNetID() && (all || oid != remote_player->GetObjID()))
+
1136  link->SendMessage(remote_player->GetNetID(), data, size, flags);
+
1137  }
+
1138  }
+
1139 }
+
1140 
+
1141 void
+ +
1143 {
+
1144  if (zombie) {
+
1145  NetDisconnect disconnect;
+
1146  BYTE* data = disconnect.Pack();
+
1147  int size = disconnect.Length();
+
1148  BYTE flags = NetMsg::RELIABLE;
+
1149 
+
1150  if (zombie->GetNetID())
+
1151  link->SendMessage(zombie->GetNetID(), data, size, flags);
+
1152  }
+
1153 }
+
1154 
+
1155 // +--------------------------------------------------------------------+
+
1156 
+
1157 bool
+ +
1159 {
+
1160  if (obj->Type() == SimObject::SIM_SHIP) {
+
1161  Ship* s = (Ship*) obj;
+
1162  if (local_player == s)
+
1163  local_player = 0;
+
1164 
+
1165  if (ships.contains(s))
+
1166  ships.remove(s);
+
1167  }
+
1168 
+
1169  return SimObserver::Update(obj);
+
1170 }
+
1171 
+
1172 const char*
+ +
1174 {
+
1175  return "NetGameServer";
+
1176 }
+
1177 
+
1178 // +--------------------------------------------------------------------+
+
1179 
+
1180 void
+
1181 NetGameServer::Respawn(DWORD oid, Ship* spawn)
+
1182 {
+
1183  if (!oid || !spawn) return;
+
1184 
+
1185  Print("NetGameServer::Respawn(%d, %s)\n", oid, spawn->Name());
+
1186  spawn->SetObjID(oid);
+
1187  Observe(spawn);
+
1188 
+
1189  NetPlayer* p = FindPlayerByObjID(oid);
+
1190  if (p)
+
1191  p->SetShip(spawn);
+
1192  else
+
1193  ships.append(spawn);
+
1194 
+
1195  if (objid == oid) {
+
1196  Print(" RESPAWN LOCAL PLAYER\n\n");
+
1197  local_player = spawn;
+
1198  }
+
1199 }
+
+
+ + + + -- cgit v1.1