feat: clean logic

This commit is contained in:
Tsubasa6848
2024-01-19 17:49:05 +08:00
Unverified
parent 71a7c59b92
commit 733b3b9397
9 changed files with 456 additions and 489 deletions
+8 -3
View File
@@ -1,5 +1,10 @@
{
"name": "Cleaner",
"entry": "Cleaner.dll",
"type": "native"
"name": "${pluginName}",
"entry": "${pluginFile}",
"type": "native",
"dependencies": [
{
"name": "GMLIB"
}
]
}
+64 -24
View File
@@ -1,39 +1,42 @@
#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::chrono_literals;
int item_despawn_time = 3000;
GameTimeAsyncScheduler scheduler;
ServerTimeAsyncScheduler scheduler;
bool auto_clean_triggerred = false;
namespace Cleaner {
bool isDeathDrop(ItemActor* itac) {
//
return false;
}
bool shouldIgnoreMob(Actor* ac) {
bool shouldIgnore(GMLIB_Actor* ac) {
if (ac->isMob() || ac->isItemActor()) {
if (ac->isTame() || ac->isTrusting() || ac->getNameTag() != "") {
return true;
}
auto nbt = ac->getNbt();
if (nbt->getByte("ShowBottom") == 1) { // End Crystal Used Only, if has this tag 1b, it is modified by cleaner.
return true;
}
}
return false;
}
bool ShouldClean(Actor* en) {
bool ShouldClean(Actor* actor) {
// Players
if (en->isType(ActorType::Player)) {
auto en = (GMLIB_Actor*)actor;
if (en->isPlayer() || shouldIgnore(en)) {
return false;
}
auto type = en->getTypeName();
// Items
if (en->hasCategory(ActorCategory::Item)) {
if (en->isItemActor()) {
return true;
if (true) { // Todo Config Toggle
auto itac = (ItemActor*)en;
if (isDeathDrop(itac)) {
return false;
}
auto itemType = itac->item().getTypeName();
if (true) { // Todo Config WhiteList
return false;
@@ -43,12 +46,8 @@ bool ShouldClean(Actor* en) {
return false;
}
// Mobs
else if (en->hasCategory(ActorCategory::Mob)) {
else if (en->isMob()) {
if (true) { // Todo Config Toggle
if (shouldIgnoreMob(en)) {
return false;
}
// Test
return true;
if (true) { // Todo WhiteList
return false;
@@ -71,7 +70,7 @@ bool ShouldClean(Actor* en) {
int ExecuteClean() {
int clean_count = 0;
auto all_entities = ll::service::bedrock::getLevel()->getRuntimeActorList();
auto all_entities = GMLIB_Level::getLevel()->getAllEntities();
for (auto entity : all_entities) {
if (ShouldClean(entity)) {
entity->despawn();
@@ -83,7 +82,7 @@ int ExecuteClean() {
int CountEntities() {
int clean_count = 0;
auto all_entities = ll::service::bedrock::getLevel()->getRuntimeActorList();
auto all_entities = GMLIB_Level::getLevel()->getAllEntities();
for (auto entity : all_entities) {
if (ShouldClean(entity)) {
clean_count++;
@@ -106,18 +105,18 @@ void CleanTask(int time, int announce_time) {
void AutoCleanTask(int 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) {
check_clean_task = scheduler.add<RepeatTask>(10s, [max_entities, min_tps] {
mCheckCleanTask = scheduler.add<RepeatTask>(10s, [max_entities, min_tps] {
auto count = CountEntities();
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);
} else if (TPS::getAverageTps() <= min_tps) {
} else if (GMLIB_Level::getLevel()->getServerAverageTps() <= min_tps) {
auto_clean_triggerred = true;
logger.warn("TPS too low! Auto started clean task!");
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
+12 -12
View File
@@ -1,23 +1,23 @@
#pragma once
#include "Plugin.h"
#include "include_all.h"
#include <GMLIB/Server/ActorAPI.h>
#include <GMLIB/Server/LevelAPI.h>
extern ll::Logger logger;
extern void RegisterCommands();
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;
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 {
extern void CaculateTPS();
extern float getCurrentTps();
extern float getAverageTps();
extern float getMspt();
}
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();
} // namespace Cleaner
-42
View File
@@ -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);
}
-56
View File
@@ -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
View File
@@ -9,10 +9,9 @@ Plugin::Plugin(ll::plugin::NativePlugin& self) : mSelf(self) {
}
bool Plugin::enable() {
TPS::CaculateTPS();
Cleaner::ListenEvents();
RegisterCommands();
item_despawn_time = 300;
Cleaner::AutoCleanTask(60);
Cleaner::AutoCleanTask(300);
Cleaner::CheckCleanTask(20, 15);
logger.info("Cleaner Loaded!");
logger.info("Author: Tsubasa6848");
@@ -23,6 +22,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();
logger.info("Cleaner Disabled!");
return true;
@@ -49,15 +49,20 @@ void RegCleanerCommand(CommandRegistry& registry) {
} else if (result["action"].isSet) {
auto act = result["action"].get<std::string>();
if (act == "tps") {
return output.success("current tps {}, average tps {}", TPS::getCurrentTps(), TPS::getAverageTps());
return output.success(
"current tps {}, average tps {}",
GMLIB_Level::getLevel()->getServerCurrentTps(),
GMLIB_Level::getLevel()->getServerAverageTps()
);
} else if (act == "mspt") {
return output.success("mspt {}", TPS::getMspt());
return output.success("mspt {}", GMLIB_Level::getLevel()->getServerMspt());
} else if (act == "clean") {
output.success("Clean task started!");
Cleaner::CleanTask(20, 5); // Config
return;
} else if (act == "reload") {
output.success("Reloading Cleaner ...");
Cleaner::ReloadCleaner();
return output.success("Cleaner Reloaded!");
}
} else if (result["despawntime"].isSet && result["ticks"].isSet) {
+248 -244
View File
File diff suppressed because it is too large Load Diff
+11 -1
View File
@@ -1,7 +1,13 @@
add_rules("mode.debug", "mode.release", "mode.releasedbg")
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.
add_cxflags(
@@ -11,7 +17,11 @@ target("Cleaner") -- Change this to your plugin name.
add_files(
"src/**.cpp"
)
add_links(
"SDK-GMLIB/Lib/GMLIB"
)
add_includedirs(
"SDK-GMLIB",
"src"
)
add_packages(