1 #ifndef __NETWORK_H 2 #define __NETWORK_H 3 4 /* 5 NETWORK.H 6 7 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc. 8 and the "Aleph One" developers. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 This license is contained in the file "COPYING", 21 which is included with this source code; it is available online at 22 http://www.gnu.org/licenses/gpl.html 23 24 Tuesday, June 21, 1994 3:26:46 PM 25 26 May 24, 2003 (Woody Zenfell): 27 compile-time constant MARATHON_NETWORK_VERSION replaced with runtime get_network_version() 28 */ 29 30 #include "cseries.h" 31 #include "cstypes.h" 32 33 // This file should be used only for stuff that folks outside the network subsystem care about 34 // (i.e. it's the interface to the subsystem) 35 36 // I'm tempted to slice the routines the network dialogs deal with away from those that the 37 // rest of the game deals with, but will leave that for another day. 38 39 // unfortunately, this requires map.h because it needs "struct entry_point" 40 41 #ifdef DEMO 42 #define MAXIMUM_NUMBER_OF_NETWORK_PLAYERS 2 43 #else 44 #define MAXIMUM_NUMBER_OF_NETWORK_PLAYERS 8 45 #endif 46 47 #define MAX_LEVEL_NAME_LENGTH 64 48 49 #define DEFAULT_GAME_PORT 4226 50 51 // change this if you make a major change to the way the setup messages work 52 #define kNetworkSetupProtocolID "Aleph One WonderNAT V1" 53 54 // ZZZ: there probably should be a published max size somewhere, but this isn't used anywhere; better 55 // not to pretend it's real. 56 //#define MAX_NET_DISTRIBUTION_BUFFER_SIZE 512 57 58 enum // base network speeds 59 { 60 _appletalk_remote, // ARA 61 _localtalk, 62 _tokentalk, 63 _ethernet, 64 #ifdef USE_MODEM 65 _modem, 66 #endif 67 NUMBER_OF_NETWORK_TYPES 68 }; 69 70 typedef struct game_info 71 { 72 uint16 initial_random_seed; 73 int16 net_game_type; 74 int32 time_limit; 75 int16 kill_limit; 76 int16 game_options; 77 int16 difficulty_level; 78 bool server_is_playing; // if false, then observing 79 bool allow_mic; 80 81 int16 cheat_flags; 82 83 // where the game takes place 84 int16 level_number; 85 char level_name[MAX_LEVEL_NAME_LENGTH+1]; 86 uint32 parent_checksum; 87 88 // network parameters 89 int16 initial_updates_per_packet; 90 int16 initial_update_latency; 91 } game_info; 92 93 #define MAX_NET_PLAYER_NAME_LENGTH 32 94 #define LONG_SERIAL_NUMBER_LENGTH 10 95 96 typedef struct player_info 97 { 98 char name[MAX_NET_PLAYER_NAME_LENGTH+1]; 99 int16 desired_color; 100 int16 team; // from player.h 101 int16 color; 102 byte long_serial_number[LONG_SERIAL_NUMBER_LENGTH]; 103 } player_info; 104 105 106 struct prospective_joiner_info { 107 uint16 stream_id; 108 char name[MAX_NET_PLAYER_NAME_LENGTH]; 109 int16 color; 110 int16 team; 111 bool gathering; 112 }; 113 114 115 116 /* ---------------- functions from network.c */ 117 enum /* message types passed to the user�s names lookup update procedure */ 118 { 119 removeEntity, 120 insertEntity 121 }; 122 123 class GatherCallbacks 124 { 125 public: ~GatherCallbacks()126 virtual ~GatherCallbacks() { }; 127 128 virtual void JoinSucceeded(const prospective_joiner_info *player) = 0; 129 virtual void JoiningPlayerDropped(const prospective_joiner_info *player) = 0; 130 virtual void JoinedPlayerDropped(const prospective_joiner_info *player) = 0; JoinedPlayerChanged(const prospective_joiner_info * player)131 virtual void JoinedPlayerChanged(const prospective_joiner_info *player) { }; 132 }; 133 134 class ChatCallbacks 135 { 136 public: ~ChatCallbacks()137 virtual ~ChatCallbacks() { }; 138 static void SendChatMessage(const std::string& message); 139 virtual void ReceivedMessageFromPlayer(const char *player_name, 140 const char *message) = 0; 141 }; 142 143 class InGameChatCallbacks : public ChatCallbacks 144 { 145 public: ~InGameChatCallbacks()146 ~InGameChatCallbacks() { } 147 static InGameChatCallbacks *instance(); 148 void ReceivedMessageFromPlayer(const char *player_name, const char *message); 149 150 static std::string prompt(); 151 152 private: InGameChatCallbacks()153 InGameChatCallbacks() { } 154 }; 155 156 157 158 // ZZZ note: netPlayerAdded, netChatMessageReceived, and netStartingResumeGame are 'pseudo-states'; 159 // they are returned from NetUpdateJoinState() but will never be assigned to the actual "NetState()". 160 // ghs: netAwaitingHello isn't ever returned or assigned to netState 161 enum /* states */ 162 { 163 netUninitialized, /* NetEnter() has not been called */ 164 netGathering, /* looking for players */ 165 netConnecting, /* trying to establish connection to gatherer */ 166 netJoining, /* waiting to be gathered */ 167 netWaiting, /* have been gathered, waiting for start message */ 168 netStartingUp, /* waiting for everyone to report (via NetSync) and begin queueing commands */ 169 netActive, /* in game */ 170 netComingDown, /* Coming down... */ 171 netDown, /* game over, waiting for new gather or join call */ 172 netCancelled, /* the game was just cancelled */ 173 netPlayerAdded, /* a new player was just added to the topology (will return to netWaiting) */ 174 netPlayerDropped, /* like netPlayerAdded */ 175 netPlayerChanged, /* like netPlayerAdded */ 176 netJoinErrorOccurred, 177 netChatMessageReceived, // ZZZ addition 178 netStartingResumeGame, // ZZZ addition: like netStartingUp, but starting a resume-game instead of a new game 179 netAwaitingHello // only used for handler state 180 }; 181 182 /* -------- typedefs */ 183 // player index is the index of the player that is sending the information 184 typedef void (*NetDistributionProc)(void *buffer, short buffer_size, short player_index); 185 typedef void (*CheckPlayerProcPtr)(short player_index, short num_players); 186 187 /* --------- prototypes/NETWORK.C */ 188 void NetSetGatherCallbacks(GatherCallbacks *gc); 189 void NetSetChatCallbacks(ChatCallbacks *cc); 190 bool NetEnter(); 191 void NetDoneGathering (void); 192 void NetExit(void); 193 194 bool NetGather(void *game_data, short game_data_size, void *player_data, 195 short player_data_size, bool resuming_game); 196 197 struct SSLP_ServiceInstance; 198 199 enum { // NetGatherPlayer results 200 kGatherPlayerFailed, // generic 201 kGatherPlayerSuccessful, // generic 202 kGatheredUnacceptablePlayer // we had already committed to gathering this jimmy, 203 // but we can't start a game with him - upper-level code needs to make sure gathering is cancelled. 204 }; 205 206 int NetGatherPlayer( 207 // ZZZ: in my formulation, player info is all passed along in one structure from the dialog here. 208 const prospective_joiner_info &player, 209 CheckPlayerProcPtr check_player); 210 211 void NetHandleUngatheredPlayer(prospective_joiner_info ungathered_player); 212 213 // jkvw: replaced SSLP hinting address with host address 214 bool NetGameJoin(void *player_data, short player_data_size, const char* host_address_string); 215 216 bool NetCheckForNewJoiner (prospective_joiner_info &info); 217 short NetUpdateJoinState(void); 218 void NetCancelJoin(void); 219 220 // ask to change color and team; it's up to the gatherer to update the topo 221 // usually he'll change your team, if the color's free you'll get that too 222 void NetChangeColors(int16 color, int16 team); 223 224 // ghs: these are obsolete, I'll get rid of them when I'm sure I won't want 225 // to refer back to them 226 227 // ZZZ addition - pre-game/(eventually) postgame chat 228 // Returns true if there was a pending message. 229 // Returns pointer to chat text. 230 // Returns pointer to sending player's data (does not copy player data). 231 // Data returned in pointers is only good until the next call to NetUpdateJoinState or NetCheckForIncomingMessages. 232 bool NetGetMostRecentChatMessage(player_info** outSendingPlayerData, char** outMessage); 233 234 // Gatherer should use this to send out his messages or to broadcast a message received from a joiner 235 OSErr NetDistributeChatMessage(short sender_identifier, const char* message); 236 237 void NetProcessMessagesInGame(); 238 239 short NetGetLocalPlayerIndex(void); 240 short NetGetPlayerIdentifier(short player_index); 241 242 bool NetNumberOfPlayerIsValid(void); 243 short NetGetNumberOfPlayers(void); 244 245 void *NetGetPlayerData(short player_index); 246 void *NetGetGameData(void); 247 248 struct player_start_data; 249 // Gatherer may call this once after all players are gathered but before NetStart() 250 void NetSetupTopologyFromStarts(const player_start_data* inStartArray, short inStartCount); 251 252 void NetSetInitialParameters(short updates_per_packet, short update_latency); 253 254 bool NetSync(void); 255 bool NetUnSync(void); 256 257 bool NetStart(void); 258 void NetCancelGather(void); 259 260 int32 NetGetNetTime(void); 261 262 bool NetChangeMap(struct entry_point *entry); 263 OSErr NetDistributeGameDataToAllPlayers(byte* wad_buffer, int32 wad_length, bool do_physics); 264 byte* NetReceiveGameData(bool do_physics); 265 266 void DeferredScriptSend (byte* data, size_t length); 267 void SetNetscriptStatus (bool status); 268 269 void display_net_game_stats(void); 270 271 // ZZZ change: caller specifies int16 ID for distribution type. Unknown types (when received) are 272 // passed along but ignored. Uses an STL 'map' so ID's need not be consecutive or in any particular 273 // sub-range. 274 void NetAddDistributionFunction(int16 type, NetDistributionProc proc, bool lossy); 275 void NetDistributeInformation(short type, void *buffer, short buffer_size, bool send_to_self, bool send_only_to_team = false); 276 void NetRemoveDistributionFunction(short type); 277 278 // disable "cheats" 279 bool NetAllowCrosshair(); 280 bool NetAllowOverlayMap(); 281 bool NetAllowTunnelVision(); 282 bool NetAllowBehindview(); 283 bool NetAllowCarnageMessages(); 284 bool NetAllowSavingLevel(); 285 286 // spoke stuf 287 288 int32 NetGetUnconfirmedActionFlagsCount(); // how many flags can we use for prediction? 289 uint32 NetGetUnconfirmedActionFlag(int32 offset); // offset < GetUnconfirmedActionFlagsCount 290 void NetUpdateUnconfirmedActionFlags(); 291 292 struct NetworkStats 293 { 294 enum { 295 invalid = -1, 296 disconnected = -2, 297 }; 298 299 int16 latency; 300 int16 jitter; 301 uint16 errors; 302 }; 303 304 // returns latency in ms, or kNetLatencyInvalid or kNetLatencyDisconnected 305 int32 NetGetLatency(); 306 307 const NetworkStats& NetGetStats(int player_index); 308 309 #endif 310