1 /*
2  *  network_private.h
3 
4 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
5 	and the "Aleph One" developers.
6 
7 	This program is free software; you can redistribute it and/or modify
8 	it under the terms of the GNU General Public License as published by
9 	the Free Software Foundation; either version 3 of the License, or
10 	(at your option) any later version.
11 
12 	This program is distributed in the hope that it will be useful,
13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 	GNU General Public License for more details.
16 
17 	This license is contained in the file "COPYING",
18 	which is included with this source code; it is available online at
19 	http://www.gnu.org/licenses/gpl.html
20 
21  * This file holds stuff that various parts of the network subsystem want to see, but that portions
22  * of Aleph One outside of the networking code should not care about.
23  *
24  * Oct 11, 2001 (Woody Zenfell): split code away from network.cpp to create this file.
25  *	Made any simple modifications needed to make things compile/work.
26  *
27  * Oct-Nov 2001 (Woody Zenfell): added code in support of text messages in stream packets.
28  *	Added many comments.
29 
30 Feb 27, 2002 (Br'fin (Jeremy Parsons)):
31 	Enabled SDL networking for Carbon without fully using SDL
32 
33  May 24, 2003 (Woody Zenfell):
34 	Split ring-protocol-specific stuff out into RingGameProtocol.cpp;
35 	"Unknown packet type response" streaming packet type; NetGetDistributionInfoForType()
36  */
37 
38 #ifndef	NETWORK_PRIVATE_H
39 #define	NETWORK_PRIVATE_H
40 
41 #include	"cstypes.h"
42 
43 #include	"sdl_network.h"
44 
45 #include	"network.h"
46 
47 // "network_dialogs_private.h"
48 #include	"SSLP_API.h"
49 
50 #include <memory>
51 
52 #define	GAME_PORT (network_preferences->game_port)
53 
54 // (ZZZ:) Moved here from sdl_network.h and macintosh_network.h
55 
56 /* ---------- constants */
57 
58 #define asyncUncompleted 1	/* ioResult value */
59 
60 #define strNETWORK_ERRORS 132
61 enum /* error string for user */
62 {
63 	netErrCantAddPlayer,
64 	netErrCouldntDistribute,
65 	netErrCouldntJoin,
66 	netErrServerCanceled,
67 	netErrMapDistribFailed,
68 	netErrWaitedTooLongForMap,
69 	netErrSyncFailed,
70 	netErrJoinFailed,
71 	netErrCantContinue,
72         netErrIncompatibleVersion,
73         netErrGatheredPlayerUnacceptable,
74         netErrUngatheredPlayerUnacceptable,
75         netErrJoinerCantFindScenario,
76 	netErrLostConnection,
77 	netErrCouldntResolve,
78 	netErrCouldntReceiveMap,
79 	netWarnJoinerHasNoStar,
80 	netWarnJoinerHasNoRing,
81 	netWarnJoinerNoLua,
82 	netErrMetaserverConnectionFailure,
83 	netWarnCouldNotAdvertiseOnMetaserver,
84 	netWarnUPnPConfigureFailed
85 };
86 
87 // (ZZZ:) Moved here from network.cpp
88 
89 /* ---------- constants */
90 
91 #define NET_DEAD_ACTION_FLAG_COUNT (-1)
92 #define NET_DEAD_ACTION_FLAG (NONE)
93 
94 #define MAXIMUM_GAME_DATA_SIZE       256
95 #define MAXIMUM_PLAYER_DATA_SIZE     128
96 #define MAXIMUM_UPDATES_PER_PACKET    16 // how many action flags per player can be sent in each ring packet
97 #define UPDATES_PER_PACKET             1  // defines action flags per packet and period of the ring
98 #define UPDATE_LATENCY                 1
99 
100 #define NET_QUEUE_SIZE (MAXIMUM_UPDATES_PER_PACKET+1)
101 
102 #define UNSYNC_TIMEOUT (3*MACHINE_TICKS_PER_SECOND) // 3 seconds
103 
104 #define STREAM_TRANSFER_CHUNK_SIZE (10000)
105 #define MAP_TRANSFER_TIME_OUT   (MACHINE_TICKS_PER_SECOND*70) // 70 seconds to wait for map.
106 #define NET_SYNC_TIME_OUT       (MACHINE_TICKS_PER_SECOND*50) // 50 seconds to time out of syncing.
107 
108 #define kACK_TIMEOUT 40
109 #define kRETRIES     50  // how many timeouts allowed before dropping the next player
110                          // kRETRIES * kACK_TIMEOUT / 1000 = timeout in seconds
111 
112 #define NUM_DISTRIBUTION_TYPES    3
113 
114 // Altering constants below should make you alter get_network_version().  - Woody
115 #define kPROTOCOL_TYPE           69
116 
117 enum /* tag */
118 {	// ZZZ annotation: these (in NetPacketHeader) indicate the rest of the datagram is a NetPacket (i.e. a ring packet).
119 	tagRING_PACKET,
120 	tagACKNOWLEDGEMENT,
121 	tagCHANGE_RING_PACKET,  // to tell a player to change his downring address. also has action flags.
122 
123         // ZZZ annotation: these should only be found in streaming data (in a NetTopology).
124 	tagNEW_PLAYER,
125 	tagCANCEL_GAME,
126 	tagSTART_GAME,
127 	tagDROPPED_PLAYER,
128 	tagCHANGED_PLAYER,
129 
130         // ZZZ annotation: these (in NetPacketHeader) indicate the rest of the datagram is a NetDistributionPacket.
131 	tagLOSSY_DISTRIBUTION,     // for transfer data other than action flags
132 	tagLOSSLESS_DISTRIBUTION,   // ditto, but currently unimplemented
133 
134         // ZZZ: more streaming data (topology) packet types
135         tagRESUME_GAME	// ZZZ addition: trying to resume a saved-game rather than start a new netgame.
136 };
137 
138 enum
139 {
140 	typeSYNC_RING_PACKET,    // first packet of the game, gets everyone in the game
141 	typeTIME_RING_PACKET,    // second packet of the game, sets everyone's clock
142 	typeNORMAL_RING_PACKET,   // all the other packets of the game
143 
144 	typeUNSYNC_RING_PACKET,	// last packet of the game, get everyone unsynced properly.
145 	typeDEAD_PACKET	// This is simply a convenience for a switch. This packet never leaves the server.
146 };
147 
148 /* ---------- structures */
149 
150 
151 // (ZZZ:) Note ye well!!: if you alter these network-related structures, you are probably going to need to modify
152 // the corresponding _NET structures in network_data_formats.h AND *both* corresponding netcpy() functions in
153 // network_data_formats.cpp.  AND, you'll probably need to alter get_network_version() while you're at it,
154 // since you've made an incompatible change to the network communication protocol.
155 
156 // (ZZZ:) Information passed in datagrams (note: the _NET version is ALWAYS the one sent/received on the wire.
157 // If not, it's a BUG.  These are used to setup/extract data.)
158 struct NetPacketHeader
159 {
160 	int16 tag;
161 	int32 sequence;
162 
163 	/* data */
164 };
165 typedef struct NetPacketHeader NetPacketHeader, *NetPacketHeaderPtr;
166 
167 struct NetPacket
168 {
169 	uint8 ring_packet_type;         // typeSYNC_RING_PACKET, etc...
170 	uint8 server_player_index;
171 	int32 server_net_time;
172 	int16 required_action_flags;                         // handed down from on high (the server)
173 	int16 action_flag_count[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];  // how many each player actually has.
174 	uint32 action_flags[1];
175 };
176 typedef struct NetPacket NetPacket, *NetPacketPtr;
177 
178 struct NetDistributionPacket
179 {
180 	int16 distribution_type;  // type of information
181 	int16 first_player_index; // who sent the information
182 	int16 data_size;          // how much they're sending.
183 	uint8  data[2];            // the chunk �o shit to send
184 };
185 typedef struct NetDistributionPacket NetDistributionPacket, *NetDistributionPacketPtr;
186 
187 // Information passed in streams
188 struct NetPlayer
189 {
190 	NetAddrBlock dspAddress, ddpAddress;
191 
192 	int16 identifier;
193 
194 	int16 stream_id; // to remind gatherer how to contact joiners
195 
196 	bool net_dead; // only valid if you are the server.
197 
198   //uint8 player_data[MAXIMUM_PLAYER_DATA_SIZE];
199   player_info player_data;
200 };
201 typedef struct NetPlayer NetPlayer, *NetPlayerPtr;
202 
203 struct NetTopology
204 {
205 	int16 tag;
206 	int16 player_count;
207 
208 	int16 nextIdentifier;
209 
210   //uint8 game_data[MAXIMUM_GAME_DATA_SIZE];
211   game_info game_data;
212 
213 	struct NetPlayer players[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];
214 };
215 typedef struct NetTopology NetTopology, *NetTopologyPtr;
216 
217 #ifdef NETWORK_CHAT
218 // (ZZZ addition)
219 enum { CHAT_MESSAGE_TEXT_BUFFER_SIZE = 250 };
220 
221 struct NetChatMessage {
222     int16   sender_identifier;
223     char    text[CHAT_MESSAGE_TEXT_BUFFER_SIZE];
224 };
225 #endif
226 
227 
228 // ZZZ: same here (should be safe to alter)
229 struct NetDistributionInfo
230 {
231 	bool              lossy;
232 	NetDistributionProc  distribution_proc;
233 };
234 
235 typedef struct NetDistributionInfo NetDistributionInfo, *NetDistributionInfoPtr;
236 
237 #define errInvalidMapPacket (42)
238 // ZZZ: taking a cue... used when trying to gather a player whose A1 doesn't support all the features we need.
239 #define errPlayerTooNaive (43)
240 
241 /* ===== application specific data structures/enums */
242 
243 // Information sent via streaming protocol - warning above still applies!
244 struct gather_player_data {
245 	int16 new_local_player_identifier;
246 };
247 
248 // used in accept_gather_data::accepted - this is a sneaky way of detecting whether
249 // we're playing with a resume netgame-capable player or not.  (Old code always sent
250 // 1 on accept, never 2; old code interprets any nonzero 'accepted' as an accept.)
251 enum {
252         kNaiveJoinerAccepted = 1,
253         kResumeNetgameSavvyJoinerAccepted = 2,	// build knows how to resume saved games as netgames
254         kFixedTagAndBallJoinerAccepted = 3,	// build lacks multiple-ball-drop bug and tag-suicide bug
255 
256         // this should always be updated to match the current best (unless our build isn't up to spec)
257         kStateOfTheArtJoinerAccepted = kFixedTagAndBallJoinerAccepted
258 };
259 
260 struct accept_gather_data {
261 	uint8 accepted;
262 	NetPlayer player;
263 };
264 
265 enum {
266 	_netscript_query_message,
267         _netscript_no_script_message,
268         _netscript_yes_script_message,
269         _netscript_script_intent_message
270 };
271 
272 // Altering these constants requires changes to get_network_version().  - Woody
273 enum {
274 	_hello_packet,
275 	_joiner_info_packet,
276 	_join_player_packet,
277 	_accept_join_packet,
278 	_topology_packet,
279 	_stream_size_packet,
280 	_stream_data_packet,
281 	// ZZZ additions below
282         _chat_packet,
283 	// The following should only be sent when get_network_version() >= kMinimumNetworkVersionForGracefulUnknownStreamPackets
284 	_unknown_packet_type_response_packet,
285         _script_packet,
286 	NUMBER_OF_BUFFERED_STREAM_PACKET_TYPES,
287 	NUMBER_OF_STREAM_PACKET_TYPES= 	NUMBER_OF_BUFFERED_STREAM_PACKET_TYPES
288 };
289 
290 /* ===== end of application specific data structures/enums */
291 
292 class CommunicationsChannel;
293 class MessageDispatcher;
294 class MessageHandler;
295 
296 class Message;
297 
298 
299 const NetDistributionInfo* NetGetDistributionInfoForType(int16 inType);
300 
301 struct ClientChatInfo
302 {
303 	std::string name;
304 	int16 color;
305 	int16 team;
306 };
307 
308 // "network_dialogs_private.h" follows
309 
310 class GathererAvailableAnnouncer
311 {
312 public:
313 	GathererAvailableAnnouncer();
314 	~GathererAvailableAnnouncer();
315 	static void pump();
316 
317 private:
318 	SSLP_ServiceInstance	mServiceInstance;
319 };
320 
321 
322 class JoinerSeekingGathererAnnouncer
323 {
324 public:
325 	JoinerSeekingGathererAnnouncer(bool shouldSeek);
326 	~JoinerSeekingGathererAnnouncer();
327 	static void pump();
328 
329 private:
330 	static void found_gatherer_callback(const SSLP_ServiceInstance* instance);
331 	static void lost_gatherer_callback(const SSLP_ServiceInstance* instance);
332 
333 	bool mShouldSeek;
334 };
335 
336 
337 #endif//NETWORK_PRIVATE_H
338