mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 01:11:44 +00:00
Networking updates.
- Added preprocessor value NETVERSION, to be incremented in the source whenever changes are made to the network protocol. - Implemented proper server-side version verification of all clients upon connection. - Implemented connection refusal when we reach MAXPLAYERS. (Should be expanded to implement server player caps.) - Protected against OOB array accesses if an invalid player id is received. - Renamed all "Recieve" to "Receive". git-svn-id: https://svn.eduke32.com/eduke32@4322 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
3b5dea7347
commit
c2cb6a9754
3 changed files with 159 additions and 100 deletions
|
@ -321,10 +321,38 @@ extern "C" {
|
||||||
# endif
|
# endif
|
||||||
#elif defined B_ENDIAN_C_INLINE
|
#elif defined B_ENDIAN_C_INLINE
|
||||||
static inline uint16_t B_SWAP16(uint16_t s) { return (s>>8)|(s<<8); }
|
static inline uint16_t B_SWAP16(uint16_t s) { return (s>>8)|(s<<8); }
|
||||||
static inline uint32_t B_SWAP32(uint32_t l) { return ((l>>8)&0xff00)|((l&0xff00)<<8)|(l<<24)|(l>>24); }
|
static inline uint32_t B_SWAP32(uint32_t l) { return ((l>>8)&0xff00)|((l&0xff00)<<8)|(l<<24)|(l>>24); }
|
||||||
static inline uint64_t B_SWAP64(uint64_t l) { return (l>>56)|((l>>40)&0xff00)|((l>>24)&0xff0000)|((l>>8)&0xff000000)|((l&255)<<56)|((l&0xff00)<<40)|((l&0xff0000)<<24)|((l&0xff000000)<<8); }
|
static inline uint64_t B_SWAP64(uint64_t l) { return (l>>56)|((l>>40)&0xff00)|((l>>24)&0xff0000)|((l>>8)&0xff000000)|((l&255)<<56)|((l&0xff00)<<40)|((l&0xff0000)<<24)|((l&0xff000000)<<8); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void B_BUF16(uint8_t *buf, uint16_t x)
|
||||||
|
{
|
||||||
|
buf[0] = (x & 0x00FF);
|
||||||
|
buf[1] = (x & 0xFF00) >> 8;
|
||||||
|
}
|
||||||
|
static inline void B_BUF32(uint8_t *buf, uint32_t x)
|
||||||
|
{
|
||||||
|
buf[0] = (x & 0x000000FF);
|
||||||
|
buf[1] = (x & 0x0000FF00) >> 8;
|
||||||
|
buf[2] = (x & 0x00FF0000) >> 16;
|
||||||
|
buf[3] = (x & 0xFF000000) >> 24;
|
||||||
|
}
|
||||||
|
static inline void B_BUF64(uint8_t *buf, uint64_t x)
|
||||||
|
{
|
||||||
|
buf[0] = (x & 0x00000000000000FF);
|
||||||
|
buf[1] = (x & 0x000000000000FF00) >> 8;
|
||||||
|
buf[2] = (x & 0x0000000000FF0000) >> 16;
|
||||||
|
buf[3] = (x & 0x00000000FF000000) >> 24;
|
||||||
|
buf[4] = (x & 0x000000FF00000000) >> 32;
|
||||||
|
buf[5] = (x & 0x0000FF0000000000) >> 40;
|
||||||
|
buf[6] = (x & 0x00FF000000000000) >> 48;
|
||||||
|
buf[7] = (x & 0xFF00000000000000) >> 56;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t B_UNBUF16(const uint8_t *buf) { return (buf[1] << 8) | (buf[0]); }
|
||||||
|
static inline uint32_t B_UNBUF32(const uint8_t *buf) { return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]); }
|
||||||
|
static inline uint64_t B_UNBUF64(const uint8_t *buf) { return ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[5] << 40) | ((uint64_t)buf[4] << 32) | (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]); }
|
||||||
|
|
||||||
#if defined(USE_MSC_PRAGMAS)
|
#if defined(USE_MSC_PRAGMAS)
|
||||||
static inline void ftol(float f, int32_t *a)
|
static inline void ftol(float f, int32_t *a)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,7 +71,7 @@ int16_t g_netStatnums[] =
|
||||||
uint32_t g_netMapRevision = 0;
|
uint32_t g_netMapRevision = 0;
|
||||||
netmapstate_t g_mapStartState;
|
netmapstate_t g_mapStartState;
|
||||||
netmapstate_t *g_mapStateHistory[NET_REVISIONS];
|
netmapstate_t *g_mapStateHistory[NET_REVISIONS];
|
||||||
char tempnetbuf[sizeof(netmapstate_t) + 400];
|
uint8_t tempnetbuf[sizeof(netmapstate_t) + 400];
|
||||||
netmapdiff_t tempMapDiff;
|
netmapdiff_t tempMapDiff;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
#define tempnetbufsize sizeof(tempnetbuf)
|
#define tempnetbufsize sizeof(tempnetbuf)
|
||||||
|
@ -85,8 +85,8 @@ static void P_RemovePlayer(int32_t p)
|
||||||
|
|
||||||
g_player[p].playerquitflag = 0;
|
g_player[p].playerquitflag = 0;
|
||||||
|
|
||||||
Bsprintf(buf,"%s^00 is history!",g_player[p].user_name);
|
Bsprintf(recbuf,"%s^00 is history!",g_player[p].user_name);
|
||||||
G_AddUserQuote(buf);
|
G_AddUserQuote(recbuf);
|
||||||
|
|
||||||
if (numplayers == 1)
|
if (numplayers == 1)
|
||||||
S_PlaySound(GENERIC_AMBIENCE17);
|
S_PlaySound(GENERIC_AMBIENCE17);
|
||||||
|
@ -112,7 +112,7 @@ static void P_RemovePlayer(int32_t p)
|
||||||
voting = -1;
|
voting = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bstrcpy(ScriptQuotes[QUOTE_RESERVED2],buf);
|
Bstrcpy(ScriptQuotes[QUOTE_RESERVED2],recbuf);
|
||||||
g_player[myconnectindex].ps->ftq = QUOTE_RESERVED2;
|
g_player[myconnectindex].ps->ftq = QUOTE_RESERVED2;
|
||||||
g_player[myconnectindex].ps->fta = 180;
|
g_player[myconnectindex].ps->fta = 180;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,13 @@ void Net_SyncPlayer(ENetEvent *event)
|
||||||
{
|
{
|
||||||
int32_t i, j;
|
int32_t i, j;
|
||||||
|
|
||||||
|
if (numplayers + g_netPlayersWaiting >= MAXPLAYERS)
|
||||||
|
{
|
||||||
|
enet_peer_disconnect_later(event->peer, DISC_SERVER_FULL);
|
||||||
|
initprintf("Refused peer; server full.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_netPlayersWaiting++;
|
g_netPlayersWaiting++;
|
||||||
|
|
||||||
S_PlaySound(DUKE_GETWEAPON2);
|
S_PlaySound(DUKE_GETWEAPON2);
|
||||||
|
@ -156,6 +163,7 @@ void Net_SyncPlayer(ENetEvent *event)
|
||||||
|
|
||||||
G_MaybeAllocPlayer(i);
|
G_MaybeAllocPlayer(i);
|
||||||
|
|
||||||
|
g_netPlayersWaiting--;
|
||||||
++numplayers;
|
++numplayers;
|
||||||
++ud.multimode;
|
++ud.multimode;
|
||||||
Net_SendNewPlayer(i);
|
Net_SendNewPlayer(i);
|
||||||
|
@ -350,7 +358,7 @@ void Net_Disconnect(void)
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
|
|
||||||
for (i=0; i<(signed)g_netServer->peerCount; i++)
|
for (i=0; i<(signed)g_netServer->peerCount; i++)
|
||||||
enet_peer_disconnect_later(&g_netServer->peers[i], 0);
|
enet_peer_disconnect_later(&g_netServer->peers[i], DISC_SERVER_QUIT);
|
||||||
|
|
||||||
while (enet_host_service(g_netServer, & event, 3000) > 0)
|
while (enet_host_service(g_netServer, & event, 3000) > 0)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +390,18 @@ void Net_ReceiveDisconnect(ENetEvent *event)
|
||||||
case DISC_BAD_PASSWORD:
|
case DISC_BAD_PASSWORD:
|
||||||
initprintf("Bad password.\n");
|
initprintf("Bad password.\n");
|
||||||
return;
|
return;
|
||||||
|
case DISC_VERSION_MISMATCH:
|
||||||
|
initprintf("Version mismatch.\n");
|
||||||
|
return;
|
||||||
|
case DISC_INVALID:
|
||||||
|
initprintf("Invalid data detected.\n");
|
||||||
|
return;
|
||||||
|
case DISC_SERVER_QUIT:
|
||||||
|
initprintf("The server is quitting.\n");
|
||||||
|
return;
|
||||||
|
case DISC_SERVER_FULL:
|
||||||
|
initprintf("The server is full.\n");
|
||||||
|
return;
|
||||||
case DISC_KICKED:
|
case DISC_KICKED:
|
||||||
initprintf("You have been kicked from the server.\n");
|
initprintf("You have been kicked from the server.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -442,6 +462,13 @@ void Net_HandleClientPackets(void)
|
||||||
{
|
{
|
||||||
const intptr_t playeridx = (intptr_t)event.peer->data;
|
const intptr_t playeridx = (intptr_t)event.peer->data;
|
||||||
|
|
||||||
|
if (playeridx < 0 || playeridx >= MAXPLAYERS)
|
||||||
|
{
|
||||||
|
enet_peer_disconnect_later(event.peer, DISC_INVALID);
|
||||||
|
initprintf("Invalid player id (%" PRIdPTR ") from client.\n", playeridx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
case ENET_EVENT_TYPE_CONNECT:
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
|
@ -452,7 +479,7 @@ void Net_HandleClientPackets(void)
|
||||||
|
|
||||||
initprintf("A new client connected from %s:%u.\n", ipaddr, event.peer->address.port);
|
initprintf("A new client connected from %s:%u.\n", ipaddr, event.peer->address.port);
|
||||||
|
|
||||||
Net_SendVersion(event.peer);
|
Net_SendAcknowledge(event.peer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +606,7 @@ void Net_ParseClientPacket(ENetEvent *event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_AUTH:
|
case PACKET_AUTH:
|
||||||
Net_RecieveChallenge(pbuf, packbufleng, event);
|
Net_ReceiveChallenge(pbuf, packbufleng, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -624,16 +651,16 @@ void Net_ParseServerPacket(ENetEvent *event)
|
||||||
Net_ReceiveNewGame(event);
|
Net_ReceiveNewGame(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_VERSION:
|
case PACKET_ACK:
|
||||||
Net_RecieveVersion(pbuf, packbufleng);
|
Net_ReceiveAcknowledge(pbuf, packbufleng);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_NUM_PLAYERS:
|
case PACKET_NUM_PLAYERS:
|
||||||
Net_RecieveNewPlayer(event->packet->data, event->packet->dataLength);
|
Net_ReceiveNewPlayer(event->packet->data, event->packet->dataLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_PLAYER_INDEX:
|
case PACKET_PLAYER_INDEX:
|
||||||
Net_RecievePlayerIndex(event->packet->data, event->packet->dataLength);
|
Net_ReceivePlayerIndex(event->packet->data, event->packet->dataLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_PLAYER_DISCONNECTED:
|
case PACKET_PLAYER_DISCONNECTED:
|
||||||
|
@ -660,7 +687,7 @@ void Net_ParseServerPacket(ENetEvent *event)
|
||||||
if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) break;
|
if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) break;
|
||||||
g_player[pbuf[1]].ps->frag_ps = pbuf[2];
|
g_player[pbuf[1]].ps->frag_ps = pbuf[2];
|
||||||
actor[g_player[pbuf[1]].ps->i].picnum = pbuf[3];
|
actor[g_player[pbuf[1]].ps->i].picnum = pbuf[3];
|
||||||
ticrandomseed = *(int32_t *)&pbuf[4];
|
ticrandomseed = B_UNBUF32(&pbuf[4]);
|
||||||
P_FragPlayer(pbuf[1]);
|
P_FragPlayer(pbuf[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -691,91 +718,83 @@ void Net_ParsePacketCommon(uint8_t *pbuf, int32_t packbufleng, int32_t serverpac
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_MAP_VOTE:
|
case PACKET_MAP_VOTE:
|
||||||
Net_RecieveMapVote(pbuf);
|
Net_ReceiveMapVote(pbuf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_MAP_VOTE_INITIATE: // call map vote
|
case PACKET_MAP_VOTE_INITIATE: // call map vote
|
||||||
Net_RecieveMapVoteInitiate(pbuf);
|
Net_ReceiveMapVoteInitiate(pbuf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_MAP_VOTE_CANCEL: // cancel map vote
|
case PACKET_MAP_VOTE_CANCEL: // cancel map vote
|
||||||
Net_RecieveMapVoteCancel(pbuf);
|
Net_ReceiveMapVoteCancel(pbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Version Packets
|
// Acknowledgement Packets
|
||||||
|
|
||||||
// TODO: switch this around so the client sends their version to the server for
|
void Net_SendAcknowledge(ENetPeer *client)
|
||||||
// verification, instead of the other way around like it is now
|
|
||||||
void Net_SendVersion(ENetPeer *client)
|
|
||||||
{
|
{
|
||||||
if (!g_netServer)
|
if (!g_netServer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
buf[0] = PACKET_VERSION;
|
tempnetbuf[0] = PACKET_ACK;
|
||||||
*(uint16_t *)&buf[1] = BYTEVERSION;
|
tempnetbuf[1] = myconnectindex;
|
||||||
// XXX: s_buildDate is outdated and useless; uint8 is not enough :/
|
|
||||||
buf[3] = (uint8_t)atoi(s_buildDate);
|
|
||||||
buf[4] = myconnectindex;
|
|
||||||
|
|
||||||
enet_peer_send(client, CHAN_GAMESTATE, enet_packet_create(&buf[0], 5, ENET_PACKET_FLAG_RELIABLE));
|
enet_peer_send(client, CHAN_GAMESTATE, enet_packet_create(&tempnetbuf[0], 2, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveVersion(uint8_t *pbuf, int32_t packbufleng)
|
void Net_ReceiveAcknowledge(uint8_t *pbuf, int32_t packbufleng)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pbuf); // remove when this variable is used
|
||||||
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
||||||
|
|
||||||
if (*(uint16_t *)&pbuf[1] != BYTEVERSION || pbuf[3] != (uint8_t)atoi(s_buildDate))
|
|
||||||
{
|
|
||||||
initprintf("Server protocol is version %d.%d, expecting %d.%d\n",
|
|
||||||
*(uint16_t *)&pbuf[1], pbuf[3], BYTEVERSION, (uint8_t)atoi(s_buildDate));
|
|
||||||
initprintf("Server version mismatch! You cannot play Duke with different versions!\n");
|
|
||||||
g_netDisconnect = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Net_SendChallenge();
|
Net_SendChallenge();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Challenge Packets
|
// Challenge Packets
|
||||||
|
|
||||||
// sends a simple crc32 of the current password, verified by the server before the connection can continue
|
// sends the version and a simple crc32 of the current password, all verified by the server before the connection can continue
|
||||||
void Net_SendChallenge()
|
void Net_SendChallenge()
|
||||||
{
|
{
|
||||||
int32_t l = 1;
|
|
||||||
|
|
||||||
if (!g_netClientPeer)
|
if (!g_netClientPeer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[0] = PACKET_AUTH;
|
tempnetbuf[0] = PACKET_AUTH;
|
||||||
*(uint32_t *)&buf[1] = crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword));
|
B_BUF16(&tempnetbuf[1], BYTEVERSION);
|
||||||
l += sizeof(int32_t);
|
B_BUF16(&tempnetbuf[3], NETVERSION);
|
||||||
|
B_BUF32(&tempnetbuf[5], crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword)));
|
||||||
|
tempnetbuf[9] = myconnectindex;
|
||||||
|
|
||||||
buf[l++] = myconnectindex;
|
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&tempnetbuf[0], 10, ENET_PACKET_FLAG_RELIABLE));
|
||||||
|
|
||||||
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event)
|
void Net_ReceiveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event)
|
||||||
{
|
{
|
||||||
uint32_t crc = *(uint32_t *)&pbuf[1];
|
const uint16_t byteVersion = B_UNBUF16(&pbuf[1]);
|
||||||
|
const uint16_t netVersion = B_UNBUF16(&pbuf[3]);
|
||||||
|
const uint32_t crc = B_UNBUF32(&pbuf[5]);
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
||||||
|
|
||||||
if (crc == crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword)))
|
if (byteVersion != BYTEVERSION || netVersion != NETVERSION)
|
||||||
{
|
{
|
||||||
Net_SyncPlayer(event);
|
enet_peer_disconnect_later(event->peer, DISC_VERSION_MISMATCH);
|
||||||
|
initprintf("Bad client protocol: version %u.%u\n", byteVersion, netVersion);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
if (crc != crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword)))
|
||||||
{
|
{
|
||||||
enet_peer_disconnect_later(event->peer, DISC_BAD_PASSWORD);
|
enet_peer_disconnect_later(event->peer, DISC_BAD_PASSWORD);
|
||||||
initprintf("Bad password from client.\n");
|
initprintf("Bad password from client.\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Net_SyncPlayer(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -793,7 +812,7 @@ void Net_SendNewPlayer(int32_t newplayerindex)
|
||||||
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 7, ENET_PACKET_FLAG_RELIABLE));
|
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 7, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveNewPlayer(uint8_t *pbuf, int32_t packbufleng)
|
void Net_ReceiveNewPlayer(uint8_t *pbuf, int32_t packbufleng)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
|
@ -848,7 +867,7 @@ void Net_SendPlayerIndex(int32_t index, ENetPeer *peer)
|
||||||
enet_peer_send(peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE));
|
enet_peer_send(peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecievePlayerIndex(uint8_t *pbuf, int32_t packbufleng)
|
void Net_ReceivePlayerIndex(uint8_t *pbuf, int32_t packbufleng)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
UNREFERENCED_PARAMETER(packbufleng); // remove when this variable is used
|
||||||
|
|
||||||
|
@ -869,38 +888,38 @@ void Net_SendClientInfo(void)
|
||||||
|
|
||||||
if (numplayers < 2) return;
|
if (numplayers < 2) return;
|
||||||
|
|
||||||
buf[0] = PACKET_CLIENT_INFO;
|
tempnetbuf[0] = PACKET_CLIENT_INFO;
|
||||||
l = 1;
|
l = 1;
|
||||||
|
|
||||||
//null terminated player name to send
|
//null terminated player name to send
|
||||||
for (i=0; szPlayerName[i]; i++)
|
for (i=0; szPlayerName[i]; i++)
|
||||||
{
|
{
|
||||||
buf[l++] = szPlayerName[i];
|
tempnetbuf[l++] = szPlayerName[i];
|
||||||
}
|
}
|
||||||
buf[l++] = 0;
|
tempnetbuf[l++] = 0;
|
||||||
|
|
||||||
buf[l++] = g_player[myconnectindex].ps->aim_mode = ud.mouseaiming;
|
tempnetbuf[l++] = g_player[myconnectindex].ps->aim_mode = ud.mouseaiming;
|
||||||
buf[l++] = g_player[myconnectindex].ps->auto_aim = ud.config.AutoAim;
|
tempnetbuf[l++] = g_player[myconnectindex].ps->auto_aim = ud.config.AutoAim;
|
||||||
buf[l++] = g_player[myconnectindex].ps->weaponswitch = ud.weaponswitch;
|
tempnetbuf[l++] = g_player[myconnectindex].ps->weaponswitch = ud.weaponswitch;
|
||||||
buf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = ud.color;
|
tempnetbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = ud.color;
|
||||||
|
|
||||||
buf[l++] = g_player[myconnectindex].pteam = ud.team;
|
tempnetbuf[l++] = g_player[myconnectindex].pteam = ud.team;
|
||||||
|
|
||||||
for (i=0; i<10; i++)
|
for (i=0; i<10; i++)
|
||||||
{
|
{
|
||||||
g_player[myconnectindex].wchoice[i] = g_player[0].wchoice[i];
|
g_player[myconnectindex].wchoice[i] = g_player[0].wchoice[i];
|
||||||
buf[l++] = (uint8_t)g_player[0].wchoice[i];
|
tempnetbuf[l++] = (uint8_t)g_player[0].wchoice[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[l++] = myconnectindex;
|
tempnetbuf[l++] = myconnectindex;
|
||||||
|
|
||||||
if (g_netClient)
|
if (g_netClient)
|
||||||
{
|
{
|
||||||
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
|
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&tempnetbuf[0], l, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
else if (g_netServer)
|
else if (g_netServer)
|
||||||
{
|
{
|
||||||
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
|
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&tempnetbuf[0], l, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,6 +1055,11 @@ void Net_SendMapUpdate(void)
|
||||||
ENetPeer *const currentPeer = &g_netServer->peers[pi];
|
ENetPeer *const currentPeer = &g_netServer->peers[pi];
|
||||||
const intptr_t playeridx = (intptr_t) currentPeer->data;
|
const intptr_t playeridx = (intptr_t) currentPeer->data;
|
||||||
|
|
||||||
|
if (playeridx < 0 || playeridx >= MAXPLAYERS)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentPeer->state != ENET_PEER_STATE_CONNECTED || !g_player[playeridx].playerquitflag)
|
if (currentPeer->state != ENET_PEER_STATE_CONNECTED || !g_player[playeridx].playerquitflag)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -1052,7 +1076,7 @@ void Net_SendMapUpdate(void)
|
||||||
diffsize += tempMapDiff.numActors * sizeof(netactor_t);
|
diffsize += tempMapDiff.numActors * sizeof(netactor_t);
|
||||||
diffsize += tempMapDiff.numToDelete * sizeof(int32_t);
|
diffsize += tempMapDiff.numToDelete * sizeof(int32_t);
|
||||||
|
|
||||||
packetsize = LZ4_compress_limitedOutput((const char*)&tempMapDiff, &tempnetbuf[5], diffsize, tempnetbufsize - 5);
|
packetsize = LZ4_compress_limitedOutput((const char*)&tempMapDiff, (char*)&tempnetbuf[5], diffsize, tempnetbufsize - 5);
|
||||||
|
|
||||||
if (packetsize == 0)
|
if (packetsize == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1061,10 +1085,7 @@ void Net_SendMapUpdate(void)
|
||||||
tempnetbuf[0] = PACKET_MAP_STREAM;
|
tempnetbuf[0] = PACKET_MAP_STREAM;
|
||||||
|
|
||||||
// apply uncompressed size
|
// apply uncompressed size
|
||||||
tempnetbuf[1] = (diffsize & 0x000000FF);
|
B_BUF32(&tempnetbuf[1], diffsize);
|
||||||
tempnetbuf[2] = (diffsize & 0x0000FF00) >> 8;
|
|
||||||
tempnetbuf[3] = (diffsize & 0x00FF0000) >> 16;
|
|
||||||
tempnetbuf[4] = (diffsize & 0xFF000000) >> 24;
|
|
||||||
|
|
||||||
packetsize += 5;
|
packetsize += 5;
|
||||||
|
|
||||||
|
@ -1076,9 +1097,9 @@ void Net_SendMapUpdate(void)
|
||||||
|
|
||||||
void Net_ReceiveMapUpdate(ENetEvent *event)
|
void Net_ReceiveMapUpdate(ENetEvent *event)
|
||||||
{
|
{
|
||||||
char *pktBuf = (char *) event->packet->data;
|
const uint8_t *pktBuf = (uint8_t *) event->packet->data;
|
||||||
uint32_t diffsize = (pktBuf[4] << 24) | (pktBuf[3] << 16) | (pktBuf[2] << 8) | (pktBuf[1]);
|
uint32_t diffsize = B_UNBUF32(&pktBuf[1]);
|
||||||
LZ4_decompress_safe(&pktBuf[5], (char*)&tempMapDiff, diffsize, sizeof(netmapdiff_t));
|
LZ4_decompress_safe((const char*)&pktBuf[5], (char*)&tempMapDiff, diffsize, sizeof(netmapdiff_t));
|
||||||
|
|
||||||
Net_RestoreMapState();
|
Net_RestoreMapState();
|
||||||
//initprintf("Update packet size: %d - num actors: %d\n", event->packet->dataLength, tempMapDiff.numActors);
|
//initprintf("Update packet size: %d - num actors: %d\n", event->packet->dataLength, tempMapDiff.numActors);
|
||||||
|
@ -1510,7 +1531,7 @@ typedef struct
|
||||||
void Net_SendServerUpdates(void)
|
void Net_SendServerUpdates(void)
|
||||||
{
|
{
|
||||||
int16_t i;
|
int16_t i;
|
||||||
char *updatebuf;
|
uint8_t *updatebuf;
|
||||||
serverupdate_t serverupdate;
|
serverupdate_t serverupdate;
|
||||||
serverplayerupdate_t playerupdate;
|
serverplayerupdate_t playerupdate;
|
||||||
input_t *osyn = (input_t *)&inputfifo[1][0];
|
input_t *osyn = (input_t *)&inputfifo[1][0];
|
||||||
|
@ -1585,7 +1606,7 @@ void Net_SendServerUpdates(void)
|
||||||
void Net_ReceiveServerUpdate(ENetEvent *event)
|
void Net_ReceiveServerUpdate(ENetEvent *event)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
char *updatebuf;
|
uint8_t *updatebuf;
|
||||||
// int8_t numupdates;
|
// int8_t numupdates;
|
||||||
serverupdate_t serverupdate;
|
serverupdate_t serverupdate;
|
||||||
serverplayerupdate_t playerupdate;
|
serverplayerupdate_t playerupdate;
|
||||||
|
@ -1595,7 +1616,7 @@ void Net_ReceiveServerUpdate(ENetEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatebuf = (char *) event->packet->data;
|
updatebuf = (uint8_t *) event->packet->data;
|
||||||
Bmemcpy(&serverupdate, updatebuf, sizeof(serverupdate_t));
|
Bmemcpy(&serverupdate, updatebuf, sizeof(serverupdate_t));
|
||||||
updatebuf += sizeof(serverupdate_t);
|
updatebuf += sizeof(serverupdate_t);
|
||||||
inputfifo[0][0] = serverupdate.nsyn;
|
inputfifo[0][0] = serverupdate.nsyn;
|
||||||
|
@ -1673,6 +1694,11 @@ void Net_ReceiveClientUpdate(ENetEvent *event)
|
||||||
|
|
||||||
playeridx = (int32_t)(intptr_t) event->peer->data;
|
playeridx = (int32_t)(intptr_t) event->peer->data;
|
||||||
|
|
||||||
|
if (playeridx < 0 || playeridx >= MAXPLAYERS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_player[playeridx].revision = update.revision;
|
g_player[playeridx].revision = update.revision;
|
||||||
inputfifo[0][playeridx] = update.nsyn;
|
inputfifo[0][playeridx] = update.nsyn;
|
||||||
|
|
||||||
|
@ -1757,9 +1783,9 @@ void Net_SendMessage(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Bsprintf(buf," %d - %s",i+1,g_player[i].user_name);
|
Bsprintf(recbuf," %d - %s",i+1,g_player[i].user_name);
|
||||||
minitextshade((320>>1)-40-6+1,j+1,buf,26,0,2+8+16);
|
minitextshade((320>>1)-40-6+1,j+1,recbuf,26,0,2+8+16);
|
||||||
minitext((320>>1)-40-6,j,buf,0,2+8+16);
|
minitext((320>>1)-40-6,j,recbuf,0,2+8+16);
|
||||||
j += 7;
|
j += 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1920,8 +1946,6 @@ void Net_SendNewGame(int32_t frommenu, ENetPeer *peer)
|
||||||
{
|
{
|
||||||
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&newgame, sizeof(newgame_t), ENET_PACKET_FLAG_RELIABLE));
|
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&newgame, sizeof(newgame_t), ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_netPlayersWaiting--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_ReceiveNewGame(ENetEvent *event)
|
void Net_ReceiveNewGame(ENetEvent *event)
|
||||||
|
@ -2023,7 +2047,7 @@ void Net_SendMapVoteInitiate(void)
|
||||||
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&newgame, sizeof(newgame_t), ENET_PACKET_FLAG_RELIABLE));
|
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&newgame, sizeof(newgame_t), ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveMapVoteInitiate(uint8_t *pbuf)
|
void Net_ReceiveMapVoteInitiate(uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
|
@ -2075,7 +2099,7 @@ void Net_SendMapVote(int32_t votefor)
|
||||||
Net_CheckForEnoughVotes();
|
Net_CheckForEnoughVotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveMapVote(uint8_t *pbuf)
|
void Net_ReceiveMapVote(uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
|
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
|
||||||
{
|
{
|
||||||
|
@ -2178,7 +2202,7 @@ void Net_SendMapVoteCancel(int32_t failed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_RecieveMapVoteCancel(uint8_t *pbuf)
|
void Net_ReceiveMapVoteCancel(uint8_t *pbuf)
|
||||||
{
|
{
|
||||||
// int32_t numvotes;
|
// int32_t numvotes;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "enet/enet.h"
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
// net packet specification/compatibility version
|
||||||
|
#define NETVERSION 1
|
||||||
|
|
||||||
extern ENetHost *g_netClient;
|
extern ENetHost *g_netClient;
|
||||||
extern ENetHost *g_netServer;
|
extern ENetHost *g_netServer;
|
||||||
extern ENetPeer *g_netClientPeer;
|
extern ENetPeer *g_netClientPeer;
|
||||||
|
@ -60,7 +63,7 @@ enum DukePacket_t
|
||||||
PACKET_PLAYER_DISCONNECTED,
|
PACKET_PLAYER_DISCONNECTED,
|
||||||
PACKET_PLAYER_SPAWN,
|
PACKET_PLAYER_SPAWN,
|
||||||
PACKET_FRAG,
|
PACKET_FRAG,
|
||||||
PACKET_VERSION,
|
PACKET_ACK,
|
||||||
PACKET_AUTH,
|
PACKET_AUTH,
|
||||||
PACKET_PLAYER_PING,
|
PACKET_PLAYER_PING,
|
||||||
PACKET_PLAYER_READY,
|
PACKET_PLAYER_READY,
|
||||||
|
@ -87,6 +90,10 @@ enum DukePacket_t
|
||||||
enum netdisconnect_t
|
enum netdisconnect_t
|
||||||
{
|
{
|
||||||
DISC_BAD_PASSWORD = 1,
|
DISC_BAD_PASSWORD = 1,
|
||||||
|
DISC_VERSION_MISMATCH,
|
||||||
|
DISC_INVALID,
|
||||||
|
DISC_SERVER_QUIT,
|
||||||
|
DISC_SERVER_FULL,
|
||||||
DISC_KICKED,
|
DISC_KICKED,
|
||||||
DISC_BANNED
|
DISC_BANNED
|
||||||
};
|
};
|
||||||
|
@ -179,17 +186,17 @@ void Net_ParseClientPacket(ENetEvent *event);
|
||||||
void Net_ParseServerPacket(ENetEvent *event);
|
void Net_ParseServerPacket(ENetEvent *event);
|
||||||
void Net_ParsePacketCommon(uint8_t *pbuf, int32_t packbufleng, int32_t serverpacketp);
|
void Net_ParsePacketCommon(uint8_t *pbuf, int32_t packbufleng, int32_t serverpacketp);
|
||||||
|
|
||||||
void Net_SendVersion(ENetPeer *client);
|
void Net_SendAcknowledge(ENetPeer *client);
|
||||||
void Net_RecieveVersion(uint8_t *pbuf, int32_t packbufleng);
|
void Net_ReceiveAcknowledge(uint8_t *pbuf, int32_t packbufleng);
|
||||||
|
|
||||||
void Net_SendChallenge();
|
void Net_SendChallenge();
|
||||||
void Net_RecieveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event);
|
void Net_ReceiveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event);
|
||||||
|
|
||||||
void Net_SendNewPlayer(int32_t newplayerindex);
|
void Net_SendNewPlayer(int32_t newplayerindex);
|
||||||
void Net_RecieveNewPlayer(uint8_t *pbuf, int32_t packbufleng);
|
void Net_ReceiveNewPlayer(uint8_t *pbuf, int32_t packbufleng);
|
||||||
|
|
||||||
void Net_SendPlayerIndex(int32_t index, ENetPeer *peer);
|
void Net_SendPlayerIndex(int32_t index, ENetPeer *peer);
|
||||||
void Net_RecievePlayerIndex(uint8_t *pbuf, int32_t packbufleng);
|
void Net_ReceivePlayerIndex(uint8_t *pbuf, int32_t packbufleng);
|
||||||
|
|
||||||
void Net_SendClientInfo(void);
|
void Net_SendClientInfo(void);
|
||||||
void Net_ReceiveClientInfo(uint8_t *pbuf, int32_t packbufleng, int32_t fromserver);
|
void Net_ReceiveClientInfo(uint8_t *pbuf, int32_t packbufleng, int32_t fromserver);
|
||||||
|
@ -235,14 +242,14 @@ void Net_FillNewGame(newgame_t *newgame, int32_t frommenu);
|
||||||
void Net_ExtractNewGame(newgame_t *newgame, int32_t menuonly);
|
void Net_ExtractNewGame(newgame_t *newgame, int32_t menuonly);
|
||||||
|
|
||||||
void Net_SendMapVoteInitiate(void);
|
void Net_SendMapVoteInitiate(void);
|
||||||
void Net_RecieveMapVoteInitiate(uint8_t *pbuf);
|
void Net_ReceiveMapVoteInitiate(uint8_t *pbuf);
|
||||||
|
|
||||||
void Net_SendMapVote(int32_t votefor);
|
void Net_SendMapVote(int32_t votefor);
|
||||||
void Net_RecieveMapVote(uint8_t *pbuf);
|
void Net_ReceiveMapVote(uint8_t *pbuf);
|
||||||
void Net_CheckForEnoughVotes();
|
void Net_CheckForEnoughVotes();
|
||||||
|
|
||||||
void Net_SendMapVoteCancel(int32_t failed);
|
void Net_SendMapVoteCancel(int32_t failed);
|
||||||
void Net_RecieveMapVoteCancel(uint8_t *pbuf);
|
void Net_ReceiveMapVoteCancel(uint8_t *pbuf);
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
|
|
||||||
|
@ -268,17 +275,17 @@ void faketimerhandler(void);
|
||||||
#define Net_ParseServerPacket(...) ((void)0)
|
#define Net_ParseServerPacket(...) ((void)0)
|
||||||
#define Net_ParsePacketCommon(...) ((void)0)
|
#define Net_ParsePacketCommon(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendVersion(...) ((void)0)
|
#define Net_SendAcknowledge(...) ((void)0)
|
||||||
#define Net_RecieveVersion(...) ((void)0)
|
#define Net_ReceiveAcknowledge(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendChallenge(...) ((void)0)
|
#define Net_SendChallenge(...) ((void)0)
|
||||||
#define Net_RecieveChallenge(...) ((void)0)
|
#define Net_ReceiveChallenge(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendNewPlayer(...) ((void)0)
|
#define Net_SendNewPlayer(...) ((void)0)
|
||||||
#define Net_RecieveNewPlayer(...) ((void)0)
|
#define Net_ReceiveNewPlayer(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendPlayerIndex(...) ((void)0)
|
#define Net_SendPlayerIndex(...) ((void)0)
|
||||||
#define Net_RecievePlayerIndex(...) ((void)0)
|
#define Net_ReceivePlayerIndex(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendClientInfo(...) ((void)0)
|
#define Net_SendClientInfo(...) ((void)0)
|
||||||
#define Net_ReceiveClientInfo(...) ((void)0)
|
#define Net_ReceiveClientInfo(...) ((void)0)
|
||||||
|
@ -312,14 +319,14 @@ void faketimerhandler(void);
|
||||||
#define Net_ExtractNewGame(...) ((void)0)
|
#define Net_ExtractNewGame(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendMapVoteInitiate(...) ((void)0)
|
#define Net_SendMapVoteInitiate(...) ((void)0)
|
||||||
#define Net_RecieveMapVoteInitiate(...) ((void)0)
|
#define Net_ReceiveMapVoteInitiate(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendMapVote(...) ((void)0)
|
#define Net_SendMapVote(...) ((void)0)
|
||||||
#define Net_RecieveMapVote(...) ((void)0)
|
#define Net_ReceiveMapVote(...) ((void)0)
|
||||||
#define Net_CheckForEnoughVotes(...) ((void)0)
|
#define Net_CheckForEnoughVotes(...) ((void)0)
|
||||||
|
|
||||||
#define Net_SendMapVoteCancel(...) ((void)0)
|
#define Net_SendMapVoteCancel(...) ((void)0)
|
||||||
#define Net_RecieveMapVoteCancel(...) ((void)0)
|
#define Net_ReceiveMapVoteCancel(...) ((void)0)
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue