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 
20 #include "game/logic/clientevents.h"
21 
22 #include "game/data/units/building.h"
23 #include "game/data/units/landingunit.h"
24 #include "game/logic/client.h"
25 #include "utility/log.h"
26 #include "netmessage.h"
27 #include "network.h"
28 #include "game/data/player/player.h"
29 #include "game/data/units/vehicle.h"
30 #include "utility/position.h"
31 #include "game/data/report/savedreport.h"
32 #include "ui/graphical/game/gameguistate.h"
33 
34 using namespace std;
35 
sendClan(const cClient & client)36 void sendClan (const cClient& client)
37 {
38 	auto message = std::make_unique<cNetMessage> (MU_MSG_CLAN);
39 	const cPlayer& player = client.getActivePlayer();
40 
41 	message->pushInt16 (player.getClan());
42 	message->pushInt16 (player.getNr());
43 
44 	client.sendNetMessage (std::move (message));
45 }
46 
sendLandingUnits(const cClient & client,const std::vector<sLandingUnit> & landingList)47 void sendLandingUnits (const cClient& client, const std::vector<sLandingUnit>& landingList)
48 {
49 	auto message = std::make_unique<cNetMessage> (MU_MSG_LANDING_VEHICLES);
50 
51 	for (size_t i = 0; i != landingList.size(); ++i)
52 	{
53 		message->pushID (landingList[i].unitID);
54 		message->pushInt16 (landingList[i].cargo);
55 	}
56 	message->pushInt16 ((int) landingList.size());
57 	message->pushInt16 (client.getActivePlayer().getNr());
58 
59 	client.sendNetMessage (std::move (message));
60 }
61 
sendUnitUpgrades(const cClient & client)62 void sendUnitUpgrades (const cClient& client)
63 {
64 	const cPlayer& player = client.getActivePlayer();
65 	std::unique_ptr<cNetMessage> message = nullptr;
66 	int count = 0;
67 
68 	// send vehicles
69 	for (unsigned int i = 0; i < UnitsData.getNrVehicles(); ++i)
70 	{
71 		const sUnitData& playerData = player.VehicleData[i];
72 		const sUnitData& originalData = UnitsData.getVehicle (i, player.getClan());
73 		if (playerData.getDamage() == originalData.getDamage() &&
74 			playerData.getShotsMax() == originalData.getShotsMax() &&
75 			playerData.getRange() == originalData.getRange() &&
76 			playerData.getAmmoMax() == originalData.getAmmoMax() &&
77 			playerData.getArmor() == originalData.getArmor() &&
78 			playerData.getHitpointsMax() == originalData.getHitpointsMax() &&
79 			playerData.getScan() == originalData.getScan() &&
80 			playerData.getSpeedMax() == originalData.getSpeedMax())
81 		{
82 			continue;
83 		}
84 		if (message == nullptr)
85 		{
86 			message = std::make_unique<cNetMessage> (MU_MSG_UPGRADES);
87 		}
88 		message->pushInt16 (playerData.getSpeedMax());
89 		message->pushInt16 (playerData.getScan());
90 		message->pushInt16 (playerData.getHitpointsMax());
91 		message->pushInt16 (playerData.getArmor());
92 		message->pushInt16 (playerData.getAmmoMax());
93 		message->pushInt16 (playerData.getRange());
94 		message->pushInt16 (playerData.getShotsMax());
95 		message->pushInt16 (playerData.getDamage());
96 		message->pushID (playerData.ID);
97 
98 		count++;
99 
100 		if (message->iLength + 38 > PACKAGE_LENGTH)
101 		{
102 			message->pushInt16 (count);
103 			message->pushInt16 (player.getNr());
104 			client.sendNetMessage (std::move (message));
105 			count = 0;
106 		}
107 	}
108 	if (message != nullptr)
109 	{
110 		message->pushInt16 (count);
111 		message->pushInt16 (player.getNr());
112 		client.sendNetMessage (std::move (message));
113 		count = 0;
114 	}
115 
116 	// send buildings
117 	for (unsigned int i = 0; i < UnitsData.getNrBuildings(); ++i)
118 	{
119 		const sUnitData& playerData = player.BuildingData[i];
120 		const sUnitData& originalData = UnitsData.getBuilding (i, player.getClan());
121 		if (playerData.getDamage() == originalData.getDamage() &&
122 			playerData.getShotsMax() == originalData.getShotsMax() &&
123 			playerData.getRange() == originalData.getRange() &&
124 			playerData.getAmmoMax() == originalData.getAmmoMax() &&
125 			playerData.getArmor() == originalData.getArmor() &&
126 			playerData.getHitpointsMax() == originalData.getHitpointsMax() &&
127 			playerData.getScan() == originalData.getScan())
128 		{
129 			continue;
130 		}
131 		if (message == nullptr)
132 		{
133 			message = std::make_unique<cNetMessage> (MU_MSG_UPGRADES);
134 		}
135 		message->pushInt16 (playerData.getScan());
136 		message->pushInt16 (playerData.getHitpointsMax());
137 		message->pushInt16 (playerData.getArmor());
138 		message->pushInt16 (playerData.getAmmoMax());
139 		message->pushInt16 (playerData.getRange());
140 		message->pushInt16 (playerData.getShotsMax());
141 		message->pushInt16 (playerData.getDamage());
142 		message->pushID (playerData.ID);
143 
144 		count++;
145 
146 		if (message->iLength + 34 > PACKAGE_LENGTH)
147 		{
148 			message->pushInt16 (count);
149 			message->pushInt16 (player.getNr());
150 			client.sendNetMessage (std::move (message));
151 			count = 0;
152 		}
153 	}
154 	if (message != nullptr)
155 	{
156 		message->pushInt16 (count);
157 		message->pushInt16 (player.getNr());
158 		client.sendNetMessage (std::move (message));
159 	}
160 }
161 
sendReconnectionSuccess(const cClient & client)162 void sendReconnectionSuccess (const cClient& client)
163 {
164 	auto message = std::make_unique<cNetMessage> (GAME_EV_RECON_SUCCESS);
165 
166 	message->pushInt16 (client.getActivePlayer().getNr());
167 	client.sendNetMessage (std::move (message));
168 }
169 
sendTakenUpgrades(const cClient & client,const std::vector<std::pair<sID,cUnitUpgrade>> & unitUpgrades)170 void sendTakenUpgrades (const cClient& client, const std::vector<std::pair<sID, cUnitUpgrade>>& unitUpgrades)
171 {
172 	const cPlayer& player = client.getActivePlayer();
173 	std::unique_ptr<cNetMessage> msg = nullptr;
174 	int iCount = 0;
175 
176 	for (size_t i = 0; i < unitUpgrades.size(); ++i)
177 	{
178 		const auto& unitId = unitUpgrades[i].first;
179 		const auto& curUpgrade = unitUpgrades[i].second;
180 
181 		if (!curUpgrade.hasBeenPurchased()) continue;
182 
183 		if (msg == nullptr)
184 		{
185 			msg = std::make_unique<cNetMessage> (GAME_EV_WANT_BUY_UPGRADES);
186 			iCount = 0;
187 		}
188 
189 		const auto currentVersion = player.getUnitDataCurrentVersion (unitId);
190 
191 		if (unitId.isAVehicle()) msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_SPEED, currentVersion->getSpeedMax()));
192 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_SCAN, currentVersion->getScan()));
193 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_HITS, currentVersion->getHitpointsMax()));
194 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_ARMOR, currentVersion->getArmor()));
195 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_AMMO, currentVersion->getAmmoMax()));
196 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_RANGE, currentVersion->getRange()));
197 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_SHOTS, currentVersion->getShotsMax()));
198 		msg->pushInt16 (curUpgrade.getValueOrDefault (sUnitUpgrade::UPGRADE_TYPE_DAMAGE, currentVersion->getDamage()));
199 		msg->pushID (currentVersion->ID);
200 
201 		iCount++; // msg contains one more upgrade struct
202 
203 		// the msg would be too long,
204 		// if another upgrade would be written into it.
205 		// So send it and put the next upgrades in a new message.
206 		if (msg->iLength + 38 > PACKAGE_LENGTH)
207 		{
208 			msg->pushInt16 (iCount);
209 			msg->pushInt16 (player.getNr());
210 			client.sendNetMessage (std::move (msg));
211 		}
212 	}
213 
214 	if (msg != nullptr)
215 	{
216 		msg->pushInt16 (iCount);
217 		msg->pushInt16 (player.getNr());
218 		client.sendNetMessage (std::move (msg));
219 	}
220 }
221 
sendLandingCoords(const cClient & client,const cPosition & coords)222 void sendLandingCoords (const cClient& client, const cPosition& coords)
223 {
224 	Log.write ("Client: sending landing coords", cLog::eLOG_TYPE_NET_DEBUG);
225 	auto message = std::make_unique<cNetMessage> (MU_MSG_LANDING_COORDS);
226 	message->pushPosition (coords);
227 	message->pushChar (client.getActivePlayer().getNr());
228 
229 	client.sendNetMessage (std::move (message));
230 }
231 
sendReadyToStart(const cClient & client)232 void sendReadyToStart (const cClient& client)
233 {
234 	auto message = std::make_unique<cNetMessage> (MU_MSG_READY_TO_START);
235 	message->pushChar (client.getActivePlayer().getNr());
236 
237 	client.sendNetMessage (std::move (message));
238 }
239 
sendChatMessageToServer(const cClient & client,const cPlayer & player,const string & msg)240 void sendChatMessageToServer (const cClient& client, const cPlayer& player, const string& msg)
241 {
242 	auto message = std::make_unique<cNetMessage> (GAME_EV_CHAT_CLIENT);
243 	message->pushString (msg);
244 	message->pushChar (player.getNr());
245 	client.sendNetMessage (std::move (message));
246 }
247 
sendWantToEndTurn(const cClient & client)248 void sendWantToEndTurn (const cClient& client)
249 {
250 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_TO_END_TURN);
251 	client.sendNetMessage (std::move (message));
252 }
253 
sendWantStartWork(const cClient & client,const cUnit & building)254 void sendWantStartWork (const cClient& client, const cUnit& building)
255 {
256 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_START_WORK);
257 	message->pushInt32 (building.iID);
258 	client.sendNetMessage (std::move (message));
259 }
260 
sendWantStopWork(const cClient & client,const cUnit & building)261 void sendWantStopWork (const cClient& client, const cUnit& building)
262 {
263 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_STOP_WORK);
264 	message->pushInt32 (building.iID);
265 	client.sendNetMessage (std::move (message));
266 }
267 
sendMoveJob(const cClient & client,sWaypoint * path,int vehicleID)268 void sendMoveJob (const cClient& client, sWaypoint* path, int vehicleID)
269 {
270 	auto message = std::make_unique<cNetMessage> (GAME_EV_MOVE_JOB_CLIENT);
271 
272 	const sWaypoint* waypoint = path;
273 	int iCount = 0;
274 	while (waypoint)
275 	{
276 		message->pushInt16 (waypoint->Costs);
277 		message->pushPosition (waypoint->position);
278 
279 		if (message->iLength > PACKAGE_LENGTH - 19)
280 		{
281 			Log.write (" Client: Error sending movejob: message too long", cLog::eLOG_TYPE_NET_ERROR);
282 			return; // don't send movejobs that are to long
283 		}
284 
285 		waypoint = waypoint->next;
286 		iCount++;
287 	}
288 
289 	message->pushInt16 (iCount);
290 	message->pushInt32 (vehicleID);
291 
292 	client.sendNetMessage (std::move (message));
293 
294 	while (path)
295 	{
296 		waypoint = path;
297 		path = path->next;
298 		delete waypoint;
299 	}
300 }
301 
sendWantStopMove(const cClient & client,int iVehicleID)302 void sendWantStopMove (const cClient& client, int iVehicleID)
303 {
304 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_STOP_MOVE);
305 	message->pushInt16 (iVehicleID);
306 	client.sendNetMessage (std::move (message));
307 }
308 
sendMoveJobResume(const cClient & client,int unitId)309 void sendMoveJobResume (const cClient& client, int unitId)
310 {
311 	auto message = std::make_unique<cNetMessage> (GAME_EV_MOVEJOB_RESUME);
312 	message->pushInt32 (unitId);
313 	client.sendNetMessage (std::move (message));
314 }
315 
sendWantAttack(const cClient & client,int aggressorID,const cPosition & targetPosition,int targetID)316 void sendWantAttack (const cClient& client, int aggressorID, const cPosition& targetPosition, int targetID)
317 {
318 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_ATTACK);
319 	message->pushInt32 (aggressorID);
320 	message->pushPosition (targetPosition);
321 	message->pushInt32 (targetID);
322 	client.sendNetMessage (std::move (message));
323 }
324 
sendMineLayerStatus(const cClient & client,const cVehicle & vehicle)325 void sendMineLayerStatus (const cClient& client, const cVehicle& vehicle)
326 {
327 	auto message = std::make_unique<cNetMessage> (GAME_EV_MINELAYERSTATUS);
328 	message->pushBool (vehicle.isUnitLayingMines());
329 	message->pushBool (vehicle.isUnitClearingMines());
330 	message->pushInt16 (vehicle.iID);
331 	client.sendNetMessage (std::move (message));
332 }
333 
sendWantBuild(const cClient & client,int iVehicleID,sID buildingTypeID,int iBuildSpeed,const cPosition & buildPosition,bool bBuildPath,const cPosition & pathEndPosition)334 void sendWantBuild (const cClient& client, int iVehicleID, sID buildingTypeID, int iBuildSpeed, const cPosition& buildPosition, bool bBuildPath, const cPosition& pathEndPosition)
335 {
336 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_BUILD);
337 	message->pushPosition (pathEndPosition);
338 	message->pushBool (bBuildPath);
339 	message->pushPosition (buildPosition);
340 	message->pushInt16 (iBuildSpeed);
341 	message->pushID (buildingTypeID);
342 	message->pushInt16 (iVehicleID);
343 	client.sendNetMessage (std::move (message));
344 }
345 
sendWantEndBuilding(const cClient & client,const cVehicle & vehicle,const cPosition & escapePosition)346 void sendWantEndBuilding (const cClient& client, const cVehicle& vehicle, const cPosition& escapePosition)
347 {
348 	auto message = std::make_unique<cNetMessage> (GAME_EV_END_BUILDING);
349 	message->pushPosition (escapePosition);
350 	message->pushInt16 (vehicle.iID);
351 	client.sendNetMessage (std::move (message));
352 }
353 
sendWantStopBuilding(const cClient & client,int iVehicleID)354 void sendWantStopBuilding (const cClient& client, int iVehicleID)
355 {
356 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_STOP_BUILDING);
357 	message->pushInt16 (iVehicleID);
358 	client.sendNetMessage (std::move (message));
359 }
360 
sendWantTransfer(const cClient & client,bool bSrcVehicle,int iSrcID,bool bDestVehicle,int iDestID,int iTransferValue,int iType)361 void sendWantTransfer (const cClient& client, bool bSrcVehicle, int iSrcID, bool bDestVehicle, int iDestID, int iTransferValue, int iType)
362 {
363 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_TRANSFER);
364 	message->pushInt16 (iType);
365 	message->pushInt16 (iTransferValue);
366 	message->pushInt16 (iDestID);
367 	message->pushBool (bDestVehicle);
368 	message->pushInt16 (iSrcID);
369 	message->pushBool (bSrcVehicle);
370 	client.sendNetMessage (std::move (message));
371 }
372 
sendWantBuildList(const cClient & client,const cBuilding & building,const std::vector<cBuildListItem> & buildList,bool bRepeat,int buildSpeed)373 void sendWantBuildList (const cClient& client, const cBuilding& building, const std::vector<cBuildListItem>& buildList, bool bRepeat, int buildSpeed)
374 {
375 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_BUILDLIST);
376 	message->pushBool (bRepeat);
377 	for (int i = (int) buildList.size() - 1; i >= 0; i--)
378 	{
379 		message->pushID (buildList[i].getType());
380 	}
381 	message->pushInt16 ((int) buildList.size());
382 	message->pushInt16 (buildSpeed);
383 	message->pushInt16 (building.iID);
384 	client.sendNetMessage (std::move (message));
385 }
386 
sendWantExitFinishedVehicle(const cClient & client,const cBuilding & building,const cPosition & position)387 void sendWantExitFinishedVehicle (const cClient& client, const cBuilding& building, const cPosition& position)
388 {
389 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_EXIT_FIN_VEH);
390 	message->pushPosition (position);
391 	message->pushInt16 (building.iID);
392 	client.sendNetMessage (std::move (message));
393 }
394 
sendChangeResources(const cClient & client,const cBuilding & building,int iMetalProd,int iOilProd,int iGoldProd)395 void sendChangeResources (const cClient& client, const cBuilding& building, int iMetalProd, int iOilProd, int iGoldProd)
396 {
397 	auto message = std::make_unique<cNetMessage> (GAME_EV_CHANGE_RESOURCES);
398 	message->pushInt16 (iGoldProd);
399 	message->pushInt16 (iOilProd);
400 	message->pushInt16 (iMetalProd);
401 	message->pushInt16 (building.iID);
402 	client.sendNetMessage (std::move (message));
403 }
404 
sendChangeManualFireStatus(const cClient & client,int iUnitID,bool bVehicle)405 void sendChangeManualFireStatus (const cClient& client, int iUnitID, bool bVehicle)
406 {
407 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_CHANGE_MANUAL_FIRE);
408 	message->pushInt16 (iUnitID);
409 	message->pushBool (bVehicle);
410 	client.sendNetMessage (std::move (message));
411 }
412 
sendChangeSentry(const cClient & client,int iUnitID,bool bVehicle)413 void sendChangeSentry (const cClient& client, int iUnitID, bool bVehicle)
414 {
415 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_CHANGE_SENTRY);
416 	message->pushInt16 (iUnitID);
417 	message->pushBool (bVehicle);
418 	client.sendNetMessage (std::move (message));
419 }
420 
sendWantSupply(const cClient & client,int iDestID,bool bDestVehicle,int iSrcID,bool bSrcVehicle,int iType)421 void sendWantSupply (const cClient& client, int iDestID, bool bDestVehicle, int iSrcID, bool bSrcVehicle, int iType)
422 {
423 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_SUPPLY);
424 	message->pushInt16 (iDestID);
425 	message->pushBool (bDestVehicle);
426 	message->pushInt16 (iSrcID);
427 	message->pushBool (bSrcVehicle);
428 	message->pushChar (iType);
429 	client.sendNetMessage (std::move (message));
430 }
431 
sendWantStartClear(const cClient & client,const cVehicle & vehicle)432 void sendWantStartClear (const cClient& client, const cVehicle& vehicle)
433 {
434 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_START_CLEAR);
435 	message->pushInt16 (vehicle.iID);
436 	client.sendNetMessage (std::move (message));
437 }
438 
sendWantStopClear(const cClient & client,const cVehicle & vehicle)439 void sendWantStopClear (const cClient& client, const cVehicle& vehicle)
440 {
441 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_STOP_CLEAR);
442 	message->pushInt16 (vehicle.iID);
443 	client.sendNetMessage (std::move (message));
444 }
445 
sendAbortWaiting(const cClient & client)446 void sendAbortWaiting (const cClient& client)
447 {
448 	auto message = std::make_unique<cNetMessage> (GAME_EV_ABORT_WAITING);
449 	client.sendNetMessage (std::move (message));
450 }
451 
sendWantLoad(const cClient & client,int unitid,bool vehicle,int loadedunitid)452 void sendWantLoad (const cClient& client, int unitid, bool vehicle, int loadedunitid)
453 {
454 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_LOAD);
455 	message->pushInt16 (unitid);
456 	message->pushBool (vehicle);
457 	message->pushInt16 (loadedunitid);
458 	client.sendNetMessage (std::move (message));
459 }
460 
sendWantActivate(const cClient & client,int unitid,bool vehicle,int activatunitid,const cPosition & position)461 void sendWantActivate (const cClient& client, int unitid, bool vehicle, int activatunitid, const cPosition& position)
462 {
463 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_EXIT);
464 	message->pushPosition (position);
465 	message->pushInt16 (unitid);
466 	message->pushBool (vehicle);
467 	message->pushInt16 (activatunitid);
468 	client.sendNetMessage (std::move (message));
469 }
470 
sendRequestResync(const cClient & client,char playerNumber,bool newGame)471 void sendRequestResync (const cClient& client, char playerNumber, bool newGame)
472 {
473 	auto message = std::make_unique<cNetMessage> (GAME_EV_REQUEST_RESYNC);
474 	message->pushBool (newGame);
475 	message->pushInt32 (playerNumber);
476 	client.sendNetMessage (std::move (message));
477 }
478 
sendSetAutoStatus(const cClient & client,int vehicleID,bool set)479 void sendSetAutoStatus (const cClient& client, int vehicleID, bool set)
480 {
481 	auto message = std::make_unique<cNetMessage> (GAME_EV_AUTOMOVE_STATUS);
482 	message->pushBool (set);
483 	message->pushInt16 (vehicleID);
484 	client.sendNetMessage (std::move (message));
485 }
486 
sendWantComAction(const cClient & client,int srcUnitID,int destUnitID,bool destIsVehicle,bool steal)487 void sendWantComAction (const cClient& client, int srcUnitID, int destUnitID, bool destIsVehicle, bool steal)
488 {
489 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_COM_ACTION);
490 	message->pushBool (steal);
491 	message->pushInt16 (destUnitID);
492 	message->pushBool (destIsVehicle);
493 	message->pushInt16 (srcUnitID);
494 	client.sendNetMessage (std::move (message));
495 }
496 
497 //------------------------------------------------------------------------
sendUpgradeBuilding(const cClient & client,const cBuilding & building,bool upgradeAll)498 void sendUpgradeBuilding (const cClient& client, const cBuilding& building, bool upgradeAll)
499 {
500 	if (building.getOwner() == 0)
501 		return;
502 
503 	const sUnitData& currentVersion = building.data;
504 	const sUnitData& upgradedVersion = *building.getOwner()->getUnitDataCurrentVersion (building.data.ID);
505 	if (currentVersion.getVersion() >= upgradedVersion.getVersion())
506 		return; // already uptodate
507 
508 	auto msg = std::make_unique<cNetMessage> (GAME_EV_WANT_BUILDING_UPGRADE);
509 	msg->pushBool (upgradeAll);
510 	msg->pushInt32 (building.iID);
511 
512 	client.sendNetMessage (std::move (msg));
513 }
514 
sendWantUpgrade(const cClient & client,int buildingID,int storageSlot,bool upgradeAll)515 void sendWantUpgrade (const cClient& client, int buildingID, int storageSlot, bool upgradeAll)
516 {
517 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_VEHICLE_UPGRADE);
518 	message->pushInt32 (buildingID);
519 	if (!upgradeAll) message->pushInt16 (storageSlot);
520 	message->pushBool (upgradeAll);
521 	client.sendNetMessage (std::move (message));
522 }
523 
sendWantResearchChange(const cClient & client,const std::array<int,cResearch::kNrResearchAreas> & newResearchSettings)524 void sendWantResearchChange (const cClient& client, const std::array<int, cResearch::kNrResearchAreas>& newResearchSettings)
525 {
526 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_RESEARCH_CHANGE);
527 	const cPlayer& player = client.getActivePlayer();
528 	for (int i = 0; i < cResearch::kNrResearchAreas; i++)
529 	{
530 		message->pushInt16 (newResearchSettings[i]);
531 	}
532 	message->pushInt16 (player.getNr());
533 	client.sendNetMessage (std::move (message));
534 }
535 
sendGameGuiState(const cClient & client,const cGameGuiState & gameGuiState,const cPlayer & owner,int savingID)536 void sendGameGuiState (const cClient& client, const cGameGuiState& gameGuiState, const cPlayer& owner, int savingID)
537 {
538 	auto message = std::make_unique<cNetMessage> (GAME_EV_SAVE_HUD_INFO);
539 
540 	gameGuiState.pushInto (*message);
541 	message->pushInt16 (owner.getNr());
542 	message->pushInt16 (savingID);
543 
544 	client.sendNetMessage (std::move (message));
545 }
546 
sendSaveReportInfo(const cClient & client,const cSavedReport & savedReport,int ownerNr,int savingID)547 void sendSaveReportInfo (const cClient& client, const cSavedReport& savedReport, int ownerNr, int savingID)
548 {
549 	auto message = std::make_unique<cNetMessage> (GAME_EV_SAVE_REPORT_INFO);
550 	savedReport.pushInto (*message);
551 	message->pushInt16 (ownerNr);
552 	message->pushInt16 (savingID);
553 	client.sendNetMessage (std::move (message));
554 }
555 
sendFinishedSendSaveInfo(const cClient & client,int ownerNr,int savingID)556 void sendFinishedSendSaveInfo (const cClient& client, int ownerNr, int savingID)
557 {
558 	auto message = std::make_unique<cNetMessage> (GAME_EV_FIN_SEND_SAVE_INFO);
559 	message->pushInt16 (ownerNr);
560 	message->pushInt16 (savingID);
561 	client.sendNetMessage (std::move (message));
562 }
563 
sendRequestCasualtiesReport(const cClient & client)564 void sendRequestCasualtiesReport (const cClient& client)
565 {
566 	auto message = std::make_unique<cNetMessage> (GAME_EV_REQUEST_CASUALTIES_REPORT);
567 	client.sendNetMessage (std::move (message));
568 }
569 
sendWantSelfDestroy(const cClient & client,const cBuilding & building)570 void sendWantSelfDestroy (const cClient& client, const cBuilding& building)
571 {
572 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_SELFDESTROY);
573 	message->pushInt16 (building.iID);
574 	client.sendNetMessage (std::move (message));
575 }
576 
sendWantChangeUnitName(const cClient & client,const string & newName,int unitID)577 void sendWantChangeUnitName (const cClient& client, const string& newName, int unitID)
578 {
579 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_CHANGE_UNIT_NAME);
580 	message->pushString (newName);
581 	message->pushInt16 (unitID);
582 	client.sendNetMessage (std::move (message));
583 }
584 
sendEndMoveAction(const cClient & client,int vehicleID,int destID,eEndMoveActionType type)585 void sendEndMoveAction (const cClient& client, int vehicleID, int destID, eEndMoveActionType type)
586 {
587 	auto message = std::make_unique<cNetMessage> (GAME_EV_END_MOVE_ACTION);
588 	message->pushChar (type);
589 	message->pushInt32 (destID);
590 	message->pushInt32 (vehicleID);
591 	client.sendNetMessage (std::move (message));
592 }
593 
sentWantKickPlayer(const cClient & client,const cPlayer & player)594 void sentWantKickPlayer (const cClient& client, const cPlayer& player)
595 {
596 	auto message = std::make_unique<cNetMessage> (GAME_EV_WANT_KICK_PLAYER);
597 	message->pushInt32 (player.getNr());
598 	client.sendNetMessage (std::move (message));
599 }
600