summaryrefslogtreecommitdiff
path: root/src/uqm/supermelee/netplay/netconnection.h
blob: 485d3c4d7e42f5f959511d08d6bbc726998bcd51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
 *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_
#define UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_

#include "netplay.h"
		// for NETPLAY_STATISTICS

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct NetConnection NetConnection;
typedef struct NetConnectionError NetConnectionError;
typedef struct ConnectStateData ConnectStateData;
#ifdef NETPLAY_STATISTICS
typedef struct NetStatistics NetStatistics;
#endif

typedef void (*NetConnection_ConnectCallback)(NetConnection *nd);
typedef void (*NetConnection_CloseCallback)(NetConnection *nd);
typedef void (*NetConnection_ErrorCallback)(NetConnection *nd,
		const NetConnectionError *error);
typedef void (*NetConnection_DeleteCallback)(NetConnection *nd);

typedef void (*NetConnection_ReadyCallback)(NetConnection *conn, void *arg);
typedef void (*NetConnection_ResetCallback)(NetConnection *conn, void *arg);

#if defined(__cplusplus)
}
#endif

#include "netstate.h"
#include "netoptions.h"
#ifdef NETPLAY_CHECKSUM
#	include "checkbuf.h"
#endif
#if defined(NETPLAY_STATISTICS) || defined(NETCONNECTION_INTERNAL)
#	include "packet.h"
#endif
#if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
#	include "libs/uio.h"
#endif

#if defined(__cplusplus)
extern "C" {
#endif

struct NetConnectionError {
	NetState state;
	int err;
	union {
		const struct ListenError *listenError;
		const struct ConnectError *connectError;
	} extra;
};

#ifdef NETPLAY_STATISTICS
struct NetStatistics {
	size_t packetsReceived;
	size_t packetTypeReceived[PACKET_NUM];
	size_t packetsSent;
	size_t packetTypeSent[PACKET_NUM];
};
#endif

#if defined(__cplusplus)
}
#endif

#ifdef NETCONNECTION_INTERNAL
#include "libs/net.h"
#include "packetq.h"

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct {
	// For actions that require agreement by both parties.
	bool localOk : 1;    /* Action confirmed by us */
	bool remoteOk : 1;   /* Action confirmed by the remote party */
	bool canceling : 1;  /* Awaiting cancel confirmation */
} HandShakeFlags;

typedef struct {
	// For actions that do not require agreement, but for which it
	// only is relevant that both sides are ready.
	bool localReady : 1;
	bool remoteReady : 1;
} ReadyFlags;

typedef struct {
	bool localReset : 1;
	bool remoteReset : 1;
} ResetFlags;

// Which parameters have we both sides of a connection reached agreement on?
typedef struct {
	bool randomSeed : 1;
} Agreement;

typedef struct {
	bool connected;
			/* This NetConnection is connected. */
	bool disconnected;
			/* This NetConnection has been disconnected. This implies
			 * !connected. It is only set if the NetConnection was once
			 * connected, but is no longer. */
	bool discriminant;
			/* If it is true here, it is false on the remote side
			 * of the same connection. It may be used to break ties.
			 * It is guaranteed not to change during a connection. Undefined
			 * while not connected. */
	HandShakeFlags handshake;
	ReadyFlags ready;
	ResetFlags reset;
	Agreement agreement;
	size_t inputDelay;
			/* Used during negotiation of the actual inputDelay. This
			 * field does NOT necessarilly contain the actual input delay,
			 * which is a property of the game, not of any specific
			 * connection. Use getBattleInputDelay() to get at it. */
#ifdef NETPLAY_CHECKSUM
	size_t checksumInterval;
#endif
} NetStateFlags;

struct NetConnection {
	NetDescriptor *nd;
	int player;
			// Number of the player for this connection, as it is
			// known locally. For the other player, it may be
			// differently.
	NetState state;
	NetStateFlags stateFlags;

	NetConnection_ReadyCallback readyCallback;
			// Called when both sides have indicated that they are ready.
			// Set by Netplay_localReady().
	void *readyCallbackArg;
			// Extra argument for readyCallback().
			// XXX: when is this cleaned up if a connection is broken?

	NetConnection_ResetCallback resetCallback;
			// Called when a reset has been signalled and confirmed.
			// Set by Netplay_localReset().
	void *resetCallbackArg;
			// Extra argument for resetCallback().
			// XXX: when is this cleaned up if a connection is broken?

	const NetplayPeerOptions *options;
	PacketQueue queue;
#ifdef NETPLAY_STATISTICS
	NetStatistics statistics;
#endif
#ifdef NETPLAY_CHECKSUM
	ChecksumBuffer checksumBuffer;
#endif
#if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
	uio_Stream *debugFile;
#endif

	NetConnection_ConnectCallback connectCallback;
	NetConnection_CloseCallback closeCallback;
			// Called when the NetConnection becomes disconnected.
	NetConnection_ErrorCallback errorCallback;
	NetConnection_DeleteCallback deleteCallback;
			// Called when the NetConnection is destroyed.
	uint8 *readBuf;
	uint8 *readEnd;
	NetConnectionStateData *stateData;
			// State dependant information.
	void *extra;
};

struct ConnectStateData {
	NETCONNECTION_STATE_DATA_COMMON

	bool isServer;
	union {
		struct ConnectState *connectState;
		struct ListenState *listenState;
	} state;
};

#endif  /* NETCONNECTION_INTERNAL */


NetConnection *NetConnection_open(int player,
		const NetplayPeerOptions *options,
		NetConnection_ConnectCallback connectCallback,
		NetConnection_CloseCallback closeCallback,
		NetConnection_ErrorCallback errorCallback,
		NetConnection_DeleteCallback deleteCallback, void *extra);
void NetConnection_close(NetConnection *conn);
bool NetConnection_isConnected(const NetConnection *conn);

void NetConnection_doErrorCallback(NetConnection *nd, int err);

void NetConnection_setStateData(NetConnection *conn,
		NetConnectionStateData *stateData);
NetConnectionStateData *NetConnection_getStateData(const NetConnection *conn);
void NetConnection_setExtra(NetConnection *conn, void *extra);
void *NetConnection_getExtra(const NetConnection *conn);
void NetConnection_setState(NetConnection *conn, NetState state);
NetState NetConnection_getState(const NetConnection *conn);
bool NetConnection_getDiscriminant(const NetConnection *conn);
const NetplayPeerOptions *NetConnection_getPeerOptions(
		const NetConnection *conn);
int NetConnection_getPlayerNr(const NetConnection *conn);
size_t NetConnection_getInputDelay(const NetConnection *conn);
#ifdef NETPLAY_CHECKSUM
ChecksumBuffer *NetConnection_getChecksumBuffer(NetConnection *conn);
size_t NetConnection_getChecksumInterval(const NetConnection *conn);
#endif
#ifdef NETPLAY_STATISTICS
NetStatistics *NetConnection_getStatistics(NetConnection *conn);
#endif

void NetConnection_setReadyCallback(NetConnection *conn,
		NetConnection_ReadyCallback callback, void *arg);
NetConnection_ReadyCallback NetConnection_getReadyCallback(
		const NetConnection *conn);
void *NetConnection_getReadyCallbackArg(const NetConnection *conn);

void NetConnection_setResetCallback(NetConnection *conn,
		NetConnection_ResetCallback callback, void *arg);
NetConnection_ResetCallback NetConnection_getResetCallback(
		const NetConnection *conn);
void *NetConnection_getResetCallbackArg(const NetConnection *conn);


#if defined(NETPLAY_DEBUG) && defined(NETPLAY_DEBUG_FILE)
extern uio_Stream *netplayDebugFile;
#endif

#if defined(__cplusplus)
}
#endif

#endif  /* UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_ */