samp-re/processnetworkpacket.c

135 lines
3.0 KiB
C

/* vim: set filetype=c ts=8 noexpandtab: */
//#define PROCESSNETWORKPACKET_PRINT
#ifdef PROCESSNETWORKPACKET_PRINT
#define dprintf(X,...) printf(X,__VA_ARGS__)
#else
#define dprintf(X,...)
#endif
#include "common.h"
#include "rakpeer.h"
#include "processnetworkpacket.h"
#include "socketlayer.h"
#include "packet.h"
#include "reliability.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static
void ShortResponse(struct CRakPeer *rp, int host, int port, char id)
{
char buf[2];
buf[0] = id;
buf[1] = 0; /*padding cuz 1 byte packet may not get sent*/
SocketLayer__SendTo(rp->socket, buf, 2, host, port);
}
static
void HandleConnectedPlayerTryingToConnect(
struct CRakPeer *rp,
struct CRemoteSystem *remoteSystem,
int host,
int port)
{
if (remoteSystem->connectMode != CONNECTED &&
remoteSystem->connectMode != DISCONNECT_ASAP &&
remoteSystem->connectMode != DISCONNECT_ASAP_SILENTLY)
{
dprintf("is from connected player, ignore\n");
return;
}
dprintf("is from disconnected player, send that it failed\n");
ShortResponse(rp, host, port, ID_CONNECTION_ATTEMPT_FAILED);
}
static
void HandleConnectingPlayer(
struct CRakPeer *rp,
struct CRemoteSystem *rs,
int host,
short port,
char *data,
int length)
{
#define assignRemoteSystem RakPeer__AssignPlayerIDToRemoteSystemList
struct CPacket *packet;
struct PlayerID playerId;
short playerIndex;
/*connection cookies, but we don't do that*/
if (rs != NULL) {
dprintf("connection request is from already connected playa\n");
HandleConnectedPlayerTryingToConnect(rp, rs, host, port);
return;
}
dprintf("it's a new player\n");
playerId.binaryAddress = host;
playerId.port = port;
if (!assignRemoteSystem(rp, playerId, UNVERIFIED_SENDER)) {
dprintf("server is full\n");
ShortResponse(rp, host, port, ID_NO_FREE_INCOMING_CONNECTIONS);
return;
}
playerIndex = RakPeer__GetIndexFromPlayerID(rp, playerId, 1);
dprintf("assigned index %hd\n", playerIndex);
packet = Packet__AllocPacket(1);
packet->playerId = playerId;
packet->bitSize = 8;
packet->playerIndex = playerIndex;
packet->ptrData[0] = ID_OPEN_CONNECTION_REQUEST;
RakPeer__AddPacketToProducer(rp, packet);
ShortResponse(rp, host, port, ID_OPEN_CONNECTION_REPLY);
}
void __stdcall ProcessNetworkPacket(
int host,
short port,
char *data,
int length,
struct CRakPeer *rp)
{
struct CRemoteSystem *rs;
struct PlayerID playerId;
int isPacketFlood;
playerId.binaryAddress = host;
playerId.port = port;
/*banned was checked here*/
if (data[0] == ID_OPEN_CONNECTION_REQUEST && length == 3) {
dprintf("got connection request\n");
rs = RakPeer__GetRemoteSystemFromPlayerID(rp, playerId, 1, 1);
HandleConnectingPlayer(rp, rs, host, port, data, length);
return;
}
rs = RakPeer__GetRemoteSystemFromPlayerID(rp, playerId, 1, 1);
if (!rs) {
dprintf("incoming from UNCONNECTED, ignoring\n");
return;
}
ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
(void*) &rs->reliabilityLayer,
data,
length,
playerId,
&rp->messageHandlerList,
rp->MTUSize,
&isPacketFlood);
}