Skip to content

Commit 40c8c0c

Browse files
committed
Add protectmod and reloadmods console commands
1 parent 7db40e0 commit 40c8c0c

4 files changed

Lines changed: 87 additions & 19 deletions

File tree

include/TConsole.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class TConsole {
5959
void Command_Settings(const std::string& cmd, const std::vector<std::string>& args);
6060
void Command_Clear(const std::string&, const std::vector<std::string>& args);
6161
void Command_Version(const std::string& cmd, const std::vector<std::string>& args);
62+
void Command_ProtectMod(const std::string& cmd, const std::vector<std::string>& args);
63+
void Command_ReloadMods(const std::string& cmd, const std::vector<std::string>& args);
6264

6365
void Command_Say(const std::string& FullCommand);
6466
bool EnsureArgsCount(const std::vector<std::string>& args, size_t n);
@@ -77,6 +79,8 @@ class TConsole {
7779
{ "clear", [this](const auto& a, const auto& b) { Command_Clear(a, b); } },
7880
{ "say", [this](const auto&, const auto&) { Command_Say(""); } }, // shouldn't actually be called
7981
{ "version", [this](const auto& a, const auto& b) { Command_Version(a, b); } },
82+
{ "protectmod", [this](const auto& a, const auto& b) { Command_ProtectMod(a, b); } },
83+
{ "reloadmods", [this](const auto& a, const auto& b) { Command_ReloadMods(a, b); } },
8084
};
8185

8286
std::unique_ptr<Commandline> mCommandline { nullptr };

include/TNetwork.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class TNetwork {
4545
void SendToAll(TClient* c, const std::vector<uint8_t>& Data, bool Self, bool Rel);
4646
void UpdatePlayer(TClient& Client);
4747

48+
TResourceManager& ResourceManager() const { return mResourceManager; }
49+
4850
private:
4951
void UDPServerMain();
5052
void TCPServerMain();

src/TConsole.cpp

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,16 +208,18 @@ void TConsole::Command_Help(const std::string&, const std::vector<std::string>&
208208
}
209209
static constexpr const char* sHelpString = R"(
210210
Commands:
211-
help displays this help
212-
exit shuts down the server
213-
kick <name> [reason] kicks specified player with an optional reason
214-
list lists all players and info about them
215-
say <message> sends the message to all players in chat
216-
lua [state id] switches to lua, optionally into a specific state id's lua
217-
settings [command] sets or gets settings for the server, run `settings help` for more info
218-
status how the server is doing and what it's up to
219-
clear clears the console window
220-
version displays the server version)";
211+
help displays this help
212+
exit shuts down the server
213+
kick <name> [reason] kicks specified player with an optional reason
214+
list lists all players and info about them
215+
say <message> sends the message to all players in chat
216+
lua [state id] switches to lua, optionally into a specific state id's lua
217+
settings [command] sets or gets settings for the server, run `settings help` for more info
218+
status how the server is doing and what it's up to
219+
clear clears the console window
220+
version displays the server version
221+
protectmod <name> <value> sets whether a mod is protected
222+
reloadmods reloads all mods from the Resources Client folder)";
221223
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
222224
}
223225

@@ -262,6 +264,32 @@ void TConsole::Command_Version(const std::string& cmd, const std::vector<std::st
262264
std::string openssl_version = fmt::format("OpenSSL: v{}.{}.{}", OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH);
263265
Application::Console().WriteRaw(openssl_version);
264266
}
267+
void TConsole::Command_ProtectMod(const std::string& cmd, const std::vector<std::string>& args) {
268+
if (!EnsureArgsCount(args, 2)) {
269+
return;
270+
}
271+
272+
const auto& ModName = args.at(0);
273+
const auto& Protect = args.at(1);
274+
275+
for (auto mod : mLuaEngine->Network().ResourceManager().GetMods()) {
276+
if (mod["file_name"].get<std::string>() == ModName) {
277+
mLuaEngine->Network().ResourceManager().SetProtected(ModName, Protect == "true");
278+
Application::Console().WriteRaw("Mod " + ModName + " is now " + (Protect == "true" ? "protected" : "unprotected"));
279+
return;
280+
}
281+
}
282+
283+
Application::Console().WriteRaw("Mod " + ModName + " not found.");
284+
}
285+
void TConsole::Command_ReloadMods(const std::string& cmd, const std::vector<std::string>& args) {
286+
if (!EnsureArgsCount(args, 0)) {
287+
return;
288+
}
289+
290+
mLuaEngine->Network().ResourceManager().RefreshFiles();
291+
Application::Console().WriteRaw("Mods reloaded.");
292+
}
265293

266294
void TConsole::Command_Kick(const std::string&, const std::vector<std::string>& args) {
267295
if (!EnsureArgsCount(args, 1, size_t(-1))) {

src/TResourceManager.cpp

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,11 @@ void TResourceManager::RefreshFiles() {
9898
dbEntry["exists"] = true;
9999

100100
mMods.push_back(nlohmann::json {
101-
{ "file_name", std::filesystem::path(File).filename() },
102-
{ "file_size", std::filesystem::file_size(File) },
103-
{ "hash_algorithm", "sha256" },
104-
{ "hash", dbEntry["hash"] },
105-
{ "protected", dbEntry["protected"] }
106-
});
101+
{ "file_name", std::filesystem::path(File).filename() },
102+
{ "file_size", std::filesystem::file_size(File) },
103+
{ "hash_algorithm", "sha256" },
104+
{ "hash", dbEntry["hash"] },
105+
{ "protected", dbEntry["protected"] } });
107106

108107
beammp_debugf("Mod '{}' loaded from cache", File);
109108

@@ -170,8 +169,7 @@ void TResourceManager::RefreshFiles() {
170169
{ "file_size", std::filesystem::file_size(File) },
171170
{ "hash_algorithm", "sha256" },
172171
{ "hash", result },
173-
{ "protected", false }
174-
});
172+
{ "protected", false } });
175173

176174
modsDB[std::filesystem::path(File).filename().string()] = {
177175
{ "lastwrite", entry.last_write_time().time_since_epoch().count() },
@@ -186,7 +184,7 @@ void TResourceManager::RefreshFiles() {
186184
}
187185
}
188186

189-
for (auto it = modsDB.begin(); it != modsDB.end(); ) {
187+
for (auto it = modsDB.begin(); it != modsDB.end();) {
190188
if (!it.value().contains("exists")) {
191189
it = modsDB.erase(it);
192190
} else {
@@ -205,3 +203,39 @@ void TResourceManager::RefreshFiles() {
205203
beammp_error("Failed to update mod DB: " + std::string(e.what()));
206204
}
207205
}
206+
207+
void TResourceManager::SetProtected(const std::string& ModName, bool Protected) {
208+
std::unique_lock Lock(mModsMutex);
209+
210+
for (auto& mod : mMods) {
211+
if (mod["file_name"].get<std::string>() == ModName) {
212+
mod["protected"] = Protected;
213+
break;
214+
}
215+
}
216+
217+
auto modsDBPath = Application::Settings.getAsString(Settings::Key::General_ResourceFolder) + "/Client/mods.json";
218+
219+
if (std::filesystem::exists(modsDBPath)) {
220+
try {
221+
nlohmann::json modsDB;
222+
223+
std::fstream stream(modsDBPath);
224+
225+
stream >> modsDB;
226+
227+
if (modsDB.contains(ModName)) {
228+
modsDB[ModName]["protected"] = Protected;
229+
}
230+
231+
stream.clear();
232+
stream.seekp(0, std::ios::beg);
233+
234+
stream << modsDB.dump(4);
235+
236+
stream.close();
237+
} catch (const std::exception& e) {
238+
beammp_errorf("Failed to update mods.json: {}", e.what());
239+
}
240+
}
241+
}

0 commit comments

Comments
 (0)