feat: add config

This commit is contained in:
Tsubasa6848
2024-01-20 21:51:55 +08:00
Unverified
parent 8fcb186766
commit b4f9433e7c
7 changed files with 527 additions and 322 deletions
+104 -26
View File
@@ -1,7 +1,12 @@
#include "Config.h"
#include "Global.h"
#include <GMLIB/Event/Entity/ItemActorSpawnEvent.h>
#include <GMLIB/Event/Entity/MobPickupItemEvent.h>
#include <GMLIB/Server/PlayerAPI.h>
#include <regex>
GMLIB_JsonConfig* Config = nullptr;
GMLIB_JsonLanguage* Language = nullptr;
using namespace ll::schedule;
using namespace ll::chrono_literals;
@@ -12,6 +17,19 @@ bool auto_clean_triggerred = false;
namespace Cleaner {
bool isMatch(std::string& A, std::string& B) {
// 如果B是正则表达式
if (B.find_first_of(".*+?()[]{}|^$") != std::string::npos) {
try {
std::regex regex(B);
return std::regex_match(A, regex);
} catch (...) {
return false;
}
}
return (A == B);
}
bool shouldIgnore(GMLIB_Actor* ac) {
if (ac->isMob() || ac->isItemActor()) {
if (ac->isTame() || ac->isTrusting() || ac->getNameTag() != "") {
@@ -34,35 +52,56 @@ bool ShouldClean(Actor* actor) {
auto type = en->getTypeName();
// Items
if (en->isItemActor()) {
return true;
if (true) { // Todo Config Toggle
auto itac = (ItemActor*)en;
auto itemType = itac->item().getTypeName();
if (true) { // Todo Config WhiteList
if (Config->getValue<bool>({"CleanItem", "Enabled"}, false)) {
auto itac = (ItemActor*)en;
if (itac->age() <= Config->getValue<int>({"CleanItem", "ExistTicks"}, 0)) {
return false;
}
auto itemType = itac->item().getTypeName();
auto whitelist = Config->getValue<std::vector<std::string>>({"CleanItem", "Whitelist"}, {});
for (auto& key : whitelist) {
if (isMatch(itemType, key)) {
return false;
}
}
return true;
}
return false;
}
// Mobs
else if (en->isMob()) {
if (true) { // Todo Config Toggle
return true;
if (true) { // Todo WhiteList
return false;
if (Config->getValue<bool>({"CleanMobs", "Enabled"}, false)) {
auto blacklist = Config->getValue<std::vector<std::string>>({"CleanMobs", "Blacklist"}, {});
for (auto& key : blacklist) {
if (isMatch(type, key)) {
return true;
}
}
auto whitelist = Config->getValue<std::vector<std::string>>({"CleanMobs", "Whitelist"}, {});
for (auto& key : whitelist) {
if (isMatch(type, key)) {
return false;
}
}
if (Config->getValue<bool>({"CleanMobs", "CleanMonstors"}, false)
&& en->hasCategory(ActorCategory::Monster)) {
return true;
}
if (Config->getValue<bool>({"CleanMobs", "CleanPeacefulMobs"}, false)) {
return true;
}
return true;
}
return false;
}
// Others
else {
if (true) { // Todo Config Toggle
if (true) { // BlackList
return true;
if (Config->getValue<bool>({"CleanInanimate", "Enabled"}, false)) {
auto blacklist = Config->getValue<std::vector<std::string>>({"CleanInanimate", "Blacklist"}, {});
for (auto& key : blacklist) {
if (isMatch(type, key)) {
return true;
}
}
return false;
}
return false;
}
@@ -94,18 +133,22 @@ int CountEntities() {
void CleanTask(int time, int announce_time) {
auto time_1 = std::chrono::seconds::duration(time);
auto time_2 = std::chrono::seconds::duration(time - announce_time);
logger.info("clean will in {}", time_1);
scheduler.add<DelayTask>(time_2, [announce_time] { logger.info("clean will in {}", announce_time); });
logger.info(Language->translate("cleaner.output.count1", {S(time_1.count())}));
scheduler.add<DelayTask>(time_2, [announce_time] {
logger.info(Language->translate("cleaner.output.count2", {S(announce_time)}));
});
scheduler.add<DelayTask>(time_1, [] {
auto count = ExecuteClean();
logger.info("Successfully cleaned {} entities", count);
logger.info(Language->translate("cleaner.output.finish", {S(count)}));
auto_clean_triggerred = false;
});
}
void AutoCleanTask(int seconds) {
auto time = std::chrono::seconds::duration(seconds);
mAutoCleanTask = scheduler.add<RepeatTask>(time, [] { CleanTask(20, 5); });
mAutoCleanTask = scheduler.add<RepeatTask>(time, [] {
CleanTask(Config->getValue<int>({"Basic", "Notice1"}, 20), Config->getValue<int>({"Basic", "Notice2"}, 15));
});
}
void CheckCleanTask(int max_entities, float min_tps) {
@@ -114,12 +157,21 @@ void CheckCleanTask(int max_entities, float min_tps) {
if (auto_clean_triggerred == false) {
if (count >= max_entities) {
auto_clean_triggerred = true;
logger.warn("Too many entities! Auto started clean task!");
CleanTask(20, 5);
logger.warn(Language->translate("cleaner.output.triggerAutoCleanCount", {S(count)}));
CleanTask(
Config->getValue<int>({"Basic", "Notice1"}, 20),
Config->getValue<int>({"Basic", "Notice2"}, 15)
);
} else if (GMLIB_Level::getLevel()->getServerAverageTps() <= min_tps) {
auto_clean_triggerred = true;
logger.warn("TPS too low! Auto started clean task!");
CleanTask(20, 5);
logger.warn(Language->translate(
"cleaner.output.triggerAutoCleanCount",
{S(GMLIB_Level::getLevel()->getServerAverageTps())}
));
CleanTask(
Config->getValue<int>({"Basic", "Notice1"}, 20),
Config->getValue<int>({"Basic", "Notice2"}, 15)
);
}
}
});
@@ -158,13 +210,39 @@ void ListenEvents() {
);
}
void ReloadCleaner() {
void reloadCleaner() {
unloadCleaner();
loadCleaner();
}
void loadConfig() {
Config = new GMLIB_JsonConfig("./plugins/Cleaner/config/config.json", defaultConfig);
Config->initConfig();
Language = new GMLIB_JsonLanguage("./plugins/Cleaner/config/language.json", defaultLanguage);
Language->initConfig();
}
void loadCleaner() {
ListenEvents();
RegisterCommands();
if (Config->getValue<bool>({"ScheduleClean", "Enabled"}, false)) {
Cleaner::AutoCleanTask(Config->getValue<int>({"ScheduleClean", "CleanInterval"}, 3000));
}
if (Config->getValue<bool>({"AutoCleanCount", "Enabled"}, false)
|| Config->getValue<bool>({"AutoCleanTPS", "Enabled"}, false)) {
Cleaner::CheckCleanTask(
Config->getValue<int>({"AutoCleanCount", "TriggerCount"}, 900),
Config->getValue<int>({"AutoCleanTPS", "TriggerTPS"}, 15)
);
}
}
void unloadCleaner() {
mAutoCleanTask->cancel();
mCheckCleanTask->cancel();
// UnregisterCommands();
// RegisterCommands();
Cleaner::AutoCleanTask(600);
Cleaner::CheckCleanTask(15, 8);
delete Config;
delete Language;
}
} // namespace Cleaner
+134
View File
@@ -0,0 +1,134 @@
#pragma once
#include <GMLIB/Files/JsonConfig.h>
#include <GMLIB/Files/JsonLanguage.h>
inline std::string defaultConfig = R"({
"AutoCleanCount": {
"Enabled": true,
"TriggerCount": 900
},
"AutoCleanTPS": {
"Enabled": false,
"TriggerTPS": 15
},
"Basic": {
"Command": "cleaner",
"ConsoleLog": true,
"Notice1": 20,
"Notice2": 5,
"SendBroadcast": true,
"SendToast": false
},
"ItemDespawn": {
"Enabled": true,
"DespawnTime": 6000,
"WhiteList": [
"minecraft:elytra"
]
},
"CleanInanimate": {
"Blacklist": [
"minecraft:xp_orb",
"minecraft:arrow",
"minecraft:fireball",
"minecraft:small_fireball",
"minecraft:wither_skull",
"minecraft:wither_skull_dangerous",
"minecraft:dragon_fireball"
],
"Enabled": true
},
"CleanItem": {
"Enabled": true,
"ExistTicks": 0,
"Whitelist": [
"minecraft:netherite_helmet",
"minecraft:netherite_sword",
"minecraft:netherite_chestplate",
"minecraft:diamond_helmet",
"minecraft:netherite_leggings",
"minecraft:undyed_shulker_box",
"minecraft:netherite_boots",
"minecraft:shulker_box",
"minecraft:elytra",
"minecraft:dragon_egg",
"minecraft:nether_star",
"minecraft:diamond_sword",
"minecraft:diamond_chestplate",
"minecraft:diamond_boots",
"minecraft:diamond_leggings",
"minecraft:diamond_hoe",
"minecraft:netherite_hoe",
"minecraft:diamond_axe",
"minecraft:netherite_axe",
"minecraft:netherite_pickaxe",
"minecraft:diamond_pickaxe"
]
},
"CleanMobs": {
"BlackList": [
"minecraft:guardian",
"minecraft:zombie_pigman"
],
"CleanMonstors": true,
"CleanPeacefulMobs": false,
"EnableAutoExclude": true,
"Enabled": true,
"IgnoreTags": [
"ignore",
"不清理"
],
"Whitelist": [
"minecraft:ender_dragon",
"minecraft:shulker",
"minecraft:wither",
"minecraft:elder_guardian",
"minecraft:piglin_brute",
"minecraft:ender_pearl",
"minecraft:phantom"
]
},
"ScheduleClean": {
"CleanInterval": 3600,
"Enabled": true
},
"VoteClean": {
"CD": 120,
"Delay": 30,
"Enabled": true,
"Percentage": 50,
"VoteCleanCommand": "voteclean"
}
})";
inline std::string defaultLanguage = R"({
"cleaner.command.cleaner": "Cleaner管理员命令。",
"cleaner.command.despawnSuccess": "已成功清除了 %1$s 个实体",
"cleaner.command.error.noTarget": "没有与选择器匹配的目标",
"cleaner.command.error.playerOnly": "该命令只能由玩家执行!",
"cleaner.command.tps.output": "当前服务器实时TPS %1$s §r,平均TPS %2$s",
"cleaner.command.mspt.output": "当前服务器实MSPT %1$s",
"cleaner.command.voteclean": "发起实体清理投票。",
"cleaner.command.despawntime" : "已成功将物品消失时间设置为 %1$s 游戏刻",
"cleaner.output.count1": "系统将在 %1$s 秒后自动清理服务器实体!",
"cleaner.output.count2": "请注意!系统将在 %1$s 秒后自动清理服务器实体!",
"cleaner.output.finish": "清理完成!本次总共清理了 %1$s 个实体。",
"cleaner.output.opClean": "管理员启用了服务器实体清理。",
"cleaner.output.reload": "已重载Cleaner插件,部分配置可能需要重启服务器才能生效。",
"cleaner.output.triggerAutoCleanCount": "检测到服务器实体过多!!当前服务器存在 %1$s 个可清理实体,已启动自动清理程序。",
"cleaner.output.triggerAutoCleanTps": "当前服务器TPS过低!!服务器平均TPS %1$s\n系统已启动清理程序。",
"cleaner.vote.cooldown": "投票清理冷却...",
"cleaner.vote.cancel": "投票已取消!",
"cleaner.vote.confirmNo": "我再想想",
"cleaner.vote.confirmOk": "发起投票",
"cleaner.vote.confirmTubtitle": "你是否要发起投票清理?",
"cleaner.vote.accept": "你已同意实体清理。",
"cleaner.vote.deny": "你已拒绝实体清理。",
"cleaner.vote.no": "拒绝",
"cleaner.vote.ok": "同意",
"cleaner.vote.Subtitle": "你是否同意现在清理服务器实体?",
"cleaner.vote.Timeout": "投票已过期!",
"cleaner.vote.succeed": "投票清理成功!",
"cleaner.vote.title": "投票清理",
"cleaner.vote.toastNotice": "通知"
})";
+12 -5
View File
@@ -1,23 +1,30 @@
#pragma once
#include "Config.h"
#include "Plugin.h"
#include "include_all.h"
#include <GMLIB/Server/ActorAPI.h>
#include <GMLIB/Server/LevelAPI.h>
#include <GMLIB/Files/JsonConfig.h>
#include <GMLIB/Files/JsonLanguage.h>
#define S(x) std::to_string(x)
extern ll::Logger logger;
extern void RegisterCommands();
extern void UnregisterCommands();
extern GMLIB_JsonConfig* Config;
extern GMLIB_JsonLanguage* Language;
extern int item_despawn_time;
namespace Cleaner {
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::ServerClock>> mAutoCleanTask;
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::ServerClock>> mCheckCleanTask;
extern void CleanTask(int time, int announce_time);
extern void AutoCleanTask(int seconds);
extern void CheckCleanTask(int max_entities, float min_tps);
extern void ReloadCleaner();
extern void ListenEvents();
extern void loadConfig();
extern void loadCleaner();
extern void unloadCleaner();
extern void reloadCleaner();
extern void CleanTask(int time, int announce_time);
} // namespace Cleaner
+3 -8
View File
@@ -6,13 +6,11 @@ namespace plugin {
Plugin::Plugin(ll::plugin::NativePlugin& self) : mSelf(self) {
// Code for loading the plugin goes here.
Cleaner::loadConfig();
}
bool Plugin::enable() {
Cleaner::ListenEvents();
RegisterCommands();
Cleaner::AutoCleanTask(300);
Cleaner::CheckCleanTask(20, 15);
Cleaner::loadCleaner();
logger.info("Cleaner Loaded!");
logger.info("Author: Tsubasa6848");
logger.info("Repository: https://github.com/GroupMountain/Cleaner");
@@ -20,11 +18,8 @@ bool Plugin::enable() {
}
bool Plugin::disable() {
logger.info("Disabling Cleaner...");
// Code for disabling the plugin goes here.
Cleaner::mAutoCleanTask->cancel();
Cleaner::mCheckCleanTask->cancel();
UnregisterCommands();
Cleaner::unloadCleaner();
logger.info("Cleaner Disabled!");
return true;
}
+22 -32
View File
@@ -17,8 +17,8 @@ void RegVoteCommand(CommandRegistry& registry) {
void RegCleanerCommand(CommandRegistry& registry) {
auto command = DynamicCommand::createCommand(
registry,
"cleaner",
"Cleaner plugin settings",
Config->getValue<std::string>({"Basic", "Command"}, "cleaner"),
Language->translate("cleaner.command.cleaner"),
CommandPermissionLevel::GameDirectors
);
command->setEnum("Despawn", {"despawn"});
@@ -40,53 +40,43 @@ void RegCleanerCommand(CommandRegistry& registry) {
if (result["despawn"].isSet && result["target"].isSet) {
auto ens = result["target"].get<std::vector<Actor*>>();
if (ens.size() == 0) {
return output.error("No matched targets found!");
return output.error(Language->translate("cleaner.command.error.noTarget"));
}
for (auto en : ens) {
en->despawn();
}
return output.success("Successfully despawned {} entities", ens.size());
return output.success(Language->translate("cleaner.command.despawnSuccess", {S(ens.size())}));
} else if (result["action"].isSet) {
auto act = result["action"].get<std::string>();
if (act == "tps") {
return output.success(
"current tps {}, average tps {}",
GMLIB_Level::getLevel()->getServerCurrentTps(),
GMLIB_Level::getLevel()->getServerAverageTps()
);
return output.success(Language->translate(
"cleaner.command.tps.output",
{S(GMLIB_Level::getLevel()->getServerCurrentTps()),
S(GMLIB_Level::getLevel()->getServerAverageTps())}
));
} else if (act == "mspt") {
return output.success("mspt {}", GMLIB_Level::getLevel()->getServerMspt());
return output.success(
Language->translate("cleaner.command.mspt.output", {S(GMLIB_Level::getLevel()->getServerMspt())})
);
} else if (act == "clean") {
output.success("Clean task started!");
Cleaner::CleanTask(20, 5); // Config
output.success(Language->translate("cleaner.output.opClean"));
Cleaner::CleanTask(
Config->getValue<int>({"Basic", "Notice1"}, 20),
Config->getValue<int>({"Basic", "Notice2"}, 15)
); // Config
return;
} else if (act == "reload") {
output.success("Reloading Cleaner ...");
Cleaner::ReloadCleaner();
return output.success("Cleaner Reloaded!");
Cleaner::reloadCleaner();
return output.success(Language->translate("cleaner.output.reload"));
}
} else if (result["despawntime"].isSet && result["ticks"].isSet) {
item_despawn_time = result["ticks"].get<int>();
return output.success("Successfully set deapawn time to {}", item_despawn_time);
return output.success(Language->translate("cleaner.command.despawntime", {S(item_despawn_time)}));
}
});
DynamicCommand::setup(registry, std::move(command));
}
void RegDespawnCommand(CommandRegistry& registry) {
auto command = DynamicCommand::createCommand(registry, "despawn", "despawn entities", CommandPermissionLevel::Any);
command->mandatory("target", ParamType::Actor);
command->addOverload({"target"});
command->addOverload();
command->setCallback([](DynamicCommand const& cmd,
CommandOrigin const& origin,
CommandOutput& output,
std::unordered_map<std::string, DynamicCommand::Result>& result) {
});
DynamicCommand::setup(registry, std::move(command));
}
void RegisterCommands() {
auto registry = ll::service::bedrock::getCommandRegistry();
RegCleanerCommand(registry);
@@ -95,6 +85,6 @@ void RegisterCommands() {
void UnregisterCommands() {
auto registry = ll::service::bedrock::getCommandRegistry();
registry->unregisterCommand("cleaner");
registry->unregisterCommand("voteclean");
registry->unregisterCommand(Config->getValue<std::string>({"Basic", "Command"}, "cleaner"));
// registry->unregisterCommand("voteclean");
}
+248 -247
View File
File diff suppressed because it is too large Load Diff