feat: clean logic
This commit is contained in:
+8
-3
@@ -1,5 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "Cleaner",
|
"name": "${pluginName}",
|
||||||
"entry": "Cleaner.dll",
|
"entry": "${pluginFile}",
|
||||||
"type": "native"
|
"type": "native",
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "GMLIB"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
+69
-29
@@ -1,39 +1,42 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
#include <GMLIB/Event/Entity/ItemActorSpawnEvent.h>
|
||||||
|
#include <GMLIB/Event/Entity/MobPickupItemEvent.h>
|
||||||
|
#include <GMLIB/Server/PlayerAPI.h>
|
||||||
|
|
||||||
using namespace ll::schedule;
|
using namespace ll::schedule;
|
||||||
using namespace ll::chrono_literals;
|
using namespace ll::chrono_literals;
|
||||||
|
int item_despawn_time = 3000;
|
||||||
|
|
||||||
GameTimeAsyncScheduler scheduler;
|
ServerTimeAsyncScheduler scheduler;
|
||||||
bool auto_clean_triggerred = false;
|
bool auto_clean_triggerred = false;
|
||||||
|
|
||||||
namespace Cleaner {
|
namespace Cleaner {
|
||||||
|
|
||||||
bool isDeathDrop(ItemActor* itac) {
|
bool shouldIgnore(GMLIB_Actor* ac) {
|
||||||
//
|
if (ac->isMob() || ac->isItemActor()) {
|
||||||
return false;
|
if (ac->isTame() || ac->isTrusting() || ac->getNameTag() != "") {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
bool shouldIgnoreMob(Actor* ac) {
|
auto nbt = ac->getNbt();
|
||||||
if (ac->isTame() || ac->isTrusting() || ac->getNameTag() != "") {
|
if (nbt->getByte("ShowBottom") == 1) { // End Crystal Used Only, if has this tag 1b, it is modified by cleaner.
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldClean(Actor* en) {
|
bool ShouldClean(Actor* actor) {
|
||||||
// Players
|
// Players
|
||||||
if (en->isType(ActorType::Player)) {
|
auto en = (GMLIB_Actor*)actor;
|
||||||
|
if (en->isPlayer() || shouldIgnore(en)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto type = en->getTypeName();
|
auto type = en->getTypeName();
|
||||||
// Items
|
// Items
|
||||||
if (en->hasCategory(ActorCategory::Item)) {
|
if (en->isItemActor()) {
|
||||||
|
return true;
|
||||||
if (true) { // Todo Config Toggle
|
if (true) { // Todo Config Toggle
|
||||||
auto itac = (ItemActor*)en;
|
auto itac = (ItemActor*)en;
|
||||||
if (isDeathDrop(itac)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto itemType = itac->item().getTypeName();
|
auto itemType = itac->item().getTypeName();
|
||||||
if (true) { // Todo Config WhiteList
|
if (true) { // Todo Config WhiteList
|
||||||
return false;
|
return false;
|
||||||
@@ -43,12 +46,8 @@ bool ShouldClean(Actor* en) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Mobs
|
// Mobs
|
||||||
else if (en->hasCategory(ActorCategory::Mob)) {
|
else if (en->isMob()) {
|
||||||
if (true) { // Todo Config Toggle
|
if (true) { // Todo Config Toggle
|
||||||
if (shouldIgnoreMob(en)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Test
|
|
||||||
return true;
|
return true;
|
||||||
if (true) { // Todo WhiteList
|
if (true) { // Todo WhiteList
|
||||||
return false;
|
return false;
|
||||||
@@ -71,7 +70,7 @@ bool ShouldClean(Actor* en) {
|
|||||||
|
|
||||||
int ExecuteClean() {
|
int ExecuteClean() {
|
||||||
int clean_count = 0;
|
int clean_count = 0;
|
||||||
auto all_entities = ll::service::bedrock::getLevel()->getRuntimeActorList();
|
auto all_entities = GMLIB_Level::getLevel()->getAllEntities();
|
||||||
for (auto entity : all_entities) {
|
for (auto entity : all_entities) {
|
||||||
if (ShouldClean(entity)) {
|
if (ShouldClean(entity)) {
|
||||||
entity->despawn();
|
entity->despawn();
|
||||||
@@ -83,7 +82,7 @@ int ExecuteClean() {
|
|||||||
|
|
||||||
int CountEntities() {
|
int CountEntities() {
|
||||||
int clean_count = 0;
|
int clean_count = 0;
|
||||||
auto all_entities = ll::service::bedrock::getLevel()->getRuntimeActorList();
|
auto all_entities = GMLIB_Level::getLevel()->getAllEntities();
|
||||||
for (auto entity : all_entities) {
|
for (auto entity : all_entities) {
|
||||||
if (ShouldClean(entity)) {
|
if (ShouldClean(entity)) {
|
||||||
clean_count++;
|
clean_count++;
|
||||||
@@ -105,19 +104,19 @@ void CleanTask(int time, int announce_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AutoCleanTask(int seconds) {
|
void AutoCleanTask(int seconds) {
|
||||||
auto time = std::chrono::seconds::duration(seconds);
|
auto time = std::chrono::seconds::duration(seconds);
|
||||||
auto_clean_task = scheduler.add<RepeatTask>(time, [] { CleanTask(20, 5); });
|
mAutoCleanTask = scheduler.add<RepeatTask>(time, [] { CleanTask(20, 5); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckCleanTask(int max_entities, float min_tps) {
|
void CheckCleanTask(int max_entities, float min_tps) {
|
||||||
check_clean_task = scheduler.add<RepeatTask>(10s, [max_entities, min_tps] {
|
mCheckCleanTask = scheduler.add<RepeatTask>(10s, [max_entities, min_tps] {
|
||||||
auto count = CountEntities();
|
auto count = CountEntities();
|
||||||
if (auto_clean_triggerred == false) {
|
if (auto_clean_triggerred == false) {
|
||||||
if (count >= max_entities) {
|
if (count >= max_entities) {
|
||||||
auto_clean_triggerred = true;
|
auto_clean_triggerred = true;
|
||||||
logger.warn("Too many entities! Auto started clean task!");
|
logger.warn("Too many entities! Auto started clean task!");
|
||||||
CleanTask(20, 5);
|
CleanTask(20, 5);
|
||||||
} else if (TPS::getAverageTps() <= min_tps) {
|
} else if (GMLIB_Level::getLevel()->getServerAverageTps() <= min_tps) {
|
||||||
auto_clean_triggerred = true;
|
auto_clean_triggerred = true;
|
||||||
logger.warn("TPS too low! Auto started clean task!");
|
logger.warn("TPS too low! Auto started clean task!");
|
||||||
CleanTask(20, 5);
|
CleanTask(20, 5);
|
||||||
@@ -126,5 +125,46 @@ void CheckCleanTask(int max_entities, float min_tps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setShouldIgnore(GMLIB_Actor* ac) {
|
||||||
|
auto nbt = ac->getNbt();
|
||||||
|
nbt->put("ShowBottom", ByteTag(1));
|
||||||
|
ac->setNbt(*nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListenEvents() {
|
||||||
|
auto eventBus = &ll::event::EventBus::getInstance();
|
||||||
|
// ItemSpawnEvent
|
||||||
|
eventBus->emplaceListener<GMLIB::Event::EntityEvent::ItemActorSpawnAfterEvent>(
|
||||||
|
[](GMLIB::Event::EntityEvent::ItemActorSpawnAfterEvent& event) {
|
||||||
|
auto& item = event.getItemActor();
|
||||||
|
auto pl = (GMLIB_Player*)event.getSpawner();
|
||||||
|
if (pl) {
|
||||||
|
if (pl->isPlayer() && !pl->isAlive()) { // Death Drop
|
||||||
|
auto ac = (GMLIB_Actor*)&item;
|
||||||
|
setShouldIgnore(ac);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.lifeTime() = item_despawn_time;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// MobTakeItemEvent
|
||||||
|
eventBus->emplaceListener<GMLIB::Event::EntityEvent::MobPickupItemAfterEvent>(
|
||||||
|
[](GMLIB::Event::EntityEvent::MobPickupItemAfterEvent& event) {
|
||||||
|
// auto item = event.getItemActor().item().getTypeName();
|
||||||
|
auto mob = (GMLIB_Actor*)&event.self();
|
||||||
|
setShouldIgnore(mob);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReloadCleaner() {
|
||||||
|
mAutoCleanTask->cancel();
|
||||||
|
mCheckCleanTask->cancel();
|
||||||
|
// UnregisterCommands();
|
||||||
|
// RegisterCommands();
|
||||||
|
Cleaner::AutoCleanTask(600);
|
||||||
|
Cleaner::CheckCleanTask(15, 8);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cleaner
|
} // namespace Cleaner
|
||||||
+14
-14
@@ -1,23 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
#include "include_all.h"
|
#include "include_all.h"
|
||||||
|
#include <GMLIB/Server/ActorAPI.h>
|
||||||
|
#include <GMLIB/Server/LevelAPI.h>
|
||||||
|
|
||||||
extern ll::Logger logger;
|
extern ll::Logger logger;
|
||||||
extern void RegisterCommands();
|
extern void RegisterCommands();
|
||||||
extern void UnregisterCommands();
|
extern void UnregisterCommands();
|
||||||
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::GameTimeClock>> auto_clean_task;
|
|
||||||
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::GameTimeClock>> check_clean_task;
|
|
||||||
extern int item_despawn_time;
|
extern int item_despawn_time;
|
||||||
|
|
||||||
namespace Cleaner {
|
namespace Cleaner {
|
||||||
extern void CleanTask(int time, int announce_time);
|
|
||||||
extern void AutoCleanTask(int seconds);
|
|
||||||
extern void CheckCleanTask(int max_entities, float min_tps);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace TPS {
|
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::ServerClock>> mAutoCleanTask;
|
||||||
extern void CaculateTPS();
|
static std::shared_ptr<ll::schedule::task::Task<ll::chrono::ServerClock>> mCheckCleanTask;
|
||||||
extern float getCurrentTps();
|
extern void CleanTask(int time, int announce_time);
|
||||||
extern float getAverageTps();
|
extern void AutoCleanTask(int seconds);
|
||||||
extern float getMspt();
|
extern void CheckCleanTask(int max_entities, float min_tps);
|
||||||
}
|
extern void ReloadCleaner();
|
||||||
|
extern void ListenEvents();
|
||||||
|
|
||||||
|
} // namespace Cleaner
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#include "Global.h"
|
|
||||||
|
|
||||||
int item_despawn_time = 3000;
|
|
||||||
|
|
||||||
LL_AUTO_TYPED_INSTANCE_HOOK(
|
|
||||||
ItemSpawnEventHook,
|
|
||||||
ll::memory::HookPriority::Normal,
|
|
||||||
Spawner,
|
|
||||||
"?spawnItem@Spawner@@QEAAPEAVItemActor@@AEAVBlockSource@@AEBVItemStack@@PEAVActor@@AEBVVec3@@H@Z",
|
|
||||||
ItemActor*,
|
|
||||||
class BlockSource& region,
|
|
||||||
class ItemStack const& item,
|
|
||||||
class Actor* spawner,
|
|
||||||
class Vec3 const& pos,
|
|
||||||
int throwTime
|
|
||||||
) {
|
|
||||||
auto itac = origin(region, item, spawner, pos, throwTime);
|
|
||||||
if (itac) {
|
|
||||||
if (spawner) {
|
|
||||||
if (spawner->isType(ActorType::Player)) {
|
|
||||||
if (!spawner->isAlive()) {
|
|
||||||
// Death Drop
|
|
||||||
return itac;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itac->mLifeTime = item_despawn_time;
|
|
||||||
}
|
|
||||||
return itac;
|
|
||||||
}
|
|
||||||
|
|
||||||
LL_AUTO_TYPED_INSTANCE_HOOK(
|
|
||||||
ItemTakeEventHook,
|
|
||||||
ll::memory::HookPriority::Normal,
|
|
||||||
Actor,
|
|
||||||
"?pickUpItem@Actor@@QEAAXAEAVItemActor@@H@Z",
|
|
||||||
void,
|
|
||||||
class ItemActor& itemActor, int count
|
|
||||||
) {
|
|
||||||
logger.warn("pickup item {}", this->getTypeName());
|
|
||||||
return origin(itemActor,count);
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#include "Global.h"
|
|
||||||
|
|
||||||
typedef std::chrono::high_resolution_clock timer_clock;
|
|
||||||
#define TIMER_START auto start = timer_clock::now();
|
|
||||||
#define TIMER_END \
|
|
||||||
auto elapsed = timer_clock::now() - start; \
|
|
||||||
long long timeReslut = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
|
|
||||||
|
|
||||||
uint ticks = 0;
|
|
||||||
float average_tps = 0;
|
|
||||||
double mspt = 0;
|
|
||||||
bool culculate_mspt = false;
|
|
||||||
std::list<ushort> avrtps = {};
|
|
||||||
|
|
||||||
LL_AUTO_TYPED_INSTANCE_HOOK(LevelTickHook, ll::memory::HookPriority::Normal, Level, "?tick@Level@@UEAAXXZ", void) {
|
|
||||||
ticks++;
|
|
||||||
TIMER_START
|
|
||||||
origin();
|
|
||||||
TIMER_END
|
|
||||||
culculate_mspt = true;
|
|
||||||
if (culculate_mspt) {
|
|
||||||
mspt = (double)timeReslut / 1000;
|
|
||||||
culculate_mspt = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace TPS {
|
|
||||||
|
|
||||||
void CaculateTPS() {
|
|
||||||
std::thread([] {
|
|
||||||
while (true) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
culculate_mspt = true;
|
|
||||||
avrtps.push_back(ticks);
|
|
||||||
ticks = 0;
|
|
||||||
if (avrtps.size() >= 60) {
|
|
||||||
avrtps.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
uint ticks_minute = 0;
|
|
||||||
for (auto i : avrtps) {
|
|
||||||
ticks_minute = ticks_minute + i;
|
|
||||||
}
|
|
||||||
float res = (float)ticks_minute / ((float)avrtps.size());
|
|
||||||
average_tps = res >= 20 ? 20 : res;
|
|
||||||
}
|
|
||||||
}).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
float getCurrentTps() { return mspt <= 50 ? 20 : (float)(1000.0 / mspt); }
|
|
||||||
|
|
||||||
float getAverageTps() { return average_tps; }
|
|
||||||
|
|
||||||
float getMspt() { return mspt; }
|
|
||||||
|
|
||||||
} // namespace TPS
|
|
||||||
+4
-3
@@ -9,10 +9,9 @@ Plugin::Plugin(ll::plugin::NativePlugin& self) : mSelf(self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Plugin::enable() {
|
bool Plugin::enable() {
|
||||||
TPS::CaculateTPS();
|
Cleaner::ListenEvents();
|
||||||
RegisterCommands();
|
RegisterCommands();
|
||||||
item_despawn_time = 300;
|
Cleaner::AutoCleanTask(300);
|
||||||
Cleaner::AutoCleanTask(60);
|
|
||||||
Cleaner::CheckCleanTask(20, 15);
|
Cleaner::CheckCleanTask(20, 15);
|
||||||
logger.info("Cleaner Loaded!");
|
logger.info("Cleaner Loaded!");
|
||||||
logger.info("Author: Tsubasa6848");
|
logger.info("Author: Tsubasa6848");
|
||||||
@@ -23,6 +22,8 @@ bool Plugin::enable() {
|
|||||||
bool Plugin::disable() {
|
bool Plugin::disable() {
|
||||||
logger.info("Disabling Cleaner...");
|
logger.info("Disabling Cleaner...");
|
||||||
// Code for disabling the plugin goes here.
|
// Code for disabling the plugin goes here.
|
||||||
|
Cleaner::mAutoCleanTask->cancel();
|
||||||
|
Cleaner::mCheckCleanTask->cancel();
|
||||||
UnregisterCommands();
|
UnregisterCommands();
|
||||||
logger.info("Cleaner Disabled!");
|
logger.info("Cleaner Disabled!");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,95 +1,100 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
|
||||||
using ParamType = DynamicCommand::ParameterType;
|
using ParamType = DynamicCommand::ParameterType;
|
||||||
|
|
||||||
void RegVoteCommand(CommandRegistry& registry) {
|
void RegVoteCommand(CommandRegistry& registry) {
|
||||||
auto command = DynamicCommand::createCommand(registry, "voteclean", "Clean entities", CommandPermissionLevel::Any);
|
auto command = DynamicCommand::createCommand(registry, "voteclean", "Clean entities", CommandPermissionLevel::Any);
|
||||||
command->addOverload();
|
command->addOverload();
|
||||||
command->setCallback([](DynamicCommand const& cmd,
|
command->setCallback([](DynamicCommand const& cmd,
|
||||||
CommandOrigin const& origin,
|
CommandOrigin const& origin,
|
||||||
CommandOutput& output,
|
CommandOutput& output,
|
||||||
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
||||||
// vote clean command
|
// vote clean command
|
||||||
});
|
});
|
||||||
DynamicCommand::setup(registry, std::move(command));
|
DynamicCommand::setup(registry, std::move(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegCleanerCommand(CommandRegistry& registry) {
|
void RegCleanerCommand(CommandRegistry& registry) {
|
||||||
auto command = DynamicCommand::createCommand(
|
auto command = DynamicCommand::createCommand(
|
||||||
registry,
|
registry,
|
||||||
"cleaner",
|
"cleaner",
|
||||||
"Cleaner plugin settings",
|
"Cleaner plugin settings",
|
||||||
CommandPermissionLevel::GameDirectors
|
CommandPermissionLevel::GameDirectors
|
||||||
);
|
);
|
||||||
command->setEnum("Despawn", {"despawn"});
|
command->setEnum("Despawn", {"despawn"});
|
||||||
command->setEnum("Action", {"tps", "clean", "reload", "mspt"});
|
command->setEnum("Action", {"tps", "clean", "reload", "mspt"});
|
||||||
command->setEnum("Despawntime", {"despawntime"});
|
command->setEnum("Despawntime", {"despawntime"});
|
||||||
command->mandatory("action", ParamType::Enum, "Action", CommandParameterOption::EnumAutocompleteExpansion);
|
command->mandatory("action", ParamType::Enum, "Action", CommandParameterOption::EnumAutocompleteExpansion);
|
||||||
command
|
command
|
||||||
->mandatory("despawntime", ParamType::Enum, "Despawntime", CommandParameterOption::EnumAutocompleteExpansion);
|
->mandatory("despawntime", ParamType::Enum, "Despawntime", CommandParameterOption::EnumAutocompleteExpansion);
|
||||||
command->mandatory("despawn", ParamType::Enum, "Despawn", CommandParameterOption::EnumAutocompleteExpansion);
|
command->mandatory("despawn", ParamType::Enum, "Despawn", CommandParameterOption::EnumAutocompleteExpansion);
|
||||||
command->mandatory("ticks", ParamType::Int);
|
command->mandatory("ticks", ParamType::Int);
|
||||||
command->mandatory("target", ParamType::Actor);
|
command->mandatory("target", ParamType::Actor);
|
||||||
command->addOverload({"action"});
|
command->addOverload({"action"});
|
||||||
command->addOverload({"despawntime", "ticks"});
|
command->addOverload({"despawntime", "ticks"});
|
||||||
command->addOverload({"despawn", "target"});
|
command->addOverload({"despawn", "target"});
|
||||||
command->setCallback([](DynamicCommand const& cmd,
|
command->setCallback([](DynamicCommand const& cmd,
|
||||||
CommandOrigin const& origin,
|
CommandOrigin const& origin,
|
||||||
CommandOutput& output,
|
CommandOutput& output,
|
||||||
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
||||||
if (result["despawn"].isSet && result["target"].isSet) {
|
if (result["despawn"].isSet && result["target"].isSet) {
|
||||||
auto ens = result["target"].get<std::vector<Actor*>>();
|
auto ens = result["target"].get<std::vector<Actor*>>();
|
||||||
if (ens.size() == 0) {
|
if (ens.size() == 0) {
|
||||||
return output.error("No matched targets found!");
|
return output.error("No matched targets found!");
|
||||||
}
|
}
|
||||||
for (auto en : ens) {
|
for (auto en : ens) {
|
||||||
en->despawn();
|
en->despawn();
|
||||||
}
|
}
|
||||||
return output.success("Successfully despawned {} entities", ens.size());
|
return output.success("Successfully despawned {} entities", ens.size());
|
||||||
} else if (result["action"].isSet) {
|
} else if (result["action"].isSet) {
|
||||||
auto act = result["action"].get<std::string>();
|
auto act = result["action"].get<std::string>();
|
||||||
if (act == "tps") {
|
if (act == "tps") {
|
||||||
return output.success("current tps {}, average tps {}", TPS::getCurrentTps(), TPS::getAverageTps());
|
return output.success(
|
||||||
} else if (act == "mspt") {
|
"current tps {}, average tps {}",
|
||||||
return output.success("mspt {}", TPS::getMspt());
|
GMLIB_Level::getLevel()->getServerCurrentTps(),
|
||||||
} else if (act == "clean") {
|
GMLIB_Level::getLevel()->getServerAverageTps()
|
||||||
output.success("Clean task started!");
|
);
|
||||||
Cleaner::CleanTask(20, 5); // Config
|
} else if (act == "mspt") {
|
||||||
return;
|
return output.success("mspt {}", GMLIB_Level::getLevel()->getServerMspt());
|
||||||
} else if (act == "reload") {
|
} else if (act == "clean") {
|
||||||
output.success("Reloading Cleaner ...");
|
output.success("Clean task started!");
|
||||||
return output.success("Cleaner Reloaded!");
|
Cleaner::CleanTask(20, 5); // Config
|
||||||
}
|
return;
|
||||||
} else if (result["despawntime"].isSet && result["ticks"].isSet) {
|
} else if (act == "reload") {
|
||||||
item_despawn_time = result["ticks"].get<int>();
|
output.success("Reloading Cleaner ...");
|
||||||
return output.success("Successfully set deapawn time to {}", item_despawn_time);
|
Cleaner::ReloadCleaner();
|
||||||
}
|
return output.success("Cleaner Reloaded!");
|
||||||
});
|
}
|
||||||
DynamicCommand::setup(registry, std::move(command));
|
} 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);
|
||||||
void RegDespawnCommand(CommandRegistry& registry) {
|
}
|
||||||
auto command = DynamicCommand::createCommand(registry, "despawn", "despawn entities", CommandPermissionLevel::Any);
|
});
|
||||||
command->mandatory("target", ParamType::Actor);
|
DynamicCommand::setup(registry, std::move(command));
|
||||||
command->addOverload({"target"});
|
}
|
||||||
command->addOverload();
|
|
||||||
command->setCallback([](DynamicCommand const& cmd,
|
void RegDespawnCommand(CommandRegistry& registry) {
|
||||||
CommandOrigin const& origin,
|
auto command = DynamicCommand::createCommand(registry, "despawn", "despawn entities", CommandPermissionLevel::Any);
|
||||||
CommandOutput& output,
|
command->mandatory("target", ParamType::Actor);
|
||||||
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
command->addOverload({"target"});
|
||||||
|
command->addOverload();
|
||||||
});
|
command->setCallback([](DynamicCommand const& cmd,
|
||||||
DynamicCommand::setup(registry, std::move(command));
|
CommandOrigin const& origin,
|
||||||
}
|
CommandOutput& output,
|
||||||
|
std::unordered_map<std::string, DynamicCommand::Result>& result) {
|
||||||
void RegisterCommands() {
|
|
||||||
auto registry = ll::service::bedrock::getCommandRegistry();
|
});
|
||||||
RegCleanerCommand(registry);
|
DynamicCommand::setup(registry, std::move(command));
|
||||||
RegVoteCommand(registry);
|
}
|
||||||
}
|
|
||||||
|
void RegisterCommands() {
|
||||||
void UnregisterCommands() {
|
auto registry = ll::service::bedrock::getCommandRegistry();
|
||||||
auto registry = ll::service::bedrock::getCommandRegistry();
|
RegCleanerCommand(registry);
|
||||||
registry->unregisterCommand("cleaner");
|
RegVoteCommand(registry);
|
||||||
registry->unregisterCommand("voteclean");
|
}
|
||||||
|
|
||||||
|
void UnregisterCommands() {
|
||||||
|
auto registry = ll::service::bedrock::getCommandRegistry();
|
||||||
|
registry->unregisterCommand("cleaner");
|
||||||
|
registry->unregisterCommand("voteclean");
|
||||||
}
|
}
|
||||||
+251
-247
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,13 @@
|
|||||||
add_rules("mode.debug", "mode.release", "mode.releasedbg")
|
add_rules("mode.debug", "mode.release", "mode.releasedbg")
|
||||||
|
|
||||||
add_repositories("liteldev-repo https://github.com/LiteLDev/xmake-repo.git")
|
add_repositories("liteldev-repo https://github.com/LiteLDev/xmake-repo.git")
|
||||||
add_requires("levilamina 0.3.0") -- or add_requires("levilamina x.x.x") to specify target LeviLamina version
|
|
||||||
|
if not has_config("vs_runtime") then
|
||||||
|
set_runtimes("MD")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Option 1: Use the latest version of LeviLamina released on GitHub.
|
||||||
|
add_requires("levilamina")
|
||||||
|
|
||||||
target("Cleaner") -- Change this to your plugin name.
|
target("Cleaner") -- Change this to your plugin name.
|
||||||
add_cxflags(
|
add_cxflags(
|
||||||
@@ -11,7 +17,11 @@ target("Cleaner") -- Change this to your plugin name.
|
|||||||
add_files(
|
add_files(
|
||||||
"src/**.cpp"
|
"src/**.cpp"
|
||||||
)
|
)
|
||||||
|
add_links(
|
||||||
|
"SDK-GMLIB/Lib/GMLIB"
|
||||||
|
)
|
||||||
add_includedirs(
|
add_includedirs(
|
||||||
|
"SDK-GMLIB",
|
||||||
"src"
|
"src"
|
||||||
)
|
)
|
||||||
add_packages(
|
add_packages(
|
||||||
|
|||||||
Reference in New Issue
Block a user