See description

* Added new function 'GetAvailablePlaylists' to all VM's.
* Moved function 'GetAvailableMaps' from UI VM to all VM's.
* Improved logic behind 'GetAvailableMaps'.
* Server browser and SQVM now rely on 'MOD_GetAllInstalledMaps'. This new function populates the global vector 'g_vAllMaps' with all installed maps.
* Improved 'KeyValues' structure to use union for shared members.
This commit is contained in:
Kawe Mazidjatari 2022-05-27 02:08:51 +02:00
parent bf4d9d4ead
commit 47d2e4c915
11 changed files with 103 additions and 77 deletions

View File

@ -15,6 +15,7 @@
#include "filesystem/filesystem.h"
string g_svLevelName;
vector<string> g_vAllMaps;
bool s_bLevelResourceInitialized = false;
bool s_bBasePaksInitialized = false;
//-----------------------------------------------------------------------------
@ -27,6 +28,39 @@ bool MOD_LevelHasChanged(const string& svLevelName)
return (strcmp(svLevelName.c_str(), g_svLevelName.c_str()) != 0);
}
//-----------------------------------------------------------------------------
// Purpose: gets all installed maps
//-----------------------------------------------------------------------------
void MOD_GetAllInstalledMaps()
{
if (!g_vAllMaps.empty())
return;
std::regex rgArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
std::smatch smRegexMatches;
for (const auto& dEntry : fs::directory_iterator("vpk"))
{
std::string svFileName = dEntry.path().string();
std::regex_search(svFileName, smRegexMatches, rgArchiveRegex);
if (smRegexMatches.size() > 0)
{
if (strcmp(smRegexMatches[1].str().c_str(), "frontend") == 0)
{
continue;
}
else if (strcmp(smRegexMatches[1].str().c_str(), "mp_common") == 0)
{
g_vAllMaps.push_back("mp_lobby");
continue;
}
g_vAllMaps.push_back(smRegexMatches[1].str());
}
}
}
//-----------------------------------------------------------------------------
// Purpose: gets the queued pak handles
// Input : *a1 -

View File

@ -37,8 +37,10 @@ inline auto sub_140441220 = p_MOD_ProcessPakQueue.RCast<void(*)(__int64 a1, __in
extern bool s_bBasePaksInitialized;
extern string g_svLevelName;
extern vector<string> g_vAllMaps;
bool MOD_LevelHasChanged(const string& svLevelName);
void MOD_GetAllInstalledMaps();
void MOD_PreloadPakFile(const string& svLevelName);
void MOD_UnloadPakFile(void);

View File

@ -21,6 +21,7 @@ History:
#include "windows/console.h"
#include "windows/resource.h"
#include "engine/net.h"
#include "engine/cmodel_bsp.h"
#include "engine/host_state.h"
#ifndef CLIENT_DLL
#include "engine/server/server.h"
@ -41,31 +42,6 @@ History:
IBrowser::IBrowser(void)
{
memset(m_chServerConnStringBuffer, 0, sizeof(m_chServerConnStringBuffer));
std::regex rgArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
std::smatch smRegexMatches;
for (const auto& dEntry : fs::directory_iterator("vpk"))
{
std::string svFileName = dEntry.path().string();
std::regex_search(svFileName, smRegexMatches, rgArchiveRegex);
if (smRegexMatches.size() > 0)
{
if (strcmp(smRegexMatches[1].str().c_str(), "frontend") == 0)
{
continue;
}
else if (strcmp(smRegexMatches[1].str().c_str(), "mp_common") == 0)
{
m_vszMapsList.push_back("mp_lobby");
continue;
}
m_vszMapsList.push_back(smRegexMatches[1].str());
}
}
#ifndef CLIENT_DLL
static std::thread hostingServerRequestThread([this]()
{
@ -430,7 +406,7 @@ void IBrowser::HostServerSection(void)
if (ImGui::BeginCombo("Playlist", m_Server.svPlaylist.c_str()))
{
for (auto& item : g_szAllPlaylists)
for (auto& item : g_vAllPlaylists)
{
if (ImGui::Selectable(item.c_str(), item == m_Server.svPlaylist))
{
@ -442,7 +418,7 @@ void IBrowser::HostServerSection(void)
if (ImGui::BeginCombo("Map##ServerHost_MapListBox", m_Server.svMapName.c_str()))
{
for (auto& item : m_vszMapsList)
for (auto& item : g_vAllMaps)
{
if (ImGui::Selectable(item.c_str(), item == m_Server.svMapName))
{

View File

@ -91,7 +91,6 @@ public:
// Host Server //
////////////////////
ServerListing m_Server;
std::vector<std::string> m_vszMapsList;
std::string m_szHostRequestMessage = "";
std::string m_szHostToken = "";
ImVec4 m_iv4HostRequestMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);

View File

@ -9,6 +9,7 @@
#include "vpc/interfaces.h"
#include "launcher/IApplication.h"
#include "ebisusdk/EbisuSDK.h"
#include "engine/cmodel_bsp.h"
#include "engine/sys_engine.h"
#include "engine/sys_dll2.h"
#include "engine/host_cmd.h"
@ -26,6 +27,7 @@ int CModAppSystemGroup::Main(CModAppSystemGroup* pModAppSystemGroup)
{
int nRunResult = RUN_OK;
HEbisuSDK_Init(); // Not here in retail. We init EbisuSDK here though.
MOD_GetAllInstalledMaps();
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) // !TODO: rebuild does not work for S1 (CModAppSystemGroup and CEngine member offsets do align with all other builds).
return CModAppSystemGroup_Main(pModAppSystemGroup);

View File

@ -343,7 +343,6 @@ void CUIBaseSurface::Init()
this->m_NetRandomKeyToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
this->m_EngineNetworkGroup->AddControl(this->m_NetRandomKeyToggle);
this->m_NoQueuedPacketThread = new UIX::UIXCheckBox();
this->m_NoQueuedPacketThread->SetSize({ 125, 18 });
this->m_NoQueuedPacketThread->SetLocation({ 15, 30 });
@ -360,7 +359,6 @@ void CUIBaseSurface::Init()
this->m_NoTimeOutToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
this->m_EngineNetworkGroup->AddControl(this->m_NoTimeOutToggle);
this->m_WindowedToggle = new UIX::UIXCheckBox();
this->m_WindowedToggle->SetSize({ 105, 18 });
this->m_WindowedToggle->SetLocation({ 15, 7 });
@ -396,7 +394,6 @@ void CUIBaseSurface::Init()
this->m_FpsLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
this->m_EngineVideoGroup->AddControl(this->m_FpsLabel);
this->m_WidthTextBox = new UIX::UIXTextBox();
this->m_WidthTextBox->SetSize({ 50, 18 });
this->m_WidthTextBox->SetLocation({ 100, 30 });

View File

@ -15,6 +15,7 @@
#ifndef CLIENT_DLL
#include "engine/server/server.h"
#endif // CLIENT_DLL
#include "engine/cmodel_bsp.h"
#include "squirrel/sqtype.h"
#include "squirrel/sqapi.h"
#include "squirrel/sqinit.h"
@ -45,6 +46,42 @@ namespace VSquirrel
sq_pushstring(v, g_pR5net->GetSDKVersion().c_str(), -1);
return SQ_OK;
}
//-----------------------------------------------------------------------------
// Purpose: return all available maps
//-----------------------------------------------------------------------------
SQRESULT GetAvailableMaps(HSQUIRRELVM v)
{
if (g_vAllMaps.empty())
return SQ_OK;
sq_newarray(v, 0);
for (auto& it : g_vAllMaps)
{
sq_pushstring(v, it.c_str(), -1);
sq_arrayappend(v, -2);
}
return SQ_OK;
}
//-----------------------------------------------------------------------------
// Purpose: return all available playlists
//-----------------------------------------------------------------------------
SQRESULT GetAvailablePlaylists(HSQUIRRELVM v)
{
if (g_vAllPlaylists.empty())
return SQ_OK;
sq_newarray(v, 0);
for (auto& it : g_vAllPlaylists)
{
sq_pushstring(v, it.c_str(), -1);
sq_arrayappend(v, -2);
}
return SQ_OK;
}
}
#ifndef CLIENT_DLL
namespace SERVER
@ -291,32 +328,6 @@ namespace VSquirrel
return SQ_OK;
}
//-----------------------------------------------------------------------------
// Purpose: return all available maps
//-----------------------------------------------------------------------------
SQRESULT GetAvailableMaps(HSQUIRRELVM v)
{
std::vector<std::string> vsvMapList = g_pIBrowser->m_vszMapsList;
if (vsvMapList.empty())
{
Warning(eDLL_T::UI, "%s: Available maps is empty!\n", __FUNCTION__);
return SQ_OK;
}
DevMsg(eDLL_T::UI, "Requesting an array of '%i' available maps from script\n", vsvMapList.size());
sq_newarray(v, 0);
for (auto& it : vsvMapList)
{
sq_pushstring(v, it.c_str(), -1);
sq_arrayappend(v, -2);
}
return SQ_OK;
}
}
#endif // !DEDICATED
}

View File

@ -21,6 +21,8 @@ namespace VSquirrel
{
SQRESULT SDKNativeTest(HSQUIRRELVM v);
SQRESULT GetSDKVersion(HSQUIRRELVM v);
SQRESULT GetAvailableMaps(HSQUIRRELVM v);
SQRESULT GetAvailablePlaylists(HSQUIRRELVM v);
}
#ifndef CLIENT_DLL
namespace SERVER
@ -45,7 +47,6 @@ namespace VSquirrel
SQRESULT JoinPrivateServerFromMenu(HSQUIRRELVM v);
SQRESULT GetPrivateServerMessage(HSQUIRRELVM v);
SQRESULT ConnectToIPFromMenu(HSQUIRRELVM v);
SQRESULT GetAvailableMaps(HSQUIRRELVM v);
}
#endif // !DEDICATED
}

View File

@ -340,6 +340,8 @@ void SQVM_RegisterServerScriptFunctions(HSQUIRRELVM v)
SQVM_RegisterFunction(v, "GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion);
SQVM_RegisterFunction(v, "GetNumHumanPlayers", "Gets the number of human players on the server", "int", "", &VSquirrel::SERVER::GetNumHumanPlayers);
SQVM_RegisterFunction(v, "GetNumFakeClients", "Gets the number of bot players on the server", "int", "", &VSquirrel::SERVER::GetNumFakeClients);
SQVM_RegisterFunction(v, "GetAvailableMaps", "Gets an array of all available maps", "array<string>", "", &VSquirrel::SHARED::GetAvailableMaps);
SQVM_RegisterFunction(v, "GetAvailablePlaylists", "Gets an array of all available playlists", "array<string>", "", &VSquirrel::SHARED::GetAvailablePlaylists);
}
#endif // !CLIENT_DLL
@ -352,6 +354,8 @@ void SQVM_RegisterClientScriptFunctions(HSQUIRRELVM v)
{
SQVM_RegisterFunction(v, "SDKNativeTest", "Native CLIENT test function", "void", "", &VSquirrel::SHARED::SDKNativeTest);
SQVM_RegisterFunction(v, "GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion);
SQVM_RegisterFunction(v, "GetAvailableMaps", "Gets an array of all available maps", "array<string>", "", &VSquirrel::SHARED::GetAvailableMaps);
SQVM_RegisterFunction(v, "GetAvailablePlaylists", "Gets an array of all available playlists", "array<string>", "", &VSquirrel::SHARED::GetAvailablePlaylists);
}
//---------------------------------------------------------------------------------
@ -377,9 +381,10 @@ void SQVM_RegisterUIScriptFunctions(HSQUIRRELVM v)
SQVM_RegisterFunction(v, "SetEncKeyAndConnect", "Set the encryption key to that of the specified server and connects to it", "void", "int", &VSquirrel::UI::SetEncKeyAndConnect);
SQVM_RegisterFunction(v, "JoinPrivateServerFromMenu", "Joins private server by token", "void", "string", &VSquirrel::UI::JoinPrivateServerFromMenu);
SQVM_RegisterFunction(v, "GetPrivateServerMessage", "Gets private server join status message", "string", "string", &VSquirrel::UI::GetPrivateServerMessage);
SQVM_RegisterFunction(v, "ConnectToIPFromMenu", "Joins server by ip and encryption key", "void", "string,string", &VSquirrel::UI::ConnectToIPFromMenu);
SQVM_RegisterFunction(v, "ConnectToIPFromMenu", "Joins server by ip address and encryption key", "void", "string,string", &VSquirrel::UI::ConnectToIPFromMenu);
SQVM_RegisterFunction(v, "GetAvailableMaps", "Gets an array of all the available maps that can be used to host a server", "array<string>", "", &VSquirrel::UI::GetAvailableMaps);
SQVM_RegisterFunction(v, "GetAvailableMaps", "Gets an array of all available maps", "array<string>", "", &VSquirrel::SHARED::GetAvailableMaps);
SQVM_RegisterFunction(v, "GetAvailablePlaylists", "Gets an array of all available playlists", "array<string>", "", &VSquirrel::SHARED::GetAvailablePlaylists);
}
//---------------------------------------------------------------------------------

View File

@ -62,13 +62,13 @@ int KeyValues::GetInt(const char* pKeyName, int nDefaultValue)
case TYPE_STRING:
return atoi(dat->m_sValue);
case TYPE_FLOAT:
return static_cast<int>(m_flValue());
return static_cast<int>(m_flValue);
case TYPE_WSTRING:
return _wtoi(dat->m_wsValue);
case TYPE_UINT64:
return 0;
default:
return dat->m_iValue();
return dat->m_iValue;
}
return nDefaultValue;
@ -84,7 +84,7 @@ void KeyValues::SetInt(const char* pKeyName, int iValue)
KeyValues* dat = FindKey(pKeyName, true);
if (dat)
{
dat->m_iValue() = iValue;
dat->m_iValue = iValue;
dat->m_iDataType = TYPE_INT;
}
}
@ -99,7 +99,7 @@ void KeyValues::SetFloat(const char* pKeyName, float flValue)
KeyValues* dat = FindKey(pKeyName, true);
if (dat)
{
dat->m_flValue() = flValue;
dat->m_flValue = flValue;
dat->m_iDataType = TYPE_FLOAT;
}
}
@ -116,10 +116,10 @@ void KeyValues::InitPlaylist(void)
KeyValues* playlists = (*g_pPlaylistKeyValues)->FindKey("Playlists", false);
if (playlists)
{
g_szAllPlaylists.clear();
g_vAllPlaylists.clear();
for (KeyValues* dat = playlists->m_pSub; dat != nullptr; dat = dat->m_pPeer) // Parse through all sub keys.
{
g_szAllPlaylists.push_back(dat->GetName()); // Get all playlist names.
g_vAllPlaylists.push_back(dat->GetName()); // Get all playlist names.
}
break; // Break if playlist got filled.
@ -176,4 +176,4 @@ void CKeyValueSystem_Detach()
///////////////////////////////////////////////////////////////////////////////
inline KeyValues** g_pPlaylistKeyValues = nullptr; // Get the KeyValue for the playlist file.
vector<string> g_szAllPlaylists = { "<<null>>" };
vector<string> g_vAllPlaylists = { "<<null>>" };

View File

@ -1,7 +1,7 @@
#pragma once
#define MAKE_3_BYTES_FROM_1_AND_2( x1, x2 ) (( (( uint16_t )x2) << 8 ) | (uint8_t)(x1))
extern vector<string> g_szAllPlaylists;
extern vector<string> g_vAllPlaylists;
//---------------------------------------------------------------------------------
// Purpose: Forward declarations
@ -40,7 +40,6 @@ enum KeyValuesTypes
class KeyValues
{
public:
static void Init(void);
KeyValues* FindKey(const char* pKeyName, bool bCreate);
const char* GetName(void) const;
@ -51,19 +50,19 @@ public:
static void InitPlaylist(void);
static bool LoadPlaylist(const char* szPlaylist);
// Compiler makes it so m_Value shares the offset spot with m_flValue that why we cast it like this.
MEMBER_AT_OFFSET(float, m_flValue, 0x18);
MEMBER_AT_OFFSET(int, m_iValue, 0x18);
public:
uint32_t m_iKeyName : 24; // 0x0000
uint32_t m_iKeyNameCaseSensitive : 8; // 0x0003
char* m_sValue; // 0x0008
wchar_t* m_wsValue; // 0x0010
int m_nValue; // 0x0018
private:
char gap1C[12]; // 0x0020
public:
union // 0x0018
{
int m_iValue;
float m_flValue;
void* m_pValue;
unsigned char m_Color[4];
};
char m_szShortName[8]; // 0x0020
char m_iDataType; // 0x0028
uint16_t m_iKeyNameCaseSensitive2; // 0x002A
KeyValues* m_pPeer; // 0x0030