From 6fa48abd3387a7fe0c00f462f08bf4b680f656f9 Mon Sep 17 00:00:00 2001 From: uniboi <64006268+uniboi@users.noreply.github.com> Date: Thu, 27 Apr 2023 12:55:06 +0000 Subject: Use structs for the Script Server Browser (#453) * fix vector garbage data * use structs for script server browser * use sq struct api wrappers * use sqfloat return type for getvector * use const references for access * move fn to make the diff more readable (hopefully) --- .../scripts/client/scriptserverbrowser.cpp | 338 +++++---------------- NorthstarDLL/squirrel/squirrel.cpp | 10 + NorthstarDLL/squirrel/squirrel.h | 13 + NorthstarDLL/squirrel/squirrelclasstypes.h | 4 + 4 files changed, 99 insertions(+), 266 deletions(-) (limited to 'NorthstarDLL') diff --git a/NorthstarDLL/scripts/client/scriptserverbrowser.cpp b/NorthstarDLL/scripts/client/scriptserverbrowser.cpp index 39279de5..ff6da6e2 100644 --- a/NorthstarDLL/scripts/client/scriptserverbrowser.cpp +++ b/NorthstarDLL/scripts/client/scriptserverbrowser.cpp @@ -36,272 +36,6 @@ ADD_SQFUNC("int", NSGetServerCount, "", "", ScriptContext::UI) return SQRESULT_NOTNULL; } -ADD_SQFUNC("string", NSGetServerName, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get name of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].name); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerDescription, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get description of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].description.c_str()); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerMap, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get map of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].map); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerPlaylist, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get playlist of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].playlist); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("int", NSGetServerPlayerCount, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get playercount of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].playerCount); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("int", NSGetServerMaxPlayerCount, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get max playercount of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].maxPlayers); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerID, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get id of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].id); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("bool", NSServerRequiresPassword, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get hasPassword of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushbool(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiresPassword); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("int", NSGetServerRequiredModsCount, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get required mods count of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerRegion, "int serverIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get region of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].region, -1); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerRequiredModName, "int serverIndex, int modIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - SQInteger modIndex = g_pSquirrel->getinteger(sqvm, 2); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get hasPassword of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - if (modIndex >= g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get required mod name of mod index {} when only {} mod are available", - modIndex, - g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Name.c_str()); - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC("string", NSGetServerRequiredModVersion, "int serverIndex, int modIndex", "", ScriptContext::UI) -{ - SQInteger serverIndex = g_pSquirrel->getinteger(sqvm, 1); - SQInteger modIndex = g_pSquirrel->getinteger(sqvm, 2); - - if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get required mod version of server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - if (modIndex >= g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) - { - g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to get required mod version of mod index {} when only {} mod are available", - modIndex, - g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) - .c_str()); - return SQRESULT_ERROR; - } - - g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Version.c_str()); - return SQRESULT_NOTNULL; -} - ADD_SQFUNC("void", NSClearRecievedServerList, "", "", ScriptContext::UI) { g_pMasterServerManager->ClearServerList(); @@ -407,3 +141,75 @@ ADD_SQFUNC("string", NSGetAuthFailReason, "", "", ScriptContext::UI) g_pSquirrel->pushstring(sqvm, g_pMasterServerManager->m_sAuthFailureReason.c_str(), -1); return SQRESULT_NOTNULL; } + +ADD_SQFUNC("array", NSGetGameServers, "", "", ScriptContext::UI) +{ + g_pSquirrel->newarray(sqvm, 0); + for (size_t i = 0; i < g_pMasterServerManager->m_vRemoteServers.size(); i++) + { + const RemoteServerInfo& remoteServer = g_pMasterServerManager->m_vRemoteServers[i]; + + g_pSquirrel->pushnewstructinstance(sqvm, 11); + + // index + g_pSquirrel->pushinteger(sqvm, i); + g_pSquirrel->sealstructslot(sqvm, 0); + + // id + g_pSquirrel->pushstring(sqvm, remoteServer.id, -1); + g_pSquirrel->sealstructslot(sqvm, 1); + + // name + g_pSquirrel->pushstring(sqvm, remoteServer.name, -1); + g_pSquirrel->sealstructslot(sqvm, 2); + + // description + g_pSquirrel->pushstring(sqvm, remoteServer.description.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 3); + + // map + g_pSquirrel->pushstring(sqvm, remoteServer.map, -1); + g_pSquirrel->sealstructslot(sqvm, 4); + + // playlist + g_pSquirrel->pushstring(sqvm, remoteServer.playlist, -1); + g_pSquirrel->sealstructslot(sqvm, 5); + + // playerCount + g_pSquirrel->pushinteger(sqvm, remoteServer.playerCount); + g_pSquirrel->sealstructslot(sqvm, 6); + + // maxPlayerCount + g_pSquirrel->pushinteger(sqvm, remoteServer.maxPlayers); + g_pSquirrel->sealstructslot(sqvm, 7); + + // requiresPassword + g_pSquirrel->pushbool(sqvm, remoteServer.requiresPassword); + g_pSquirrel->sealstructslot(sqvm, 8); + + // region + g_pSquirrel->pushstring(sqvm, remoteServer.region, -1); + g_pSquirrel->sealstructslot(sqvm, 9); + + // requiredMods + g_pSquirrel->newarray(sqvm); + for (const RemoteModInfo& mod : remoteServer.requiredMods) + { + g_pSquirrel->pushnewstructinstance(sqvm, 2); + + // name + g_pSquirrel->pushstring(sqvm, mod.Name.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 0); + + // version + g_pSquirrel->pushstring(sqvm, mod.Version.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 1); + + g_pSquirrel->arrayappend(sqvm, -2); + } + g_pSquirrel->sealstructslot(sqvm, 10); + + g_pSquirrel->arrayappend(sqvm, -2); + } + return SQRESULT_NOTNULL; +} diff --git a/NorthstarDLL/squirrel/squirrel.cpp b/NorthstarDLL/squirrel/squirrel.cpp index 43c5296b..3bb5c154 100644 --- a/NorthstarDLL/squirrel/squirrel.cpp +++ b/NorthstarDLL/squirrel/squirrel.cpp @@ -780,6 +780,12 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel->__sq_stackinfos = module.Offset(0x35970).As(); g_pSquirrel->__sq_stackinfos = g_pSquirrel->__sq_stackinfos; + // Structs + g_pSquirrel->__sq_pushnewstructinstance = module.Offset(0x5400).As(); + g_pSquirrel->__sq_sealstructslot = module.Offset(0x5530).As(); + g_pSquirrel->__sq_pushnewstructinstance = g_pSquirrel->__sq_pushnewstructinstance; + g_pSquirrel->__sq_sealstructslot = g_pSquirrel->__sq_sealstructslot; + MAKEHOOK( module.Offset(0x108E0), &RegisterSquirrelFunctionHook, @@ -869,6 +875,10 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel->__sq_getfunction = module.Offset(0x6C85).As(); g_pSquirrel->__sq_stackinfos = module.Offset(0x35920).As(); + // Structs + g_pSquirrel->__sq_pushnewstructinstance = module.Offset(0x53e0).As(); + g_pSquirrel->__sq_sealstructslot = module.Offset(0x5510).As(); + MAKEHOOK( module.Offset(0x1DD10), &RegisterSquirrelFunctionHook, diff --git a/NorthstarDLL/squirrel/squirrel.h b/NorthstarDLL/squirrel/squirrel.h index 9bf3a794..3d18d6c1 100644 --- a/NorthstarDLL/squirrel/squirrel.h +++ b/NorthstarDLL/squirrel/squirrel.h @@ -107,6 +107,9 @@ class SquirrelManagerBase sq_getentityfrominstanceType __sq_getentityfrominstance; sq_GetEntityConstantType __sq_GetEntityConstant_CBaseEntity; + sq_pushnewstructinstanceType __sq_pushnewstructinstance; + sq_sealstructslotType __sq_sealstructslot; + #pragma endregion #pragma region SQVM func wrappers @@ -288,6 +291,16 @@ class SquirrelManagerBase // there are entity constants for other types, but seemingly CBaseEntity's is the only one needed return (T*)__sq_getentityfrominstance(m_pSQVM, &obj, __sq_GetEntityConstant_CBaseEntity()); } + + inline SQRESULT pushnewstructinstance(HSquirrelVM* sqvm, const int fieldCount) + { + return __sq_pushnewstructinstance(sqvm, fieldCount); + } + + inline SQRESULT sealstructslot(HSquirrelVM* sqvm, const int fieldIndex) + { + return __sq_sealstructslot(sqvm, fieldIndex); + } #pragma endregion }; diff --git a/NorthstarDLL/squirrel/squirrelclasstypes.h b/NorthstarDLL/squirrel/squirrelclasstypes.h index 67f69827..ac813334 100644 --- a/NorthstarDLL/squirrel/squirrelclasstypes.h +++ b/NorthstarDLL/squirrel/squirrelclasstypes.h @@ -236,6 +236,10 @@ typedef char** (*sq_GetEntityConstantType)(); typedef int (*sq_getfunctionType)(HSquirrelVM* sqvm, const char* name, SQObject* returnObj, const char* signature); +// structs +typedef SQRESULT (*sq_pushnewstructinstanceType)(HSquirrelVM* sqvm, int fieldCount); +typedef SQRESULT (*sq_sealstructslotType)(HSquirrelVM* sqvm, int slotIndex); + #pragma endregion // These "external" versions of the types are for plugins -- cgit v1.2.3