1 /*
2  *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
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 Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #ifndef UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_
20 #define UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_
21 
22 #include "netplay.h"
23 		// for NETPLAY_STATISTICS
24 
25 #if defined(__cplusplus)
26 extern "C" {
27 #endif
28 
29 typedef struct NetConnection NetConnection;
30 typedef struct NetConnectionError NetConnectionError;
31 typedef struct ConnectStateData ConnectStateData;
32 #ifdef NETPLAY_STATISTICS
33 typedef struct NetStatistics NetStatistics;
34 #endif
35 
36 typedef void (*NetConnection_ConnectCallback)(NetConnection *nd);
37 typedef void (*NetConnection_CloseCallback)(NetConnection *nd);
38 typedef void (*NetConnection_ErrorCallback)(NetConnection *nd,
39 		const NetConnectionError *error);
40 typedef void (*NetConnection_DeleteCallback)(NetConnection *nd);
41 
42 typedef void (*NetConnection_ReadyCallback)(NetConnection *conn, void *arg);
43 typedef void (*NetConnection_ResetCallback)(NetConnection *conn, void *arg);
44 
45 #if defined(__cplusplus)
46 }
47 #endif
48 
49 #include "netstate.h"
50 #include "netoptions.h"
51 #ifdef NETPLAY_CHECKSUM
52 #	include "checkbuf.h"
53 #endif
54 #if defined(NETPLAY_STATISTICS) || defined(NETCONNECTION_INTERNAL)
55 #	include "packet.h"
56 #endif
57 #if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
58 #	include "libs/uio.h"
59 #endif
60 
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64 
65 struct NetConnectionError {
66 	NetState state;
67 	int err;
68 	union {
69 		const struct ListenError *listenError;
70 		const struct ConnectError *connectError;
71 	} extra;
72 };
73 
74 #ifdef NETPLAY_STATISTICS
75 struct NetStatistics {
76 	size_t packetsReceived;
77 	size_t packetTypeReceived[PACKET_NUM];
78 	size_t packetsSent;
79 	size_t packetTypeSent[PACKET_NUM];
80 };
81 #endif
82 
83 #if defined(__cplusplus)
84 }
85 #endif
86 
87 #ifdef NETCONNECTION_INTERNAL
88 #include "libs/net.h"
89 #include "packetq.h"
90 
91 #if defined(__cplusplus)
92 extern "C" {
93 #endif
94 
95 typedef struct {
96 	// For actions that require agreement by both parties.
97 	bool localOk : 1;    /* Action confirmed by us */
98 	bool remoteOk : 1;   /* Action confirmed by the remote party */
99 	bool canceling : 1;  /* Awaiting cancel confirmation */
100 } HandShakeFlags;
101 
102 typedef struct {
103 	// For actions that do not require agreement, but for which it
104 	// only is relevant that both sides are ready.
105 	bool localReady : 1;
106 	bool remoteReady : 1;
107 } ReadyFlags;
108 
109 typedef struct {
110 	bool localReset : 1;
111 	bool remoteReset : 1;
112 } ResetFlags;
113 
114 // Which parameters have we both sides of a connection reached agreement on?
115 typedef struct {
116 	bool randomSeed : 1;
117 } Agreement;
118 
119 typedef struct {
120 	bool connected;
121 			/* This NetConnection is connected. */
122 	bool disconnected;
123 			/* This NetConnection has been disconnected. This implies
124 			 * !connected. It is only set if the NetConnection was once
125 			 * connected, but is no longer. */
126 	bool discriminant;
127 			/* If it is true here, it is false on the remote side
128 			 * of the same connection. It may be used to break ties.
129 			 * It is guaranteed not to change during a connection. Undefined
130 			 * while not connected. */
131 	HandShakeFlags handshake;
132 	ReadyFlags ready;
133 	ResetFlags reset;
134 	Agreement agreement;
135 	size_t inputDelay;
136 			/* Used during negotiation of the actual inputDelay. This
137 			 * field does NOT necessarilly contain the actual input delay,
138 			 * which is a property of the game, not of any specific
139 			 * connection. Use getBattleInputDelay() to get at it. */
140 #ifdef NETPLAY_CHECKSUM
141 	size_t checksumInterval;
142 #endif
143 } NetStateFlags;
144 
145 struct NetConnection {
146 	NetDescriptor *nd;
147 	int player;
148 			// Number of the player for this connection, as it is
149 			// known locally. For the other player, it may be
150 			// differently.
151 	NetState state;
152 	NetStateFlags stateFlags;
153 
154 	NetConnection_ReadyCallback readyCallback;
155 			// Called when both sides have indicated that they are ready.
156 			// Set by Netplay_localReady().
157 	void *readyCallbackArg;
158 			// Extra argument for readyCallback().
159 			// XXX: when is this cleaned up if a connection is broken?
160 
161 	NetConnection_ResetCallback resetCallback;
162 			// Called when a reset has been signalled and confirmed.
163 			// Set by Netplay_localReset().
164 	void *resetCallbackArg;
165 			// Extra argument for resetCallback().
166 			// XXX: when is this cleaned up if a connection is broken?
167 
168 	const NetplayPeerOptions *options;
169 	PacketQueue queue;
170 #ifdef NETPLAY_STATISTICS
171 	NetStatistics statistics;
172 #endif
173 #ifdef NETPLAY_CHECKSUM
174 	ChecksumBuffer checksumBuffer;
175 #endif
176 #if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
177 	uio_Stream *debugFile;
178 #endif
179 
180 	NetConnection_ConnectCallback connectCallback;
181 	NetConnection_CloseCallback closeCallback;
182 			// Called when the NetConnection becomes disconnected.
183 	NetConnection_ErrorCallback errorCallback;
184 	NetConnection_DeleteCallback deleteCallback;
185 			// Called when the NetConnection is destroyed.
186 	uint8 *readBuf;
187 	uint8 *readEnd;
188 	NetConnectionStateData *stateData;
189 			// State dependant information.
190 	void *extra;
191 };
192 
193 struct ConnectStateData {
194 	NETCONNECTION_STATE_DATA_COMMON
195 
196 	bool isServer;
197 	union {
198 		struct ConnectState *connectState;
199 		struct ListenState *listenState;
200 	} state;
201 };
202 
203 #endif  /* NETCONNECTION_INTERNAL */
204 
205 
206 NetConnection *NetConnection_open(int player,
207 		const NetplayPeerOptions *options,
208 		NetConnection_ConnectCallback connectCallback,
209 		NetConnection_CloseCallback closeCallback,
210 		NetConnection_ErrorCallback errorCallback,
211 		NetConnection_DeleteCallback deleteCallback, void *extra);
212 void NetConnection_close(NetConnection *conn);
213 bool NetConnection_isConnected(const NetConnection *conn);
214 
215 void NetConnection_doErrorCallback(NetConnection *nd, int err);
216 
217 void NetConnection_setStateData(NetConnection *conn,
218 		NetConnectionStateData *stateData);
219 NetConnectionStateData *NetConnection_getStateData(const NetConnection *conn);
220 void NetConnection_setExtra(NetConnection *conn, void *extra);
221 void *NetConnection_getExtra(const NetConnection *conn);
222 void NetConnection_setState(NetConnection *conn, NetState state);
223 NetState NetConnection_getState(const NetConnection *conn);
224 bool NetConnection_getDiscriminant(const NetConnection *conn);
225 const NetplayPeerOptions *NetConnection_getPeerOptions(
226 		const NetConnection *conn);
227 int NetConnection_getPlayerNr(const NetConnection *conn);
228 size_t NetConnection_getInputDelay(const NetConnection *conn);
229 #ifdef NETPLAY_CHECKSUM
230 ChecksumBuffer *NetConnection_getChecksumBuffer(NetConnection *conn);
231 size_t NetConnection_getChecksumInterval(const NetConnection *conn);
232 #endif
233 #ifdef NETPLAY_STATISTICS
234 NetStatistics *NetConnection_getStatistics(NetConnection *conn);
235 #endif
236 
237 void NetConnection_setReadyCallback(NetConnection *conn,
238 		NetConnection_ReadyCallback callback, void *arg);
239 NetConnection_ReadyCallback NetConnection_getReadyCallback(
240 		const NetConnection *conn);
241 void *NetConnection_getReadyCallbackArg(const NetConnection *conn);
242 
243 void NetConnection_setResetCallback(NetConnection *conn,
244 		NetConnection_ResetCallback callback, void *arg);
245 NetConnection_ResetCallback NetConnection_getResetCallback(
246 		const NetConnection *conn);
247 void *NetConnection_getResetCallbackArg(const NetConnection *conn);
248 
249 
250 #if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
251 extern uio_Stream *netplayDebugFile;
252 #endif
253 
254 #if defined(__cplusplus)
255 }
256 #endif
257 
258 #endif  /* UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_ */
259 
260 
261