Compressed and reduced rate of Player packets

Now player packets are only sent immediately if their inputs or actions changed.
Otherwise, it waits a bit before sending out another one
This commit is contained in:
MysterD 2023-04-16 02:29:59 -07:00
parent d63e65cd4a
commit bc0bd0a77d
2 changed files with 84 additions and 6 deletions

View File

@ -9,7 +9,7 @@
#define UNKNOWN_GLOBAL_INDEX ((u8)-1)
#define UNKNOWN_NETWORK_INDEX ((u64)-1)
#define NETWORK_PLAYER_TIMEOUT 10
#define NETWORK_PLAYER_PING_TIMEOUT 1
#define NETWORK_PLAYER_PING_TIMEOUT 3
#define MAX_RX_SEQ_IDS 64
#define USE_REAL_PALETTE_VAR 0xFF

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <zlib.h>
#include "../network.h"
#include "object_fields.h"
#include "object_constants.h"
@ -75,6 +76,37 @@ struct PacketPlayerData {
};
#pragma pack()
uLong sourceLen = sizeof(struct PacketPlayerData);
static u32 sCompBufferLen = 0;
static Bytef* sCompBuffer = NULL;
static void increase_comp_buffer(u32 compressedLen) {
if (compressedLen <= sCompBufferLen && sCompBuffer) { return; }
if (sCompBuffer != NULL) { free(sCompBuffer); }
sCompBufferLen = compressedLen;
sCompBuffer = (Bytef*)malloc(sCompBufferLen);
}
static u32 compress_player_data(struct PacketPlayerData* data) {
uLongf compressedLen = compressBound(sizeof(struct PacketPlayerData));
increase_comp_buffer(compressedLen);
if (!sCompBuffer) { return 0; }
if (compress2((Bytef*)sCompBuffer, &compressedLen, (Bytef*)data, sourceLen, Z_BEST_COMPRESSION) == Z_OK) {
return compressedLen;
} else {
return 0;
}
}
static bool decompress_player_data(u32 compressedLen, struct PacketPlayerData* data) {
if (!sCompBuffer) { return false; }
uLong decompLen = sizeof(struct PacketPlayerData);
return uncompress((Bytef*)data, &decompLen, sCompBuffer, compressedLen) == Z_OK;
}
static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m) {
u32 heldSyncID = (m->heldObj != NULL) ? m->heldObj->oSyncID : 0;
u32 heldBySyncID = (m->heldByObj != NULL) ? m->heldByObj->oSyncID : 0;
@ -211,10 +243,19 @@ void network_send_player(u8 localIndex) {
struct PacketPlayerData data = { 0 };
read_packet_data(&data, &gMarioStates[localIndex]);
// compress
u32 compressedSize = compress_player_data(&data);
struct Packet p = { 0 };
packet_init(&p, PACKET_PLAYER, false, PLMT_AREA);
packet_write(&p, &gNetworkPlayers[localIndex].globalIndex, sizeof(u8));
packet_write(&p, &data, sizeof(struct PacketPlayerData));
packet_write(&p, &compressedSize, sizeof(u32));
if (compressedSize > 0) {
packet_write(&p, sCompBuffer, compressedSize);
} else {
packet_write(&p, &data, sizeof(struct PacketPlayerData));
}
network_send(&p);
}
@ -244,9 +285,22 @@ void network_receive_player(struct Packet* p) {
u16 playerIndex = np->localIndex;
u32 oldBehParams = m->marioObj->oBehParams;
// read compressed size
u32 compressedSize = 0;
packet_read(p, &compressedSize, sizeof(u32));
// load mario information from packet
struct PacketPlayerData data = { 0 };
packet_read(p, &data, sizeof(struct PacketPlayerData));
if (compressedSize > 0) {
// read compressed data
increase_comp_buffer(compressedSize);
if (!sCompBuffer) { LOG_ERROR("No compressed buffer!"); return; }
packet_read(p, sCompBuffer, compressedSize);
if (!decompress_player_data(compressedSize, &data)) { LOG_ERROR("Failed to decompress data!"); return; }
} else {
// read uncompressed data
packet_read(p, &data, sizeof(struct PacketPlayerData));
}
// check to see if we should just drop this packet
if (oldData.action == ACT_JUMBO_STAR_CUTSCENE && data.action == ACT_JUMBO_STAR_CUTSCENE) {
@ -403,9 +457,33 @@ void network_receive_player(struct Packet* p) {
void network_update_player(void) {
if (!network_player_any_connected()) { return; }
struct MarioState* m = &gMarioStates[0];
u8 localIsHeadless = (&gNetworkPlayers[0] == gNetworkPlayerServer && gServerSettings.headlessServer);
if (!localIsHeadless) {
network_send_player(0);
}
if (localIsHeadless) { return; }
// figure out if we should send it or not
static u8 sTicksSinceSend = 0;
static u32 sLastPlayerAction = 0;
static f32 sLastStickX = 0;
static f32 sLastStickY = 0;
static u32 sLastButtonDown = 0;
static u32 sLastButtonPressed = 0;
f32 stickDist = sqrtf(powf(sLastStickX - m->controller->stickX, 2) + powf(sLastStickY - m->controller->stickY, 2));
bool shouldSend = (sTicksSinceSend > 2)
|| (sLastPlayerAction != m->action)
|| (sLastButtonDown != m->controller->buttonDown)
|| (sLastButtonPressed != m->controller->buttonPressed)
|| (stickDist > 5.0f);
if (!shouldSend) { sTicksSinceSend++; return; }
network_send_player(0);
sTicksSinceSend = 0;
sLastPlayerAction = m->action;
sLastStickX = m->controller->stickX;
sLastStickY = m->controller->stickY;
sLastButtonDown = m->controller->buttonDown;
sLastButtonPressed = m->controller->buttonPressed;
}