From dc85bd6f86dc2378018519dc5b2fa81ac1b85ddd Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sat, 25 Feb 2012 22:33:55 -0500 Subject: [PATCH 1/3] Implement Game auto pinger Evidently, the game connection never actually pinged. Instead, it relied on the propagation of a redundant game message. This is evil because we can sometimes hang out in the loading process for quite some time (eg beyond the socket timeout on either end) --- .../plNetGameLib/Private/plNglGame.cpp | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp index 1040c346..1c376e2f 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp @@ -74,6 +74,11 @@ struct CliGmConn : AtomicRef { CliGmConn (); ~CliGmConn (); + // ping + void AutoPing (); + void StopAutoPing (); + void TimerPing (); + void Send (const uintptr_t fields[], unsigned count); }; @@ -207,6 +212,8 @@ static void UnlinkAndAbandonConn_CS (CliGmConn * conn) { //============================================================================ static bool ConnEncrypt (ENetError error, void * param) { CliGmConn * conn = (CliGmConn *) param; + if (!s_perf[kPingDisabled]) + conn->AutoPing(); if (IS_NET_SUCCESS(error)) { s_critsect.Enter(); @@ -262,6 +269,7 @@ static void NotifyConnSocketConnectFailed (CliGmConn * conn) { //============================================================================ static void NotifyConnSocketDisconnect (CliGmConn * conn) { + conn->StopAutoPing(); bool notify; s_critsect.Enter(); @@ -392,6 +400,19 @@ static void Connect ( * ***/ +//=========================================================================== +static unsigned CliGmConnTimerDestroyed (void * param) { + CliGmConn * conn = (CliGmConn *) param; + conn->DecRef("TimerDestroyed"); + return kAsyncTimeInfinite; +} + +//=========================================================================== +static unsigned CliGmConnPingTimerProc (void * param) { + ((CliGmConn *) param)->TimerPing(); + return kPingIntervalMs; +} + //============================================================================ CliGmConn::CliGmConn () { AtomicAdd(&s_perf[kPerfConnCount], 1); @@ -404,6 +425,59 @@ CliGmConn::~CliGmConn () { AtomicAdd(&s_perf[kPerfConnCount], -1); } +//============================================================================ +void CliGmConn::AutoPing () { + ASSERT(!pingTimer); + IncRef("PingTimer"); + critsect.Enter(); + { + AsyncTimerCreate( + &pingTimer, + CliGmConnPingTimerProc, + sock ? 0 : kAsyncTimeInfinite, + this + ); + } + critsect.Leave(); +} + +//============================================================================ +void CliGmConn::StopAutoPing () { + critsect.Enter(); + { + if (AsyncTimer * timer = pingTimer) { + pingTimer = nil; + AsyncTimerDeleteCallback(timer, CliGmConnTimerDestroyed); + } + } + critsect.Leave(); +} + +//============================================================================ +void CliGmConn::TimerPing () { + +#if 0 + // if the time difference between when we last sent a ping and when we last + // heard from the server is >= 3x the ping interval, the socket is stale. + if (pingSendTimeMs && abs(int(pingSendTimeMs - lastHeardTimeMs)) >= kPingTimeoutMs) { + // ping timed out, disconnect the socket + AsyncSocketDisconnect(sock, true); + } + else +#endif + { + // Send a ping request + pingSendTimeMs = GetNonZeroTimeMs(); + + const uintptr_t msg[] = { + kCli2Game_PingRequest, + pingSendTimeMs + }; + + Send(msg, arrsize(msg)); + } +} + //============================================================================ void CliGmConn::Send (const uintptr_t fields[], unsigned count) { critsect.Enter(); @@ -710,6 +784,17 @@ unsigned GameGetConnId () { //============================================================================ void GamePingEnable (bool enable) { s_perf[kPingDisabled] = !enable; + s_critsect.Enter(); + for (;;) { + if (!s_active) + break; + if (enable) + s_active->AutoPing(); + else + s_active->StopAutoPing(); + break; + } + s_critsect.Leave(); } } using namespace Ngl; From 29f2bc25479fef9d84455b3dc5b03438b61adab0 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sat, 25 Feb 2012 22:35:41 -0500 Subject: [PATCH 2/3] Only synch input states when they dirty Sending dupe input state messages every 10 seconds is wasteful. They are already sent when the fields dirty, so there's no sense in sending them any more than that. For keeping the connection alive, we'll use lightweight pings. --- Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp | 10 ---------- Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h | 1 - 2 files changed, 11 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp index 5233b8d2..3e8c27cb 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp @@ -628,7 +628,6 @@ void plArmatureModBase::IEnableBones(int lod, hsBool enable) const char *plArmatureMod::BoneStrings[] = {"Male", "Female", "Critter", "Actor"}; -const float plArmatureMod::kAvatarInputSynchThreshold = 10.f; float plArmatureMod::fMouseTurnSensitivity = 1.f; hsBool plArmatureMod::fClickToTurn = true; @@ -656,7 +655,6 @@ void plArmatureMod::IInitDefaults() fReverseFBOnIdle = false; fFollowerParticleSystemSO = nil; fPendingSynch = false; - fLastInputSynch = 0; fOpaque = true; fPhysHeight = 0.f; fPhysWidth = 0.f; @@ -1524,8 +1522,6 @@ void plArmatureMod::SynchInputState(uint32_t rcvID /* = kInvalidPlayerID */) msg->AddNetReceiver(rcvID); msg->Send(); - - fLastInputSynch = hsTimer::GetSysSeconds(); } void plArmatureMod::ILinkToPersonalAge() @@ -1589,12 +1585,6 @@ hsBool plArmatureMod::IEval(double time, float elapsed, uint32_t dirty) } } } - - if (localPlayer == this) - { - if (time - fLastInputSynch > kAvatarInputSynchThreshold) - SynchInputState(); - } if (noOverlap) { diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h index 93455aa9..04b2fa17 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h @@ -414,7 +414,6 @@ protected: uint8_t fStealthMode; int fStealthLevel; // you are invisible to other players/CCRs of lower stealthLevel - double fLastInputSynch; plAGModifier * fRootAGMod; plAvBoneMap * fBoneMap; // uses id codes to look up bones. set up by the brain as needed. double fLastSynch; From bd6300d6c7c6cd749ec4175431406b4337ae6183 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sat, 25 Feb 2012 22:56:30 -0500 Subject: [PATCH 3/3] Remove some eap stupid --- .../plNetGameLib/Private/plNglAuth.cpp | 36 +++++++------------ .../plNetGameLib/Private/plNglGame.cpp | 30 +++++----------- .../plNetGameLib/Private/plNglGateKeeper.cpp | 36 +++++++------------ 3 files changed, 33 insertions(+), 69 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index a2819c91..fe7a5a5f 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp @@ -1698,9 +1698,9 @@ void CliAuConn::AutoPing () { void CliAuConn::StopAutoPing () { critsect.Enter(); { - if (AsyncTimer * timer = pingTimer) { + if (pingTimer) { + AsyncTimerDeleteCallback(pingTimer, CliAuConnTimerDestroyed); pingTimer = nil; - AsyncTimerDeleteCallback(timer, CliAuConnTimerDestroyed); } } critsect.Leave(); @@ -1708,30 +1708,18 @@ void CliAuConn::StopAutoPing () { //============================================================================ void CliAuConn::TimerPing () { - -#if 0 - // if the time difference between when we last sent a ping and when we last - // heard from the server is >= 3x the ping interval, the socket is stale. - if (pingSendTimeMs && abs(int(pingSendTimeMs - lastHeardTimeMs)) >= kPingTimeoutMs) { - // ping timed out, disconnect the socket - AsyncSocketDisconnect(sock, true); - } - else -#endif - { - // Send a ping request - pingSendTimeMs = GetNonZeroTimeMs(); + // Send a ping request + pingSendTimeMs = GetNonZeroTimeMs(); - const uintptr_t msg[] = { - kCli2Auth_PingRequest, - pingSendTimeMs, - 0, // not a transaction - 0, // no payload - nil - }; + const uintptr_t msg[] = { + kCli2Auth_PingRequest, + pingSendTimeMs, + 0, // not a transaction + 0, // no payload + nil + }; - Send(msg, arrsize(msg)); - } + Send(msg, arrsize(msg)); } //============================================================================ diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp index 1c376e2f..3ec789de 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp @@ -445,9 +445,9 @@ void CliGmConn::AutoPing () { void CliGmConn::StopAutoPing () { critsect.Enter(); { - if (AsyncTimer * timer = pingTimer) { + if (pingTimer) { + AsyncTimerDeleteCallback(pingTimer, CliGmConnTimerDestroyed); pingTimer = nil; - AsyncTimerDeleteCallback(timer, CliGmConnTimerDestroyed); } } critsect.Leave(); @@ -455,27 +455,15 @@ void CliGmConn::StopAutoPing () { //============================================================================ void CliGmConn::TimerPing () { + // Send a ping request + pingSendTimeMs = GetNonZeroTimeMs(); -#if 0 - // if the time difference between when we last sent a ping and when we last - // heard from the server is >= 3x the ping interval, the socket is stale. - if (pingSendTimeMs && abs(int(pingSendTimeMs - lastHeardTimeMs)) >= kPingTimeoutMs) { - // ping timed out, disconnect the socket - AsyncSocketDisconnect(sock, true); - } - else -#endif - { - // Send a ping request - pingSendTimeMs = GetNonZeroTimeMs(); - - const uintptr_t msg[] = { - kCli2Game_PingRequest, - pingSendTimeMs - }; + const uintptr_t msg[] = { + kCli2Game_PingRequest, + pingSendTimeMs + }; - Send(msg, arrsize(msg)); - } + Send(msg, arrsize(msg)); } //============================================================================ diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp index 7334aa41..ee49e7cc 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp @@ -636,9 +636,9 @@ void CliGkConn::AutoPing () { void CliGkConn::StopAutoPing () { critsect.Enter(); { - if (AsyncTimer * timer = pingTimer) { + if (pingTimer) { + AsyncTimerDeleteCallback(pingTimer, CliGkConnTimerDestroyed); pingTimer = nil; - AsyncTimerDeleteCallback(timer, CliGkConnTimerDestroyed); } } critsect.Leave(); @@ -646,30 +646,18 @@ void CliGkConn::StopAutoPing () { //============================================================================ void CliGkConn::TimerPing () { - -#if 0 - // if the time difference between when we last sent a ping and when we last - // heard from the server is >= 3x the ping interval, the socket is stale. - if (pingSendTimeMs && abs(int(pingSendTimeMs - lastHeardTimeMs)) >= kPingTimeoutMs) { - // ping timed out, disconnect the socket - AsyncSocketDisconnect(sock, true); - } - else -#endif - { - // Send a ping request - pingSendTimeMs = GetNonZeroTimeMs(); + // Send a ping request + pingSendTimeMs = GetNonZeroTimeMs(); - const uintptr_t msg[] = { - kCli2GateKeeper_PingRequest, - pingSendTimeMs, - 0, // not a transaction - 0, // no payload - nil - }; + const uintptr_t msg[] = { + kCli2GateKeeper_PingRequest, + pingSendTimeMs, + 0, // not a transaction + 0, // no payload + nil + }; - //Send(msg, arrsize(msg)); - } + Send(msg, arrsize(msg)); } //============================================================================