1 /*
2 	This file is part of Warzone 2100.
3 	Copyright (C) 1999-2004  Eidos Interactive
4 	Copyright (C) 2005-2020  Warzone 2100 Project
5 
6 	Warzone 2100 is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	Warzone 2100 is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with Warzone 2100; if not, write to the Free Software
18 	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /*
21  *  Alex Lee 1997/98, Pumpkin Studios, Bath.
22  */
23 
24 #ifndef __INCLUDED_SRC_MULTIPLAY_H__
25 #define __INCLUDED_SRC_MULTIPLAY_H__
26 
27 #include "lib/framework/frame.h"
28 #include "lib/framework/types.h"
29 #include "lib/framework/vector.h"
30 #include "lib/framework/crc.h"
31 #include "lib/netplay/nettypes.h"
32 #include "orderdef.h"
33 #include "stringdef.h"
34 #include "messagedef.h"
35 #include "levels.h"
36 #include "console.h"
37 #include "multirecv.h"
38 #include <vector>
39 #include <string>
40 
41 class DROID_GROUP;
42 struct BASE_OBJECT;
43 struct DROID;
44 struct DROID_TEMPLATE;
45 struct FEATURE;
46 struct INITIAL_DROID_ORDERS;
47 struct STRUCTURE;
48 
49 // /////////////////////////////////////////////////////////////////////////////////////////////////
50 // Game Options Structure. Enough info to completely describe the static stuff in a multiplayer game.
51 // Also used for skirmish games. And sometimes for campaign. Should be moved somewhere else.
52 struct MULTIPLAYERGAME
53 {
54 	LEVEL_TYPE	type;						// DMATCH/CAMPAIGN/SKIRMISH/TEAMPLAY etc...
55 	bool		scavengers;					// whether scavengers are on or off
56 	char		map[128];					// name of multiplayer map being used.
57 	uint8_t		maxPlayers;					// max players to allow
58 	char		name[128];					// game name   (to be used)
59 	Sha256      hash;                       ///< Hash of map file. Zero if built in.
60 	std::vector<Sha256> modHashes;          // Hash of mods.
61 	uint32_t    power;						// power level for arena game
62 	uint8_t		base;						// clean/base/base&defence
63 	uint8_t		alliance;					// no/yes/locked
64 	bool		mapHasScavengers;
65 	bool		isMapMod;					// if a map has mods
66 	bool        isRandom;                   // If a map is non-static.
67 	uint32_t	techLevel;					// what technology level is being used
68 };
69 
70 struct MULTISTRUCTLIMITS
71 {
72 	uint32_t        id;
73 	uint32_t        limit;
74 };
75 
76 // The side we are *configured* as. Used to indicate whether we are the server or the client. Note that when
77 // playing singleplayer, we are running as a host, not a client. Values are booleans as this replaces the old
78 // `bool bHostSetup`.
79 enum class InGameSide : bool {
80 	HOST_OR_SINGLEPLAYER = true,
81 	MULTIPLAYER_CLIENT = false
82 };
83 
84 // info used inside games.
85 struct MULTIPLAYERINGAME
86 {
87 	UDWORD				PingTimes[MAX_PLAYERS];				// store for pings.
88 	bool				localOptionsReceived;				// used to show if we have game options yet..
89 	bool				localJoiningInProgress;				// used before we know our player number.
90 	bool				JoiningInProgress[MAX_PLAYERS];
91 	bool				DataIntegrity[MAX_PLAYERS];
92 	InGameSide			side;
93 	int32_t				TimeEveryoneIsInGame;
94 	bool				isAllPlayersDataOK;
95 	UDWORD				startTime;
96 	std::vector<MULTISTRUCTLIMITS> structureLimits;
97 	uint8_t				flags;  ///< Bitmask, shows which structures are disabled.
98 #define MPFLAGS_NO_TANKS	0x01  		///< Flag for tanks disabled
99 #define MPFLAGS_NO_CYBORGS	0x02  		///< Flag for cyborgs disabled
100 #define MPFLAGS_NO_VTOLS	0x04  		///< Flag for VTOLs disabled
101 #define MPFLAGS_NO_UPLINK	0x08  		///< Flag for Satellite Uplink disabled
102 #define MPFLAGS_NO_LASSAT	0x10  		///< Flag for Laser Satellite Command Post disabled
103 #define MPFLAGS_FORCELIMITS	0x20  		///< Flag to force structure limits
104 #define MPFLAGS_MAX		0x3f
105 	SDWORD		skScores[MAX_PLAYERS][2];			// score+kills for local skirmish players.
106 };
107 
108 struct NetworkTextMessage
109 {
110 	/**
111 	 * Sender can be a player index, SYSTEM_MESSAGE or NOTIFY_MESSAGE.
112 	 **/
113 	int32_t sender;
114 	char text[MAX_CONSOLE_STRING_LENGTH];
115 	bool teamSpecific = false;
116 
NetworkTextMessageNetworkTextMessage117 	NetworkTextMessage() {}
118 	NetworkTextMessage(int32_t messageSender, char const *messageText);
119 	void enqueue(NETQUEUE queue);
120 	bool receive(NETQUEUE queue);
121 };
122 
123 enum STRUCTURE_INFO
124 {
125 	STRUCTUREINFO_MANUFACTURE,
126 	STRUCTUREINFO_CANCELPRODUCTION,
127 	STRUCTUREINFO_HOLDPRODUCTION,
128 	STRUCTUREINFO_RELEASEPRODUCTION,
129 	STRUCTUREINFO_HOLDRESEARCH,
130 	STRUCTUREINFO_RELEASERESEARCH
131 };
132 
133 // ////////////////////////////////////////////////////////////////////////////
134 // Game Options and stats.
135 extern MULTIPLAYERGAME		game;						// the game description.
136 extern MULTIPLAYERINGAME	ingame;						// the game description.
137 
138 extern bool bMultiPlayer;				// true when more than 1 player.
139 extern bool bMultiMessages;				// == bMultiPlayer unless multi messages are disabled
140 extern bool openchannels[MAX_PLAYERS];
141 extern UBYTE bDisplayMultiJoiningStatus;	// draw load progress?
142 
143 #define RUN_ONLY_ON_SIDE(_side) \
144 	if (ingame.side != _side) \
145 	{ \
146 		return; \
147 	}
148 
149 
150 // ////////////////////////////////////////////////////////////////////////////
151 // defines
152 
153 // Bitmask for client lobby
154 
155 #define NO_VTOLS  1
156 #define NO_TANKS 2
157 #define NO_BORGS 4
158 
159 
160 #define ANYPLAYER				99
161 
162 #define CAMP_CLEAN				0			// campaign subtypes
163 #define CAMP_BASE				1
164 #define CAMP_WALLS				2
165 
166 #define PING_LIMIT				4000		// If ping is bigger than this, then worry and panic, and don't even try showing the ping.
167 
168 #define LEV_LOW					0
169 #define LEV_MED					1
170 #define LEV_HI					2
171 
172 #define TECH_1					1
173 #define TECH_2					2
174 #define TECH_3					3
175 #define TECH_4					4
176 
177 #define MAX_KICK_REASON			80			// max array size for the reason your kicking someone
178 // functions
179 
180 WZ_DECL_WARN_UNUSED_RESULT BASE_OBJECT		*IdToPointer(UDWORD id, UDWORD player);
181 WZ_DECL_WARN_UNUSED_RESULT STRUCTURE		*IdToStruct(UDWORD id, UDWORD player);
182 WZ_DECL_WARN_UNUSED_RESULT DROID			*IdToDroid(UDWORD id, UDWORD player);
183 WZ_DECL_WARN_UNUSED_RESULT DROID			*IdToMissionDroid(UDWORD id, UDWORD player);
184 WZ_DECL_WARN_UNUSED_RESULT FEATURE		*IdToFeature(UDWORD id, UDWORD player);
185 WZ_DECL_WARN_UNUSED_RESULT DROID_TEMPLATE	*IdToTemplate(UDWORD tempId, UDWORD player);
186 
187 const char *getPlayerName(int player);
188 bool setPlayerName(int player, const char *sName);
189 const char *getPlayerColourName(int player);
190 bool isHumanPlayer(int player);				//to tell if the player is a computer or not.
191 bool myResponsibility(int player);
192 bool responsibleFor(int player, int playerinquestion);
193 int whosResponsible(int player);
194 bool canGiveOrdersFor(int player, int playerInQuestion);
195 int scavengerSlot();    // Returns the player number that scavengers would have if they were enabled.
196 int scavengerPlayer();  // Returns the player number that the scavengers have, or -1 if disabled.
197 Vector3i cameraToHome(UDWORD player, bool scroll);
198 
199 bool multiPlayerLoop();							// for loop.c
200 
201 bool recvMessage();
202 bool SendResearch(uint8_t player, uint32_t index, bool trigger);
203 void printInGameTextMessage(NetworkTextMessage const &message);
204 void sendInGameSystemMessage(const char *text);
205 int32_t findPlayerIndexByPosition(uint32_t position);
206 void printConsoleNameChange(const char *oldName, const char *newName);  ///< Print message to console saying a name changed.
207 
208 void turnOffMultiMsg(bool bDoit);
209 
210 void sendMap();
211 bool multiplayerWinSequence(bool firstCall);
212 
213 /////////////////////////////////////////////////////////
214 // definitions of functions in multiplay's other c files.
215 
216 // Buildings . multistruct
217 bool SendDestroyStructure(STRUCTURE *s);
218 bool SendBuildFinished(STRUCTURE *psStruct);
219 bool sendLasSat(UBYTE player, STRUCTURE *psStruct, BASE_OBJECT *psObj);
220 void sendStructureInfo(STRUCTURE *psStruct, STRUCTURE_INFO structureInfo, DROID_TEMPLATE *psTempl);
221 
222 // droids . multibot
223 bool SendDroid(DROID_TEMPLATE *pTemplate, uint32_t x, uint32_t y, uint8_t player, uint32_t id, const INITIAL_DROID_ORDERS *initialOrders);
224 bool SendDestroyDroid(const DROID *psDroid);
225 void sendQueuedDroidInfo();  ///< Actually sends the droid orders which were queued by SendDroidInfo.
226 void sendDroidInfo(DROID *psDroid, DroidOrder const &order, bool add);
227 
228 bool sendDroidSecondary(const DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE state);
229 bool sendDroidDisembark(DROID const *psTransporter, DROID const *psDroid);
230 
231 // Startup. mulitopt
232 bool multiShutdown();
233 bool sendLeavingMsg();
234 
235 bool hostCampaign(const char *SessionName, char *hostPlayerName, bool skipResetAIs);
236 struct JoinConnectionDescription
237 {
238 public:
JoinConnectionDescriptionJoinConnectionDescription239 	JoinConnectionDescription() { }
JoinConnectionDescriptionJoinConnectionDescription240 	JoinConnectionDescription(const std::string& host, uint32_t port)
241 	: host(host)
242 	, port(port)
243 	{ }
244 public:
245 	std::string host;
246 	uint32_t port = 0;
247 };
248 std::vector<JoinConnectionDescription> findLobbyGame(const std::string& lobbyAddress, unsigned int lobbyPort, uint32_t lobbyGameId);
249 enum class JoinGameResult {
250 	FAILED,
251 	JOINED,
252 	PENDING_PASSWORD
253 };
254 JoinGameResult joinGame(const char *connectionString);
255 JoinGameResult joinGame(const char *host, uint32_t port);
256 JoinGameResult joinGame(const std::vector<JoinConnectionDescription>& connection_list);
257 void playerResponding();
258 bool multiGameInit();
259 bool multiGameShutdown();
260 
261 // syncing.
262 bool sendScoreCheck();							//score check only(frontend)
263 bool sendPing();							// allow game to request pings.
264 void HandleBadParam(const char *msg, const int from, const int actual);
265 // multijoin
266 bool sendResearchStatus(const STRUCTURE *psBuilding, UDWORD index, UBYTE player, bool bStart);
267 
268 bool sendBeacon(int32_t locX, int32_t locY, int32_t forPlayer, int32_t sender, const char *pStr);
269 
270 void startMultiplayerGame();
271 void resetReadyStatus(bool bSendOptions, bool ignoreReadyReset = false);
272 
273 STRUCTURE *findResearchingFacilityByResearchIndex(unsigned player, unsigned index);
274 
275 void sendSyncRequest(int32_t req_id, int32_t x, int32_t y, const BASE_OBJECT *psObj, const BASE_OBJECT *psObj2);
276 
277 
278 bool sendBeaconToPlayer(SDWORD locX, SDWORD locY, SDWORD forPlayer, SDWORD sender, const char *beaconMsg);
279 MESSAGE *findBeaconMsg(UDWORD player, SDWORD sender);
280 VIEWDATA *CreateBeaconViewData(SDWORD sender, UDWORD LocX, UDWORD LocY);
281 
282 #endif // __INCLUDED_SRC_MULTIPLAY_H__
283