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