Figure out a ping between every player, adjust resend rate based on it

This commit is contained in:
MysterD 2023-03-27 11:50:32 -07:00
parent 406bcb158d
commit b596cb2af2
13 changed files with 115 additions and 13 deletions

View file

@ -86,11 +86,12 @@ override_field_immutable = {
"GlobalObjectAnimations": [ "*"],
"SpawnParticlesInfo": [ "model" ],
"MarioBodyState": [ "updateTorsoTime" ],
"Area": [ "localAreaTimer" ],
"Area": [ "localAreaTimer", "nextSyncID" ],
"Mod": [ "*" ],
"ModFile": [ "*" ],
"BassAudio": [ "*" ],
"Painting": [ "id", "imageCount", "textureType", "textureWidth", "textureHeight" ]
"Painting": [ "id", "imageCount", "textureType", "textureWidth", "textureHeight" ],
"SpawnInfo": [ "syncID" ]
}
override_allowed_structs = {

View file

@ -4740,6 +4740,9 @@ PLAYER_INTERACTIONS_PVP = 2
--- @type integer
MAX_RX_SEQ_IDS = 64
--- @type integer
NETWORK_PLAYER_PING_TIMEOUT = 3
--- @type integer
NETWORK_PLAYER_TIMEOUT = 10
@ -11516,7 +11519,7 @@ MAX_VERSION_LENGTH = 10
MINOR_VERSION_NUMBER = 0
--- @type integer
PATCH_VERSION_NUMBER = 1
PATCH_VERSION_NUMBER = 3
--- @type integer
VERSION_NUMBER = 32

View file

@ -34,6 +34,7 @@
--- @field public macroObjectsAltered Pointer_integer
--- @field public musicParam integer
--- @field public musicParam2 integer
--- @field public nextSyncID integer
--- @field public numRedCoins integer
--- @field public numSecrets integer
--- @field public objectSpawnInfos SpawnInfo
@ -821,6 +822,7 @@
--- @field public descriptionR integer
--- @field public fadeOpacity integer
--- @field public globalIndex integer
--- @field public lastPingSent number
--- @field public lastReceived number
--- @field public lastSent number
--- @field public localIndex integer
@ -833,6 +835,7 @@
--- @field public overridePaletteIndexLp integer
--- @field public palette PlayerPalette
--- @field public paletteIndex integer
--- @field public ping integer
--- @field public type integer
--- @class Object
@ -1736,6 +1739,7 @@
--- @field public next SpawnInfo
--- @field public startAngle Vec3s
--- @field public startPos Vec3s
--- @field public syncID integer
--- @field public unk18 GraphNode
--- @class SpawnParticlesInfo

View file

@ -1704,6 +1704,7 @@
## [network_player.h](#network_player.h)
- MAX_RX_SEQ_IDS
- NETWORK_PLAYER_PING_TIMEOUT
- NETWORK_PLAYER_TIMEOUT
- UNKNOWN_GLOBAL_INDEX
- UNKNOWN_LOCAL_INDEX

View file

@ -131,6 +131,7 @@
| macroObjectsAltered | `Pointer` <`integer`> | read-only |
| musicParam | `integer` | |
| musicParam2 | `integer` | |
| nextSyncID | `integer` | read-only |
| numRedCoins | `integer` | |
| numSecrets | `integer` | |
| objectSpawnInfos | [SpawnInfo](structs.md#SpawnInfo) | |
@ -1175,6 +1176,7 @@
| descriptionR | `integer` | read-only |
| fadeOpacity | `integer` | read-only |
| globalIndex | `integer` | read-only |
| lastPingSent | `number` | read-only |
| lastReceived | `number` | read-only |
| lastSent | `number` | read-only |
| localIndex | `integer` | read-only |
@ -1187,6 +1189,7 @@
| overridePaletteIndexLp | `integer` | read-only |
| palette | [PlayerPalette](structs.md#PlayerPalette) | read-only |
| paletteIndex | `integer` | read-only |
| ping | `integer` | read-only |
| type | `integer` | read-only |
[:arrow_up_small:](#)
@ -2210,6 +2213,7 @@
| next | [SpawnInfo](structs.md#SpawnInfo) | |
| startAngle | [Vec3s](structs.md#Vec3s) | read-only |
| startPos | [Vec3s](structs.md#Vec3s) | read-only |
| syncID | `integer` | read-only |
| unk18 | [GraphNode](structs.md#GraphNode) | |
[:arrow_up_small:](#)

View file

@ -51,10 +51,8 @@ static struct LuaObjectField sAnimationFields[LUA_ANIMATION_FIELD_COUNT] = {
{ "values", LVT_S16_P, offsetof(struct Animation, values), true, LOT_POINTER },
};
#define LUA_AREA_FIELD_COUNT 17
#define LUA_AREA_FIELD_COUNT 18
static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = {
// { "cachedBehaviors", LOT_???, offsetof(struct Area, cachedBehaviors), false, LOT_??? }, <--- UNIMPLEMENTED
// { "cachedPositions", LOT_???, offsetof(struct Area, cachedPositions), false, LOT_??? }, <--- UNIMPLEMENTED
{ "camera", LVT_COBJECT_P, offsetof(struct Area, camera), false, LOT_CAMERA },
// { "dialog", LOT_???, offsetof(struct Area, dialog), false, LOT_??? }, <--- UNIMPLEMENTED
{ "flags", LVT_S8, offsetof(struct Area, flags), false, LOT_NONE },
@ -65,6 +63,7 @@ static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = {
{ "macroObjectsAltered", LVT_U8_P, offsetof(struct Area, macroObjectsAltered), true, LOT_POINTER },
{ "musicParam", LVT_U16, offsetof(struct Area, musicParam), false, LOT_NONE },
{ "musicParam2", LVT_U16, offsetof(struct Area, musicParam2), false, LOT_NONE },
{ "nextSyncID", LVT_U32, offsetof(struct Area, nextSyncID), true, LOT_NONE },
{ "numRedCoins", LVT_U8, offsetof(struct Area, numRedCoins), false, LOT_NONE },
{ "numSecrets", LVT_U8, offsetof(struct Area, numSecrets), false, LOT_NONE },
{ "objectSpawnInfos", LVT_COBJECT_P, offsetof(struct Area, objectSpawnInfos), false, LOT_SPAWNINFO },
@ -928,7 +927,7 @@ static struct LuaObjectField sModeTransitionInfoFields[LUA_MODE_TRANSITION_INFO_
{ "transitionStart", LVT_COBJECT, offsetof(struct ModeTransitionInfo, transitionStart), true, LOT_LINEARTRANSITIONPOINT },
};
#define LUA_NETWORK_PLAYER_FIELD_COUNT 29
#define LUA_NETWORK_PLAYER_FIELD_COUNT 31
static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT] = {
{ "connected", LVT_BOOL, offsetof(struct NetworkPlayer, connected), true, LOT_NONE },
{ "currActNum", LVT_S16, offsetof(struct NetworkPlayer, currActNum), true, LOT_NONE },
@ -946,6 +945,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT
{ "descriptionR", LVT_U8, offsetof(struct NetworkPlayer, descriptionR), true, LOT_NONE },
{ "fadeOpacity", LVT_U8, offsetof(struct NetworkPlayer, fadeOpacity), true, LOT_NONE },
{ "globalIndex", LVT_U8, offsetof(struct NetworkPlayer, globalIndex), true, LOT_NONE },
{ "lastPingSent", LVT_F32, offsetof(struct NetworkPlayer, lastPingSent), true, LOT_NONE },
{ "lastReceived", LVT_F32, offsetof(struct NetworkPlayer, lastReceived), true, LOT_NONE },
{ "lastSent", LVT_F32, offsetof(struct NetworkPlayer, lastSent), true, LOT_NONE },
{ "localIndex", LVT_U8, offsetof(struct NetworkPlayer, localIndex), true, LOT_NONE },
@ -958,6 +958,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT
{ "overridePaletteIndexLp", LVT_U8, offsetof(struct NetworkPlayer, overridePaletteIndexLp), true, LOT_NONE },
{ "palette", LVT_COBJECT, offsetof(struct NetworkPlayer, palette), true, LOT_PLAYERPALETTE },
{ "paletteIndex", LVT_U8, offsetof(struct NetworkPlayer, paletteIndex), true, LOT_NONE },
{ "ping", LVT_U32, offsetof(struct NetworkPlayer, ping), true, LOT_NONE },
// { "rxPacketHash", LOT_???, offsetof(struct NetworkPlayer, rxPacketHash), true, LOT_??? }, <--- UNIMPLEMENTED
// { "rxSeqIds", LOT_???, offsetof(struct NetworkPlayer, rxSeqIds), true, LOT_??? }, <--- UNIMPLEMENTED
{ "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE },
@ -1907,7 +1908,7 @@ static struct LuaObjectField sSoundStateFields[LUA_SOUND_STATE_FIELD_COUNT] = {
{ "soundMagic", LVT_S32, offsetof(struct SoundState, soundMagic), false, LOT_NONE },
};
#define LUA_SPAWN_INFO_FIELD_COUNT 7
#define LUA_SPAWN_INFO_FIELD_COUNT 8
static struct LuaObjectField sSpawnInfoFields[LUA_SPAWN_INFO_FIELD_COUNT] = {
{ "activeAreaIndex", LVT_S8, offsetof(struct SpawnInfo, activeAreaIndex), false, LOT_NONE },
{ "areaIndex", LVT_S8, offsetof(struct SpawnInfo, areaIndex), false, LOT_NONE },
@ -1916,6 +1917,7 @@ static struct LuaObjectField sSpawnInfoFields[LUA_SPAWN_INFO_FIELD_COUNT] = {
{ "next", LVT_COBJECT_P, offsetof(struct SpawnInfo, next), false, LOT_SPAWNINFO },
{ "startAngle", LVT_COBJECT, offsetof(struct SpawnInfo, startAngle), true, LOT_VEC3S },
{ "startPos", LVT_COBJECT, offsetof(struct SpawnInfo, startPos), true, LOT_VEC3S },
{ "syncID", LVT_U32, offsetof(struct SpawnInfo, syncID), true, LOT_NONE },
{ "unk18", LVT_COBJECT_P, offsetof(struct SpawnInfo, unk18), false, LOT_GRAPHNODE },
};

View file

@ -1766,6 +1766,7 @@ char gSmluaConstants[] = ""
"UNKNOWN_GLOBAL_INDEX = (-1)\n"
"UNKNOWN_NETWORK_INDEX = (-1)\n"
"NETWORK_PLAYER_TIMEOUT = 10\n"
"NETWORK_PLAYER_PING_TIMEOUT = 3\n"
"MAX_RX_SEQ_IDS = 64\n"
"USE_REAL_PALETTE_VAR = 0xFF\n"
"NPT_UNKNOWN = 0\n"
@ -4014,7 +4015,7 @@ char gSmluaConstants[] = ""
"VERSION_TEXT = 'beta'\n"
"VERSION_NUMBER = 32\n"
"MINOR_VERSION_NUMBER = 0\n"
"PATCH_VERSION_NUMBER = 1\n"
"PATCH_VERSION_NUMBER = 3\n"
"MAX_VERSION_LENGTH = 10\n"
"MAX_LOCAL_VERSION_LENGTH = 12\n"
;

View file

@ -155,6 +155,16 @@ void network_player_update(void) {
if (!network_player_any_connected()) { return; }
for (s32 i = 1; i < MAX_PLAYERS; i++) {
struct NetworkPlayer *np = &gNetworkPlayers[i];
if (!np->connected && i > 0) { continue; }
float elapsed = (clock_elapsed() - np->lastPingSent);
if (elapsed > NETWORK_PLAYER_PING_TIMEOUT) {
network_send_ping(np);
}
}
if (gNetworkType == NT_SERVER) {
for (s32 i = 1; i < MAX_PLAYERS; i++) {
struct NetworkPlayer *np = &gNetworkPlayers[i];
@ -239,6 +249,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
np->type = type;
np->localIndex = localIndex;
np->globalIndex = globalIndex;
np->ping = 50;
if ((type != NPT_LOCAL) && (gNetworkType == NT_SERVER || type == NPT_SERVER)) { gNetworkSystem->save_id(localIndex, 0); }
network_player_set_description(np, NULL, 0, 0, 0, 0);

View file

@ -9,6 +9,7 @@
#define UNKNOWN_GLOBAL_INDEX ((u8)-1)
#define UNKNOWN_NETWORK_INDEX ((u64)-1)
#define NETWORK_PLAYER_TIMEOUT 10
#define NETWORK_PLAYER_PING_TIMEOUT 3
#define MAX_RX_SEQ_IDS 64
#define USE_REAL_PALETTE_VAR 0xFF
@ -26,6 +27,7 @@ struct NetworkPlayer {
u8 globalIndex;
f32 lastReceived;
f32 lastSent;
f32 lastPingSent;
u16 currLevelAreaSeqId;
s16 currCourseNum;
s16 currActNum;
@ -37,6 +39,7 @@ struct NetworkPlayer {
u8 fadeOpacity;
u8 onRxSeqId;
u8 modelIndex;
u32 ping;
struct PlayerPalette palette;
char name[MAX_PLAYER_STRING+1];

View file

@ -61,6 +61,9 @@ void packet_process(struct Packet* p) {
case PACKET_NETWORK_PLAYERS: network_receive_network_players(p); break;
case PACKET_DEATH: network_receive_death(p); break;
case PACKET_PING: network_receive_ping(p); break;
case PACKET_PONG: network_receive_pong(p); break;
// location
case PACKET_CHANGE_LEVEL: network_receive_change_level(p); break;
case PACKET_CHANGE_AREA: network_receive_change_area(p); break;

View file

@ -35,8 +35,8 @@ enum PacketType {
PACKET_NETWORK_PLAYERS,
PACKET_DEATH,
PACKET_UNUSED_21,
PACKET_UNUSED_22,
PACKET_PING,
PACKET_PONG,
PACKET_UNUSED_23,
PACKET_CHANGE_LEVEL,
@ -263,6 +263,11 @@ void network_receive_network_players(struct Packet* p);
void network_send_death(void);
void network_receive_death(struct Packet* p);
// packet_ping.c
void network_send_ping(struct NetworkPlayer* toNp);
void network_receive_ping(struct Packet* p);
void network_receive_pong(struct Packet* p);
// packet_change_level.c
void network_send_change_level(void);
void network_receive_change_level(struct Packet* p);

View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include "../network.h"
#include "pc/utils/misc.h"
#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
void network_send_ping(struct NetworkPlayer* toNp) {
struct Packet p = { 0 };
f64 timestamp = clock_elapsed_f64();
toNp->lastPingSent = clock_elapsed();
packet_init(&p, PACKET_PING, true, PLMT_NONE);
packet_write(&p, &toNp->globalIndex, sizeof(u8));
packet_write(&p, &timestamp, sizeof(f64));
network_send_to(toNp->localIndex, &p);
LOG_INFO("tx ping");
}
void network_receive_ping(struct Packet* p) {
LOG_INFO("rx ping");
u8 globalIndex;
f64 timestamp;
packet_read(p, &globalIndex, sizeof(u8));
packet_read(p, &timestamp, sizeof(f64));
struct Packet p2 = { 0 };
packet_init(&p2, PACKET_PONG, true, PLMT_NONE);
packet_write(&p2, &globalIndex, sizeof(u8));
packet_write(&p2, &timestamp, sizeof(f64));
network_send_to(p->localIndex, &p2);
}
void network_receive_pong(struct Packet* p) {
f64 now = clock_elapsed_f64();
u8 globalIndex;
f64 timestamp;
packet_read(p, &globalIndex, sizeof(u8));
packet_read(p, &timestamp, sizeof(f64));
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) {
LOG_ERROR("Receiving pong from inactive player!");
return;
}
u32 ping = (now - timestamp) * 1000;
np->ping = np->ping * 0.5f + ping * 0.5f;
if (np->ping > 1000) { np->ping = 1000; }
LOG_INFO("rx pong from %u: %u", globalIndex, ping);
}

View file

@ -143,9 +143,17 @@ static float get_max_elapsed_time(int sendAttempts) {
void network_update_reliable(void) {
struct PacketLinkedList* node = head;
while (node != NULL) {
float elapsed = (clock_elapsed() - node->lastSend);
float maxElapsed = get_max_elapsed_time(node->sendAttempts);
f32 elapsed = (clock_elapsed() - node->lastSend);
f32 maxElapsed = get_max_elapsed_time(node->sendAttempts);
maxElapsed = adjust_max_elapsed(node->p.packetType, maxElapsed);
// adjust resend time based on ping
struct NetworkPlayer* np = &gNetworkPlayers[node->p.localIndex];
f32 pingElapsed = np->ping / 1000.0f;
if (pingElapsed > 1.0f) { pingElapsed = 1.0f; }
pingElapsed *= 1.1f;
if (maxElapsed < pingElapsed) { maxElapsed = pingElapsed; }
if (elapsed > maxElapsed) {
if (node->p.packetType == PACKET_JOIN_REQUEST && gNetworkPlayerServer != NULL) {
node->p.localIndex = gNetworkPlayerServer->localIndex;