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