openmohaa/code/gamespy/gt2/gt2Main.h
2023-02-04 21:00:01 +01:00

255 lines
11 KiB
C

/*
GameSpy GT2 SDK
Dan "Mr. Pants" Schoenblum
dan@gamespy.com
Copyright 2002 GameSpy Industries, Inc
devsupport@gamespy.com
*/
#ifndef _GT2_MAIN_H_
#define _GT2_MAIN_H_
#include "gt2.h"
#include "../darray.h"
#include "../hashtable.h"
#include "gt2Auth.h"
/*************************
** CONFIGURABLE DEFINES **
*************************/
// these defines are internal to GT2 and are NOT guaranteed to persist from version to version.
// If set, this will convert all big endian vars to little endian before sending accross the net
// And on big endian machines, convert little endian to big endian on recv
//#define _GT2_ENDIAN_CONVERT_ENABLE // add this to your compiler pre-processor options
#if defined GSI_BIG_ENDIAN && defined _GT2_ENDIAN_CONVERT_ENABLE
#define _GT2_ENDIAN_CONVERT
#endif
// any unreliable application message that starts with this magic string will have extra overhead.
// the string can be changed to something that your application will not use, or not use frequently.
// the only impact of this change will be to make your application incomatible with other application's
// using either the original or another different magic string.
// the string can consist of any number of characters, as long as there's at least one character, and the
// length define matches the string's length.
#define GTI2_MAGIC_STRING "\xFE\xFE"
#define GTI2_MAGIC_STRING_LEN 2
// the size of the buffer into which GT2 directly receives messages. this buffer is declared on the stack,
// and so can be fairly large on most systems without having any impact. however, on some systems with small
// stacks, this size can overflow the stack, in which case it should be lowered.
// note, this buffer size only needs to be slighty larger than the largest message that will be sent ("slighty
// larger" due to overhead with reliable messages, and unreliable messages starting with the magic string).
#if defined(_PS2) && defined(INSOCK)
#define GTI2_STACK_RECV_BUFFER_SIZE NETBUFSIZE // Max for Insock. Otherwise SOCKET_ERROR
#elif defined(_NITRO)
#define GTI2_STACK_RECV_BUFFER_SIZE 1500
#elif defined (_XBOX) // Xbox packets are 1304,
#define GTI2_STACK_RECV_BUFFER_SIZE 4096 // when using VDP sockets, 2 bytes are used for data length
#else
#define GTI2_STACK_RECV_BUFFER_SIZE 65535
#endif
// a server will disconnect a client that doesn't not successfully connect within this time (in milliseconds).
// if the connectAttemptCallback has been called, and GT2 is awaiting an accept/reject, the attempt will
// not be timed-out (although the client may abort the attempt at any time).
#define GTI2_SERVER_TIMEOUT (1 * 60 * 1000)
// the time (in milliseconds) GT2 waits between resending a message whose delivery has not yet been confirmed.
#define GTI2_RESEND_TIME 1000
// the time (in milliseconds) GT2 waits after receiving a message it must acknowledge before it actually sends
// the ack. this allows it to combine acks, or include acks as part of other reliable messages it sends.
// if an ack is pending, a new incoming message does not reset this timer.
#define GTI2_PENDING_ACK_TIME 100
// if GT2 does not send a message for this amount of time (in milliseconds), it sends a keep-alive message.
#define GTI2_KEEP_ALIVE_TIME (30 * 1000)
// if this is defined, it sets the percentage of sent datagrams to drop. this is good for simulating what will
// happen on a high packet loss connection.
//#define GTI2_DROP_SEND_RATE 30
typedef enum
{
GTI2UdpProtocol, // UDP socket type for standard sockets
GTI2VdpProtocol = 2, // VDP socket type only used for Xbox VDP sockets
GTI2AdHocProtocol = 3 // socket type only used for PSP Adhoc sockets
} GTI2ProtocolType;
// The Maximum offset of eiter UDP or VDP
// measured in bytes
// used as a buffer offset
#define MAX_PROTOCOL_OFFSET 2
/**********
** TYPES **
**********/
typedef enum
{
// client-only states
GTI2AwaitingServerChallenge, // sent challenge, waiting for server's challenge
GTI2AwaitingAcceptance, // sent response, waiting for accept/reject from server
// server-only states
GTI2AwaitingClientChallenge, // receiving challenge from a new client
GTI2AwaitingClientResponse, // sent challenge, waiting for client's response
GTI2AwaitingAcceptReject, // got client's response, waiting for app to accept/reject
// post-negotiation states
GTI2Connected, // connected
GTI2Closing, // sent a close message (GTI2Close or GTI2Reject), waiting for confirmation
GTI2Closed // connection has been closed, free it as soon as possible
} GTI2ConnectionState;
// message types
typedef enum
{
// reliable messages
// all start with <magic-string> <type> <serial-number> <expected-serial-number>
// type is 1 bytes, SN and ESN are 2 bytes each
GTI2MsgAppReliable, // reliable application message
GTI2MsgClientChallenge, // client's challenge to the server (initial connection request)
GTI2MsgServerChallenge, // server's response to the client's challenge, and his challenge to the client
GTI2MsgClientResponse, // client's response to the server's challenge
GTI2MsgAccept, // server accepting client's connection attempt
GTI2MsgReject, // server rejecting client's connection attempt
GTI2MsgClose, // message indicating the connection is closing
GTI2MsgKeepAlive, // keep-alive used to help detect dropped connections
GTI2NumReliableMessages,
// unreliable messages
GTI2MsgAck = 100, // acknowledge receipt of reliable message(s)
GTI2MsgNack, // alert sender to missing reliable message(s)
GTI2MsgPing, // used to determine latency
GTI2MsgPong, // a reply to a ping
GTI2MsgClosed // confirmation of connection closure (GTI2MsgClose or GTI2MsgReject) - also sent in response to bad messages from unknown addresses
// unreliable messages don't really have a message type, just the magic string repeated at the start
} GTI2MessageType;
/***************
** STRUCTURES **
***************/
typedef struct GTI2Buffer
{
GT2Byte * buffer; // The buffer's bytes.
int size; // Number of bytes in buffer.
int len; // Length of actual data in buffer.
} GTI2Buffer;
typedef struct GTI2IncomingBufferMessage
{
int start; // the start of the message
int len; // the length of the message
GTI2MessageType type; // the type
unsigned short serialNumber; // the serial number
} GTI2IncomingBufferMessage;
typedef struct GTI2OutgoingBufferMessage
{
int start; // the start of the message
int len; // the length of the message
unsigned short serialNumber; // the serial number
gsi_time lastSend; // last time this message was sent
} GTI2OutgoingBufferMessage;
typedef struct GTI2Socket
{
SOCKET socket; // the network socket used for all network communication
unsigned int ip; // the ip this socket is bound to
unsigned short port; // the port this socket is bound to
HashTable connections; // the connections that are using this socket
DArray closedConnections; // connections that are closed no longer get a spot in the hash table
GT2Bool close; // if true, a close was attempted inside a callback, and it should be closed as soon as possible
GT2Bool error; // if true, there was a socket error using this socket
int callbackLevel; // if >0, then we're inside a callback (or recursive callbacks)
gt2ConnectAttemptCallback connectAttemptCallback; // if set, callback used to handle incoming connection attempts
gt2SocketErrorCallback socketErrorCallback; // if set, call this in case of an error
gt2DumpCallback sendDumpCallback; // if set, gets called for every datagram sent
gt2DumpCallback receiveDumpCallback; // if set, gets called for every datagram and connection reset received
gt2UnrecognizedMessageCallback unrecognizedMessageCallback; // if set, gets called for all unrecognized messages
void * data; // user data
int outgoingBufferSize; // per-connection buffer sizes
int incomingBufferSize;
GTI2ProtocolType protocolType; // set to UDP or VDP protocol depending on the call to create socket
// also used as an offset for VDP sockets
int protocolOffset;
GT2Bool broadcastEnabled; // set to true if the socket has already been broadcast enabled
} GTI2Socket;
typedef struct GTI2Connection
{
// ip and port uniquely identify this connection on this socket
unsigned int ip; // the ip on the other side of this connection (network byte order)
unsigned short port; // the port on the other side of this connection (host byte order)
GTI2Socket * socket; // the parent socket
GTI2ConnectionState state; // connection state
GT2Bool initiated; // if true, the local side of the connection initiated the connection (client)
GT2Bool freeAtAcceptReject; // if true, don't free the connection until accept/reject is called
GT2Result connectionResult; // the result of the connect attempt
gsi_time startTime; // the time the connection was created
gsi_time timeout; // the timeout value passed into gt2Connect
int callbackLevel; // if >0, then we're inside a callback (or recursive callbacks)
GT2ConnectionCallbacks callbacks; // connection callbacks
char * initialMessage; // this is the initial message for the client
int initialMessageLen; // the initial message length
void * data; // user data
GTI2Buffer incomingBuffer; // buffer for incoming data
GTI2Buffer outgoingBuffer; // buffer for outgoing data
DArray incomingBufferMessages; // identifies incoming messages stored in the buffer
DArray outgoingBufferMessages; // identifies outgoing messages stored in the buffer
unsigned short serialNumber; // serial number of the next message to be sent out
unsigned short expectedSerialNumber; // the next serial number we're expecting from the remote side
char response[GTI2_RESPONSE_LEN]; // after the challenge is sent during negotiation, this is the response we're expecting
gsi_time lastSend; // the last time something was sent on this connection
gsi_time challengeTime; // the time the challenge was sent
GT2Bool pendingAck; // if true, there is an ack waiting to go out, either on its own or as part of a reliable message
gsi_time pendingAckTime; // the time at which the pending ack was first set
DArray sendFilters; // filters that apply to outgoing data
DArray receiveFilters; // filters that apply to incoming data
} GTI2Connection;
// store last 32 ip's in a ring buffer
#define MAC_TABLE_SIZE 32 // must be power of 2
typedef struct
{
gsi_u32 ip;
char mac[6];
} GTI2MacEntry;
#ifdef GSI_ADHOC
static int lastmactableentry = 0;
static GTI2MacEntry MacTable[MAC_TABLE_SIZE];
#endif // GSI_ADHOC
#endif