From 2c35c748d1eaa74597bbe8eba8c5bdebe2341bb2 Mon Sep 17 00:00:00 2001 From: engsr6982 Date: Wed, 22 Jan 2025 16:16:23 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=20ll=201.0.0-rc.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plotcraft/EconomySystem.h | 1 - include/plotcraft/Global.h | 7 +- include/plotcraft/data/PlotMetadata.h | 2 - include/plotcraft/math/PlotCross.h | 2 - include/plotcraft/math/PlotPos.h | 6 +- include/plotcraft/math/PlotRoad.h | 2 - include/plotcraft/math/Polygon.h | 1 - include/plotcraft/utils/Mc.h | 51 ++- scripts/after_build.lua | 121 ------- src/plotcraft/EconomySystem.cc | 58 +++- src/plotcraft/Global.cc | 2 - src/plotcraft/command/Command.cc | 1 - src/plotcraft/command/Command.h | 26 +- src/plotcraft/command/DebugCommand.cc | 292 ++++++++-------- src/plotcraft/command/TemplateCommand.cc | 6 +- src/plotcraft/core/DefaultGenerator.cc | 36 +- src/plotcraft/core/DefaultGenerator.h | 2 +- src/plotcraft/core/OverworldHook.cc | 27 +- src/plotcraft/core/TemplateGenerator.cc | 14 +- src/plotcraft/core/TemplateGenerator.h | 2 +- src/plotcraft/core/TemplateManager.cc | 14 +- src/plotcraft/data/PlotDBStorage.cc | 5 +- src/plotcraft/event/Event.cc | 412 +++++++++++++---------- src/plotcraft/event/Scheduler.cc | 107 +++--- src/plotcraft/gui/PlayerSettingGUI.cc | 9 +- src/plotcraft/gui/PlotPermissionGUI.cc | 2 +- src/plotcraft/math/PlotCross.cc | 7 +- src/plotcraft/math/PlotPos.cc | 6 +- src/plotcraft/math/PlotRoad.cc | 13 +- src/plugin/MyPlugin.cpp | 15 +- src/plugin/MyPlugin.h | 3 +- xmake.lua | 2 +- 32 files changed, 603 insertions(+), 651 deletions(-) delete mode 100644 scripts/after_build.lua diff --git a/include/plotcraft/EconomySystem.h b/include/plotcraft/EconomySystem.h index c77f8c0..d0b050c 100644 --- a/include/plotcraft/EconomySystem.h +++ b/include/plotcraft/EconomySystem.h @@ -1,5 +1,4 @@ #pragma once -#include "mc/deps/core/mce/UUID.h" #include "mc/world/actor/player/Player.h" #include "plotcraft/Global.h" diff --git a/include/plotcraft/Global.h b/include/plotcraft/Global.h index c09f36b..f782465 100644 --- a/include/plotcraft/Global.h +++ b/include/plotcraft/Global.h @@ -1,6 +1,7 @@ #pragma once -#include "ll/api/schedule/Scheduler.h" -#include "mc/deps/core/mce/UUID.h" +#include "ll/api/chrono/GameChrono.h" +#include "mc/deps/core/math/Vec3.h" +#include "mc/platform/UUID.h" #include "mc/world/level/BlockPos.h" #include #include @@ -25,7 +26,6 @@ namespace plot { - using string = std::string; using json = nlohmann::json; using DiagonPos = std::pair; @@ -44,7 +44,6 @@ PLAPI int getPlotWorldDimensionId(); using ll::chrono_literals::operator""_tick; -PLAPI extern ll::schedule::GameTickScheduler GlobalPlotScheduler; } // namespace plot \ No newline at end of file diff --git a/include/plotcraft/data/PlotMetadata.h b/include/plotcraft/data/PlotMetadata.h index 6f04d23..4dacddd 100644 --- a/include/plotcraft/data/PlotMetadata.h +++ b/include/plotcraft/data/PlotMetadata.h @@ -1,6 +1,4 @@ #pragma once -#include "mc/math/Vec3.h" -#include "mc/world/level/BlockPos.h" #include "plotcraft/Global.h" #include "plotcraft/math/PlotPos.h" #include diff --git a/include/plotcraft/math/PlotCross.h b/include/plotcraft/math/PlotCross.h index f55204d..13af1cb 100644 --- a/include/plotcraft/math/PlotCross.h +++ b/include/plotcraft/math/PlotCross.h @@ -1,6 +1,4 @@ #pragma once -#include "mc/math/Vec3.h" -#include "mc/world/level/BlockPos.h" #include "mc/world/level/block/Block.h" #include "plotcraft/Global.h" #include diff --git a/include/plotcraft/math/PlotPos.h b/include/plotcraft/math/PlotPos.h index 89c50ab..c6a921b 100644 --- a/include/plotcraft/math/PlotPos.h +++ b/include/plotcraft/math/PlotPos.h @@ -1,6 +1,4 @@ #pragma once -#include "mc/math/Vec3.h" -#include "mc/world/level/BlockPos.h" #include "mc/world/level/block/Block.h" #include "plotcraft/Global.h" #include @@ -35,9 +33,9 @@ class PlotPos { PLAPI bool isPosInPlot(const Vec3& vec3) const; // 判断一个点是否在地皮内 - PLAPI bool isPosOnBorder(Vec3 const& vec3) const; // 判断一个点是否在地皮边界上 + PLAPI bool isPosOnBorder(Vec3 const& vec3) const; // 判断一个点是否在地皮边界上 PLAPI bool isAABBOnBorder(BlockPos const& min, BlockPos const& max) const; // 判断一个立方体是否在地皮边界上 - PLAPI bool isRadiusOnBorder(BlockPos const& center, int radius) const; // 判断一个圆是否在地皮边界上 + PLAPI bool isRadiusOnBorder(BlockPos const& center, int radius) const; // 判断一个圆是否在地皮边界上 PLAPI bool operator==(PlotPos const& other) const; PLAPI bool operator!=(PlotPos const& other) const; diff --git a/include/plotcraft/math/PlotRoad.h b/include/plotcraft/math/PlotRoad.h index 05f8cdb..845e3e9 100644 --- a/include/plotcraft/math/PlotRoad.h +++ b/include/plotcraft/math/PlotRoad.h @@ -1,7 +1,5 @@ #pragma once #include "PlotDirection.h" -#include "mc/math/Vec3.h" -#include "mc/world/level/BlockPos.h" #include "mc/world/level/block/Block.h" #include "plotcraft/Global.h" #include diff --git a/include/plotcraft/math/Polygon.h b/include/plotcraft/math/Polygon.h index 263c6d7..6064e47 100644 --- a/include/plotcraft/math/Polygon.h +++ b/include/plotcraft/math/Polygon.h @@ -1,5 +1,4 @@ #pragma once -#include "mc/math/Vec3.h" #include "mc/world/level/BlockPos.h" #include "plotcraft/Global.h" diff --git a/include/plotcraft/utils/Mc.h b/include/plotcraft/utils/Mc.h index 5c9e677..531bb64 100644 --- a/include/plotcraft/utils/Mc.h +++ b/include/plotcraft/utils/Mc.h @@ -1,56 +1,44 @@ #pragma once -#include "ll/api/command/CommandRegistrar.h" -#include "ll/api/event/EventBus.h" -#include "ll/api/event/server/ServerStartedEvent.h" +#include "fmt/format.h" #include "ll/api/service/Bedrock.h" -#include "ll/api/service/ServerInfo.h" -#include "ll/api/service/Service.h" -#include "ll/api/service/ServiceId.h" -#include "ll/api/utils/HashUtils.h" #include "mc/_HeaderOutputPredefine.h" -#include "mc/codebuilder/MCRESULT.h" -#include "mc/common/wrapper/GenerateMessageResult.h" -#include "mc/deps/json/JsonHelpers.h" -#include "mc/enums/CurrentCmdVersion.h" +#include "mc/deps/core/string/HashedString.h" +#include "mc/deps/core/utility/MCRESULT.h" +#include "mc/external/render_dragon/frame_renderer/CommandContext.h" #include "mc/locale/I18n.h" #include "mc/locale/Localization.h" #include "mc/server/ServerLevel.h" -#include "mc/server/commands/BlockStateCommandParam.h" -#include "mc/server/commands/CommandBlockName.h" #include "mc/server/commands/CommandBlockNameResult.h" #include "mc/server/commands/CommandContext.h" -#include "mc/server/commands/CommandOriginLoader.h" +#include "mc/server/commands/CommandOrigin.h" #include "mc/server/commands/CommandOutput.h" -#include "mc/server/commands/CommandOutputParameter.h" #include "mc/server/commands/CommandOutputType.h" #include "mc/server/commands/CommandPermissionLevel.h" #include "mc/server/commands/CommandVersion.h" +#include "mc/server/commands/CurrentCmdVersion.h" #include "mc/server/commands/MinecraftCommands.h" +#include "mc/server/commands/PlayerCommandOrigin.h" #include "mc/server/commands/ServerCommandOrigin.h" #include "mc/world/Minecraft.h" #include "mc/world/actor/player/Player.h" -#include "mc/world/item/ItemInstance.h" -#include "mc/world/item/registry/ItemStack.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" -#include "mc/world/level/ChunkBlockPos.h" #include "mc/world/level/Level.h" #include "mc/world/level/block/Block.h" #include "mc/world/level/block/actor/BlockActor.h" -#include "mc/world/level/chunk/LevelChunk.h" #include "mc/world/level/dimension/Dimension.h" #include "plotcraft/Global.h" #include #include #include #include -#include +#include +#include #include #include #include #include #include -#include #include #include @@ -63,11 +51,15 @@ PLAPI inline Block const& getBlock(BlockPos& bp, int dimid) { return ll::service::getLevel()->getDimension(dimid)->getBlockSourceFromMainChunkSource().getBlock(bp); } -PLAPI inline void executeCommand(const string& cmd, Player* player = nullptr) { +PLAPI inline void executeCommand(const std::string& cmd, Player* player = nullptr) { if (player) { // player - CommandContext ctx = CommandContext(cmd, std::make_unique(PlayerCommandOrigin(*player))); - ll::service::getMinecraft()->getCommands().executeCommand(ctx); + CommandContext ctx = CommandContext( + cmd, + std::make_unique(PlayerCommandOrigin(*player)), + CommandVersion::CurrentVersion() + ); + ll::service::getMinecraft()->getCommands().executeCommand(ctx, true); } else { // console CommandContext ctx = CommandContext( @@ -77,19 +69,20 @@ PLAPI inline void executeCommand(const string& cmd, Player* player = nullptr) { ll::service::getLevel()->asServer(), CommandPermissionLevel::Owner, 0 - ) + ), + CommandVersion::CurrentVersion() ); - ll::service::getMinecraft()->getCommands().executeCommand(ctx); + ll::service::getMinecraft()->getCommands().executeCommand(ctx, true); } } -PLAPI inline std::pair executeCommandEx(const string& cmd) { +PLAPI inline std::pair executeCommandEx(const std::string& cmd) { std::pair result; auto origin = ServerCommandOrigin("Server", ll::service::getLevel()->asServer(), CommandPermissionLevel::Internal, 0); auto command = ll::service::getMinecraft()->getCommands().compileCommand( - std::string(cmd), + cmd.c_str(), origin, - (CurrentCmdVersion)CommandVersion::CurrentVersion, + (CurrentCmdVersion)CommandVersion::CurrentVersion(), [&](std::string const& err) { result.second.append(err).append("\n"); } ); if (command) { diff --git a/scripts/after_build.lua b/scripts/after_build.lua deleted file mode 100644 index c82414c..0000000 --- a/scripts/after_build.lua +++ /dev/null @@ -1,121 +0,0 @@ -function beautify_json(value, indent) - import("core.base.json") - local json_text = "" - local stack = {} - - local function escape_str(s) - return string.gsub(s, '[%c\\"]', function(c) - local replacements = {['\b'] = '\\b', ['\f'] = '\\f', ['\n'] = '\\n', ['\r'] = '\\r', ['\t'] = '\\t', ['"'] = '\\"', ['\\'] = '\\\\'} - return replacements[c] or string.format('\\u%04x', c:byte()) - end) - end - - local function is_null(v) - return v == json.null - end - - local function is_empty_table(t) - if type(t) ~= 'table' then return false end - for _ in pairs(t) do - return false - end - return true - end - - local function is_array(t) - return type(t) == 'table' and json.is_marked_as_array(t) or #t > 0 - end - - local function serialize(val, level) - local spaces = string.rep(" ", level * indent) - - if type(val) == "table" and not stack[val] then - if is_empty_table(val) then - json_text = json_text .. (is_array(val) and "[]" or "{}") - return - end - - stack[val] = true - local isArray = is_array(val) - json_text = json_text .. (isArray and "[\n" or "{\n") - - local keys = isArray and {} or {} - for k in pairs(val) do - table.insert(keys, k) - end - if not isArray then - table.sort(keys) - end - - for _, k in ipairs(keys) do - local v = val[k] - json_text = json_text .. spaces .. (isArray and "" or '"' .. escape_str(tostring(k)) .. '": ') - serialize(v, level + 1) - json_text = json_text .. ",\n" - end - - json_text = string.sub(json_text, 1, -3) .. "\n" .. string.rep(" ", (level - 1) * indent) .. (isArray and "]" or "}") - stack[val] = nil - elseif type(val) == "string" then - json_text = json_text .. '"' .. escape_str(val) .. '"' - elseif type(val) == "number" then - if val % 1 == 0 then - json_text = json_text .. tostring(math.floor(val)) - else - json_text = json_text .. tostring(val) - end - elseif type(val) == "boolean" then - json_text = json_text .. tostring(val) - elseif is_null(val) then - json_text = json_text .. "null" - else - error("Invalid value type: " .. type(val)) - end - end - serialize(value, 1) - return json_text -end - -function string_formatter(str, variables) - return str:gsub("%${(.-)}", function(var) - return variables[var] or "${" .. var .. "}" - end) -end - -function pack_plugin(target,plugin_define) - import("lib.detect.find_file") - - local manifest_path = find_file("manifest.json", os.projectdir()) - if manifest_path then - local manifest = io.readfile(manifest_path) - local bindir = path.join(os.projectdir(), "bin") - local outputdir = path.join(bindir, plugin_define.pluginName) - local targetfile = path.join(outputdir, plugin_define.pluginFile) - local pdbfile = path.join(outputdir, path.basename(plugin_define.pluginFile) .. ".pdb") - local manifestfile = path.join(outputdir, "manifest.json") - local oritargetfile = target:targetfile() - local oripdbfile = path.join(path.directory(oritargetfile), path.basename(oritargetfile) .. ".pdb") - - os.mkdir(outputdir) - os.cp(oritargetfile, targetfile) - if os.isfile(oripdbfile) then - os.cp(oripdbfile, pdbfile) - end - - local langdir = path.join(os.projectdir(), "assets", "lang") - os.cp(langdir, outputdir) - - formattedmanifest = string_formatter(manifest, plugin_define) - io.writefile(manifestfile,formattedmanifest) - cprint("${bright green}[Plugin Packer]: ${reset}plugin already generated to " .. outputdir) - else - cprint("${bright yellow}warn: ${reset}not found manifest.json in root dir!") - end -end - - -return { - pack_plugin = pack_plugin, - beautify_json = beautify_json, - string_formatter = string_formatter -} diff --git a/src/plotcraft/EconomySystem.cc b/src/plotcraft/EconomySystem.cc index cde25d9..f189d42 100644 --- a/src/plotcraft/EconomySystem.cc +++ b/src/plotcraft/EconomySystem.cc @@ -1,25 +1,47 @@ -#include "plotcraft/EconomySystem.h" +#include "mc/nbt/CompoundTag.h" +#include "mc\nbt\CompoundTagVariant.h" + #include "fmt/core.h" +#include "ll/api/memory/Hook.h" #include "ll/api/service/Bedrock.h" -#include "mc/deps/core/mce/UUID.h" -#include "mc/nbt/CompoundTag.h" -#include "mc/world/actor/player/PlayerScoreSetFunction.h" +#include "mc/common/CompactionStatus.h" +#include "mc/deps/core/file/PathBuffer.h" +#include "mc/deps/core/threading/IAsyncResult.h" +#include "mc/deps/core/utility/NonOwnerPointer.h" +#include "mc/nbt/ByteArrayTag.h" +#include "mc/nbt/ByteTag.h" +#include "mc/nbt/DoubleTag.h" +#include "mc/nbt/EndTag.h" +#include "mc/nbt/FloatTag.h" +#include "mc/nbt/Int64Tag.h" +#include "mc/nbt/IntArrayTag.h" +#include "mc/nbt/IntTag.h" +#include "mc/nbt/ListTag.h" +#include "mc/nbt/ShortTag.h" +#include "mc/nbt/StringTag.h" +#include "mc/platform/UUID.h" +#include "mc/platform/brstd/move_only_function.h" #include "mc/world/level/Level.h" +#include "mc/world/level/storage/DBStorage.h" +#include "mc/world/level/storage/LevelStorage.h" +#include "mc/world/level/storage/StorageVersion.h" +#include "mc/world/level/storage/db_helpers/Category.h" +#include "mc/world/scores/PlayerScoreSetFunction.h" #include "mc/world/scores/ScoreInfo.h" +#include "mc\nbt\Tag.h" +#include "mc\world\level\storage\DBStorageConfig.h" +#include "mc\world\scores\PlayerScoreboardId.h" +#include "plotcraft/EconomySystem.h" +#include #include #include #include #include #include #include - -#include "ll/api/memory/Hook.h" -#include "mc/world/level/storage/DBStorage.h" - - -#include #include + namespace plot { // 在线计分板 @@ -34,7 +56,7 @@ int ScoreBoard_Get_Online(Player& player, string const& scoreName) { if (!id.isValid()) { scoreboard.createScoreboardId(player); } - return obj->getPlayerScore(id).mScore; + return obj->getPlayerScore(id).mValue; } bool ScoreBoard_Set_Online(Player& player, int score, string const& scoreName) { Scoreboard& scoreboard = ll::service::getLevel()->getScoreboard(); @@ -88,13 +110,13 @@ LL_AUTO_TYPE_INSTANCE_HOOK( DBStorageHook, HookPriority::Normal, DBStorage, - "??0DBStorage@@QEAA@UDBStorageConfig@@V?$not_null@V?$NonOwnerPointer@VLevelDbEnv@@@Bedrock@@@gsl@@@Z", - DBStorage*, - struct DBStorageConfig& cfg, - Bedrock::NotNullNonOwnerPtr& dbEnv + &DBStorage::$ctor, + void*, + DBStorageConfig cfg, + ::Bedrock::NotNullNonOwnerPtr dbEnv ) { - DBStorage* ori = origin(cfg, dbEnv); - MC_DBStorage = ori; + auto ori = origin(std::move(cfg), dbEnv); + MC_DBStorage = this; return ori; }; @@ -123,7 +145,7 @@ int ScoreBoard_Get_Offline(mce::UUID const& uuid, string const& scoreName) { if (!sid.isValid() || !objective->hasScore(sid)) { return 0; } - return objective->getPlayerScore(sid).mScore; + return objective->getPlayerScore(sid).mValue; } bool ScoreBoard_Set_Offline(mce::UUID const& uuid, int score, string const& scoreName) { Scoreboard& scoreboard = ll::service::getLevel()->getScoreboard(); diff --git a/src/plotcraft/Global.cc b/src/plotcraft/Global.cc index 569edbd..70c230f 100644 --- a/src/plotcraft/Global.cc +++ b/src/plotcraft/Global.cc @@ -12,6 +12,4 @@ int getPlotWorldDimensionId() { #endif } -ll::schedule::GameTickScheduler GlobalPlotScheduler; - } // namespace plot \ No newline at end of file diff --git a/src/plotcraft/command/Command.cc b/src/plotcraft/command/Command.cc index 95cdb34..40a1ab1 100644 --- a/src/plotcraft/command/Command.cc +++ b/src/plotcraft/command/Command.cc @@ -1,6 +1,5 @@ #include "Command.h" #include "ll/api/command/CommandRegistrar.h" -#include "mc/math/Vec3.h" #include "mc/server/commands/CommandOrigin.h" #include "mc/server/commands/CommandOriginType.h" #include "mc/world/level/BlockPos.h" diff --git a/src/plotcraft/command/Command.h b/src/plotcraft/command/Command.h index 2aab1e5..8b0d713 100644 --- a/src/plotcraft/command/Command.h +++ b/src/plotcraft/command/Command.h @@ -1,45 +1,36 @@ #pragma once #include "ll/api/command/CommandRegistrar.h" #include "ll/api/service/Bedrock.h" -#include "mc/common/wrapper/optional_ref.h" #include "mc/deps/core/string/HashedString.h" +#include "mc/deps/core/utility/optional_ref.h" #include "mc/nbt/CompoundTag.h" #include "mc/network/ServerNetworkHandler.h" #include "mc/network/packet/SetTimePacket.h" #include "mc/server/commands/CommandOriginType.h" #include "mc/server/commands/CommandPositionFloat.h" #include "mc/server/commands/CommandSelector.h" +#include "mc/world/actor/ActorDefinitionIdentifier.h" +#include "mc/world/actor/agent/agent_commands/Command.h" #include "mc/world/actor/player/Player.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/ChunkBlockPos.h" #include "mc/world/level/ChunkPos.h" -#include "mc/world/level/Command.h" #include "mc/world/level/Level.h" #include "mc/world/level/block/Block.h" #include "mc/world/level/block/actor/BlockActor.h" #include "mc/world/level/chunk/LevelChunk.h" #include "mc/world/level/dimension/Dimension.h" -#include "plotcraft/utils/Mc.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include #include #include +#include #include #include #include #include -#include -#include -#include #include #include #include @@ -52,12 +43,9 @@ #include #include #include +#include #include -#include -#include -#include -#include -#include +#include using string = std::string; diff --git a/src/plotcraft/command/DebugCommand.cc b/src/plotcraft/command/DebugCommand.cc index f2ad512..2278f60 100644 --- a/src/plotcraft/command/DebugCommand.cc +++ b/src/plotcraft/command/DebugCommand.cc @@ -27,152 +27,152 @@ struct DTestClass2 { }; void SetupDebugCommand() { - auto& cmd = ll::command::CommandRegistrar::getInstance().getOrCreateCommand(COMMAND_NAME); - - cmd.overload() - .text("debug_fill_cross") - .required("name") - .required("remove_border") - .execute([](CommandOrigin const& ori, CommandOutput& out, DParam const& param) { - auto ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - auto bl = param.name.resolveBlock((int)param.name.id).getBlock(); - if (!bl) { - out.error("Could not find block"); - return; - } - - PlotCross cross = PlotCross(ent->getPosition()); - if (cross.isValid()) { - cross.fill(*bl, param.remove_border); - } else { - out.error("Invalid cross"); - } - }); - - cmd.overload() - .text("debug_fill_road") - .required("name") - .required("remove_border") - .execute([](CommandOrigin const& ori, CommandOutput& out, DParam const& param) { - auto ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - auto bl = param.name.resolveBlock((int)param.name.id).getBlock(); - if (!bl) { - out.error("Could not find block"); - return; - } - - PlotRoad road = PlotRoad(ent->getPosition()); - if (road.isValid()) { - road.fill(*bl, param.remove_border); - } else { - out.error("Invalid road"); - } - }); - - cmd.overload().text("debug_fix_border").execute([](CommandOrigin const& ori, CommandOutput& out) { - auto ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - PlotPos pos = PlotPos(ent->getPosition()); - if (pos.isValid()) { - pos.fixBorder(); - } else { - out.error("Invalid PlotPos"); - } - }); - - cmd.overload().text("debug_get_adjacent_road").execute([](CommandOrigin const& ori, CommandOutput& out) { - Actor* ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - PlotCross cross = PlotCross(ent->getPosition()); - if (cross.isValid()) { - auto roads = cross.getAdjacentRoads(); - string out_str = "Adjacent roads: \n"; - for (auto const& road : roads) { - out_str += road.toString() + "\n"; - } - out.success(out_str); - } else { - out.error("Invalid cross"); - } - }); - - cmd.overload().text("debug_get_adjacent_cross").execute([](CommandOrigin const& ori, CommandOutput& out) { - Actor* ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - PlotRoad road = PlotRoad(ent->getPosition()); - if (road.isValid()) { - auto crosses = road.getAdjacentCrosses(); - string out_str = "Adjacent crosses: \n"; - for (auto const& cross : crosses) { - out_str += cross.toString() + "\n"; - } - out.success(out_str); - } else { - out.error("Invalid road"); - } - }); - - cmd.overload() - .text("debug_is_adjacent") - .required("road_pos") - .required("cross_pos") - .execute([](CommandOrigin const& ori, CommandOutput& out, DTestClass2 const& param) { - Actor* ent = ori.getEntity(); - if (!ent || !ent->isPlayer()) { - out.error("Must be a player"); - return; - } - - auto road_pos = param.road_pos.getBlockPos(CommandVersion::CurrentVersion, ori); - auto cross_pos = param.cross_pos.getBlockPos(CommandVersion::CurrentVersion, ori); - - PlotRoad road(road_pos); - PlotCross cross(cross_pos); - - if (!road.isValid() || !cross.isValid()) { - out.error("Invalid road or cross"); - return; - } - - std::ostringstream out_str; - out_str << "Road => Cross: " << road.isAdjacent(cross) << "\n"; - out_str << "Cross => Road: " << cross.isAdjacent(road) << "\n"; - out.success(out_str.str()); - }); - - cmd.overload().text("debug_reset_db").execute([](CommandOrigin const&, CommandOutput&) { - auto& db = data::PlotDBStorage::getInstance(); - auto& impl = db.getDB(); - - impl.iter([&impl](auto k, auto) { - impl.del(k); - return true; - }); - - db.load(); - }); + // auto& cmd = ll::command::CommandRegistrar::getInstance().getOrCreateCommand(COMMAND_NAME); + + // cmd.overload() + // .text("debug_fill_cross") + // .required("name") + // .required("remove_border") + // .execute([](CommandOrigin const& ori, CommandOutput& out, DParam const& param) { + // auto ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // auto bl = param.name.resolveBlock((int)param.name.id).getBlock(); + // if (!bl) { + // out.error("Could not find block"); + // return; + // } + + // PlotCross cross = PlotCross(ent->getPosition()); + // if (cross.isValid()) { + // cross.fill(*bl, param.remove_border); + // } else { + // out.error("Invalid cross"); + // } + // }); + + // cmd.overload() + // .text("debug_fill_road") + // .required("name") + // .required("remove_border") + // .execute([](CommandOrigin const& ori, CommandOutput& out, DParam const& param) { + // auto ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // auto bl = param.name.resolveBlock((int)param.name.id).getBlock(); + // if (!bl) { + // out.error("Could not find block"); + // return; + // } + + // PlotRoad road = PlotRoad(ent->getPosition()); + // if (road.isValid()) { + // road.fill(*bl, param.remove_border); + // } else { + // out.error("Invalid road"); + // } + // }); + + // cmd.overload().text("debug_fix_border").execute([](CommandOrigin const& ori, CommandOutput& out) { + // auto ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // PlotPos pos = PlotPos(ent->getPosition()); + // if (pos.isValid()) { + // pos.fixBorder(); + // } else { + // out.error("Invalid PlotPos"); + // } + // }); + + // cmd.overload().text("debug_get_adjacent_road").execute([](CommandOrigin const& ori, CommandOutput& out) { + // Actor* ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // PlotCross cross = PlotCross(ent->getPosition()); + // if (cross.isValid()) { + // auto roads = cross.getAdjacentRoads(); + // string out_str = "Adjacent roads: \n"; + // for (auto const& road : roads) { + // out_str += road.toString() + "\n"; + // } + // out.success(out_str); + // } else { + // out.error("Invalid cross"); + // } + // }); + + // cmd.overload().text("debug_get_adjacent_cross").execute([](CommandOrigin const& ori, CommandOutput& out) { + // Actor* ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // PlotRoad road = PlotRoad(ent->getPosition()); + // if (road.isValid()) { + // auto crosses = road.getAdjacentCrosses(); + // string out_str = "Adjacent crosses: \n"; + // for (auto const& cross : crosses) { + // out_str += cross.toString() + "\n"; + // } + // out.success(out_str); + // } else { + // out.error("Invalid road"); + // } + // }); + + // cmd.overload() + // .text("debug_is_adjacent") + // .required("road_pos") + // .required("cross_pos") + // .execute([](CommandOrigin const& ori, CommandOutput& out, DTestClass2 const& param) { + // Actor* ent = ori.getEntity(); + // if (!ent || !ent->isPlayer()) { + // out.error("Must be a player"); + // return; + // } + + // auto road_pos = param.road_pos.getBlockPos(CommandVersion::CurrentVersion, ori); + // auto cross_pos = param.cross_pos.getBlockPos(CommandVersion::CurrentVersion, ori); + + // PlotRoad road(road_pos); + // PlotCross cross(cross_pos); + + // if (!road.isValid() || !cross.isValid()) { + // out.error("Invalid road or cross"); + // return; + // } + + // std::ostringstream out_str; + // out_str << "Road => Cross: " << road.isAdjacent(cross) << "\n"; + // out_str << "Cross => Road: " << cross.isAdjacent(road) << "\n"; + // out.success(out_str.str()); + // }); + + // cmd.overload().text("debug_reset_db").execute([](CommandOrigin const&, CommandOutput&) { + // auto& db = data::PlotDBStorage::getInstance(); + // auto& impl = db.getDB(); + + // impl.iter([&impl](auto k, auto) { + // impl.del(k); + // return true; + // }); + + // db.load(); + // }); } diff --git a/src/plotcraft/command/TemplateCommand.cc b/src/plotcraft/command/TemplateCommand.cc index cea5e16..7b9d836 100644 --- a/src/plotcraft/command/TemplateCommand.cc +++ b/src/plotcraft/command/TemplateCommand.cc @@ -7,6 +7,7 @@ #include "mc/server/commands/CommandSelector.h" #include "plotcraft/core/TemplateManager.h" #include "plotcraft/data/PlotDBStorage.h" +#include "plotcraft/utils/Mc.h" namespace plot::command { using namespace plot::data; @@ -37,11 +38,14 @@ const auto start = [](CommandOrigin const& ori, CommandOutput& out, StartData co return; } - auto bl = data.defaultBlock.resolveBlock((int)data.defaultBlock.id).getBlock(); + auto bl = data.defaultBlock.resolveBlock(data.defaultBlock.mBlockNameHash).getBlock(); if (bl == nullptr) { sendText(player, "获取默认方块失败"); return; } +#ifdef DEBUG + std::cout << "Block: " << bl->getTypeName() << std::endl; +#endif bool ok = TemplateManager::prepareRecordTemplate( data.starty, diff --git a/src/plotcraft/core/DefaultGenerator.cc b/src/plotcraft/core/DefaultGenerator.cc index 45e506f..c5c4587 100644 --- a/src/plotcraft/core/DefaultGenerator.cc +++ b/src/plotcraft/core/DefaultGenerator.cc @@ -1,21 +1,25 @@ #include "DefaultGenerator.h" -#include "mc/deps/core/utility/buffer_span_mut.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/ChunkBlockPos.h" +#include "mc/world/level/ChunkPos.h" #include "mc/world/level/Level.h" -#include "mc/world/level/biome/VanillaBiomeNames.h" #include "mc/world/level/biome/registry/BiomeRegistry.h" #include "mc/world/level/block/Block.h" #include "mc/world/level/block/BlockLegacy.h" #include "mc/world/level/block/BlockVolume.h" #include "mc/world/level/block/actor/BlockActor.h" #include "mc/world/level/block/registry/BlockTypeRegistry.h" -#include "mc/world/level/block/utils/VanillaBlockTypeIds.h" #include "mc/world/level/chunk/LevelChunk.h" #include "mc/world/level/levelgen/v1/ChunkLocalNoiseCache.h" +#include "mc\_HeaderOutputPredefine.h" #include "plotcraft/Config.h" #include +#include +#include +#include +#include +#include #include #include @@ -24,15 +28,15 @@ namespace plot::core { DefaultGenerator::DefaultGenerator(Dimension& dimension, uint seed, Json::Value const& generationOptionsJSON) : FlatWorldGenerator(dimension, seed, generationOptionsJSON) { - mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains); + mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains()); mBiomeSource = std::make_unique(*mBiome); auto& gen = Config::cfg.generator; // 初始化方块指针 - mBlock_Dirt = &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Dirt); - mBlock_Bedrock = &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Bedrock); + mBlock_Dirt = &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Dirt()); + mBlock_Bedrock = &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Bedrock()); mBlock_Road = &BlockTypeRegistry::getDefaultBlockState(gen.roadBlock.c_str()); mBlock_Fill = &BlockTypeRegistry::getDefaultBlockState(gen.fillBlock.c_str()); mBlock_Border = &BlockTypeRegistry::getDefaultBlockState(gen.borderBlock.c_str()); @@ -59,22 +63,22 @@ DefaultGenerator::DefaultGenerator(Dimension& dimension, uint seed, Json::Value // 生成4个模板子区块Volume for (int i = 0; i < mSubChunkNum; i++) { // 拷贝原有的 BlockVolume 而不使用构造函数(使用构造函数不生效,原因未知) - auto ptr = std::make_unique(mPrototype); - ptr->mBlocks.mBegin = &*mVector_Dirt16.begin(); // 指向 mVector_Dirt - ptr->mBlocks.mEnd = &*mVector_Dirt16.end(); + auto ptr = std::make_unique(mPrototype); + ptr->mBlocks->mBegin = &*mVector_Dirt16.begin(); // 指向 mVector_Dirt + ptr->mBlocks->mEnd = &*mVector_Dirt16.end(); mTemplateSubChunks.push_back(std::move(ptr)); } // 确保有基岩和草方块 - auto begin = mTemplateSubChunks[0].get(); - begin->mBlocks.mBegin = &*mVector_Bedrock1_Dirt15.begin(); // 指向 mVector_Bedrock1_Dirt15 - begin->mBlocks.mEnd = &*mVector_Bedrock1_Dirt15.end(); - auto end = mTemplateSubChunks[mSubChunkNum - 1].get(); - end->mBlocks.mEnd = &*mVector_Dirt15_Grass1.end(); // 指向 mVector_Dirt15_Grass1 - end->mBlocks.mBegin = &*mVector_Dirt15_Grass1.begin(); + auto begin = mTemplateSubChunks[0].get(); + begin->mBlocks->mBegin = &*mVector_Bedrock1_Dirt15.begin(); // 指向 mVector_Bedrock1_Dirt15 + begin->mBlocks->mEnd = &*mVector_Bedrock1_Dirt15.end(); + auto end = mTemplateSubChunks[mSubChunkNum - 1].get(); + end->mBlocks->mEnd = &*mVector_Dirt15_Grass1.end(); // 指向 mVector_Dirt15_Grass1 + end->mBlocks->mBegin = &*mVector_Dirt15_Grass1.begin(); // 设置群系 mBiomeSource = - std::make_unique(*dimension.getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains)); + std::make_unique(*dimension.getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains())); } diff --git a/src/plotcraft/core/DefaultGenerator.h b/src/plotcraft/core/DefaultGenerator.h index 00cd4d3..ad9c8be 100644 --- a/src/plotcraft/core/DefaultGenerator.h +++ b/src/plotcraft/core/DefaultGenerator.h @@ -33,7 +33,7 @@ class DefaultGenerator : public FlatWorldGenerator { DefaultGenerator(Dimension& dimension, uint seed, Json::Value const& generationOptionsJSON); - void loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad); + void loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad) override; }; } // namespace plot::core diff --git a/src/plotcraft/core/OverworldHook.cc b/src/plotcraft/core/OverworldHook.cc index 3d2565a..283ec26 100644 --- a/src/plotcraft/core/OverworldHook.cc +++ b/src/plotcraft/core/OverworldHook.cc @@ -6,7 +6,9 @@ #include "mc/world/level/Level.h" #include "mc/world/level/dimension/OverworldDimension.h" #include "mc/world/level/levelgen/WorldGenerator.h" -#include "mc/world/level/levelgen/structure/StructureSetRegistry.h" +#include "mc\world\level\biome\source\FixedBiomeSource.h" +#include "mc\world\level\levelgen\structure\registry\StructureSetRegistry.h" +#include "mc\world\level\storage\LevelData.h" #include "plotcraft/Config.h" @@ -14,26 +16,23 @@ LL_AUTO_TYPE_INSTANCE_HOOK( OverworldDimensionCreateGeneratorHook, ll::memory::HookPriority::Normal, OverworldDimension, - "?createGenerator@OverworldDimension@@UEAA?AV?$unique_ptr@VWorldGenerator@@U?$default_delete@VWorldGenerator@@@std@" - "@@std@@AEBVStructureSetRegistry@worldgen@br@@@Z", - // &OverworldDimension::createGenerator, + &OverworldDimension::$createGenerator, std::unique_ptr, - br::worldgen::StructureSetRegistry const& + br::worldgen::StructureSetRegistry const& /* structureSetRegistry */ ) { std::unique_ptr worldGenerator; - mSeaLevel = -61; - auto seed = getLevel().getSeed(); - auto& levelData = getLevel().getLevelData(); + mSeaLevel = -61; + auto seed = getLevel().getSeed(); + auto& levelData = getLevel().getLevelData(); + auto const& enerationOptionsJSON = levelData.getFlatWorldGeneratorOptions(); - if (plot::Config::cfg.generator.type == plot::Config::PlotGeneratorType::Default) { - worldGenerator = - std::make_unique(*this, seed, levelData.getFlatWorldGeneratorOptions()); + if (plot::Config::cfg.generator.type == plot::PlotGeneratorType::Default) { + worldGenerator = std::make_unique(*this, seed, enerationOptionsJSON); } else { - worldGenerator = - std::make_unique(*this, seed, levelData.getFlatWorldGeneratorOptions()); + worldGenerator = std::make_unique(*this, seed, enerationOptionsJSON); } - worldGenerator->init(); + // worldGenerator->init(); // removed ? return std::move(worldGenerator); } diff --git a/src/plotcraft/core/TemplateGenerator.cc b/src/plotcraft/core/TemplateGenerator.cc index 196a802..3a32c64 100644 --- a/src/plotcraft/core/TemplateGenerator.cc +++ b/src/plotcraft/core/TemplateGenerator.cc @@ -1,10 +1,14 @@ #include "TemplateGenerator.h" #include "TemplateManager.h" #include "mc/world/level/Level.h" -#include "mc/world/level/biome/VanillaBiomeNames.h" #include "mc/world/level/biome/registry/BiomeRegistry.h" #include "mc/world/level/chunk/LevelChunk.h" #include "mc/world/level/levelgen/v1/ChunkLocalNoiseCache.h" +#include +#include +#include +#include +#include #include @@ -13,7 +17,7 @@ namespace plot::core { TemplateGenerator::TemplateGenerator(Dimension& dimension, uint seed, Json::Value const& generationOptionsJSON) : FlatWorldGenerator(dimension, seed, generationOptionsJSON) { - mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains); + mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains()); mBiomeSource = std::make_unique(*mBiome); bool ok = TemplateManager::generatorBlockVolume(mPrototype); @@ -26,7 +30,11 @@ TemplateGenerator::TemplateGenerator(Dimension& dimension, uint seed, Json::Valu void TemplateGenerator::loadChunk(LevelChunk& levelchunk, bool) { auto& chunkPos = levelchunk.getPosition(); - levelchunk.setBlockVolume(TemplateManager::mBlockVolume[TemplateManager::calculateChunkID(chunkPos)], 0); + auto iter = TemplateManager::mBlockVolume.find(TemplateManager::calculateChunkID(chunkPos)); + if (iter == TemplateManager::mBlockVolume.end()) { + throw std::runtime_error("Failed to find chunk in TemplateManager"); + } + levelchunk.setBlockVolume(iter->second, 0); levelchunk.recomputeHeightMap(0); diff --git a/src/plotcraft/core/TemplateGenerator.h b/src/plotcraft/core/TemplateGenerator.h index b1ab5f1..ac1a9d8 100644 --- a/src/plotcraft/core/TemplateGenerator.h +++ b/src/plotcraft/core/TemplateGenerator.h @@ -9,7 +9,7 @@ class TemplateGenerator : public FlatWorldGenerator { public: TemplateGenerator(Dimension& dimension, uint seed, Json::Value const& generationOptionsJSON); - void loadChunk(class LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad); + void loadChunk(class LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad) override; }; diff --git a/src/plotcraft/core/TemplateManager.cc b/src/plotcraft/core/TemplateManager.cc index ddbea55..13a0a7e 100644 --- a/src/plotcraft/core/TemplateManager.cc +++ b/src/plotcraft/core/TemplateManager.cc @@ -1,6 +1,5 @@ #include "TemplateManager.h" -#include "mc/deps/core/utility/buffer_span_mut.h" -#include "mc/enums/LogLevel.h" +#include "mc/_HeaderOutputPredefine.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/ChunkPos.h" #include "mc/world/level/block/Block.h" @@ -111,13 +110,12 @@ bool TemplateManager::generatorBlockVolume(BlockVolume& volume) { int totalHeight = startHeight + data.template_height; // 起点 + buffer 高度 for (auto& [key, buffer] : mBlockBuffer) { - mBlockVolume[string(key)] = BlockVolume(volume); + auto vol = BlockVolume(volume); // 拷贝构造 + vol.mHeight = totalHeight; + vol.mBlocks->mBegin = &*buffer.begin(); + vol.mBlocks->mEnd = &*buffer.end(); - auto& v = mBlockVolume[key]; - - v.mHeight = totalHeight; - v.mBlocks.mBegin = &*buffer.begin(); - v.mBlocks.mEnd = &*buffer.end(); + mBlockVolume.emplace(string(key), std::move(vol)); } return true; } diff --git a/src/plotcraft/data/PlotDBStorage.cc b/src/plotcraft/data/PlotDBStorage.cc index 41178d7..8a92b27 100644 --- a/src/plotcraft/data/PlotDBStorage.cc +++ b/src/plotcraft/data/PlotDBStorage.cc @@ -59,7 +59,7 @@ void PlotDBStorage::load() { // Load data from database auto* logger = &my_plugin::MyPlugin::getInstance().getSelf().getLogger(); - mDB->iter([this, logger](std::string_view key, std::string_view value) { + for (auto const& [key, value] : mDB->iter()) { try { if (key.starts_with("(") && key.ends_with(")")) { auto j = nlohmann::json::parse(value); @@ -84,8 +84,7 @@ void PlotDBStorage::load() { } catch (...) { logger->fatal("Fail in {}, error key: {}", __func__, key); } - return true; - }); + }; logger->info("已加载 {}条 地皮数据", mPlotList.size()); logger->info("已加载 {}位 管理员数据", mAdminList.size()); diff --git a/src/plotcraft/event/Event.cc b/src/plotcraft/event/Event.cc index 104f310..240092a 100644 --- a/src/plotcraft/event/Event.cc +++ b/src/plotcraft/event/Event.cc @@ -3,29 +3,15 @@ #include "ll/api/event/EventBus.h" #include "ll/api/event/Listener.h" #include "ll/api/event/ListenerBase.h" -#include "ll/api/event/player/PlayerAttackEvent.h" -#include "ll/api/event/player/PlayerDestroyBlockEvent.h" -#include "ll/api/event/player/PlayerInteractBlockEvent.h" -#include "ll/api/event/player/PlayerJoinEvent.h" -#include "ll/api/event/player/PlayerPickUpItemEvent.h" -#include "ll/api/event/player/PlayerPlaceBlockEvent.h" -#include "ll/api/event/player/PlayerUseItemEvent.h" -#include "ll/api/event/world/FireSpreadEvent.h" -#include "ll/api/event/world/SpawnMobEvent.h" -#include "ll/api/service/Bedrock.h" -#include "mc/common/wrapper/optional_ref.h" -#include "mc/enums/BlockUpdateFlag.h" -#include "mc/enums/GameType.h" +#include "mc/deps/core/math/Vec3.h" #include "mc/network/packet/UpdateBlockPacket.h" #include "mc/server/ServerPlayer.h" -#include "mc/world/actor/player/Player.h" -#include "mc/world/gamemode/GameMode.h" -#include "mc/world/level/Level.h" -#include "mc/world/level/block/Block.h" -#include "mc/world/level/dimension/Dimension.h" +#include "mc/world/level/BlockPos.h" #include "mc/world/level/material/Material.h" #include "mc/world/phys/AABB.h" #include "mc/world/phys/HitResult.h" +#include "mc\world\level\block\components\BlockLiquidDetectionComponent.h" +#include "mc\world\level\chunk\SubChunk.h" #include "plotcraft/Config.h" #include "plotcraft/Global.h" #include "plotcraft/data/PlayerNameDB.h" @@ -36,59 +22,78 @@ #include "plotcraft/utils/Mc.h" #include "plotcraft/utils/Utils.h" #include "plugin/MyPlugin.h" +#include #include +#include #include -#include "more_events/ActorRideEvent.h" -#include "more_events/ArmorStandSwapItemEvent.h" -#include "more_events/ExplodeEvent.h" -#include "more_events/FarmDecayEvent.h" -#include "more_events/LiquidFlowEvent.h" -#include "more_events/MobHurtEffectEvent.h" -#include "more_events/MossFertilizerEvent.h" -#include "more_events/PistonTryPushEvent.h" -#include "more_events/PlayerAttackBlockEvent.h" -#include "more_events/PlayerDropItemEvent.h" -#include "more_events/PlayerUseItemFrameEvent.h" -#include "more_events/PressurePlateTriggerEvent.h" -#include "more_events/ProjectileSpawnEvent.h" -#include "more_events/RedstoneUpdateEvent.h" -#include "more_events/SculkCatalystAbsorbExperienceEvent.h" -#include "more_events/WitherDestroyBlockEvent.h" + +#include "ll/api/event/entity/ActorHurtEvent.h" +#include "ll/api/event/player/PlayerAttackEvent.h" +#include "ll/api/event/player/PlayerDestroyBlockEvent.h" +#include "ll/api/event/player/PlayerInteractBlockEvent.h" +#include "ll/api/event/player/PlayerJoinEvent.h" +#include "ll/api/event/player/PlayerPickUpItemEvent.h" +#include "ll/api/event/player/PlayerPlaceBlockEvent.h" +#include "ll/api/event/player/PlayerUseItemEvent.h" +#include "ll/api/event/world/FireSpreadEvent.h" +#include "ll/api/event/world/SpawnMobEvent.h" + +#include "ila/event/minecraft/actor/ActorRideEvent.h" +#include "ila/event/minecraft/actor/ActorTriggerPressurePlateEvent.h" +#include "ila/event/minecraft/actor/ArmorStandSwapItemEvent.h" +#include "ila/event/minecraft/actor/MobHurtEffectEvent.h" +#include "ila/event/minecraft/actor/ProjectileCreateEvent.h" +// #include "ila/event/minecraft/level/SculkCatalystAbsorbExperienceEvent.h" +#include "ila/event/minecraft/player/PlayerAttackBlockEvent.h" +#include "ila/event/minecraft/player/PlayerDropItemEvent.h" +#include "ila/event/minecraft/player/PlayerOperatedItemFrameEvent.h" +#include "ila/event/minecraft/world/ExplosionEvent.h" +#include "ila/event/minecraft/world/FarmDecayEvent.h" +#include "ila/event/minecraft/world/LiquidTryFlowEvent.h" +#include "ila/event/minecraft/world/MossGrowthEvent.h" +#include "ila/event/minecraft/world/PistonPushEvent.h" +#include "ila/event/minecraft/world/RedstoneUpdateEvent.h" +#include "ila/event/minecraft/world/SculkBlockGrowthEvent.h" +#include "ila/event/minecraft/world/SculkSpreadEvent.h" +#include "ila/event/minecraft/world/WitherDestroyEvent.h" using PlotPermission = plot::data::PlotPermission; // Global variables -ll::event::ListenerPtr mPlayerJoinEvent; // 玩家进入服务器 -ll::event::ListenerPtr mSpawningMobEvent; // 生物尝试生成 -ll::event::ListenerPtr mPlayerDestroyBlockEvent; // 玩家尝试破坏方块 -ll::event::ListenerPtr mPlayerPlaceingBlockEvent; // 玩家尝试放置方块 -ll::event::ListenerPtr mPlayerUseItemOnEvent; // 玩家对方块使用物品(点击右键) -ll::event::ListenerPtr mFireSpreadEvent; // 火焰蔓延 -ll::event::ListenerPtr mPlayerAttackEntityEvent; // 玩家攻击实体 -ll::event::ListenerPtr mPlayerPickUpItemEvent; // 玩家捡起物品 -ll::event::ListenerPtr mPlayerInteractBlockEvent; // 方块接受玩家互动 -ll::event::ListenerPtr mPlayerLeavePlotEvent; // 玩家离开地皮 -ll::event::ListenerPtr mPlayerEnterPlotEvent; // 玩家进入地皮 -ll::event::ListenerPtr mPlayerUseItemEvent; // 玩家使用物品 -ll::event::ListenerPtr mArmorStandSwapItemEvent; // 玩家交换盔甲架物品 (more_events) -ll::event::ListenerPtr mPlayerAttackBlockEvent; // 玩家攻击方块 (more_events) -ll::event::ListenerPtr mPlayerDropItemEvent; // 玩家丢弃物品 (more_events) -ll::event::ListenerPtr mActorRideEvent; // 实体骑乘 (more_events) -ll::event::ListenerPtr mExplodeEvent; // 爆炸 (more_events) -ll::event::ListenerPtr mFarmDecayEvent; // 农田退化 (more_events) -ll::event::ListenerPtr mMobHurtEffectEvent; // 实体受伤效果 (more_events) -ll::event::ListenerPtr mPistonTryPushEvent; // 活塞尝试推动方块 (more_events) -ll::event::ListenerPtr mPlayerUseItemFrameEvent; // 玩家使用物品展示框 (more_events) -ll::event::ListenerPtr mPressurePlateTriggerEvent; // 压力板触发 (more_events) -ll::event::ListenerPtr mProjectileSpawnEvent; // 投掷物生成 (more_events) -ll::event::ListenerPtr mRedstoneUpdateEvent; // 红石更新 (more_events) -ll::event::ListenerPtr mWitherDestroyBlockEvent; // 凋零破坏方块 (more_events) -ll::event::ListenerPtr mMossFertilizerEvent; // 苔藓施肥 (more_events) -ll::event::ListenerPtr mLiquidFlowEvent; // 流体流动 (more_events) -ll::event::ListenerPtr mSculkCatalystAbsorbExperienceEvent; // 幽匿催发体吸收经验 (more_events) +ll::event::ListenerPtr mPlayerJoinEvent; // 玩家进入服务器 +ll::event::ListenerPtr mActorHurtEvent; // 实体受伤 +ll::event::ListenerPtr mSpawningMobEvent; // 生物尝试生成 +ll::event::ListenerPtr mPlayerDestroyBlockEvent; // 玩家尝试破坏方块 +ll::event::ListenerPtr mPlayerPlaceingBlockEvent; // 玩家尝试放置方块 +ll::event::ListenerPtr mPlayerUseItemOnEvent; // 玩家对方块使用物品(点击右键) +ll::event::ListenerPtr mFireSpreadEvent; // 火焰蔓延 +ll::event::ListenerPtr mPlayerAttackEntityEvent; // 玩家攻击实体 +ll::event::ListenerPtr mPlayerPickUpItemEvent; // 玩家捡起物品 +ll::event::ListenerPtr mPlayerInteractBlockEvent; // 方块接受玩家互动 +ll::event::ListenerPtr mPlayerLeavePlotEvent; // 玩家离开地皮 +ll::event::ListenerPtr mPlayerEnterPlotEvent; // 玩家进入地皮 +ll::event::ListenerPtr mPlayerUseItemEvent; // 玩家使用物品 +ll::event::ListenerPtr mArmorStandSwapItemEvent; // 玩家交换盔甲架物品 (iListenAttentively) +ll::event::ListenerPtr mPlayerAttackBlockEvent; // 玩家攻击方块 (iListenAttentively) +ll::event::ListenerPtr mPlayerDropItemEvent; // 玩家丢弃物品 (iListenAttentively) +ll::event::ListenerPtr mActorRideEvent; // 实体骑乘 (iListenAttentively) +ll::event::ListenerPtr mExplodeEvent; // 爆炸 (iListenAttentively) +ll::event::ListenerPtr mFarmDecayEvent; // 农田退化 (iListenAttentively) +ll::event::ListenerPtr mMobHurtEffectEvent; // 实体受伤效果 (iListenAttentively) +ll::event::ListenerPtr mPistonTryPushEvent; // 活塞尝试推动方块 (iListenAttentively) +ll::event::ListenerPtr mPlayerUseItemFrameEvent; // 玩家使用物品展示框 (iListenAttentively) +ll::event::ListenerPtr mPressurePlateTriggerEvent; // 压力板触发 (iListenAttentively) +ll::event::ListenerPtr mProjectileSpawnEvent; // 投掷物生成 (iListenAttentively) +ll::event::ListenerPtr mRedstoneUpdateEvent; // 红石更新 (iListenAttentively) +ll::event::ListenerPtr mWitherDestroyBlockEvent; // 凋零破坏方块 (iListenAttentively) +ll::event::ListenerPtr mMossFertilizerEvent; // 苔藓施肥 (iListenAttentively) +ll::event::ListenerPtr mLiquidFlowEvent; // 流体流动 (iListenAttentively) +// ll::event::ListenerPtr mSculkCatalystAbsorbExperienceEvent; // 幽匿催发体吸收经验 (iListenAttentively) +ll::event::ListenerPtr mSculkBlockGrowthEvent; // 幽匿尖啸体生成 (iListenAttentively) +ll::event::ListenerPtr mSculkSpreadEvent; // 幽匿蔓延 (iListenAttentively) namespace plot::event { @@ -147,7 +152,7 @@ bool registerEventListener() { }); } - // Minecraft events + // LeviLamina's events mPlayerJoinEvent = bus->emplaceListener([ndb, db](ll::event::PlayerJoinEvent& e) { if (e.self().isSimulatedPlayer()) return true; // skip simulated player ndb->insertPlayer(e.self()); @@ -157,7 +162,7 @@ bool registerEventListener() { mPlayerDestroyBlockEvent = bus->emplaceListener([db, logger](ll::event::PlayerDestroyBlockEvent& ev) { - ServerPlayer& player = ev.self(); + auto& player = ev.self(); if (player.getDimensionId() != getPlotWorldDimensionId()) return; // 被破坏的方块不在地皮世界 BlockPos const& blockPos = ev.pos(); @@ -183,7 +188,7 @@ bool registerEventListener() { mPlayerPlaceingBlockEvent = bus->emplaceListener([db, logger](ll::event::PlayerPlacingBlockEvent& ev) { - ServerPlayer& player = ev.self(); + auto& player = ev.self(); if (player.getDimensionId() != getPlotWorldDimensionId()) return; BlockPos blockPos = mc::face2Pos(ev.pos(), ev.face()); // 计算实际放置位置 @@ -389,12 +394,11 @@ bool registerEventListener() { auto& player = ev.self(); auto val = player.traceRay(5.5f, false, true, [&](BlockSource const&, Block const& bl, bool) { - // if (!bl.isSolid()) return false; // 非固体方块 if (bl.getMaterial().isLiquid()) return false; // 液体方块 return true; }); - BlockPos const& pos = val.mBlockPos; + BlockPos const& pos = val.mBlock; ItemStack const& item = ev.item(); Block const& bl = player.getDimensionBlockSource().getBlock(pos); @@ -403,19 +407,62 @@ bool registerEventListener() { auto pps = PlotPos(pos); if (pps.isValid() && pps.isPosOnBorder(pos)) { ev.cancel(); + static uchar flags = (1 << 0) | (1 << 1); // 0b11 BlockUpdateFlag::All v0.13.5 UpdateBlockPacket( pos, - (uint)UpdateBlockPacket::BlockLayer::Extra, + (uint)SubChunk::BlockLayer::Extra, bl.getBlockItemId(), - (uchar)BlockUpdateFlag::All + flags ) .sendTo(player); // 防刁民在边框放水,导致客户端不更新 }; }); + // 可开关事件(作用于地皮世界) + mSpawningMobEvent = + bus->emplaceListener([/* logger */](ll::event::SpawningMobEvent& ev) { + if (ev.blockSource().getDimensionId() != getPlotWorldDimensionId()) return; + + // logger->debug("[SpawningMob]: {}", ev.identifier().getFullName()); + + if (Config::cfg.plotWorld.spawnMob) return; + + ev.cancel(); + }); + + mActorHurtEvent = bus->emplaceListener([db, logger](ll::event::ActorHurtEvent& ev) { + auto& self = ev.self(); + if (self.getDimensionId() != getPlotWorldDimensionId()) return; + + logger->debug("[ActorHurtEvent] mob: {}", self.getTypeName()); + + auto pps = PlotPos(ev.self().getPosition()); + if (!pps.isValid()) return; + + auto meta = db->getPlot(pps.getPlotID()); + if (meta) { + auto const& et = self.getTypeName(); + auto const& tab = meta->getPermissionTableConst(); + if (tab.allowAttackPlayer && self.isPlayer()) return; + if (tab.allowAttackAnimal && TypeNameMap::AnimalEntityMap.contains(et)) return; + if (tab.allowAttackMob && !TypeNameMap::AnimalEntityMap.contains(et)) return; + } + + if (self.isPlayer()) { + auto const pl = self.getWeakEntity().tryUnwrap(); + if (pl.has_value()) { + if (PreCheck(meta, pl->getUuid().asString())) return; + } + } + + ev.cancel(); + }); + + // iLa mPlayerAttackBlockEvent = - bus->emplaceListener([logger](more_events::PlayerAttackBlockEvent& ev) { - optional_ref pl = ev.getPlayer(); + bus->emplaceListener([logger](ila::mc::PlayerAttackBlockBeforeEvent& ev + ) { + optional_ref pl = ev.self(); if (!pl.has_value()) return; Player& player = pl.value(); @@ -438,7 +485,8 @@ bool registerEventListener() { }); mArmorStandSwapItemEvent = - bus->emplaceListener([logger](more_events::ArmorStandSwapItemEvent& ev) { + bus->emplaceListener([logger](ila::mc::ArmorStandSwapItemBeforeEvent& ev + ) { Player& player = ev.getPlayer(); if (player.getDimensionId() != getPlotWorldDimensionId()) return; @@ -458,8 +506,8 @@ bool registerEventListener() { }); mPlayerDropItemEvent = - bus->emplaceListener([logger](more_events::PlayerDropItemEvent& ev) { - Player& player = ev.getPlayer(); + bus->emplaceListener([logger](ila::mc::PlayerDropItemBeforeEvent& ev) { + Player& player = ev.self(); if (player.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[PlayerDropItem]: executed"); @@ -477,30 +525,18 @@ bool registerEventListener() { ev.cancel(); }); - // 可开关事件(作用于地皮世界) - mSpawningMobEvent = - bus->emplaceListener([/* logger */](ll::event::SpawningMobEvent& ev) { - if (ev.blockSource().getDimensionId() != getPlotWorldDimensionId()) return; - - // logger->debug("[SpawningMob]: {}", ev.identifier().getFullName()); - - if (Config::cfg.plotWorld.spawnMob) return; - - ev.cancel(); - }); - - // MoreEvents - mActorRideEvent = bus->emplaceListener([logger](more_events::ActorRideEvent& ev) { - if (ev.getPassenger().getDimensionId() != getPlotWorldDimensionId()) return; + mActorRideEvent = bus->emplaceListener([logger](ila::mc::ActorRideBeforeEvent& ev) { + Actor& passenger = ev.self(); + if (passenger.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[生物骑乘] executed!"); - if (!ev.getPassenger().isPlayer()) return; + if (!passenger.isPlayer()) return; - auto pps = PlotPos(ev.getPassenger().getPosition()); + auto pps = PlotPos(passenger.getPosition()); if (!pps.isValid()) return; - auto const& type = ev.getRided().getTypeName(); + auto const& type = ev.getTarget().getTypeName(); auto const meta = PlotDBStorage::getInstance().getPlot(pps.getPlotID()); if (meta) { auto const& tab = meta->getPermissionTableConst(); @@ -511,8 +547,8 @@ bool registerEventListener() { } } - if (ev.getPassenger().isPlayer()) { - auto pl = ev.getPassenger().getWeakEntity().tryUnwrap(); + if (passenger.isPlayer()) { + auto pl = passenger.getWeakEntity().tryUnwrap(); if (pl.has_value()) { if (PreCheck(meta, pl->getUuid().asString())) return; } @@ -521,16 +557,16 @@ bool registerEventListener() { return; }); - mExplodeEvent = bus->emplaceListener([logger](more_events::ExplodeEvent& ev) { - auto& bs = ev.getRegion(); - auto& pos = ev.getPos(); - auto& exp = ev.getExplosionRadius(); + mExplodeEvent = bus->emplaceListener([logger](ila::mc::ExplosionBeforeEvent& ev) { + auto& bs = ev.blockSource(); + auto& exp = ev.getExplosion(); + auto pos = BlockPos{exp.mPos}; if (bs.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[Explode] pos: {}", pos.toString()); - int r = (int)(exp + 1.0f); + int r = (int)(exp.mRadius + 1.0); auto land = PlotPos::getPlotPosAt(pos, r); auto& db = PlotDBStorage::getInstance(); @@ -551,8 +587,8 @@ bool registerEventListener() { ev.cancel(); // 地皮世界禁止爆炸 }); - mFarmDecayEvent = bus->emplaceListener([logger](more_events::FarmDecayEvent& ev) { - auto& region = ev.getBlockSource(); + mFarmDecayEvent = bus->emplaceListener([logger](ila::mc::FarmDecayBeforeEvent& ev) { + auto& region = ev.blockSource(); if (region.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[耕地退化] pos: {}", ev.getPos().toString()); @@ -569,25 +605,26 @@ bool registerEventListener() { }); mMobHurtEffectEvent = - bus->emplaceListener([logger](more_events::MobHurtEffectEvent& ev) { - if (ev.getSelf().getDimensionId() != getPlotWorldDimensionId()) return; + bus->emplaceListener([logger](ila::mc::MobHurtEffectBeforeEvent& ev) { + auto& self = ev.self(); + if (self.getDimensionId() != getPlotWorldDimensionId()) return; - logger->debug("[MobHurt] mob: {}", ev.getSelf().getTypeName()); + logger->debug("[MobHurt] mob: {}", self.getTypeName()); - auto pps = PlotPos(ev.getSelf().getPosition()); + auto pps = PlotPos(ev.self().getPosition()); if (!pps.isValid()) return; auto meta = PlotDBStorage::getInstance().getPlot(pps.getPlotID()); if (meta) { - auto const& et = ev.getSelf().getTypeName(); + auto const& et = self.getTypeName(); auto const& tab = meta->getPermissionTableConst(); - if (tab.allowAttackPlayer && ev.getSelf().isPlayer()) return; + if (tab.allowAttackPlayer && self.isPlayer()) return; if (tab.allowAttackAnimal && TypeNameMap::AnimalEntityMap.contains(et)) return; if (tab.allowAttackMob && !TypeNameMap::AnimalEntityMap.contains(et)) return; } - if (ev.getSelf().isPlayer()) { - auto const pl = ev.getSelf().getWeakEntity().tryUnwrap(); + if (self.isPlayer()) { + auto const pl = self.getWeakEntity().tryUnwrap(); if (pl.has_value()) { if (PreCheck(meta, pl->getUuid().asString())) return; } @@ -597,8 +634,8 @@ bool registerEventListener() { }); mPistonTryPushEvent = - bus->emplaceListener([logger](more_events::PistonTryPushEvent& ev) { - auto& region = ev.getRegion(); + bus->emplaceListener([logger](ila::mc::PistonPushBeforeEvent& ev) { + auto& region = ev.blockSource(); if (region.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[活塞推动方块] 目标: {}", ev.getPushPos().toString()); @@ -618,36 +655,35 @@ bool registerEventListener() { ev.cancel(); }); - mPlayerUseItemFrameEvent = - bus->emplaceListener([logger](more_events::PlayerUseItemFrameEvent& ev) { - auto player = ev.getPlayer(); - if (!player) return; - if (player->getDimensionId() != getPlotWorldDimensionId()) return; + mPlayerUseItemFrameEvent = bus->emplaceListener( + [logger](ila::mc::PlayerOperatedItemFrameBeforeEvent& ev) { + auto& player = ev.self(); + if (player.getDimensionId() != getPlotWorldDimensionId()) return; - logger->debug("[物品展示框] pos: {}", ev.getPos().toString()); + logger->debug("[物品展示框] pos: {}", ev.getBlockPos().toString()); - auto pps = PlotPos(ev.getPos()); + auto pps = PlotPos(ev.getBlockPos()); if (!pps.isValid()) return; auto const meta = PlotDBStorage::getInstance().getPlot(pps.getPlotID()); if (meta) { if (meta->getPermissionTableConst().useItemFrame) return; } - if (PreCheck(meta, player->getUuid().asString())) return; + if (PreCheck(meta, player.getUuid().asString())) return; ev.cancel(); - }); + } + ); - mPressurePlateTriggerEvent = - bus->emplaceListener([logger](more_events::PressurePlateTriggerEvent& ev - ) { - auto& region = ev.getRegion(); + mPressurePlateTriggerEvent = bus->emplaceListener( + [logger](ila::mc::ActorTriggerPressurePlateBeforeEvent& ev) { + auto& self = ev.self(); + auto& region = self.getDimensionBlockSource(); auto& pos = ev.getPos(); - auto& entity = ev.getEntity(); if (region.getDimensionId() != getPlotWorldDimensionId()) return; - logger->debug("[压力板] pos: {} entity: {}", pos.toString(), entity.getTypeName()); + logger->debug("[压力板] pos: {} entity: {}", pos.toString(), self.getTypeName()); auto pps = PlotPos(pos); if (!pps.isValid()) return; @@ -657,28 +693,29 @@ bool registerEventListener() { if (meta->getPermissionTableConst().usePressurePlate) return; } - if (entity.isPlayer()) { - auto pl = entity.getWeakEntity().tryUnwrap(); + if (self.isPlayer()) { + auto pl = self.getWeakEntity().tryUnwrap(); if (pl.has_value()) { if (PreCheck(meta, pl->getUuid().asString())) return; } } ev.cancel(); - }); + } + ); mProjectileSpawnEvent = - bus->emplaceListener([logger](more_events::ProjectileSpawnEvent& ev) { - auto actor = ev.getSpawner(); - if (!actor) return; - if (actor->getDimensionId() != getPlotWorldDimensionId()) return; + bus->emplaceListener([logger](ila::mc::ProjectileCreateBeforeEvent& ev) { + auto& actor = ev.self(); + if (actor.getDimensionId() != getPlotWorldDimensionId()) return; + + auto const& type = actor.getTypeName(); - logger->debug("[弹射物生成] type: {}", ev.getProjectileType()); + logger->debug("[弹射物生成] type: {}", type); - auto pps = PlotPos(actor->getPosition()); + auto pps = PlotPos(actor.getPosition()); if (!pps.isValid()) return; - auto const& type = ev.getProjectileType(); auto const meta = PlotDBStorage::getInstance().getPlot(pps.getPlotID()); if (meta) { @@ -694,8 +731,8 @@ bool registerEventListener() { if (type == "minecraft:egg" && tab.allowThrowEgg) return; // 鸡蛋 } - if (actor->isPlayer()) { - auto pl = actor->getWeakEntity().tryUnwrap(); + if (actor.isPlayer()) { + auto pl = actor.getWeakEntity().tryUnwrap(); if (pl.has_value()) { if (PreCheck(meta, pl->getUuid().asString())) return; } @@ -705,8 +742,8 @@ bool registerEventListener() { }); mRedstoneUpdateEvent = - bus->emplaceListener([logger](more_events::RedstoneUpdateEvent& ev) { - auto& region = ev.getBlockSource(); + bus->emplaceListener([logger](ila::mc::RedstoneUpdateBeforeEvent& ev) { + auto& region = ev.blockSource(); if (region.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[RedstoneUpdate] pos: {}", ev.getPos().toString()); @@ -723,13 +760,13 @@ bool registerEventListener() { }); mWitherDestroyBlockEvent = - bus->emplaceListener([logger](more_events::WitherDestroyBlockEvent& ev) { - auto& region = ev.getRegion(); + bus->emplaceListener([logger](ila::mc::WitherDestroyBeforeEvent& ev) { + auto& region = ev.blockSource(); if (region.getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[凋零破坏方块] executed!"); - auto& bb = ev.getAABB(); + auto& bb = ev.getBox(); auto land = PlotPos::getPlotPosAt(bb.min, bb.max); auto& db = PlotDBStorage::getInstance(); @@ -758,8 +795,8 @@ bool registerEventListener() { }); mMossFertilizerEvent = - bus->emplaceListener([logger, db](more_events::MossFertilizerEvent& ev) { - if (ev.getRegion().getDimensionId() != getPlotWorldDimensionId()) return; + bus->emplaceListener([logger, db](ila::mc::MossGrowthBeforeEvent& ev) { + if (ev.blockSource().getDimensionId() != getPlotWorldDimensionId()) return; logger->debug("[MossSpread] {}", ev.getPos().toString()); @@ -781,45 +818,78 @@ bool registerEventListener() { } }); - mLiquidFlowEvent = bus->emplaceListener([](more_events::LiquidFlowEvent& ev) { - auto& bs = ev.getBlockSource(); - if (bs.getDimensionId() != getPlotWorldDimensionId()) return; + mLiquidFlowEvent = + bus->emplaceListener([](ila::mc::LiquidTryFlowBeforeEvent& ev) { + auto& bs = ev.blockSource(); + if (bs.getDimensionId() != getPlotWorldDimensionId()) return; - auto& sou = ev.getLiquidPos(); - auto pps = PlotPos(sou); - if (!pps.isValid()) { - ev.cancel(); // 禁止在非领地流动 - return; - } + auto& sou = ev.getPos(); + auto pps = PlotPos(sou); + if (!pps.isValid()) { + ev.cancel(); // 禁止在非领地流动 + return; + } - if (pps.isPosOnBorder(sou)) { - ev.cancel(); // 禁止在边框流动 - return; - } - }); + if (pps.isPosOnBorder(sou)) { + ev.cancel(); // 禁止在边框流动 + return; + } + }); - mSculkCatalystAbsorbExperienceEvent = bus->emplaceListener( - [logger](more_events::SculkCatalystAbsorbExperienceEvent& ev) { - auto& actor = ev.getDiedActor(); - auto& region = actor.getDimensionBlockSource(); - if (region.getDimensionId() != getPlotWorldDimensionId()) return; + // mSculkCatalystAbsorbExperienceEvent = bus->emplaceListener( + // [logger](more_events::SculkCatalystAbsorbExperienceEvent& ev) { + // auto& actor = ev.getDiedActor(); + // auto& region = actor.getDimensionBlockSource(); + // if (region.getDimensionId() != getPlotWorldDimensionId()) return; - auto pos = actor.getBlockPosCurrentlyStandingOn(&actor); + // auto pos = actor.getBlockPosCurrentlyStandingOn(&actor); - logger->debug("[SculkCatalystAbsorbExperience] Pos: {}", pos.toString()); + // logger->debug("[SculkCatalystAbsorbExperience] Pos: {}", pos.toString()); - auto pps = PlotPos(pos); + // auto pps = PlotPos(pos); + // if (!pps.isValid()) { + // ev.cancel(); // 禁止在非领地蔓延 + // return; + // } + + // if (pps.isAABBOnBorder(pos - 9, pos + 9)) { + // ev.cancel(); // 禁止在边框蔓延 + // return; + // } + // } + // ); + + mSculkBlockGrowthEvent = + bus->emplaceListener([db, + logger](ila::mc::SculkBlockGrowthBeforeEvent& ev) { + auto& pos = ev.getPos(); + logger->debug("[SculkBlockGrowth] {}", pos.toString()); + + PlotPos pps(pos); if (!pps.isValid()) { ev.cancel(); // 禁止在非领地蔓延 return; } - if (pps.isAABBOnBorder(pos - 9, pos + 9)) { + if (pps.isPosOnBorder(pos)) { ev.cancel(); // 禁止在边框蔓延 return; } - } - ); + }); + + mSculkSpreadEvent = + bus->emplaceListener([logger](ila::mc::SculkSpreadBeforeEvent& ev) { + logger->debug("[SculkSpread] {} -> {}", ev.getSelfPos().toString(), ev.getTargetPos().toString()); + + PlotPos sou{ev.getSelfPos()}; + PlotPos tar{ev.getTargetPos()}; + + if (!sou.isValid() || !tar.isValid()) { + ev.cancel(); // 道路禁止蔓延 + return; + } + }); + return true; } @@ -851,7 +921,7 @@ bool unRegisterEventListener() { bus.removeListener(mWitherDestroyBlockEvent); bus.removeListener(mMossFertilizerEvent); bus.removeListener(mLiquidFlowEvent); - bus.removeListener(mSculkCatalystAbsorbExperienceEvent); + // bus.removeListener(mSculkCatalystAbsorbExperienceEvent); return true; } diff --git a/src/plotcraft/event/Scheduler.cc b/src/plotcraft/event/Scheduler.cc index f377fd2..5f0932c 100644 --- a/src/plotcraft/event/Scheduler.cc +++ b/src/plotcraft/event/Scheduler.cc @@ -1,10 +1,11 @@ -#include "ll/api/schedule/Scheduler.h" #include "ll/api/chrono/GameChrono.h" +#include "ll/api/coro/CoroTask.h" #include "ll/api/event/EventBus.h" #include "ll/api/event/ListenerBase.h" -#include "ll/api/schedule/Task.h" #include "ll/api/service/Bedrock.h" -#include "mc/common/wrapper/optional_ref.h" +#include "ll/api/service/GamingStatus.h" +#include "ll/api/thread/ServerThreadExecutor.h" +#include "mc/deps/core/utility/optional_ref.h" #include "mc/network/packet/TextPacket.h" #include "mc/world/actor/player/Player.h" #include "mc/world/gamemode/GameMode.h" @@ -85,60 +86,64 @@ void _SetupPlotEventScheduler() { auto* db = &data::PlotDBStorage::getInstance(); auto* ndb = &data::PlayerNameDB::getInstance(); - GlobalPlotScheduler.add(5_tick, [bus, db, ndb]() { - ll::service::getLevel()->forEachPlayer([bus, db, ndb](Player& pl) { - auto& uuid = pl.getUuid(); - - // 获取当前位置信息 - auto const& curPos = pl.getPosition(); - auto const curDim = pl.getDimensionId(); - auto const curPlot = PlotPos(curPos); - - // 获取上一次位置信息 - auto& lastDim = EventHelper::mDimidMap[uuid]; - auto& lastPlot = EventHelper::mPlotMap[uuid]; - - int const plotDimid = getPlotWorldDimensionId(); - - // 维度变化 - if (curDim != lastDim) { - // 当前不在地皮维度 & 上一次在地皮维度 & 上一次在地皮内 - if (curDim != plotDimid && lastDim == plotDimid && lastPlot.isValid()) { - bus->publish(PlayerLeavePlot{lastPlot, &pl}); // 玩家离开地皮 - } - // 当前在地皮维度 & 上一次不在地皮维度 & 当前在地皮内 - else if (curDim == plotDimid && lastDim != plotDimid && curPlot.isValid()) { - bus->publish(PlayerEnterPlot{curPlot, &pl}); // 玩家进入地皮 + ll::coro::keepThis([bus, db, ndb]() -> ll::coro::CoroTask<> { + while (ll::getGamingStatus() == ll::GamingStatus::Running) { + co_await 5_tick; + ll::service::getLevel()->forEachPlayer([bus, db, ndb](Player& pl) { + auto& uuid = pl.getUuid(); + + // 获取当前位置信息 + auto const& curPos = pl.getPosition(); + auto const curDim = pl.getDimensionId(); + auto const curPlot = PlotPos(curPos); + + // 获取上一次位置信息 + auto& lastDim = EventHelper::mDimidMap[uuid]; + auto& lastPlot = EventHelper::mPlotMap[uuid]; + + int const plotDimid = getPlotWorldDimensionId(); + + // 维度变化 + if (curDim != lastDim) { + // 当前不在地皮维度 & 上一次在地皮维度 & 上一次在地皮内 + if (curDim != plotDimid && lastDim == plotDimid && lastPlot.isValid()) { + bus->publish(PlayerLeavePlot{lastPlot, &pl}); // 玩家离开地皮 + } + // 当前在地皮维度 & 上一次不在地皮维度 & 当前在地皮内 + else if (curDim == plotDimid && lastDim != plotDimid && curPlot.isValid()) { + bus->publish(PlayerEnterPlot{curPlot, &pl}); // 玩家进入地皮 + } + lastDim = curDim; // 更新维度缓存 + lastPlot = curPlot; // 更新地皮缓存 + return true; } - lastDim = curDim; // 更新维度缓存 - lastPlot = curPlot; // 更新地皮缓存 - return true; - } - - if (curDim != plotDimid) return true; // 不在地皮维度 - if (db->getPlayerSetting(uuid.asString()).showPlotTip) { - SendPlotTip(pl, curPlot, ndb, db); - } + if (curDim != plotDimid) return true; // 不在地皮维度 - // 地皮变化 - // 1. 离开地皮 - // 2. 进入地皮 - if (curPlot != lastPlot) { - // 上一次在地皮内 & 当前不在地皮内 - if (lastPlot.isValid() && !curPlot.isValid()) { - bus->publish(PlayerLeavePlot{lastPlot, &pl}); // 玩家离开地皮 + if (db->getPlayerSetting(uuid.asString()).showPlotTip) { + SendPlotTip(pl, curPlot, ndb, db); } - // 上一次不在地皮内 & 当前在地皮内 - else if (!lastPlot.isValid() && curPlot.isValid()) { - bus->publish(PlayerEnterPlot{curPlot, &pl}); // 玩家进入地皮 + + // 地皮变化 + // 1. 离开地皮 + // 2. 进入地皮 + if (curPlot != lastPlot) { + // 上一次在地皮内 & 当前不在地皮内 + if (lastPlot.isValid() && !curPlot.isValid()) { + bus->publish(PlayerLeavePlot{lastPlot, &pl}); // 玩家离开地皮 + } + // 上一次不在地皮内 & 当前在地皮内 + else if (!lastPlot.isValid() && curPlot.isValid()) { + bus->publish(PlayerEnterPlot{curPlot, &pl}); // 玩家进入地皮 + } + lastPlot = curPlot; // 更新地皮缓存 } - lastPlot = curPlot; // 更新地皮缓存 - } - return true; - }); - }); + return true; + }); + } + co_return; + }).launch(ll::thread::ServerThreadExecutor::getDefault()); } } // namespace plot::event \ No newline at end of file diff --git a/src/plotcraft/gui/PlayerSettingGUI.cc b/src/plotcraft/gui/PlayerSettingGUI.cc index b059ebf..6453da7 100644 --- a/src/plotcraft/gui/PlayerSettingGUI.cc +++ b/src/plotcraft/gui/PlayerSettingGUI.cc @@ -1,4 +1,5 @@ #include "Global.h" +#include "ll/api/i18n/I18n.h" namespace plot::gui { @@ -6,13 +7,13 @@ namespace plot::gui { void PlayerSettingGUI(Player& player) { CustomForm fm{PLUGIN_TITLE}; - auto setting = data::PlotDBStorage::getInstance().getPlayerSetting(player.getUuid().asString()); - auto i18n = ll::i18n::getInstance().get(); - auto settingJson = JsonHelper::structToJson(setting); + auto setting = data::PlotDBStorage::getInstance().getPlayerSetting(player.getUuid().asString()); + auto& i18n = ll::i18n::getInstance(); + auto settingJson = JsonHelper::structToJson(setting); for (auto const& [key, value] : settingJson.items()) { if (key == "version") continue; - fm.appendToggle(key, string(i18n->get(key)), value.get()); + fm.appendToggle(key, string(i18n.get(key, ll::i18n::getDefaultLocaleCode())), value.get()); } fm.sendTo(player, [setting, settingJson](Player& pl, CustomFormResult const& dt, FormCancelReason) { diff --git a/src/plotcraft/gui/PlotPermissionGUI.cc b/src/plotcraft/gui/PlotPermissionGUI.cc index ef88d66..589bda6 100644 --- a/src/plotcraft/gui/PlotPermissionGUI.cc +++ b/src/plotcraft/gui/PlotPermissionGUI.cc @@ -14,7 +14,7 @@ void PlotPermissionGUI(Player& player, PlotMetadataPtr pt) { CustomForm fm{PLUGIN_TITLE}; for (auto& [key, value] : permissionTableJson.items()) { - fm.appendToggle(string(key), string(i18n->get(key)), value.get()); + fm.appendToggle(string(key), string(i18n.get(key, ll::i18n::getDefaultLocaleCode())), value.get()); } fm.sendTo(player, [pt, permissionTableJson](Player& pl, CustomFormResult const& dt, FormCancelReason) { diff --git a/src/plotcraft/math/PlotCross.cc b/src/plotcraft/math/PlotCross.cc index 0c9c685..867334b 100644 --- a/src/plotcraft/math/PlotCross.cc +++ b/src/plotcraft/math/PlotCross.cc @@ -1,8 +1,6 @@ #include "plotcraft/math/PlotCross.h" #include "fmt/core.h" #include "ll/api/service/Bedrock.h" -#include "mc/enums/BlockUpdateFlag.h" -#include "mc/math/Vec3.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/dimension/Dimension.h" @@ -113,17 +111,18 @@ void PlotCross::fill(Block const& block, bool removeBorder) { Block const& air = Block::tryGetFromRegistry("minecraft:air").value(); int const y = PlotPos::getSurfaceYStatic() - 1; + static uchar flags = (1 << 0) | (1 << 1); // 0b11 BlockUpdateFlag::All v0.13.5 for (int x = (int)min.x; x <= max.x; x++) { for (int z = (int)min.z; z <= max.z; z++) { auto& bl = bs.getBlock(x, y, z); if (!bl.isAir()) { - bs.setBlock(x, y, z, block, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y, z, block, flags, nullptr); } auto& borderBlock = bs.getBlock(x, y + 1, z); if ((removeBorder && !borderBlock.isAir()) && (x == min.x || x == max.x || z == min.z || z == max.z)) { - bs.setBlock(x, y + 1, z, air, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y + 1, z, air, flags, nullptr); } } } diff --git a/src/plotcraft/math/PlotPos.cc b/src/plotcraft/math/PlotPos.cc index a54f751..4bc453f 100644 --- a/src/plotcraft/math/PlotPos.cc +++ b/src/plotcraft/math/PlotPos.cc @@ -1,8 +1,6 @@ #include "plotcraft/math/PlotPos.h" #include "fmt/core.h" #include "ll/api/service/Bedrock.h" -#include "mc/enums/BlockUpdateFlag.h" -#include "mc/math/Vec3.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/dimension/Dimension.h" @@ -364,6 +362,7 @@ std::unique_ptr PlotPos::tryMerge(PlotPos const& other) const { bool PlotPos::operator!=(PlotPos const& other) const { return !(*this == other); } bool PlotPos::operator==(PlotPos const& other) const { return other.mVertexs == this->mVertexs; } + // static bool PlotPos::isAdjacent(const PlotPos& plot1, const PlotPos& plot2) { int dx = std::abs(plot1.mX - plot2.mX); @@ -476,10 +475,11 @@ void PlotPos::fillAABB(const BlockPos& min, const BlockPos& max, const Block& bl BlockPos end = max; Polygon::fixAABB(start, end); + static uchar flags = (1 << 0) | (1 << 1); // 0b11 BlockUpdateFlag::All v0.13.5 for (int x = start.x; x <= end.x; ++x) { for (int z = start.z; z <= end.z; ++z) { for (int y = start.y; y <= end.y; ++y) { - bs.setBlock(x, y, z, block, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y, z, block, flags, nullptr); } } } diff --git a/src/plotcraft/math/PlotRoad.cc b/src/plotcraft/math/PlotRoad.cc index b370af5..90ec5e3 100644 --- a/src/plotcraft/math/PlotRoad.cc +++ b/src/plotcraft/math/PlotRoad.cc @@ -1,8 +1,6 @@ #include "plotcraft/math/PlotRoad.h" #include "fmt/core.h" #include "ll/api/service/Bedrock.h" -#include "mc/enums/BlockUpdateFlag.h" -#include "mc/math/Vec3.h" #include "mc/world/level/BlockPos.h" #include "mc/world/level/BlockSource.h" #include "mc/world/level/dimension/Dimension.h" @@ -140,26 +138,27 @@ void PlotRoad::fill(Block const& block, bool removeBorder) { int min_z = min.z - 1; int max_z = max.z + 1; + static uchar flags = (1 << 0) | (1 << 1); // 0b11 BlockUpdateFlag::All v0.13.5 for (int x = min.x; x <= max.x; x++) { for (int z = min.z; z <= max.z; z++) { auto& bl = bs.getBlock(x, y_road, z); if (!bl.isAir()) { - bs.setBlock(x, y_road, z, block, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y_road, z, block, flags, nullptr); } if (removeBorder) { if (isX && x - 1 == min_x) { - bs.setBlock(x - 1, y_border, z, air, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x - 1, y_border, z, air, flags, nullptr); } else if (isX && x + 1 == max_x) { - bs.setBlock(x + 1, y_border, z, air, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x + 1, y_border, z, air, flags, nullptr); } else if (!isX && z - 1 == min_z) { - bs.setBlock(x, y_border, z - 1, air, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y_border, z - 1, air, flags, nullptr); } else if (!isX && z + 1 == max_z) { - bs.setBlock(x, y_border, z + 1, air, (int)BlockUpdateFlag::AllPriority, nullptr); + bs.setBlock(x, y_border, z + 1, air, flags, nullptr); } } } diff --git a/src/plugin/MyPlugin.cpp b/src/plugin/MyPlugin.cpp index 6408984..c3da5c7 100644 --- a/src/plugin/MyPlugin.cpp +++ b/src/plugin/MyPlugin.cpp @@ -39,18 +39,15 @@ namespace fs = std::filesystem; namespace my_plugin { -static std::unique_ptr instance; - -MyPlugin& MyPlugin::getInstance() { return *instance; } +MyPlugin& MyPlugin::getInstance() { + static MyPlugin instance; + return instance; +} bool MyPlugin::load() { auto& self = getSelf(); auto& logger = self.getLogger(); - if (ll::sys_utils::isStdoutSupportAnsi()) { - logger.title = fmt::format(fmt::fg(fmt::color::light_green), logger.title); - } - logger.info(R"( )"); logger.info(R"( ____ __ __ ______ ____ __ )"); logger.info(R"( / __ \ / /____ / /_ / ____/_____ ____ _ / __// /_)"); @@ -71,7 +68,7 @@ bool MyPlugin::load() { logger.info("加载数据..."); plot::Config::loadConfig(); - ll::i18n::load(langDir); + auto un_used = ll::i18n::getInstance().load(langDir); plot::data::PlotDBStorage::getInstance().load(); plot::data::PlayerNameDB::getInstance().initPlayerNameDB(); plot::EconomySystem::getInstance().update(&plot::Config::cfg.economy); @@ -128,4 +125,4 @@ bool MyPlugin::disable() { } // namespace my_plugin -LL_REGISTER_MOD(my_plugin::MyPlugin, my_plugin::instance); +LL_REGISTER_MOD(my_plugin::MyPlugin, my_plugin::MyPlugin::getInstance()); diff --git a/src/plugin/MyPlugin.h b/src/plugin/MyPlugin.h index 834c599..05f8d4c 100644 --- a/src/plugin/MyPlugin.h +++ b/src/plugin/MyPlugin.h @@ -9,7 +9,8 @@ class MyPlugin { public: static MyPlugin& getInstance(); - MyPlugin(ll::mod::NativeMod& self) : mSelf(self) {} + // MyPlugin(ll::mod::NativeMod& self) : mSelf(self) {} + MyPlugin() : mSelf(*ll::mod::NativeMod::current()) {} [[nodiscard]] ll::mod::NativeMod& getSelf() const { return mSelf; } diff --git a/xmake.lua b/xmake.lua index 0ffd5cb..8659b2b 100644 --- a/xmake.lua +++ b/xmake.lua @@ -53,7 +53,7 @@ target("PlotCraft") ) add_packages( "levilamina", - "more_events" + "ilistenattentively" ) add_files("src/**.cpp", "src/**.cc") add_includedirs(