1 /***************************************************************************
2 * Mechanized Assault and Exploration Reloaded Projectfile *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #include "game/logic/serverevents.h"
20
21 #include "game/data/units/building.h"
22 #include "game/logic/casualtiestracker.h"
23 #include "game/logic/clientevents.h"
24 #include "utility/listhelpers.h"
25 #include "utility/log.h"
26 #include "menuevents.h"
27 #include "game/logic/movejobs.h"
28 #include "netmessage.h"
29 #include "network.h"
30 #include "game/data/player/player.h"
31 #include "game/logic/server.h"
32 #include "game/logic/upgradecalculator.h"
33 #include "game/data/units/vehicle.h"
34 #include "ui/graphical/menu/windows/windowgamesettings/gamesettings.h"
35 #include "ui/graphical/game/gameguistate.h"
36 #include "game/data/report/savedreport.h"
37
38 //------------------------------------------------------------------------------
sendAddUnit(cServer & server,const cPosition & position,int id,bool isVehicle,sID unitID,const cPlayer & player,bool isInit,bool shouldAddToMap)39 void sendAddUnit (cServer& server, const cPosition& position, int id, bool isVehicle, sID unitID, const cPlayer& player, bool isInit, bool shouldAddToMap)
40 {
41 std::unique_ptr<cNetMessage> message;
42
43 if (isVehicle) message = std::make_unique<cNetMessage> (GAME_EV_ADD_VEHICLE);
44 else message = std::make_unique<cNetMessage> (GAME_EV_ADD_BUILDING);
45
46 message->pushBool (shouldAddToMap);
47 message->pushInt16 (id);
48 message->pushPosition (position);
49 message->pushID (unitID);
50 message->pushInt16 (player.getNr());
51 message->pushBool (isInit);
52
53 server.sendNetMessage (std::move (message), &player);
54 }
55
56 //------------------------------------------------------------------------------
sendAddRubble(cServer & server,const cBuilding & building,const cPlayer & receiver)57 void sendAddRubble (cServer& server, const cBuilding& building, const cPlayer& receiver)
58 {
59 auto message = std::make_unique<cNetMessage> (GAME_EV_ADD_RUBBLE);
60
61 message->pushPosition (building.getPosition());
62 message->pushInt16 (building.iID);
63 message->pushInt16 (building.RubbleValue);
64 message->pushInt16 (building.RubbleTyp);
65 message->pushBool (building.data.isBig);
66
67 server.sendNetMessage (std::move (message), &receiver);
68 }
69
70 //------------------------------------------------------------------------------
sendDeleteUnitMessage(cServer & server,const cUnit & unit,const cPlayer & receiver)71 void sendDeleteUnitMessage (cServer& server, const cUnit& unit, const cPlayer& receiver)
72 {
73 auto message = std::make_unique<cNetMessage> (unit.isABuilding() ? GAME_EV_DEL_BUILDING : GAME_EV_DEL_VEHICLE);
74 message->pushInt16 (unit.iID);
75 server.sendNetMessage (std::move (message), &receiver);
76 }
77
78 //------------------------------------------------------------------------------
sendDeleteUnit(cServer & server,const cUnit & unit,const cPlayer * receiver)79 void sendDeleteUnit (cServer& server, const cUnit& unit, const cPlayer* receiver)
80 {
81 if (receiver == nullptr)
82 {
83 for (unsigned int i = 0; i < unit.seenByPlayerList.size(); i++)
84 sendDeleteUnitMessage (server, unit, *unit.seenByPlayerList[i]);
85
86 //send message to owner, since he is not in the seenByPlayerList
87 if (unit.getOwner() != 0)
88 sendDeleteUnitMessage (server, unit, *unit.getOwner());
89 }
90 else
91 sendDeleteUnitMessage (server, unit, *receiver);
92 }
93
94 //------------------------------------------------------------------------------
sendAddEnemyUnit(cServer & server,const cUnit & unit,const cPlayer & receiver)95 void sendAddEnemyUnit (cServer& server, const cUnit& unit, const cPlayer& receiver)
96 {
97 auto message = std::make_unique<cNetMessage> (unit.isABuilding() ? GAME_EV_ADD_ENEM_BUILDING : GAME_EV_ADD_ENEM_VEHICLE);
98
99 message->pushInt16 (unit.data.getVersion());
100 message->pushInt16 (unit.iID);
101 if (unit.isAVehicle())
102 message->pushInt16 (unit.dir);
103 message->pushPosition (unit.getPosition());
104 message->pushID (unit.data.ID);
105 message->pushInt16 (unit.getOwner()->getNr());
106
107 server.sendNetMessage (std::move (message), &receiver);
108 }
109
110 //------------------------------------------------------------------------------
sendMakeTurnEnd(cServer & server,const cPlayer * receiver)111 void sendMakeTurnEnd (cServer& server, const cPlayer* receiver)
112 {
113 auto message = std::make_unique<cNetMessage> (GAME_EV_MAKE_TURNEND);
114
115 server.sendNetMessage (std::move (message), receiver);
116 }
117
118 //------------------------------------------------------------------------------
sendTurnFinished(cServer & server,const cPlayer & playerWhoEndedTurn,const cPlayer * nextPlayer,const cPlayer * receiver)119 void sendTurnFinished (cServer& server, const cPlayer& playerWhoEndedTurn, const cPlayer* nextPlayer, const cPlayer* receiver)
120 {
121 auto message = std::make_unique<cNetMessage> (GAME_EV_FINISHED_TURN);
122
123 if (nextPlayer)
124 {
125 message->pushInt16 (nextPlayer->getNr());
126 message->pushBool (true);
127 }
128 else
129 {
130 message->pushBool (false);
131 }
132 message->pushInt16 (playerWhoEndedTurn.getNr());
133
134 server.sendNetMessage (std::move (message), receiver);
135 }
136
137 //------------------------------------------------------------------------------
sendTurnStartTime(cServer & server,unsigned int gameTime)138 void sendTurnStartTime (cServer& server, unsigned int gameTime)
139 {
140 auto message = std::make_unique<cNetMessage> (GAME_EV_TURN_START_TIME);
141
142 message->pushInt32 (gameTime);
143
144 server.sendNetMessage (std::move (message));
145 }
146
147 //------------------------------------------------------------------------------
sendTurnEndDeadlineStartTime(cServer & server,unsigned int gameTime)148 void sendTurnEndDeadlineStartTime (cServer& server, unsigned int gameTime)
149 {
150 auto message = std::make_unique<cNetMessage> (GAME_EV_TURN_END_DEADLINE_START_TIME);
151
152 message->pushInt32 (gameTime);
153
154 server.sendNetMessage (std::move (message));
155 }
156
157 //------------------------------------------------------------------------------
sendUnitData(cServer & server,const cUnit & unit,const cPlayer & receiver)158 void sendUnitData (cServer& server, const cUnit& unit, const cPlayer& receiver)
159 {
160 auto message = std::make_unique<cNetMessage> (GAME_EV_UNIT_DATA);
161
162 // The unit data values
163 if (unit.isAVehicle())
164 {
165 message->pushInt16 (static_cast<const cVehicle*> (&unit)->getFlightHeight());
166 message->pushInt16 (unit.data.getSpeedMax());
167 message->pushInt16 (unit.data.getSpeed());
168 }
169 message->pushInt16 (unit.data.getVersion());
170 message->pushInt16 (unit.data.getHitpointsMax());
171 message->pushInt16 (unit.data.getHitpoints());
172 message->pushInt16 (unit.data.getArmor());
173 message->pushInt16 (unit.data.getScan());
174 message->pushInt16 (unit.data.getRange());
175 message->pushInt16 (unit.data.getShotsMax());
176 message->pushInt16 (unit.data.getShots());
177 message->pushInt16 (unit.data.getDamage());
178 message->pushInt16 (unit.data.storageUnitsMax);
179 message->pushInt16 (unit.data.getStoredUnits());
180 message->pushInt16 (unit.data.storageResMax);
181 message->pushInt16 (unit.data.getStoredResources());
182 message->pushInt16 (unit.data.getAmmoMax());
183 message->pushInt16 (unit.data.getAmmo());
184 message->pushInt16 (unit.data.buildCosts);
185
186 // Current state of the unit
187 // TODO: remove information such sentrystatus,
188 // build or clearrounds from normal data
189 // because this data will be received by enemys, too
190 if (unit.isABuilding())
191 message->pushInt16 (static_cast<const cBuilding*> (&unit)->points);
192
193 message->pushBool (unit.isManualFireActive());
194 message->pushBool (unit.isSentryActive());
195
196 if (unit.isAVehicle())
197 {
198 const cVehicle& vehicle = *static_cast<const cVehicle*> (&unit);
199 message->pushInt16 (vehicle.getClearingTurns());
200 message->pushInt16 (vehicle.getBuildTurns());
201 message->pushBool (vehicle.isUnitBuildingABuilding());
202 message->pushBool (vehicle.isUnitClearing());
203 message->pushInt16 ((int) vehicle.getCommandoRank());
204 }
205 else
206 {
207 const cBuilding& building = *static_cast<const cBuilding*> (&unit);
208 message->pushBool (building.isUnitWorking());
209 message->pushInt16 (building.getResearchArea());
210 }
211
212 message->pushInt16 (unit.getDisabledTurns());
213
214 message->pushBool (unit.isBeeingAttacked());
215 message->pushBool (unit.isAttacking());
216
217 if (unit.isNameOriginal() == false)
218 {
219 message->pushString (unit.getName());
220 message->pushBool (true);
221 }
222 else
223 message->pushBool (false);
224
225 if (unit.isAVehicle())
226 message->pushBool (unit.data.isBig);
227
228 // Data for identifying the unit by the client
229 message->pushPosition (unit.getPosition());
230 message->pushBool (unit.isAVehicle());
231 message->pushInt16 (unit.iID);
232 message->pushInt16 (unit.getOwner()->getNr());
233
234 server.sendNetMessage (std::move (message), &receiver);
235 }
236
237 //------------------------------------------------------------------------------
sendUnitData(cServer & server,const cUnit & unit)238 void sendUnitData (cServer& server, const cUnit& unit)
239 {
240 if (unit.getOwner())
241 {
242 sendUnitData (server, unit, *unit.getOwner());
243 }
244 for (size_t i = 0; i < unit.seenByPlayerList.size(); ++i)
245 {
246 sendUnitData (server, unit, *unit.seenByPlayerList[i]);
247 }
248 }
249
250 //------------------------------------------------------------------------------
sendSpecificUnitData(cServer & server,const cVehicle & vehicle)251 void sendSpecificUnitData (cServer& server, const cVehicle& vehicle)
252 {
253 auto message = std::make_unique<cNetMessage> (GAME_EV_SPECIFIC_UNIT_DATA);
254 message->pushPosition (vehicle.bandPosition);
255 message->pushBool (vehicle.BuildPath);
256 message->pushID (vehicle.getBuildingType());
257 message->pushInt16 (vehicle.dir);
258 message->pushInt16 (vehicle.iID);
259 server.sendNetMessage (std::move (message), vehicle.getOwner());
260 }
261
262 //------------------------------------------------------------------------------
sendDoStartWork(cServer & server,const cBuilding & building)263 void sendDoStartWork (cServer& server, const cBuilding& building)
264 {
265 //check all players
266 const auto& playerList = server.playerList;
267 for (unsigned int i = 0; i < playerList.size(); i++)
268 {
269 const auto& player = *playerList[i];
270
271 //do not send to players who can't see the building
272 if (!player.canSeeAnyAreaUnder (building) && &player != building.getOwner()) continue;
273
274 auto message = std::make_unique<cNetMessage> (GAME_EV_DO_START_WORK);
275 message->pushInt32 (building.iID);
276 server.sendNetMessage (std::move (message), &player);
277 }
278 }
279
280 //------------------------------------------------------------------------------
sendDoStopWork(cServer & server,const cBuilding & building)281 void sendDoStopWork (cServer& server, const cBuilding& building)
282 {
283 //check all players
284 const auto& playerList = server.playerList;
285 for (unsigned int i = 0; i < playerList.size(); i++)
286 {
287 const auto& player = *playerList[i];
288
289 //do not send to players who can't see the building
290 if (!player.canSeeAnyAreaUnder (building) && &player != building.getOwner()) continue;
291
292 auto message = std::make_unique<cNetMessage> (GAME_EV_DO_STOP_WORK);
293 message->pushInt32 (building.iID);
294 server.sendNetMessage (std::move (message), &player);
295 }
296 }
297
298 //------------------------------------------------------------------------------
sendNextMove(cServer & server,const cVehicle & vehicle,int iType,int iSavedSpeed)299 void sendNextMove (cServer& server, const cVehicle& vehicle, int iType, int iSavedSpeed)
300 {
301 for (unsigned int i = 0; i < vehicle.seenByPlayerList.size(); i++)
302 {
303 auto message = std::make_unique<cNetMessage> (GAME_EV_NEXT_MOVE);
304 if (iSavedSpeed >= 0) message->pushChar (iSavedSpeed);
305 message->pushChar (iType);
306 message->pushInt16 (vehicle.iID);
307 server.sendNetMessage (std::move (message), vehicle.seenByPlayerList[i]);
308 }
309
310 auto message = std::make_unique<cNetMessage> (GAME_EV_NEXT_MOVE);
311 if (iSavedSpeed >= 0) message->pushChar (iSavedSpeed);
312 message->pushChar (iType);
313 message->pushInt16 (vehicle.iID);
314 server.sendNetMessage (std::move (message), vehicle.getOwner());
315 }
316
317 //------------------------------------------------------------------------------
sendMoveJobServer(cServer & server,const cServerMoveJob & moveJob,const cPlayer & receiver)318 void sendMoveJobServer (cServer& server, const cServerMoveJob& moveJob, const cPlayer& receiver)
319 {
320 auto message = std::make_unique<cNetMessage> (GAME_EV_MOVE_JOB_SERVER);
321
322 const sWaypoint* waypoint = moveJob.Waypoints;
323 int iCount = 0;
324 while (waypoint)
325 {
326 message->pushInt16 (waypoint->Costs);
327 message->pushPosition (waypoint->position);
328
329 if (message->iLength > PACKAGE_LENGTH - 19)
330 {
331 Log.write (" Server: Error sending movejob: message too long", cLog::eLOG_TYPE_NET_ERROR);
332 return; // don't send movejobs that are to long
333 }
334
335 waypoint = waypoint->next;
336 iCount++;
337 }
338
339 message->pushInt16 (iCount);
340 message->pushInt16 (moveJob.iSavedSpeed);
341 message->pushPosition (moveJob.destination);
342 message->pushPosition (moveJob.source);
343 message->pushInt32 (moveJob.Vehicle->iID);
344
345 server.sendNetMessage (std::move (message), &receiver);
346 }
347
348 //------------------------------------------------------------------------------
sendVehicleResources(cServer & server,const cVehicle & vehicle)349 void sendVehicleResources (cServer& server, const cVehicle& vehicle)
350 {
351 int iCount = 0;
352 auto message = std::make_unique<cNetMessage> (GAME_EV_RESOURCES);
353 const cMap& map = *server.Map;
354 // TODO: only send new scaned resources
355
356 const int minx = std::max (vehicle.getPosition().x() - 1, 0);
357 const int maxx = std::min (vehicle.getPosition().x() + 1, map.getSize().x() - 1);
358 const int miny = std::max (vehicle.getPosition().y() - 1, 0);
359 const int maxy = std::min (vehicle.getPosition().y() + 1, map.getSize().y() - 1);
360 for (int y = miny; y <= maxy; ++y)
361 {
362 for (int x = minx; x <= maxx; ++x)
363 {
364 const cPosition position (x, y);
365 if (vehicle.getOwner()->hasResourceExplored (position)) continue;
366
367 const sResources& resource = map.getResource (position);
368 message->pushInt16 (resource.value);
369 message->pushInt16 (resource.typ);
370 message->pushPosition (position);
371 iCount++;
372 }
373 }
374 message->pushInt16 (iCount);
375
376 server.sendNetMessage (std::move (message), vehicle.getOwner());
377 }
378
379 //------------------------------------------------------------------------------
sendResources(cServer & server,const cPlayer & player)380 void sendResources (cServer& server, const cPlayer& player)
381 {
382 int iCount = 0;
383 auto message = std::make_unique<cNetMessage> (GAME_EV_RESOURCES);
384 for (int x = 0; x != server.Map->getSize().x(); ++x)
385 {
386 for (int y = 0; y != server.Map->getSize().y(); ++y)
387 {
388 const cPosition position (x, y);
389
390 if (!player.hasResourceExplored (position)) continue;
391
392 const sResources& resource = server.Map->getResource (position);
393 message->pushInt16 (resource.value);
394 message->pushInt16 (resource.typ);
395 message->pushPosition (position);
396 iCount++;
397
398 if (message->iLength >= PACKAGE_LENGTH - 10)
399 {
400 message->pushInt16 (iCount);
401 server.sendNetMessage (std::move (message), &player);
402 message = std::make_unique<cNetMessage> (GAME_EV_RESOURCES);
403 iCount = 0;
404 }
405 }
406 }
407 if (iCount > 0)
408 {
409 message->pushInt16 (iCount);
410 server.sendNetMessage (std::move (message), &player);
411 }
412 }
413
414 //------------------------------------------------------------------------------
sendScore(cServer & server,const cPlayer & subject,int turn,const cPlayer * receiver)415 void sendScore (cServer& server, const cPlayer& subject, int turn, const cPlayer* receiver)
416 {
417 if (!receiver)
418 {
419 const auto& playerList = server.playerList;
420 for (unsigned int n = 0; n < playerList.size(); n++)
421 sendScore (server, subject, turn, playerList[n].get());
422 }
423 else
424 {
425 auto message = std::make_unique<cNetMessage> (GAME_EV_SCORE);
426 message->pushInt16 (subject.getScore (turn));
427 message->pushInt16 (turn);
428 message->pushInt16 (subject.getNr());
429
430 server.sendNetMessage (std::move (message), receiver);
431 }
432 }
433
sendUnitScore(cServer & server,const cBuilding & building)434 void sendUnitScore (cServer& server, const cBuilding& building)
435 {
436 auto message = std::make_unique<cNetMessage> (GAME_EV_UNIT_SCORE);
437 message->pushInt16 (building.points);
438 message->pushInt16 (building.iID);
439 server.sendNetMessage (std::move (message), building.getOwner());
440 }
441
sendNumEcos(cServer & server,cPlayer & subject,const cPlayer * receiver)442 void sendNumEcos (cServer& server, cPlayer& subject, const cPlayer* receiver)
443 {
444 subject.countEcoSpheres();
445
446 if (!receiver)
447 {
448 const auto& playerList = server.playerList;
449 for (unsigned int n = 0; n < playerList.size(); n++)
450 sendNumEcos (server, subject, playerList[n].get());
451 }
452 else
453 {
454 auto message = std::make_unique<cNetMessage> (GAME_EV_NUM_ECOS);
455 message->pushInt16 (subject.numEcos);
456 message->pushInt16 (subject.getNr());
457
458 server.sendNetMessage (std::move (message), receiver);
459 }
460 }
461
sendGameSettings(cServer & server,const cPlayer & receiver)462 void sendGameSettings (cServer& server, const cPlayer& receiver)
463 {
464 auto message = std::make_unique<cNetMessage> (GAME_EV_GAME_SETTINGS);
465
466 const auto& gameSettings = server.getGameSettings();
467
468 if (!gameSettings) return;
469
470 gameSettings->pushInto (*message);
471
472 server.sendNetMessage (std::move (message), &receiver);
473 }
474
475 //------------------------------------------------------------------------------
sendBuildAnswer(cServer & server,bool bOK,const cVehicle & vehicle)476 void sendBuildAnswer (cServer& server, bool bOK, const cVehicle& vehicle)
477 {
478 //message for the owner
479 auto message = std::make_unique<cNetMessage> (GAME_EV_BUILD_ANSWER);
480 if (bOK)
481 {
482 message->pushPosition (vehicle.bandPosition);
483 message->pushBool (vehicle.BuildPath);
484 message->pushInt16 (vehicle.getBuildTurns());
485 message->pushID (vehicle.getBuildingType());
486 message->pushBool (vehicle.getBuildingType().getUnitDataOriginalVersion()->isBig);
487 message->pushPosition (vehicle.getPosition());
488 }
489
490 message->pushInt16 (vehicle.iID);
491 message->pushBool (bOK);
492 server.sendNetMessage (std::move (message), vehicle.getOwner());
493
494 //message for the enemys
495 for (unsigned int i = 0; i < vehicle.seenByPlayerList.size(); i++)
496 {
497 auto message = std::make_unique<cNetMessage> (GAME_EV_BUILD_ANSWER);
498 if (bOK)
499 {
500 message->pushBool (vehicle.getBuildingType().getUnitDataOriginalVersion()->isBig);
501 message->pushPosition (vehicle.getPosition());
502 }
503 message->pushInt16 (vehicle.iID);
504 message->pushBool (bOK);
505 server.sendNetMessage (std::move (message), vehicle.seenByPlayerList[i]);
506 }
507 }
508
509 //------------------------------------------------------------------------------
sendStopBuild(cServer & server,int iVehicleID,const cPosition & newPosition,const cPlayer & receiver)510 void sendStopBuild (cServer& server, int iVehicleID, const cPosition& newPosition, const cPlayer& receiver)
511 {
512 auto message = std::make_unique<cNetMessage> (GAME_EV_STOP_BUILD);
513 message->pushPosition (newPosition);
514 message->pushInt16 (iVehicleID);
515 server.sendNetMessage (std::move (message), &receiver);
516 }
517
518 //------------------------------------------------------------------------------
sendSubbaseValues(cServer & server,const sSubBase & subBase,const cPlayer & receiver)519 void sendSubbaseValues (cServer& server, const sSubBase& subBase, const cPlayer& receiver)
520 {
521 // temporary debug check
522 if (subBase.isDitributionMaximized() == false)
523 {
524 Log.write (" Server: Mine distribution values are not a maximum", cLog::eLOG_TYPE_NET_WARNING);
525 }
526
527 auto message = std::make_unique<cNetMessage> (GAME_EV_SUBBASE_VALUES);
528
529 subBase.pushInto (*message);
530 message->pushInt16 (subBase.getID());
531 server.sendNetMessage (std::move (message), &receiver);
532 }
533
534 //------------------------------------------------------------------------------
sendBuildList(cServer & server,const cBuilding & building)535 void sendBuildList (cServer& server, const cBuilding& building)
536 {
537 auto message = std::make_unique<cNetMessage> (GAME_EV_BUILDLIST);
538 message->pushBool (building.getRepeatBuild());
539 message->pushInt16 (building.getBuildSpeed());
540 message->pushInt16 (building.getMetalPerRound());
541 for (int i = (int) building.getBuildListSize() - 1; i >= 0; i--)
542 {
543 message->pushInt16 (building.getBuildListItem (i).getRemainingMetal());
544 message->pushID (building.getBuildListItem (i).getType());
545 }
546 message->pushInt16 ((int)building.getBuildListSize());
547 message->pushInt16 (building.iID);
548 server.sendNetMessage (std::move (message), building.getOwner());
549 }
550
551 //------------------------------------------------------------------------------
sendProduceValues(cServer & server,const cBuilding & building)552 void sendProduceValues (cServer& server, const cBuilding& building)
553 {
554 auto message = std::make_unique<cNetMessage> (GAME_EV_MINE_PRODUCE_VALUES);
555 message->pushInt16 (building.MaxGoldProd);
556 message->pushInt16 (building.MaxOilProd);
557 message->pushInt16 (building.MaxMetalProd);
558 message->pushInt16 (building.iID);
559 server.sendNetMessage (std::move (message), building.getOwner());
560 }
561
562 //------------------------------------------------------------------------------
sendSupply(cServer & server,int iDestID,bool bDestVehicle,int iValue,int iType,const cPlayer & receiver)563 void sendSupply (cServer& server, int iDestID, bool bDestVehicle, int iValue, int iType, const cPlayer& receiver)
564 {
565 auto message = std::make_unique<cNetMessage> (GAME_EV_SUPPLY);
566 message->pushInt16 (iValue);
567 message->pushInt16 (iDestID);
568 message->pushBool (bDestVehicle);
569 message->pushChar (iType);
570 server.sendNetMessage (std::move (message), &receiver);
571 }
572
573 //------------------------------------------------------------------------------
sendDetectionState(cServer & server,const cVehicle & vehicle)574 void sendDetectionState (cServer& server, const cVehicle& vehicle)
575 {
576 auto message = std::make_unique<cNetMessage> (GAME_EV_DETECTION_STATE);
577 message->pushBool (!vehicle.detectedByPlayerList.empty());
578 message->pushInt32 (vehicle.iID);
579 server.sendNetMessage (std::move (message), vehicle.getOwner());
580 }
581
582 //------------------------------------------------------------------------------
sendClearAnswer(cServer & server,int answertype,const cVehicle & vehicle,int turns,const cPosition & bigPosition,const cPlayer * receiver)583 void sendClearAnswer (cServer& server, int answertype, const cVehicle& vehicle, int turns, const cPosition& bigPosition, const cPlayer* receiver)
584 {
585 auto message = std::make_unique<cNetMessage> (GAME_EV_CLEAR_ANSWER);
586 message->pushPosition (bigPosition);
587 message->pushInt16 (turns);
588 message->pushInt16 (vehicle.iID);
589 message->pushInt16 (answertype);
590 server.sendNetMessage (std::move (message), receiver);
591 }
592
593 //------------------------------------------------------------------------------
sendStopClear(cServer & server,const cVehicle & vehicle,const cPosition & bigPosition,const cPlayer & receiver)594 void sendStopClear (cServer& server, const cVehicle& vehicle, const cPosition& bigPosition, const cPlayer& receiver)
595 {
596 auto message = std::make_unique<cNetMessage> (GAME_EV_STOP_CLEARING);
597 message->pushPosition (bigPosition);
598 message->pushInt16 (vehicle.iID);
599 server.sendNetMessage (std::move (message), &receiver);
600 }
601
602 //------------------------------------------------------------------------------
sendNoFog(cServer & server,const cPlayer & receiver)603 void sendNoFog (cServer& server, const cPlayer& receiver)
604 {
605 auto message = std::make_unique<cNetMessage> (GAME_EV_NOFOG);
606 server.sendNetMessage (std::move (message), &receiver);
607 }
608
609 //------------------------------------------------------------------------------
sendDefeated(cServer & server,const cPlayer & player,const cPlayer * receiver)610 void sendDefeated (cServer& server, const cPlayer& player, const cPlayer* receiver)
611 {
612 auto message = std::make_unique<cNetMessage> (GAME_EV_DEFEATED);
613 message->pushInt16 (player.getNr());
614 server.sendNetMessage (std::move (message), receiver);
615 }
616
617 //------------------------------------------------------------------------------
sendFreeze(cServer & server,eFreezeMode mode,int waitForPlayer)618 void sendFreeze (cServer& server, eFreezeMode mode, int waitForPlayer)
619 {
620 auto message = std::make_unique<cNetMessage> (GAME_EV_FREEZE);
621 message->pushInt16 (waitForPlayer);
622 message->pushInt16 (mode);
623 server.sendNetMessage (std::move (message), nullptr);
624 }
625
626 //------------------------------------------------------------------------------
sendUnfreeze(cServer & server,eFreezeMode mode)627 void sendUnfreeze (cServer& server, eFreezeMode mode)
628 {
629 auto message = std::make_unique<cNetMessage> (GAME_EV_UNFREEZE);
630 message->pushInt16 (mode);
631 server.sendNetMessage (std::move (message), nullptr);
632 }
633
634 //------------------------------------------------------------------------------
sendWaitFor(cServer & server,const cPlayer & player,const cPlayer * receiver)635 void sendWaitFor (cServer& server, const cPlayer& player, const cPlayer* receiver)
636 {
637 auto message = std::make_unique<cNetMessage> (GAME_EV_WAIT_FOR);
638 message->pushInt32 (player.getNr());
639 server.sendNetMessage (std::move (message), receiver);
640 }
641
642 //------------------------------------------------------------------------------
sendDeletePlayer(cServer & server,const cPlayer & player,const cPlayer * receiver)643 void sendDeletePlayer (cServer& server, const cPlayer& player, const cPlayer* receiver)
644 {
645 auto message = std::make_unique<cNetMessage> (GAME_EV_DEL_PLAYER);
646 message->pushInt16 (player.getNr());
647 server.sendNetMessage (std::move (message), receiver);
648 }
649
650 //------------------------------------------------------------------------------
sendRequestIdentification(cTCP & network,int iSocket)651 void sendRequestIdentification (cTCP& network, int iSocket)
652 {
653 cNetMessage message (GAME_EV_REQ_RECON_IDENT);
654 message.pushInt16 (iSocket);
655 Log.write ("Server: --> " + message.getTypeAsString() + ", Hexdump: " + message.getHexDump(), cLog::eLOG_TYPE_NET_DEBUG);
656 network.sendTo (iSocket, message.iLength, message.serialize());
657 }
658
659 //------------------------------------------------------------------------------
sendReconnectAnswer(cServer & server,int socketNumber)660 void sendReconnectAnswer (cServer& server, int socketNumber)
661 {
662 cNetMessage message (GAME_EV_RECONNECT_ANSWER);
663 message.pushBool (false);
664
665 Log.write ("Server: --> " + message.getTypeAsString() + ", Hexdump: " + message.getHexDump(), cLog::eLOG_TYPE_NET_DEBUG);
666 server.network->sendTo (socketNumber, message.iLength, message.serialize());
667 }
668
669 //------------------------------------------------------------------------------
sendReconnectAnswer(cServer & server,int socketNumber,const cPlayer & player)670 void sendReconnectAnswer (cServer& server, int socketNumber, const cPlayer& player)
671 {
672 cNetMessage message (GAME_EV_RECONNECT_ANSWER);
673
674 const auto& playerList = server.playerList;
675 for (unsigned int i = 0; i < playerList.size(); i++)
676 {
677 const auto& secondPlayer = *playerList[i];
678 if (&player == &secondPlayer) continue;
679 message.pushInt16 (secondPlayer.getNr());
680 message.pushColor (secondPlayer.getColor().getColor());
681 message.pushString (secondPlayer.getName());
682 }
683 message.pushInt16 ((int) playerList.size());
684 message.pushString (server.Map->getName());
685 message.pushColor (player.getColor().getColor());
686 message.pushInt16 (player.getNr());
687
688 message.pushBool (true);
689
690 Log.write ("Server: --> " + message.getTypeAsString() + ", Hexdump: " + message.getHexDump(), cLog::eLOG_TYPE_NET_DEBUG);
691 server.network->sendTo (socketNumber, message.iLength, message.serialize());
692 }
693
694 //------------------------------------------------------------------------------
sendTurn(cServer & server,int turn,const cPlayer & receiver)695 void sendTurn (cServer& server, int turn, const cPlayer& receiver)
696 {
697 auto message = std::make_unique<cNetMessage> (GAME_EV_TURN);
698 message->pushInt16 (turn);
699 server.sendNetMessage (std::move (message), &receiver);
700 }
701
702 //------------------------------------------------------------------------------
sendGameGuiState(cServer & server,const cGameGuiState & gameGuiState,const cPlayer & player)703 void sendGameGuiState (cServer& server, const cGameGuiState& gameGuiState, const cPlayer& player)
704 {
705 auto message = std::make_unique<cNetMessage> (GAME_EV_HUD_SETTINGS);
706
707 gameGuiState.pushInto (*message);
708
709 server.sendNetMessage (std::move (message), &player);
710 }
711
712 //------------------------------------------------------------------------------
sendStoreVehicle(cServer & server,int unitid,bool vehicle,int storedunitid,const cPlayer & receiver)713 void sendStoreVehicle (cServer& server, int unitid, bool vehicle, int storedunitid, const cPlayer& receiver)
714 {
715 auto message = std::make_unique<cNetMessage> (GAME_EV_STORE_UNIT);
716 message->pushInt16 (unitid);
717 message->pushBool (vehicle);
718 message->pushInt16 (storedunitid);
719 server.sendNetMessage (std::move (message), &receiver);
720 }
721
722 //------------------------------------------------------------------------------
sendActivateVehicle(cServer & server,int unitid,bool vehicle,int activatunitid,const cPosition & position,const cPlayer & receiver)723 void sendActivateVehicle (cServer& server, int unitid, bool vehicle, int activatunitid, const cPosition& position, const cPlayer& receiver)
724 {
725 auto message = std::make_unique<cNetMessage> (GAME_EV_EXIT_UNIT);
726 message->pushPosition (position);
727 message->pushInt16 (unitid);
728 message->pushBool (vehicle);
729 message->pushInt16 (activatunitid);
730 server.sendNetMessage (std::move (message), &receiver);
731 }
732
733 //------------------------------------------------------------------------------
sendDeleteEverything(cServer & server,const cPlayer & receiver)734 void sendDeleteEverything (cServer& server, const cPlayer& receiver)
735 {
736 auto message = std::make_unique<cNetMessage> (GAME_EV_DELETE_EVERYTHING);
737 server.sendNetMessage (std::move (message), &receiver);
738 }
739
740 //------------------------------------------------------------------------------
sendResearchLevel(cServer & server,const cResearch & researchLevel,const cPlayer & receiver)741 void sendResearchLevel (cServer& server, const cResearch& researchLevel, const cPlayer& receiver)
742 {
743 auto message = std::make_unique<cNetMessage> (GAME_EV_RESEARCH_LEVEL);
744 for (int area = 0; area < cResearch::kNrResearchAreas; area++)
745 {
746 message->pushInt16 (researchLevel.getCurResearchLevel (area));
747 message->pushInt16 (researchLevel.getCurResearchPoints (area));
748 }
749 server.sendNetMessage (std::move (message), &receiver);
750 }
751
752 //------------------------------------------------------------------------------
sendFinishedResearchAreas(cServer & server,const std::vector<int> & areas,const cPlayer & receiver)753 void sendFinishedResearchAreas (cServer& server, const std::vector<int>& areas, const cPlayer& receiver)
754 {
755 auto message = std::make_unique<cNetMessage> (GAME_EV_FINISHED_RESEARCH_AREAS);
756 for (size_t i = 0; i < areas.size(); ++i)
757 {
758 message->pushInt32 (areas[i]);
759 }
760 message->pushInt32 (areas.size());
761 server.sendNetMessage (std::move (message), &receiver);
762 }
763
764 //------------------------------------------------------------------------------
sendRefreshResearchCount(cServer & server,const cPlayer & receiver)765 void sendRefreshResearchCount (cServer& server, const cPlayer& receiver)
766 {
767 auto message = std::make_unique<cNetMessage> (GAME_EV_REFRESH_RESEARCH_COUNT);
768 server.sendNetMessage (std::move (message), &receiver);
769 }
770
771 //------------------------------------------------------------------------------
sendUnitUpgrades(cServer & server,const sUnitData & unitData,const cPlayer & receiver)772 void sendUnitUpgrades (cServer& server, const sUnitData& unitData, const cPlayer& receiver)
773 {
774 auto message = std::make_unique<cNetMessage> (GAME_EV_UNIT_UPGRADE_VALUES);
775 message->pushInt16 (unitData.getHitpointsMax());
776 message->pushInt16 (unitData.getAmmoMax());
777 message->pushInt16 (unitData.getShotsMax());
778 message->pushInt16 (unitData.getSpeedMax());
779 message->pushInt16 (unitData.getArmor());
780 message->pushInt16 (unitData.buildCosts);
781 message->pushInt16 (unitData.getDamage());
782 message->pushInt16 (unitData.getRange());
783 message->pushInt16 (unitData.getScan());
784 message->pushInt16 (unitData.getVersion());
785 message->pushID (unitData.ID);
786 server.sendNetMessage (std::move (message), &receiver);
787 }
788
789 //------------------------------------------------------------------------------
sendCredits(cServer & server,int newCredits,const cPlayer & receiver)790 void sendCredits (cServer& server, int newCredits, const cPlayer& receiver)
791 {
792 auto message = std::make_unique<cNetMessage> (GAME_EV_CREDITS_CHANGED);
793 message->pushInt32 (newCredits);
794 server.sendNetMessage (std::move (message), &receiver);
795 }
796
797 //------------------------------------------------------------------------------
sendUpgradeBuildings(cServer & server,const std::vector<cBuilding * > & upgradedBuildings,int totalCosts,const cPlayer & receiver)798 void sendUpgradeBuildings (cServer& server, const std::vector<cBuilding*>& upgradedBuildings, int totalCosts, const cPlayer& receiver)
799 {
800 // send to owner
801 std::unique_ptr<cNetMessage> message;
802 int buildingsInMsg = 0;
803 for (unsigned int i = 0; i < upgradedBuildings.size(); i++)
804 {
805 if (message == nullptr)
806 {
807 message = std::make_unique<cNetMessage> (GAME_EV_UPGRADED_BUILDINGS);
808 buildingsInMsg = 0;
809 }
810
811 message->pushInt32 (upgradedBuildings[i]->iID);
812 buildingsInMsg++;
813 if (message->iLength + 8 > PACKAGE_LENGTH)
814 {
815 message->pushInt16 ((totalCosts * buildingsInMsg) / (int) upgradedBuildings.size());
816 message->pushInt16 (buildingsInMsg);
817 server.sendNetMessage (std::move (message), &receiver);
818 }
819 }
820 if (message != nullptr)
821 {
822 message->pushInt16 ((int) (totalCosts * buildingsInMsg) / (int) upgradedBuildings.size());
823 message->pushInt16 (buildingsInMsg);
824 server.sendNetMessage (std::move (message), &receiver);
825 }
826
827 // send to other players
828 const auto& playerList = server.playerList;
829 for (unsigned int n = 0; n < playerList.size(); n++)
830 {
831 const auto curPlayer = playerList[n].get();
832 // don't send to the owner of the buildings
833 if (curPlayer == 0 || curPlayer->getNr() == receiver.getNr()) continue;
834
835 for (unsigned int buildingIdx = 0; buildingIdx < upgradedBuildings.size(); buildingIdx++)
836 {
837 if (Contains (upgradedBuildings[buildingIdx]->seenByPlayerList, curPlayer)) // that player can see the building
838 sendUnitData (server, *upgradedBuildings[buildingIdx], *curPlayer);
839 }
840 }
841 }
842
843 //------------------------------------------------------------------------------
sendUpgradeVehicles(cServer & server,const std::vector<cVehicle * > & upgradedVehicles,int totalCosts,unsigned int storingBuildingID,const cPlayer & receiver)844 void sendUpgradeVehicles (cServer& server, const std::vector<cVehicle*>& upgradedVehicles, int totalCosts, unsigned int storingBuildingID, const cPlayer& receiver)
845 {
846 if (upgradedVehicles.size() * 4 > PACKAGE_LENGTH - 50)
847 {
848 Log.write ("Server: sendUpgradeVehicles: Message would exceed messagesize!!!", cLog::eLOG_TYPE_NET_ERROR);
849 return;
850 }
851 // send to owner
852 auto message = std::make_unique<cNetMessage> (GAME_EV_UPGRADED_VEHICLES);
853 for (unsigned int i = 0; i < upgradedVehicles.size(); i++)
854 message->pushInt32 (upgradedVehicles[i]->iID);
855
856 message->pushInt32 (storingBuildingID);
857 message->pushInt16 (totalCosts);
858 message->pushInt16 ((int) upgradedVehicles.size());
859 server.sendNetMessage (std::move (message), &receiver);
860
861 //TODO: send to other players as well?
862 }
863
864 //------------------------------------------------------------------------------
sendResearchSettings(cServer & server,const std::vector<cBuilding * > & researchCentersToChangeArea,const std::vector<cResearch::ResearchArea> & newAreasForResearchCenters,const cPlayer & receiver)865 void sendResearchSettings (cServer& server, const std::vector<cBuilding*>& researchCentersToChangeArea, const std::vector<cResearch::ResearchArea>& newAreasForResearchCenters, const cPlayer& receiver)
866 {
867 if (researchCentersToChangeArea.size() != newAreasForResearchCenters.size())
868 return;
869
870 std::unique_ptr<cNetMessage> message;
871 int buildingsInMsg = 0;
872 for (unsigned int i = 0; i < researchCentersToChangeArea.size(); i++)
873 {
874 if (message == nullptr)
875 {
876 message = std::make_unique<cNetMessage> (GAME_EV_RESEARCH_SETTINGS);
877 buildingsInMsg = 0;
878 }
879
880 message->pushChar (newAreasForResearchCenters[i]);
881 message->pushInt32 (researchCentersToChangeArea[i]->iID);
882 buildingsInMsg++;
883 if (message->iLength + 7 > PACKAGE_LENGTH)
884 {
885 message->pushInt16 (buildingsInMsg);
886 server.sendNetMessage (std::move (message), &receiver);
887 }
888 }
889 if (message != nullptr)
890 {
891 message->pushInt16 (buildingsInMsg);
892 server.sendNetMessage (std::move (message), &receiver);
893 }
894 }
895
896 //------------------------------------------------------------------------------
sendClans(cServer & server,const std::vector<std::unique_ptr<cPlayer>> & playerList,const cPlayer & receiver)897 void sendClans (cServer& server, const std::vector<std::unique_ptr<cPlayer>>& playerList, const cPlayer& receiver)
898 {
899 auto message = std::make_unique<cNetMessage> (GAME_EV_PLAYER_CLANS);
900 for (unsigned int i = 0; i < playerList.size(); i++)
901 {
902 message->pushChar (playerList[i]->getClan());
903 message->pushChar (playerList[i]->getNr());
904 }
905 server.sendNetMessage (std::move (message), &receiver);
906 }
907
908 //------------------------------------------------------------------------------
sendGameTime(cServer & server,const cPlayer & receiver,int gameTime)909 void sendGameTime (cServer& server, const cPlayer& receiver, int gameTime)
910 {
911 auto message = std::make_unique<cNetMessage> (GAME_EV_SET_GAME_TIME);
912 message->pushInt32 (gameTime);
913 server.sendNetMessage (std::move (message), &receiver);
914 }
915
916 //------------------------------------------------------------------------------
sendClansToClients(cServer & server,const std::vector<std::unique_ptr<cPlayer>> & playerList)917 void sendClansToClients (cServer& server, const std::vector<std::unique_ptr<cPlayer>>& playerList)
918 {
919 for (unsigned int n = 0; n < playerList.size(); n++)
920 sendClans (server, playerList, *playerList[n]);
921 }
922
923 //------------------------------------------------------------------------------
sendSetAutomoving(cServer & server,const cVehicle & vehicle)924 void sendSetAutomoving (cServer& server, const cVehicle& vehicle)
925 {
926 auto message = std::make_unique<cNetMessage> (GAME_EV_SET_AUTOMOVE);
927 message->pushInt16 (vehicle.iID);
928 server.sendNetMessage (std::move (message), vehicle.getOwner());
929 }
930
931 //------------------------------------------------------------------------------
sendCommandoAnswer(cServer & server,bool success,bool steal,const cVehicle & srcUnit,const cPlayer & receiver)932 void sendCommandoAnswer (cServer& server, bool success, bool steal, const cVehicle& srcUnit, const cPlayer& receiver)
933 {
934 auto message = std::make_unique<cNetMessage> (GAME_EV_COMMANDO_ANSWER);
935 message->pushInt16 (srcUnit.iID);
936 message->pushBool (steal);
937 message->pushBool (success);
938 server.sendNetMessage (std::move (message), &receiver);
939 }
940
941 //------------------------------------------------------------------------------
sendRequestSaveInfo(cServer & server,int saveingID)942 void sendRequestSaveInfo (cServer& server, int saveingID)
943 {
944 auto message = std::make_unique<cNetMessage> (GAME_EV_REQ_SAVE_INFO);
945 message->pushInt16 (saveingID);
946 server.sendNetMessage (std::move (message));
947 }
948
949 //------------------------------------------------------------------------------
sendSavedReport(cServer & server,const cSavedReport & savedReport,const cPlayer * receiver)950 void sendSavedReport (cServer& server, const cSavedReport& savedReport, const cPlayer* receiver)
951 {
952 auto message = std::make_unique<cNetMessage> (GAME_EV_SAVED_REPORT);
953
954 savedReport.pushInto (*message);
955 server.sendNetMessage (std::move (message), receiver);
956 }
957
958 //------------------------------------------------------------------------------
sendCasualtiesReport(cServer & server,const cPlayer * receiver)959 void sendCasualtiesReport (cServer& server, const cPlayer* receiver)
960 {
961 const auto casualtiesTracker = server.getCasualtiesTracker().get();
962 if (casualtiesTracker)
963 {
964 auto messages = casualtiesTracker->prepareNetMessagesForClient (GAME_EV_CASUALTIES_REPORT);
965 for (auto&& message : messages)
966 {
967 server.sendNetMessage (std::move (message), receiver);
968 }
969 }
970 }
971
972 //------------------------------------------------------------------------------
sendSelfDestroy(cServer & server,const cBuilding & building)973 void sendSelfDestroy (cServer& server, const cBuilding& building)
974 {
975 auto message = std::make_unique<cNetMessage> (GAME_EV_SELFDESTROY);
976 message->pushInt16 (building.iID);
977 server.sendNetMessage (std::move (message), building.getOwner());
978
979 for (unsigned int i = 0; i < building.seenByPlayerList.size(); i++)
980 {
981 message = std::make_unique<cNetMessage> (GAME_EV_SELFDESTROY);
982 message->pushInt16 (building.iID);
983 server.sendNetMessage (std::move (message), building.seenByPlayerList[i]);
984 }
985 }
986
987 //------------------------------------------------------------------------------
sendEndMoveActionToClient(cServer & server,const cVehicle & vehicle,int destID,eEndMoveActionType type)988 void sendEndMoveActionToClient (cServer& server, const cVehicle& vehicle, int destID, eEndMoveActionType type)
989 {
990 auto message = std::make_unique<cNetMessage> (GAME_EV_END_MOVE_ACTION_SERVER);
991 message->pushChar (type);
992 message->pushInt32 (destID);
993 message->pushInt32 (vehicle.iID);
994
995 server.sendNetMessage (std::move (message), vehicle.getOwner());
996 }
997
998 //------------------------------------------------------------------------------
sendRevealMap(cServer & server,const cPlayer & receiver)999 void sendRevealMap (cServer& server, const cPlayer& receiver)
1000 {
1001 auto message = std::make_unique<cNetMessage> (GAME_EV_REVEAL_MAP);
1002
1003 server.sendNetMessage (std::move (message), &receiver);
1004 }
1005