Skip to content

Commit

Permalink
Standardise signature parameters & better handle steam disconnection …
Browse files Browse the repository at this point in the history
…event (#2)

* Added hook "GroupDataSteamStatusChanged" which returns a boolean for when the module believes the connection status to Steam has changed.
* Changed how each Steam connection events gets handled. Now relies more on the underlying connection instead of forcing new contexts.
* No longer listen for GSPolicyResponse
* Now listen for SteamServerConnectFailure
* In the event the underlying Steam connection gives up trying to reconnect, we now force a new context.
* Fixed a rare crash where the context could be valid but the Steam backend had literally just died.
* Bumped version to 1.1
* Upgraded to Steamworks v150.
  • Loading branch information
TeddiO committed Nov 20, 2020
1 parent 2ea3642 commit 2dd4a49
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
name: sdk-persistence
path: gfwens/deps

- uses: microsoft/setup-msbuild@v1.0.0
- uses: microsoft/setup-msbuild@v1.0.2

- run: |
cd gfwens
Expand Down
90 changes: 59 additions & 31 deletions src/fwens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#include <stdlib.h>

Fwens* Fwens::instance = NULL;
Fwens::~Fwens() {
Fwens::~Fwens()
{
if (GetSteamContextActive())
{
ClearSteamContext();
Expand All @@ -13,11 +14,13 @@ Fwens::Fwens():
m_steamcallback_HandleConnected(this, &Fwens::Steam_HandleSteamConnected),
m_steamcallback_HandleGroupRequest(this, &Fwens::Steam_HandleGroupRequest),
m_steamcallback_HandleDisconnected(this, &Fwens::Steam_HandleOnDisconnect),
m_steamcallback_HandlePolicyResponse(this, &Fwens::Steam_HandleOnPolicyResponse)
m_steamcallback_HandleConnectionFailed(this, &Fwens::Steam_HandleConnectionFailed)
{}

Fwens* Fwens::GetInstance() {
if (instance == NULL) {
Fwens* Fwens::GetInstance()
{
if (instance == NULL)
{
instance = new Fwens;
}

Expand All @@ -31,65 +34,92 @@ void Fwens::SetLuaInstance(GarrysMod::Lua::ILuaBase* ILuaBase)

void Fwens::InitSteamAPIConnection()
{
bool status = steamContext.Init();
if (!status)
{
return;
}
steamContext_active = true;
steamContext_active = steamContext.Init();
NotifyLuaSteamConnectionEvent(steamContext_active);
}

bool Fwens::GetSteamContextActive()
{
return steamContext_active;
}

void Fwens::ClearSteamContext() {
steamContext.Clear();
void Fwens::ClearSteamContext()
{
steamContext_active = false;
steamContext.Clear();
}

void Fwens::Steam_HandleOnPolicyResponse(GSPolicyResponse_t* policyResponse)
void Fwens::Steam_HandleSteamConnected(SteamServersConnected_t* result)
{
bool status = GetSteamContextActive();
if (!status)
if (!GetSteamContextActive())
{
InitSteamAPIConnection();
return;
}
steamContext_active = true;
NotifyLuaSteamConnectionEvent(steamContext_active);
}

void Fwens::Steam_HandleSteamConnected(SteamServersConnected_t* connnected)
void Fwens::NotifyLuaSteamConnectionEvent(bool connected)
{
bool status = GetSteamContextActive();
if (!status)
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);
LUA->GetField(-1, "hook");
LUA->GetField(-1, "Run");
LUA->PushString("GroupDataSteamStatusChanged");
LUA->PushBool(connected);

int returnValue = LUA->PCall(2, 0, 0);
if (returnValue != 0)
{
InitSteamAPIConnection();
return;
LUA->Remove(1);
LUA->Remove(1);

LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);
LUA->GetField(-1, "ErrorNoHalt");
LUA->Push(-3);
LUA->PushString("\n");
LUA->Call(2, 0);
}
steamContext_active = true;

LUA->Pop(2);
}

void Fwens::Steam_HandleOnDisconnect(SteamServersDisconnected_t* something)
void Fwens::Steam_HandleOnDisconnect(SteamServersDisconnected_t* result)
{
steamContext_active = false;
bool status = GetSteamContextActive();
if (!status)
NotifyLuaSteamConnectionEvent(steamContext_active);
}

void Fwens::Steam_HandleConnectionFailed(SteamServerConnectFailure_t* result)
{
steamContext_active = false;
if (!result->m_bStillRetrying)
{
ClearSteamContext();
InitSteamAPIConnection();
return;
}
steamContext_active = true;
}

void Fwens::RequestUserGroupStatus(CSteamID player, CSteamID groupID)
{
if (GetSteamContextActive() == false)
{
LUA->ThrowError("No connection to the Steam API. Is Steam up?");
return;
}

ISteamGameServer* steamGameServer = steamContext.SteamGameServer();
if (steamGameServer == NULL)
{
// This shouldn't really ever happen. But when it rarely does, gracefully bow out.
LUA->ThrowError("ISteamGameServer is NULL. Invalid Steam connection.");
return;
}

steamGameServer->RequestUserGroupStatus(player, groupID);
}


void Fwens::Steam_HandleGroupRequest(GSClientGroupStatus_t* pCallback)
{
// CSteamID.Render() no longer appears to function, we'll cast these manually.
Expand Down Expand Up @@ -118,7 +148,8 @@ void Fwens::Steam_HandleGroupRequest(GSClientGroupStatus_t* pCallback)
LUA->SetField(-2, "groupID64");

int returnValue = LUA->PCall(2, 0, 0);
if (returnValue != 0) {
if (returnValue != 0)
{
// Dump our two current tables to simplify this. Can't pop because LIFO.
LUA->Remove(1);
LUA->Remove(1);
Expand All @@ -128,10 +159,7 @@ void Fwens::Steam_HandleGroupRequest(GSClientGroupStatus_t* pCallback)
LUA->Push(-3);
LUA->PushString("\n");
LUA->Call(2, 0);
LUA->Pop(2);

return;
}

LUA->Pop(2);
}
}
3 changes: 2 additions & 1 deletion src/fwens.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ class Fwens
void SetLuaInstance(GarrysMod::Lua::ILuaBase* ILuaBase);
void RequestUserGroupStatus(CSteamID player, CSteamID groupID);
void ClearSteamContext();
void NotifyLuaSteamConnectionEvent(bool connected);

STEAM_GAMESERVER_CALLBACK(Fwens, Steam_HandleSteamConnected, SteamServersConnected_t, m_steamcallback_HandleConnected);
STEAM_GAMESERVER_CALLBACK(Fwens, Steam_HandleGroupRequest, GSClientGroupStatus_t, m_steamcallback_HandleGroupRequest);
STEAM_GAMESERVER_CALLBACK(Fwens, Steam_HandleOnDisconnect, SteamServersDisconnected_t, m_steamcallback_HandleDisconnected);
STEAM_GAMESERVER_CALLBACK(Fwens, Steam_HandleOnPolicyResponse, GSPolicyResponse_t, m_steamcallback_HandlePolicyResponse);
STEAM_GAMESERVER_CALLBACK(Fwens, Steam_HandleConnectionFailed, SteamServerConnectFailure_t, m_steamcallback_HandleConnectionFailed);
};
10 changes: 2 additions & 8 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,10 @@ LUA_FUNCTION(GetInSteamGroup)
}

Fwens* fwenVar = Fwens::GetInstance();
if (!fwenVar->GetSteamContextActive())
{
LUA->ThrowError("No connection to the Steam API. Is Steam up?");
return 0;
}

fwenVar->RequestUserGroupStatus(player, groupID);
return 0;
}


GMOD_MODULE_OPEN()
{
LUA->PushSpecial(SPECIAL_GLOB);
Expand All @@ -62,13 +55,14 @@ GMOD_MODULE_OPEN()
LUA->SetField(-2, "fwens");

LUA->GetField(-1, "print");
LUA->PushString("gfwens v1 loaded.");
LUA->PushString("gfwens v1.1 loaded.");
LUA->Call(1, 0);
LUA->Pop();

Fwens* fwenVar = Fwens::GetInstance();
fwenVar->SetLuaInstance(LUA);

// Exists for changelevel purposes. Will silently fail during first boot of the server.
if (!fwenVar->GetSteamContextActive())
{
fwenVar->InitSteamAPIConnection();
Expand Down

0 comments on commit 2dd4a49

Please sign in to comment.