diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 85f506b6..9fe4a11c 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -122,11 +122,13 @@ #include "game/server/gameinterface.h" #include "game/server/movehelper_server.h" #include "game/server/physics_main.h" +#include "game/server/vscript_server.h" #endif // !CLIENT_DLL #ifndef DEDICATED #include "game/client/viewrender.h" #include "game/client/input.h" #include "game/client/movehelper_client.h" +#include "game/client/vscript_client.h" #endif // !DEDICATED #include "public/edict.h" #ifndef DEDICATED @@ -197,12 +199,18 @@ void Systems_Init() // Script context registration callbacks. #ifndef CLIENT_DLL ServerScriptRegister_Callback = Script_RegisterServerFunctions; + CoreServerScriptRegister_Callback = Script_RegisterCoreServerFunctions; + AdminPanelScriptRegister_Callback = Script_RegisterAdminPanelFunctions; #endif // !CLIENT_DLL #ifndef SERVER_DLL ClientScriptRegister_Callback = Script_RegisterClientFunctions; UiScriptRegister_Callback = Script_RegisterUIFunctions; #endif // !SERVER_DLL + +#ifdef CLIENT_DLL + g_bClientDLL = true; +#endif } ////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/engine/client/cl_main.h b/r5dev/engine/client/cl_main.h index 74278853..f7394048 100644 --- a/r5dev/engine/client/cl_main.h +++ b/r5dev/engine/client/cl_main.h @@ -15,6 +15,13 @@ inline int(*CL_ClearState)(void); inline CMemory p_CL_RunPrediction; inline void(*CL_RunPrediction)(void); +inline bool g_bClientDLL = false; + +// Returns true if this is a dedicated server. +inline bool IsClientDLL() +{ + return g_bClientDLL; +} /////////////////////////////////////////////////////////////////////////////// class VCL_Main : public IDetour diff --git a/r5dev/game/client/vscript_client.cpp b/r5dev/game/client/vscript_client.cpp index d29d06d9..c7ce1955 100644 --- a/r5dev/game/client/vscript_client.cpp +++ b/r5dev/game/client/vscript_client.cpp @@ -12,17 +12,17 @@ #include "vpc/keyvalues.h" #include "engine/cmodel_bsp.h" #include "engine/host_state.h" +#include "engine/client/cl_main.h" #include "networksystem/pylon.h" #include "networksystem/listmanager.h" #include "game/shared/vscript_shared.h" #include "vscript/languages/squirrel_re/include/sqvm.h" +#include "vscript_client.h" + namespace VScriptCode { namespace Client - { - } - namespace Ui { //----------------------------------------------------------------------------- // Purpose: refreshes the server list @@ -37,6 +37,68 @@ namespace VScriptCode return SQ_OK; } + //----------------------------------------------------------------------------- + // Purpose: get current server count from pylon + //----------------------------------------------------------------------------- + SQRESULT GetServerCount(HSQUIRRELVM v) + { + size_t iCount = g_pServerListManager->m_vServerList.size(); + sq_pushinteger(v, static_cast(iCount)); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: get response from private server request + //----------------------------------------------------------------------------- + SQRESULT GetHiddenServerName(HSQUIRRELVM v) + { + SQChar* privateToken = sq_getstring(v, 1); + + if (!VALID_CHARSTAR(privateToken)) + return SQ_OK; + + string hiddenServerRequestMessage; + NetGameServer_t serverListing; + + bool result = g_pMasterServer->GetServerByToken(serverListing, hiddenServerRequestMessage, privateToken); // Send token connect request. + if (!result) + { + if (hiddenServerRequestMessage.empty()) + { + sq_pushstring(v, "Request failed", -1); + } + else + { + hiddenServerRequestMessage = Format("Request failed: %s", hiddenServerRequestMessage.c_str()); + sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); + } + + return SQ_OK; + } + + if (serverListing.m_svHostName.empty()) + { + if (hiddenServerRequestMessage.empty()) + { + hiddenServerRequestMessage = Format("Server listing empty"); + } + else + { + hiddenServerRequestMessage = Format("Server listing empty: %s", hiddenServerRequestMessage.c_str()); + } + + sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); + } + else + { + hiddenServerRequestMessage = Format("Found server: %s", serverListing.m_svHostName.c_str()); + sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); + } + + return SQ_OK; + } + //----------------------------------------------------------------------------- // Purpose: get server's current name from serverlist index //----------------------------------------------------------------------------- @@ -169,17 +231,6 @@ namespace VScriptCode return SQ_OK; } - //----------------------------------------------------------------------------- - // Purpose: get current server count from pylon - //----------------------------------------------------------------------------- - SQRESULT GetServerCount(HSQUIRRELVM v) - { - size_t iCount = g_pServerListManager->m_vServerList.size(); - sq_pushinteger(v, static_cast(iCount)); - - return SQ_OK; - } - //----------------------------------------------------------------------------- // Purpose: get promo data for serverbrowser panels //----------------------------------------------------------------------------- @@ -241,47 +292,6 @@ namespace VScriptCode return SQ_OK; } - //----------------------------------------------------------------------------- - // Purpose: create server via native serverbrowser entries - // TODO: return a boolean on failure instead of raising an error, so we could - // determine from scripts whether or not to spin a local server, or connect - // to a dedicated server (for disconnecting and loading the lobby, for example) - //----------------------------------------------------------------------------- - SQRESULT CreateServer(HSQUIRRELVM v) - { -#ifndef CLIENT_DLL - SQChar* serverName = sq_getstring(v, 1); - SQChar* serverDescription = sq_getstring(v, 2); - SQChar* serverMapName = sq_getstring(v, 3); - SQChar* serverPlaylist = sq_getstring(v, 4); - EServerVisibility_t eServerVisibility = static_cast(sq_getinteger(v, 5)); - - if (!VALID_CHARSTAR(serverName) || - !VALID_CHARSTAR(serverMapName) || - !VALID_CHARSTAR(serverPlaylist)) - { - return SQ_OK; - } - - // Adjust browser settings. - std::lock_guard l(g_pServerListManager->m_Mutex); - - g_pServerListManager->m_Server.m_svHostName = serverName; - g_pServerListManager->m_Server.m_svDescription = serverDescription; - g_pServerListManager->m_Server.m_svHostMap = serverMapName; - g_pServerListManager->m_Server.m_svPlaylist = serverPlaylist; - g_pServerListManager->m_ServerVisibility = eServerVisibility; - - // Launch server. - g_pServerListManager->LaunchServer(); - - return SQ_OK; -#else - v_SQVM_RaiseError(v, "\"%s\" is not supported for client builds.\n", "CreateServer"); - return SQ_ERROR; -#endif - } - //----------------------------------------------------------------------------- // Purpose: connect to server from native server browser entries //----------------------------------------------------------------------------- @@ -350,53 +360,11 @@ namespace VScriptCode } //----------------------------------------------------------------------------- - // Purpose: get response from private server request + // Purpose: checks whether this SDK build is a client dll //----------------------------------------------------------------------------- - SQRESULT GetHiddenServerName(HSQUIRRELVM v) + SQRESULT IsClientDLL(HSQUIRRELVM v) { - SQChar* privateToken = sq_getstring(v, 1); - - if (!VALID_CHARSTAR(privateToken)) - return SQ_OK; - - string hiddenServerRequestMessage; - NetGameServer_t serverListing; - - bool result = g_pMasterServer->GetServerByToken(serverListing, hiddenServerRequestMessage, privateToken); // Send token connect request. - if (!result) - { - if (hiddenServerRequestMessage.empty()) - { - sq_pushstring(v, "Request failed", -1); - } - else - { - hiddenServerRequestMessage = Format("Request failed: %s", hiddenServerRequestMessage.c_str()); - sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); - } - - return SQ_OK; - } - - if (serverListing.m_svHostName.empty()) - { - if (hiddenServerRequestMessage.empty()) - { - hiddenServerRequestMessage = Format("Server listing empty"); - } - else - { - hiddenServerRequestMessage = Format("Server listing empty: %s", hiddenServerRequestMessage.c_str()); - } - - sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); - } - else - { - hiddenServerRequestMessage = Format("Found server: %s", serverListing.m_svHostName.c_str()); - sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1); - } - + sq_pushbool(v, ::IsClientDLL()); return SQ_OK; } } @@ -408,14 +376,8 @@ namespace VScriptCode //--------------------------------------------------------------------------------- void Script_RegisterClientFunctions(CSquirrelVM* s) { - s->RegisterFunction("SDKNativeTest", "Script_SDKNativeTest", "Native CLIENT test function", "void", "", &VScriptCode::Shared::SDKNativeTest); - s->RegisterFunction("GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VScriptCode::Shared::GetSDKVersion); - - s->RegisterFunction("GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VScriptCode::Shared::GetAvailableMaps); - s->RegisterFunction("GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VScriptCode::Shared::GetAvailablePlaylists); - - s->RegisterFunction("ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VScriptCode::Shared::ShutdownHostGame); - s->RegisterFunction("IsClientDLL", "Script_IsClientDLL", "Returns whether this build is client only", "bool", "", &VScriptCode::Shared::IsClientDLL); + Script_RegisterCommonAbstractions(s); + Script_RegisterCoreClientFunctions(s); } //--------------------------------------------------------------------------------- @@ -424,47 +386,37 @@ void Script_RegisterClientFunctions(CSquirrelVM* s) //--------------------------------------------------------------------------------- void Script_RegisterUIFunctions(CSquirrelVM* s) { - s->RegisterFunction("SDKNativeTest", "Script_SDKNativeTest", "Native UI test function", "void", "", &VScriptCode::Shared::SDKNativeTest); - s->RegisterFunction("GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VScriptCode::Shared::GetSDKVersion); + Script_RegisterCommonAbstractions(s); + Script_RegisterCoreClientFunctions(s); - s->RegisterFunction("RefreshServerList", "Script_RefreshServerList", "Refreshes the public server list and returns the count", "int", "", &VScriptCode::Ui::RefreshServerCount); + s->RegisterFunction("RefreshServerList", "Script_RefreshServerList", "Refreshes the public server list and returns the count", "int", "", &VScriptCode::Client::RefreshServerCount); + s->RegisterFunction("GetServerCount", "Script_GetServerCount", "Gets the number of public servers", "int", "", &VScriptCode::Client::GetServerCount); // Functions for retrieving server browser data - s->RegisterFunction("GetServerName", "Script_GetServerName", "Gets the name of the server at the specified index of the server list", "string", "int", &VScriptCode::Ui::GetServerName); - s->RegisterFunction("GetServerDescription", "Script_GetServerDescription", "Gets the description of the server at the specified index of the server list", "string", "int", &VScriptCode::Ui::GetServerDescription); - s->RegisterFunction("GetServerMap", "Script_GetServerMap", "Gets the map of the server at the specified index of the server list", "string", "int", &VScriptCode::Ui::GetServerMap); - s->RegisterFunction("GetServerPlaylist", "Script_GetServerPlaylist", "Gets the playlist of the server at the specified index of the server list", "string", "int", &VScriptCode::Ui::GetServerPlaylist); - s->RegisterFunction("GetServerCurrentPlayers", "Script_GetServerCurrentPlayers", "Gets the current player count of the server at the specified index of the server list", "int", "int", &VScriptCode::Ui::GetServerCurrentPlayers); - s->RegisterFunction("GetServerMaxPlayers", "Script_GetServerMaxPlayers", "Gets the max player count of the server at the specified index of the server list", "int", "int", &VScriptCode::Ui::GetServerMaxPlayers); - s->RegisterFunction("GetServerCount", "Script_GetServerCount", "Gets the number of public servers", "int", "", &VScriptCode::Ui::GetServerCount); + s->RegisterFunction("GetHiddenServerName", "Script_GetHiddenServerName", "Gets hidden server name by token", "string", "string", &VScriptCode::Client::GetHiddenServerName); + s->RegisterFunction("GetServerName", "Script_GetServerName", "Gets the name of the server at the specified index of the server list", "string", "int", &VScriptCode::Client::GetServerName); + s->RegisterFunction("GetServerDescription", "Script_GetServerDescription", "Gets the description of the server at the specified index of the server list", "string", "int", &VScriptCode::Client::GetServerDescription); + + s->RegisterFunction("GetServerMap", "Script_GetServerMap", "Gets the map of the server at the specified index of the server list", "string", "int", &VScriptCode::Client::GetServerMap); + s->RegisterFunction("GetServerPlaylist", "Script_GetServerPlaylist", "Gets the playlist of the server at the specified index of the server list", "string", "int", &VScriptCode::Client::GetServerPlaylist); + s->RegisterFunction("GetServerCurrentPlayers", "Script_GetServerCurrentPlayers", "Gets the current player count of the server at the specified index of the server list", "int", "int", &VScriptCode::Client::GetServerCurrentPlayers); + + s->RegisterFunction("GetServerMaxPlayers", "Script_GetServerMaxPlayers", "Gets the max player count of the server at the specified index of the server list", "int", "int", &VScriptCode::Client::GetServerMaxPlayers); // Misc main menu functions - s->RegisterFunction("GetPromoData", "Script_GetPromoData", "Gets promo data for specified slot type", "string", "int", &VScriptCode::Ui::GetPromoData); - - // Functions for creating servers - s->RegisterFunction("CreateServer", "Script_CreateServer", "Starts server with the specified settings", "void", "string, string, string, string, int", &VScriptCode::Ui::CreateServer); - s->RegisterFunction("IsServerActive", "Script_IsServerActive", "Returns whether the server is active", "bool", "", &VScriptCode::Shared::IsServerActive); + s->RegisterFunction("GetPromoData", "Script_GetPromoData", "Gets promo data for specified slot type", "string", "int", &VScriptCode::Client::GetPromoData); // Functions for connecting to servers - s->RegisterFunction("ConnectToServer", "Script_ConnectToServer", "Joins server by ip address and encryption key", "void", "string, string", &VScriptCode::Ui::ConnectToServer); - s->RegisterFunction("ConnectToListedServer", "Script_ConnectToListedServer", "Joins listed server by index", "void", "int", &VScriptCode::Ui::ConnectToListedServer); - s->RegisterFunction("ConnectToHiddenServer", "Script_ConnectToHiddenServer", "Joins hidden server by token", "void", "string", &VScriptCode::Ui::ConnectToHiddenServer); - - s->RegisterFunction("GetHiddenServerName", "Script_GetHiddenServerName", "Gets hidden server name by token", "string", "string", &VScriptCode::Ui::GetHiddenServerName); - s->RegisterFunction("GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VScriptCode::Shared::GetAvailableMaps); - s->RegisterFunction("GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VScriptCode::Shared::GetAvailablePlaylists); - -#ifndef CLIENT_DLL // UI 'admin' functions controlling server code - s->RegisterFunction("KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VScriptCode::SHARED::KickPlayerByName); - s->RegisterFunction("KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VScriptCode::SHARED::KickPlayerById); - - s->RegisterFunction("BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VScriptCode::SHARED::BanPlayerByName); - s->RegisterFunction("BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VScriptCode::SHARED::BanPlayerById); - - s->RegisterFunction("UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VScriptCode::SHARED::UnbanPlayer); - - s->RegisterFunction("ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VScriptCode::SHARED::ShutdownHostGame); -#endif // !CLIENT_DLL - - s->RegisterFunction("IsClientDLL", "Script_IsClientDLL", "Returns whether this build is client only", "bool", "", &VScriptCode::Shared::IsClientDLL); + s->RegisterFunction("ConnectToServer", "Script_ConnectToServer", "Joins server by ip address and encryption key", "void", "string, string", &VScriptCode::Client::ConnectToServer); + s->RegisterFunction("ConnectToListedServer", "Script_ConnectToListedServer", "Joins listed server by index", "void", "int", &VScriptCode::Client::ConnectToListedServer); + s->RegisterFunction("ConnectToHiddenServer", "Script_ConnectToHiddenServer", "Joins hidden server by token", "void", "string", &VScriptCode::Client::ConnectToHiddenServer); +} + +//--------------------------------------------------------------------------------- +// Purpose: core client script functions +// Input : *s - +//--------------------------------------------------------------------------------- +void Script_RegisterCoreClientFunctions(CSquirrelVM* s) +{ + s->RegisterFunction("IsClientDLL", "Script_IsClientDLL", "Returns whether this build is client only", "bool", "", &VScriptCode::Client::IsClientDLL); } diff --git a/r5dev/game/client/vscript_client.h b/r5dev/game/client/vscript_client.h index e69de29b..4009126e 100644 --- a/r5dev/game/client/vscript_client.h +++ b/r5dev/game/client/vscript_client.h @@ -0,0 +1,35 @@ +#ifndef VSCRIPT_CLIENT_H +#define VSCRIPT_CLIENT_H + +namespace VScriptCode +{ + namespace Client + { + SQRESULT RefreshServerCount(HSQUIRRELVM v); + SQRESULT GetServerCount(HSQUIRRELVM v); + + SQRESULT GetHiddenServerName(HSQUIRRELVM v); + SQRESULT GetServerName(HSQUIRRELVM v); + SQRESULT GetServerDescription(HSQUIRRELVM v); + + SQRESULT GetServerMap(HSQUIRRELVM v); + SQRESULT GetServerPlaylist(HSQUIRRELVM v); + + SQRESULT GetServerCurrentPlayers(HSQUIRRELVM v); + SQRESULT GetServerMaxPlayers(HSQUIRRELVM v); + + SQRESULT GetPromoData(HSQUIRRELVM v); + + SQRESULT ConnectToListedServer(HSQUIRRELVM v); + SQRESULT ConnectToHiddenServer(HSQUIRRELVM v); + SQRESULT ConnectToServer(HSQUIRRELVM v); + + SQRESULT IsClientDLL(HSQUIRRELVM v); + } +} + +void Script_RegisterClientFunctions(CSquirrelVM* s); +void Script_RegisterUIFunctions(CSquirrelVM* s); +void Script_RegisterCoreClientFunctions(CSquirrelVM* s); + +#endif // VSCRIPT_CLIENT_H diff --git a/r5dev/game/server/vscript_server.cpp b/r5dev/game/server/vscript_server.cpp index 563741f4..219133fe 100644 --- a/r5dev/game/server/vscript_server.cpp +++ b/r5dev/game/server/vscript_server.cpp @@ -13,10 +13,142 @@ #include "game/shared/vscript_shared.h" #include "vscript/languages/squirrel_re/include/sqvm.h" +#include "vscript_server.h" +#include +#include + namespace VScriptCode { namespace Server { + //----------------------------------------------------------------------------- + // Purpose: create server via native serverbrowser entries + // TODO: return a boolean on failure instead of raising an error, so we could + // determine from scripts whether or not to spin a local server, or connect + // to a dedicated server (for disconnecting and loading the lobby, for example) + //----------------------------------------------------------------------------- + SQRESULT CreateServer(HSQUIRRELVM v) + { + SQChar* serverName = sq_getstring(v, 1); + SQChar* serverDescription = sq_getstring(v, 2); + SQChar* serverMapName = sq_getstring(v, 3); + SQChar* serverPlaylist = sq_getstring(v, 4); + EServerVisibility_t eServerVisibility = static_cast(sq_getinteger(v, 5)); + + if (!VALID_CHARSTAR(serverName) || + !VALID_CHARSTAR(serverMapName) || + !VALID_CHARSTAR(serverPlaylist)) + { + return SQ_OK; + } + + // Adjust browser settings. + std::lock_guard l(g_pServerListManager->m_Mutex); + + g_pServerListManager->m_Server.m_svHostName = serverName; + g_pServerListManager->m_Server.m_svDescription = serverDescription; + g_pServerListManager->m_Server.m_svHostMap = serverMapName; + g_pServerListManager->m_Server.m_svPlaylist = serverPlaylist; + g_pServerListManager->m_ServerVisibility = eServerVisibility; + + // Launch server. + g_pServerListManager->LaunchServer(g_pServer->IsActive()); + + return SQ_OK; + + //v_SQVM_RaiseError(v, "\"%s\" is not supported on client builds.\n", "CreateServer"); + //return SQ_ERROR; + } + //----------------------------------------------------------------------------- + // Purpose: shuts the server down and disconnects all clients + //----------------------------------------------------------------------------- + SQRESULT DestroyServer(HSQUIRRELVM v) + { + if (g_pHostState->m_bActiveGame) + g_pHostState->m_iNextState = HostStates_t::HS_GAME_SHUTDOWN; + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: kicks a player by given name + //----------------------------------------------------------------------------- + SQRESULT KickPlayerByName(HSQUIRRELVM v) + { + SQChar* playerName = sq_getstring(v, 1); + SQChar* reason = sq_getstring(v, 2); + + // Discard empty strings, this will use the default message instead. + if (!VALID_CHARSTAR(reason)) + reason = nullptr; + + g_pBanSystem->KickPlayerByName(playerName, reason); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: kicks a player by given handle or id + //----------------------------------------------------------------------------- + SQRESULT KickPlayerById(HSQUIRRELVM v) + { + SQChar* playerHandle = sq_getstring(v, 1); + SQChar* reason = sq_getstring(v, 2); + + // Discard empty strings, this will use the default message instead. + if (!VALID_CHARSTAR(reason)) + reason = nullptr; + + g_pBanSystem->KickPlayerById(playerHandle, reason); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: bans a player by given name + //----------------------------------------------------------------------------- + SQRESULT BanPlayerByName(HSQUIRRELVM v) + { + SQChar* playerName = sq_getstring(v, 1); + SQChar* reason = sq_getstring(v, 2); + + // Discard empty strings, this will use the default message instead. + if (!VALID_CHARSTAR(reason)) + reason = nullptr; + + g_pBanSystem->BanPlayerByName(playerName, reason); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: bans a player by given handle or id + //----------------------------------------------------------------------------- + SQRESULT BanPlayerById(HSQUIRRELVM v) + { + SQChar* playerHandle = sq_getstring(v, 1); + SQChar* reason = sq_getstring(v, 2); + + // Discard empty strings, this will use the default message instead. + if (!VALID_CHARSTAR(reason)) + reason = nullptr; + + g_pBanSystem->BanPlayerById(playerHandle, reason); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: unbans a player by given nucleus id or ip address + //----------------------------------------------------------------------------- + SQRESULT UnbanPlayer(HSQUIRRELVM v) + { + SQChar* szCriteria = sq_getstring(v, 1); + g_pBanSystem->UnbanPlayer(szCriteria); + + return SQ_OK; + } + //----------------------------------------------------------------------------- // Purpose: gets the number of real players on this server //----------------------------------------------------------------------------- @@ -35,6 +167,17 @@ namespace VScriptCode return SQ_OK; } + //----------------------------------------------------------------------------- + // Purpose: checks whether the server is active + //----------------------------------------------------------------------------- + SQRESULT IsServerActive(HSQUIRRELVM v) + { + bool isActive = g_pServer->IsActive(); + + sq_pushbool(v, isActive); + return SQ_OK; + } + //----------------------------------------------------------------------------- // Purpose: checks whether this SDK build is a dedicated server //----------------------------------------------------------------------------- @@ -52,24 +195,38 @@ namespace VScriptCode //--------------------------------------------------------------------------------- void Script_RegisterServerFunctions(CSquirrelVM* s) { - s->RegisterFunction("SDKNativeTest", "Script_SDKNativeTest", "Native SERVER test function", "void", "", &VScriptCode::Shared::SDKNativeTest); - s->RegisterFunction("GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VScriptCode::Shared::GetSDKVersion); + Script_RegisterCommonAbstractions(s); + Script_RegisterCoreServerFunctions(s); + Script_RegisterAdminPanelFunctions(s); +} +//--------------------------------------------------------------------------------- +// Purpose: core server script functions +// Input : *s - +//--------------------------------------------------------------------------------- +void Script_RegisterCoreServerFunctions(CSquirrelVM* s) +{ + s->RegisterFunction("IsServerActive", "Script_IsServerActive", "Returns whether the server is active", "bool", "", &VScriptCode::Server::IsServerActive); + s->RegisterFunction("IsDedicated", "Script_IsDedicated", "Returns whether this is a dedicated server", "bool", "", &VScriptCode::Server::IsDedicated); + + s->RegisterFunction("CreateServer", "Script_CreateServer", "Starts server with the specified settings", "void", "string, string, string, string, int", &VScriptCode::Server::CreateServer); + s->RegisterFunction("DestroyServer", "Script_DestroyServer", "Shuts the local host game down", "void", "", &VScriptCode::Server::DestroyServer); +} + +//--------------------------------------------------------------------------------- +// Purpose: admin panel script functions +// Input : *s - +//--------------------------------------------------------------------------------- +void Script_RegisterAdminPanelFunctions(CSquirrelVM* s) +{ s->RegisterFunction("GetNumHumanPlayers", "Script_GetNumHumanPlayers", "Gets the number of human players on the server", "int", "", &VScriptCode::Server::GetNumHumanPlayers); s->RegisterFunction("GetNumFakeClients", "Script_GetNumFakeClients", "Gets the number of bot players on the server", "int", "", &VScriptCode::Server::GetNumFakeClients); - s->RegisterFunction("GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VScriptCode::Shared::GetAvailableMaps); - s->RegisterFunction("GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VScriptCode::Shared::GetAvailablePlaylists); + s->RegisterFunction("KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VScriptCode::Server::KickPlayerByName); + s->RegisterFunction("KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VScriptCode::Server::KickPlayerById); - s->RegisterFunction("KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string, string", &VScriptCode::Shared::KickPlayerByName); - s->RegisterFunction("KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string, string", &VScriptCode::Shared::KickPlayerById); + s->RegisterFunction("BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VScriptCode::Server::BanPlayerByName); + s->RegisterFunction("BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VScriptCode::Server::BanPlayerById); - s->RegisterFunction("BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VScriptCode::Shared::BanPlayerByName); - s->RegisterFunction("BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string, string", &VScriptCode::Shared::BanPlayerById); - - s->RegisterFunction("UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string, string", &VScriptCode::Shared::UnbanPlayer); - - s->RegisterFunction("ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VScriptCode::Shared::ShutdownHostGame); - - s->RegisterFunction("IsDedicated", "Script_IsDedicated", "Returns whether this is a dedicated server", "bool", "", &VScriptCode::Server::IsDedicated); + s->RegisterFunction("UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VScriptCode::Server::UnbanPlayer); } diff --git a/r5dev/game/server/vscript_server.h b/r5dev/game/server/vscript_server.h index e69de29b..ed82598d 100644 --- a/r5dev/game/server/vscript_server.h +++ b/r5dev/game/server/vscript_server.h @@ -0,0 +1,29 @@ +#ifndef VSCRIPT_SERVER_H +#define VSCRIPT_SERVER_H + +namespace VScriptCode +{ + namespace Server + { + SQRESULT CreateServer(HSQUIRRELVM v); + SQRESULT DestroyServer(HSQUIRRELVM v); + + SQRESULT KickPlayerByName(HSQUIRRELVM v); + SQRESULT KickPlayerById(HSQUIRRELVM v); + SQRESULT BanPlayerByName(HSQUIRRELVM v); + SQRESULT BanPlayerById(HSQUIRRELVM v); + SQRESULT UnbanPlayer(HSQUIRRELVM v); + + SQRESULT GetNumHumanPlayers(HSQUIRRELVM v); + SQRESULT GetNumFakeClients(HSQUIRRELVM v); + + SQRESULT IsServerActive(HSQUIRRELVM v); + SQRESULT IsDedicated(HSQUIRRELVM v); + } +} + +void Script_RegisterServerFunctions(CSquirrelVM* s); +void Script_RegisterCoreServerFunctions(CSquirrelVM* s); +void Script_RegisterAdminPanelFunctions(CSquirrelVM* s); + +#endif // VSCRIPT_SERVER_H diff --git a/r5dev/game/shared/vscript_shared.cpp b/r5dev/game/shared/vscript_shared.cpp index 0e951046..25c9b167 100644 --- a/r5dev/game/shared/vscript_shared.cpp +++ b/r5dev/game/shared/vscript_shared.cpp @@ -13,18 +13,12 @@ #include "core/stdafx.h" #include "vpc/keyvalues.h" -#ifndef CLIENT_DLL #include "engine/server/server.h" -#endif // CLIENT_DLL #include "engine/cmodel_bsp.h" #include "engine/host_state.h" #include "networksystem/pylon.h" -#ifndef CLIENT_DLL #include "networksystem/bansystem.h" -#endif // !CLIENT_DLL -#ifndef SERVER_DLL #include "networksystem/listmanager.h" -#endif // !SERVER_DLL #include "vscript_shared.h" #include "vscript/languages/squirrel_re/include/sqvm.h" @@ -32,15 +26,6 @@ namespace VScriptCode { namespace Shared { - //----------------------------------------------------------------------------- - // Purpose: SDK test and example body - //----------------------------------------------------------------------------- - SQRESULT SDKNativeTest(HSQUIRRELVM v) - { - // Function code goes here. - return SQ_OK; - } - //----------------------------------------------------------------------------- // Purpose: expose SDK version to the VScript API //----------------------------------------------------------------------------- @@ -89,123 +74,17 @@ namespace VScriptCode return SQ_OK; } - //----------------------------------------------------------------------------- - // Purpose: checks whether the server is active - //----------------------------------------------------------------------------- - SQRESULT IsServerActive(HSQUIRRELVM v) - { - bool isActive = false; -#ifndef CLIENT_DLL - isActive = g_pServer->IsActive(); -#endif // !CLIENT_DLL - - sq_pushbool(v, isActive); - return SQ_OK; - } -#ifndef CLIENT_DLL - - //----------------------------------------------------------------------------- - // Purpose: kicks a player by given name - //----------------------------------------------------------------------------- - SQRESULT KickPlayerByName(HSQUIRRELVM v) - { - SQChar* playerName = sq_getstring(v, 1); - SQChar* reason = sq_getstring(v, 2); - - // Discard empty strings, this will use the default message instead. - if (!VALID_CHARSTAR(reason)) - reason = nullptr; - - g_pBanSystem->KickPlayerByName(playerName, reason); - - return SQ_OK; - } - - //----------------------------------------------------------------------------- - // Purpose: kicks a player by given handle or id - //----------------------------------------------------------------------------- - SQRESULT KickPlayerById(HSQUIRRELVM v) - { - SQChar* playerHandle = sq_getstring(v, 1); - SQChar* reason = sq_getstring(v, 2); - - // Discard empty strings, this will use the default message instead. - if (!VALID_CHARSTAR(reason)) - reason = nullptr; - - g_pBanSystem->KickPlayerById(playerHandle, reason); - - return SQ_OK; - } - - //----------------------------------------------------------------------------- - // Purpose: bans a player by given name - //----------------------------------------------------------------------------- - SQRESULT BanPlayerByName(HSQUIRRELVM v) - { - SQChar* playerName = sq_getstring(v, 1); - SQChar* reason = sq_getstring(v, 2); - - // Discard empty strings, this will use the default message instead. - if (!VALID_CHARSTAR(reason)) - reason = nullptr; - - g_pBanSystem->BanPlayerByName(playerName, reason); - - return SQ_OK; - } - - //----------------------------------------------------------------------------- - // Purpose: bans a player by given handle or id - //----------------------------------------------------------------------------- - SQRESULT BanPlayerById(HSQUIRRELVM v) - { - SQChar* playerHandle = sq_getstring(v, 1); - SQChar* reason = sq_getstring(v, 2); - - // Discard empty strings, this will use the default message instead. - if (!VALID_CHARSTAR(reason)) - reason = nullptr; - - g_pBanSystem->BanPlayerById(playerHandle, reason); - - return SQ_OK; - } - - //----------------------------------------------------------------------------- - // Purpose: unbans a player by given nucleus id or ip address - //----------------------------------------------------------------------------- - SQRESULT UnbanPlayer(HSQUIRRELVM v) - { - SQChar* szCriteria = sq_getstring(v, 1); - g_pBanSystem->UnbanPlayer(szCriteria); - - return SQ_OK; - } -#endif // !CLIENT_DLL - //----------------------------------------------------------------------------- - // Purpose: shutdown local game (host only) - //----------------------------------------------------------------------------- - SQRESULT ShutdownHostGame(HSQUIRRELVM v) - { - if (g_pHostState->m_bActiveGame) - g_pHostState->m_iNextState = HostStates_t::HS_GAME_SHUTDOWN; - - return SQ_OK; - } - - //----------------------------------------------------------------------------- - // Purpose: checks whether this SDK build is a client dll - //----------------------------------------------------------------------------- - SQRESULT IsClientDLL(HSQUIRRELVM v) - { -#ifdef CLIENT_DLL - constexpr SQBool bClientOnly = true; -#else - constexpr SQBool bClientOnly = false; -#endif - sq_pushbool(v, bClientOnly); - return SQ_OK; - } } } + +//--------------------------------------------------------------------------------- +// Purpose: common script abstractions +// Input : *s - +//--------------------------------------------------------------------------------- +void Script_RegisterCommonAbstractions(CSquirrelVM* s) +{ + s->RegisterFunction("GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VScriptCode::Shared::GetSDKVersion); + + s->RegisterFunction("GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VScriptCode::Shared::GetAvailableMaps); + s->RegisterFunction("GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VScriptCode::Shared::GetAvailablePlaylists); +} diff --git a/r5dev/game/shared/vscript_shared.h b/r5dev/game/shared/vscript_shared.h index 2abb9ccf..fd579a22 100644 --- a/r5dev/game/shared/vscript_shared.h +++ b/r5dev/game/shared/vscript_shared.h @@ -9,74 +9,20 @@ inline void*(*Script_Remote_BeginRegisteringFunctions)(void); inline CMemory p_RestoreRemoteChecksumsFromSaveGame; inline void*(*RestoreRemoteChecksumsFromSaveGame)(void* a1, void* a2); -#ifndef CLIENT_DLL inline uint32_t* g_nServerRemoteChecksum = nullptr; -#endif // !CLIENT_DLL -#ifndef SERVER_DLL inline uint32_t* g_nClientRemoteChecksum = nullptr; -#endif // !SERVER_DLL namespace VScriptCode { namespace Shared { - SQRESULT SDKNativeTest(HSQUIRRELVM v); SQRESULT GetSDKVersion(HSQUIRRELVM v); SQRESULT GetAvailableMaps(HSQUIRRELVM v); SQRESULT GetAvailablePlaylists(HSQUIRRELVM v); - SQRESULT ShutdownHostGame(HSQUIRRELVM v); -#ifndef SERVER_DLL - SQRESULT IsClientDLL(HSQUIRRELVM v); -#endif // !SERVER_DLL - SQRESULT IsServerActive(HSQUIRRELVM v); -#ifndef CLIENT_DLL - SQRESULT KickPlayerByName(HSQUIRRELVM v); - SQRESULT KickPlayerById(HSQUIRRELVM v); - SQRESULT BanPlayerByName(HSQUIRRELVM v); - SQRESULT BanPlayerById(HSQUIRRELVM v); - SQRESULT UnbanPlayer(HSQUIRRELVM v); -#endif // !CLIENT_DLL } -#ifndef CLIENT_DLL - namespace Server - { - SQRESULT GetNumHumanPlayers(HSQUIRRELVM v); - SQRESULT GetNumFakeClients(HSQUIRRELVM v); - SQRESULT IsDedicated(HSQUIRRELVM v); - } -#endif // !CLIENT_DLL -#ifndef SERVER_DLL - namespace Client - { - } - namespace Ui - { - SQRESULT RefreshServerCount(HSQUIRRELVM v); - SQRESULT GetServerName(HSQUIRRELVM v); - SQRESULT GetServerDescription(HSQUIRRELVM v); - SQRESULT GetServerMap(HSQUIRRELVM v); - SQRESULT GetServerPlaylist(HSQUIRRELVM v); - SQRESULT GetServerCurrentPlayers(HSQUIRRELVM v); - SQRESULT GetServerMaxPlayers(HSQUIRRELVM v); - SQRESULT GetServerCount(HSQUIRRELVM v); - SQRESULT GetPromoData(HSQUIRRELVM v); - SQRESULT ConnectToListedServer(HSQUIRRELVM v); - SQRESULT CreateServer(HSQUIRRELVM v); - SQRESULT ConnectToHiddenServer(HSQUIRRELVM v); - SQRESULT GetHiddenServerName(HSQUIRRELVM v); - SQRESULT ConnectToServer(HSQUIRRELVM v); - } -#endif // !SERVER_DLL } -#ifndef CLIENT_DLL -void Script_RegisterServerFunctions(CSquirrelVM* s); -#endif // !CLIENT_DLL - -#ifndef SERVER_DLL -void Script_RegisterClientFunctions(CSquirrelVM* s); -void Script_RegisterUIFunctions(CSquirrelVM* s); -#endif // !SERVER_DLL +void Script_RegisterCommonAbstractions(CSquirrelVM* s); /////////////////////////////////////////////////////////////////////////////// class VScriptShared : public IDetour @@ -85,12 +31,8 @@ class VScriptShared : public IDetour { LogFunAdr("Remote_BeginRegisteringFunctions", p_Script_Remote_BeginRegisteringFunctions.GetPtr()); LogFunAdr("RestoreRemoteChecksumsFromSaveGame", p_RestoreRemoteChecksumsFromSaveGame.GetPtr()); -#ifndef CLIENT_DLL LogVarAdr("g_nServerRemoteChecksum", reinterpret_cast(g_nServerRemoteChecksum)); -#endif // !CLIENT_DLL -#ifndef SERVER_DLL LogVarAdr("g_nClientRemoteChecksum", reinterpret_cast(g_nClientRemoteChecksum)); -#endif // !SERVER_DLL } virtual void GetFun(void) const { @@ -102,12 +44,8 @@ class VScriptShared : public IDetour } virtual void GetVar(void) const { -#ifndef CLIENT_DLL g_nServerRemoteChecksum = p_RestoreRemoteChecksumsFromSaveGame.Offset(0x1C0).FindPatternSelf("48 8D 15", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); -#endif // !CLIENT_DLL -#ifndef SERVER_DLL g_nClientRemoteChecksum = p_Script_Remote_BeginRegisteringFunctions.Offset(0x0).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast(); -#endif // !SERVER_DLL } virtual void GetCon(void) const { } virtual void Attach(void) const { } diff --git a/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp b/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp index 76d069ac..990141f2 100644 --- a/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp +++ b/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp @@ -13,6 +13,10 @@ void(*ServerScriptRegister_Callback)(CSquirrelVM* s) = nullptr; void(*ClientScriptRegister_Callback)(CSquirrelVM* s) = nullptr; void(*UiScriptRegister_Callback)(CSquirrelVM* s) = nullptr; +// Admin panel functions, NULL on client only builds. +void(*CoreServerScriptRegister_Callback)(CSquirrelVM* s) = nullptr; +void(*AdminPanelScriptRegister_Callback)(CSquirrelVM* s) = nullptr; + //--------------------------------------------------------------------------------- // Purpose: Initialises a Squirrel VM instance // Output : True on success, false on failure @@ -29,28 +33,32 @@ SQBool CSquirrelVM::Init(CSquirrelVM* s, SQCONTEXT context, SQFloat curTime) switch (context) { -#ifndef CLIENT_DLL case SQCONTEXT::SERVER: g_pServerScript = s; + if (ServerScriptRegister_Callback) ServerScriptRegister_Callback(s); break; -#endif -#ifndef DEDICATED case SQCONTEXT::CLIENT: g_pClientScript = s; + if (ClientScriptRegister_Callback) ClientScriptRegister_Callback(s); break; case SQCONTEXT::UI: g_pUIScript = s; + if (UiScriptRegister_Callback) UiScriptRegister_Callback(s); + if (CoreServerScriptRegister_Callback) + CoreServerScriptRegister_Callback(s); + if (AdminPanelScriptRegister_Callback) + AdminPanelScriptRegister_Callback(s); + break; -#endif } return true; @@ -110,21 +118,17 @@ void CSquirrelVM::SetAsCompiler(RSON::Node_t* rson) const SQCONTEXT context = GetContext(); switch (context) { -#ifndef CLIENT_DLL case SQCONTEXT::SERVER: { v_Script_SetServerPrecompiler(context, rson); break; } -#endif -#ifndef DEDICATED case SQCONTEXT::CLIENT: case SQCONTEXT::UI: { v_Script_SetClientPrecompiler(context, rson); break; } -#endif } } @@ -187,21 +191,17 @@ void CSquirrelVM::CompileModScripts() switch (GetVM()->GetContext()) { -#ifndef CLIENT_DLL case SQCONTEXT::SERVER: { v_CSquirrelVM_PrecompileServerScripts(this, GetContext(), (char**)scriptPathArray, scriptCount); break; } -#endif -#ifndef DEDICATED case SQCONTEXT::CLIENT: case SQCONTEXT::UI: { v_CSquirrelVM_PrecompileClientScripts(this, GetContext(), (char**)scriptPathArray, scriptCount); break; } -#endif } // clean up our allocated script paths diff --git a/r5dev/vscript/languages/squirrel_re/vsquirrel.h b/r5dev/vscript/languages/squirrel_re/vsquirrel.h index 2ef9c871..94fe8d8b 100644 --- a/r5dev/vscript/languages/squirrel_re/vsquirrel.h +++ b/r5dev/vscript/languages/squirrel_re/vsquirrel.h @@ -47,6 +47,9 @@ extern void(*ServerScriptRegister_Callback)(CSquirrelVM* s); extern void(*ClientScriptRegister_Callback)(CSquirrelVM* s); extern void(*UiScriptRegister_Callback)(CSquirrelVM* s); +extern void(*CoreServerScriptRegister_Callback)(CSquirrelVM* s); +extern void(*AdminPanelScriptRegister_Callback)(CSquirrelVM* s); + inline CMemory p_CSquirrelVM_Init; inline bool(*v_CSquirrelVM_Init)(CSquirrelVM* s, SQCONTEXT context, SQFloat curtime);