mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-05 23:58:24 -08:00
feat: Add Automatic Gamedata Updates (#925)
This commit is contained in:
@@ -5,6 +5,9 @@ project(counterstrikesharp C CXX ASM)
|
||||
|
||||
include("makefiles/shared.cmake")
|
||||
|
||||
# Find OpenSSL for httplib SSL support
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
add_subdirectory(libraries/spdlog)
|
||||
@@ -43,6 +46,8 @@ set(SOURCE_FILES
|
||||
src/core/coreconfig.cpp
|
||||
src/core/gameconfig.h
|
||||
src/core/gameconfig.cpp
|
||||
src/core/gameconfig_updater.h
|
||||
src/core/gameconfig_updater.cpp
|
||||
src/core/log.h
|
||||
src/core/log.cpp
|
||||
src/scripting/script_engine.h
|
||||
|
||||
@@ -6,5 +6,7 @@
|
||||
"PluginAutoLoadEnabled": true,
|
||||
"ServerLanguage": "en",
|
||||
"UnlockConCommands": true,
|
||||
"UnlockConVars": true
|
||||
"UnlockConVars": true,
|
||||
"AutoUpdateEnabled": true,
|
||||
"AutoUpdateURL": "https://gamedata.cssharp.dev"
|
||||
}
|
||||
@@ -47,3 +47,10 @@ When enabled, will remove the `FCVAR_HIDDEN`,`FCVAR_DEVELOPMENTONLY`, `FCVAR_MIS
|
||||
## UnlockConVars
|
||||
|
||||
When enabled, will remove the `FCVAR_HIDDEN`,`FCVAR_DEVELOPMENTONLY`, `FCVAR_MISSING0`, `FCVAR_MISSING1`, `FCVAR_MISSING2`, `FCVAR_MISSING3` flags from all console variables.
|
||||
|
||||
## AutoUpdateEnabled
|
||||
|
||||
When enabled, CS# will check for any updates to the gamedata.json file and automatically update it if a new version is available.
|
||||
|
||||
## AutoUpdateURL
|
||||
The URL to use for the auto-update feature. This URL should point to a JSON file that contains the latest version of the gamedata.json file.
|
||||
12818
libraries/httplib/httplib.h
Normal file
12818
libraries/httplib/httplib.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -29,4 +29,6 @@ set(
|
||||
distorm
|
||||
funchook-static
|
||||
dynohook
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
)
|
||||
|
||||
@@ -19,4 +19,6 @@ set(COUNTER_STRIKE_SHARP_LINK_LIBRARIES
|
||||
distorm
|
||||
funchook-static
|
||||
dynohook
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
)
|
||||
|
||||
@@ -61,6 +61,12 @@ namespace CounterStrikeSharp.API.Core
|
||||
|
||||
[JsonPropertyName("UnlockConVars")]
|
||||
public bool UnlockConVars { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("AutoUpdateEnabled")]
|
||||
public bool AutoUpdateEnabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("AutoUpdateURL")]
|
||||
public string AutoUpdateURL { get; set; } = "https://gamedata.cssharp.dev";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,7 +163,7 @@ namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<CoreConfigData>(File.ReadAllText(_coreConfigPath),
|
||||
new JsonSerializerOptions() { ReadCommentHandling = JsonCommentHandling.Skip });
|
||||
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
_coreConfig = data;
|
||||
|
||||
@@ -60,6 +60,8 @@ bool CCoreConfig::Init(char* conf_error, int conf_error_size)
|
||||
ServerLanguage = m_json.value("ServerLanguage", ServerLanguage);
|
||||
UnlockConCommands = m_json.value("UnlockConCommands", UnlockConCommands);
|
||||
UnlockConVars = m_json.value("UnlockConVars", UnlockConVars);
|
||||
AutoUpdateEnabled = m_json.value("AutoUpdateEnabled", AutoUpdateEnabled);
|
||||
AutoUpdateURL = m_json.value("AutoUpdateURL", AutoUpdateURL);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,8 @@ class CCoreConfig
|
||||
std::string ServerLanguage = "en";
|
||||
bool UnlockConCommands = true;
|
||||
bool UnlockConVars = true;
|
||||
bool AutoUpdateEnabled = true;
|
||||
std::string AutoUpdateURL = std::string("https://gamedata.cssharp.dev");
|
||||
|
||||
using json = nlohmann::json;
|
||||
CCoreConfig(const std::string& path);
|
||||
|
||||
82
src/core/gameconfig_updater.cpp
Normal file
82
src/core/gameconfig_updater.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "core/gameconfig_updater.h"
|
||||
#include "core/utils.h"
|
||||
#include "core/coreconfig.h"
|
||||
#include "core/log.h"
|
||||
#include "core/globals.h"
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
#include "httplib/httplib.h"
|
||||
|
||||
namespace counterstrikesharp::update {
|
||||
|
||||
/// @brief
|
||||
/// Attempts to update the game configuration by checking the ETag of the remote gamedata.json file.
|
||||
/// If the ETag has changed, it downloads the new gamedata.json and updates the local
|
||||
/// etag file with the new ETag.
|
||||
/// @return
|
||||
bool TryUpdateGameConfig()
|
||||
{
|
||||
auto gamedata_path = std::string(utils::GamedataDirectory() + "/gamedata.json");
|
||||
auto etag_path = std::string(utils::GamedataDirectory() + "/gamedata.etag");
|
||||
|
||||
httplib::Client client(globals::coreConfig->AutoUpdateURL);
|
||||
client.set_follow_location(true);
|
||||
client.set_read_timeout(10, 0);
|
||||
|
||||
auto headRes = client.Head("/");
|
||||
if (!headRes || headRes->status != 200)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto etag = headRes->get_header_value("ETag");
|
||||
std::string localETag = "";
|
||||
if (std::filesystem::exists(etag_path))
|
||||
{
|
||||
std::ifstream etag_file(etag_path);
|
||||
if (etag_file.is_open())
|
||||
{
|
||||
std::getline(etag_file, localETag);
|
||||
etag_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (etag == localETag)
|
||||
{
|
||||
CSSHARP_CORE_INFO("Gamedata is up to date, ETag: {}", etag);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto res = client.Get("/");
|
||||
if (res && res->status == 200)
|
||||
{
|
||||
auto etag = res->get_header_value("ETag");
|
||||
|
||||
std::ofstream gamedata_file(gamedata_path);
|
||||
if (gamedata_file.is_open())
|
||||
{
|
||||
gamedata_file << res->body;
|
||||
gamedata_file.close();
|
||||
CSSHARP_CORE_INFO("Gamedata file written to: {} with ETag {}", gamedata_path, res->get_header_value("ETag"));
|
||||
}
|
||||
|
||||
std::ofstream etag_file_out(etag_path);
|
||||
if (etag_file_out.is_open())
|
||||
{
|
||||
etag_file_out << etag;
|
||||
etag_file_out.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSSHARP_CORE_ERROR("Failed to connect to the auto update server at: {}", globals::coreConfig->AutoUpdateURL);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace counterstrikesharp::update
|
||||
5
src/core/gameconfig_updater.h
Normal file
5
src/core/gameconfig_updater.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace counterstrikesharp::update {
|
||||
bool TryUpdateGameConfig();
|
||||
} // namespace counterstrikesharp::update
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "core/coreconfig.h"
|
||||
#include "core/game_system.h"
|
||||
#include "core/gameconfig.h"
|
||||
#include "core/gameconfig_updater.h"
|
||||
#include "core/global_listener.h"
|
||||
#include "core/log.h"
|
||||
#include "core/managers/entity_manager.h"
|
||||
@@ -117,6 +118,16 @@ bool CounterStrikeSharpMMPlugin::Load(PluginId id, ISmmAPI* ismm, char* error, s
|
||||
|
||||
CSSHARP_CORE_INFO("CoreConfig loaded.");
|
||||
|
||||
if (globals::coreConfig->AutoUpdateEnabled)
|
||||
{
|
||||
CSSHARP_CORE_INFO("AutoUpdate enabled, checking for gamedata updates...");
|
||||
|
||||
if (!update::TryUpdateGameConfig())
|
||||
{
|
||||
CSSHARP_CORE_ERROR("Failed to update game config.");
|
||||
}
|
||||
}
|
||||
|
||||
auto gamedata_path = std::string(utils::GamedataDirectory() + "/gamedata.json");
|
||||
globals::gameConfig = new CGameConfig(gamedata_path);
|
||||
char conf_error[255] = "";
|
||||
|
||||
Reference in New Issue
Block a user