From ce09c29431d43f162731ecb30b254ce1ac32ad72 Mon Sep 17 00:00:00 2001 From: wed150 Date: Sat, 20 Jun 2026 16:49:21 +0800 Subject: [PATCH] feat: adapt to Levilamina 26.10.5 Code references logic from ActorDamageCause.cc(GMLIB 0.13.5) --- .gitignore | 3 +- src/DeathMessage.cpp | 556 ++++++++++++++++++++++++++++++++++++++----- src/Entry.cpp | 31 ++- src/Entry.h | 9 +- src/Global.h | 6 +- xmake.lua | 49 +--- 6 files changed, 539 insertions(+), 115 deletions(-) diff --git a/.gitignore b/.gitignore index 7d43b0d..eb91e4b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ build/ /.xmake /CMakeLists.txt /bin -/.cache \ No newline at end of file +/.cache +/.idea diff --git a/src/DeathMessage.cpp b/src/DeathMessage.cpp index f55d6c0..addb139 100644 --- a/src/DeathMessage.cpp +++ b/src/DeathMessage.cpp @@ -1,123 +1,553 @@ #include "Entry.h" -#include "GMLIB/Mod/Addons/CustomDamageCause.h" -#include "Global.h" #include "ll/api/event/player/PlayerConnectEvent.h" #include "ll/api/event/player/PlayerDisconnectEvent.h" +#include "ll/api/memory/Hook.h" +#include "ll/api/chrono/GameChrono.h" +#include "ll/api/thread/ThreadPoolExecutor.h" +#include +#include "mc/world/actor/Mob.h" +#include "mc/world/actor/ActorDamageSource.h" +#include "mc/world/actor/ActorDamageByActorSource.h" +#include "mc/world/actor/ActorDamageByBlockSource.h" +#include "mc/world/actor/ActorDamageByChildActorSource.h" +#include "ll/api/service/Bedrock.h" +#include "mc/world/level/Level.h" + +#include "mc/world/actor/Actor.h" +phmap::flat_hash_map mFallHeightMap; +phmap::flat_hash_map mHurtByEntityMap; + +LL_AUTO_TYPE_INSTANCE_HOOK( + MobDieHook, + HookPriority::Normal, + Mob, + &Mob::$die, + void, + ActorDamageSource const& ads +) { + auto uid = getOrCreateUniqueID(); + + if (ads.mCause == SharedTypes::Legacy::ActorDamageCause::Fall) { + mFallHeightMap[uid.rawID] = getFallDistance(); + logger->info("跌落高度为 {}", getFallDistance()); + } + if (hasCategory(ActorCategory::Player) || isTame()) { + if (mLastHurtByMobTime != 0) { + auto hm = getLastHurtByMob(); + mHurtByEntityMap[uid.rawID] = hm->getOrCreateUniqueID(); + if (!getLastHurtByMob()->getNameTag().empty()) logger->info("伤害来源为 {}", getLastHurtByMob()->getNameTag()); + logger->info("伤害来源为 {}", getLastHurtByMob()->getTypeName()); + + + if (!getLastHurtByMob()->getCarriedItem().getCustomName().empty()) logger->info("伤害来源为 {}", getLastHurtByMob()->getCarriedItem().getCustomName()); + } + } + origin(ads); + + auto& executor = ll::thread::ThreadPoolExecutor::getDefault(); + auto callback = executor.executeAfter( + [] { + mHurtByEntityMap.clear(); + mFallHeightMap.clear(); + }, + ll::chrono::game::ticks(1) + ); +} +using DeathMessageResult = std::pair>; + +int mMaxCauseId = 34; +std::vector> mCustomCauseMap; +phmap::flat_hash_map mVanillaCauseMessage; + +phmap::flat_hash_map> mHardCodedDeathMessage; + +bool isCrystal = false; + +bool isCustomDefinition(int cause) { + if (cause >= 35) { + return true; + } + if (mVanillaCauseMessage.count(cause)) { + return true; + } + return false; +} + +bool isCustomCauseExist(std::string const& causeName) { + for (auto& key : mCustomCauseMap) { + if (key.first == causeName) { + return true; + } + } + return false; +} + +bool isCustomCauseExist(int cause) { + for (auto& key : mCustomCauseMap) { + if (key.second == cause) { + return true; + } + } + return false; +} + +SharedTypes::Legacy::ActorDamageCause getCustomCause(std::string const& causeName) { + for (auto& key : mCustomCauseMap) { + if (key.first == causeName) { + return (SharedTypes::Legacy::ActorDamageCause)key.second; + } + } + return SharedTypes::Legacy::ActorDamageCause::None; +} + +std::string getCustomCause(SharedTypes::Legacy::ActorDamageCause cause) { + for (auto& key : mCustomCauseMap) { + if ((SharedTypes::Legacy::ActorDamageCause)key.second == cause) { + return key.first; + } + } + return "none"; +} + +std::string getCause(SharedTypes::Legacy::ActorDamageCause cause) { + auto id = (int)cause; + if (isCustomCauseExist(id)) { + return getCustomCause(cause); + } + if (mVanillaCauseMessage.count(id)) { + return std::string(mVanillaCauseMessage[id]); + } + return ""; +} + + + +Actor* getDamagingEntity(ActorDamageSource* ads) { + auto id = ads->getDamagingEntityUniqueID(); + return ll::service::getLevel()->fetchEntity(id,true); +} + +// %entity.warden.name +std::string getResourcePackKey(std::string const& name, Actor* ac) { + if (ac->hasCategory(ActorCategory::Player)) { + return name; + } + auto type = ac->getTypeName(); + ll::utils::string_utils::replaceAll(type, "minecraft:", ""); + std::string res = "%entity." + type + ".name"; + return res; +} + +// 构造死亡信息输出 +DeathMessageResult makeDeathMessage( + int cause, + DeathMessageResult& deathMessage, + std::string& name, + Actor* killer, + std::string& weaponName, + bool isEscaping, + bool isHardCodedMessage = false +) { + // 自定义类型构造 + if (isCustomDefinition(cause) || isHardCodedMessage) { + std::string msg = "death.attack.damageCause.item"; + ll::utils::string_utils::replaceAll(msg, "damageCause", getCause(SharedTypes::Legacy::ActorDamageCause(cause))); + if (isHardCodedMessage) { + msg = deathMessage.first; + } + // 没有武器名不使用.item结尾 + if (weaponName.empty()) { + // 试图逃离 xx 使用.player + if (killer) { + if (isEscaping) { + ll::utils::string_utils::replaceAll(msg, ".item", ".player"); + } + } else { + ll::utils::string_utils::replaceAll(msg, ".item", ""); + } + } + DeathMessageResult res = {msg, {name}}; + if (killer) { + if (killer->isPlayer()) { + res.second.push_back(((Player*)killer)->getRealName()); + } else { + res.second.push_back(getResourcePackKey(name, killer)); + } + auto weaponname = killer->getCarriedItem().getCustomName(); + if (!weaponname.empty()) { + weaponname = "[" + weaponname + "§r]"; + res.second.push_back(weaponname); + } else { + ll::utils::string_utils::replaceAll(res.first, ".item", ""); + } + } else { + // 如果没有击杀者和试图逃离,那么不可能使用 .player 结尾 + ll::utils::string_utils::replaceAll(res.first, ".player", ""); + } + return res; + } + // 未定义返回vanilla值 + return deathMessage; +} + +DeathMessageResult tryTranslateHardCodedFallingDeathMessage( + DeathMessageResult& deathMessage, + std::string& name, + Actor* killer, + std::string& directKiller, + std::string& weaponName, + bool isEscaping, + int64 deadUniqueId +) { + if (!directKiller.empty()) { + deathMessage.first = "death.fell.finish.item"; + } + // 低处 + else if (deathMessage.first == "death.attack.fall") { + deathMessage.first = "death.attack.fall.item"; + } + // 高处 + else if (deathMessage.first == "death.fell.accident.generic") { + // 试图逃离而亡 + if (killer) { + std::string weapon = killer->getCarriedItem().getCustomName(); + if (!weapon.empty()) { + deathMessage.first = "death.fell.assist.item"; + } else { + deathMessage.first = "death.fell.assist"; + } + } + // 超高 + else if (mFallHeightMap[deadUniqueId] >= 100) { + deathMessage.first = "death.fell.killer"; + } else { + deathMessage.first = "death.fell.accident.generic"; + } + } else { + deathMessage.first = "death.attack.generic"; + } + return makeDeathMessage((int)SharedTypes::Legacy::ActorDamageCause::Fall, deathMessage, name, killer, weaponName, isEscaping, true); +} + +std::optional tryTranslateHardCodedDeathMessage( + SharedTypes::Legacy::ActorDamageCause cause, + DeathMessageResult& deathMessage, + std::string& name, + Actor* killer, + std::string& directKiller, + std::string& weaponName, + bool isEscaping, + int64 deadUniqueId +) { + switch (cause) { + // 硬编码摔死信息 + case SharedTypes::Legacy::ActorDamageCause::Fall: { + return tryTranslateHardCodedFallingDeathMessage( + deathMessage, + name, + killer, + directKiller, + weaponName, + isEscaping, + deadUniqueId + ); + } + // 硬编码爆炸信息 + case SharedTypes::Legacy::ActorDamageCause::BlockExplosion: { + if (!isCrystal) { + deathMessage.first = "death.attack.badRespawnPoint.message"; + } else { + deathMessage.first = "death.attack.explosion.item"; + } + return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true); + } + case SharedTypes::Legacy::ActorDamageCause::Contact: { + switch (ll::hash_utils::doHash(deathMessage.first)) { + case ll::hash_utils::doHash("death.attack.cactus"): + deathMessage.first = "death.attack.cactus.item"; + break; + case ll::hash_utils::doHash("death.attack.sweetBerry"): + deathMessage.first = "death.attack.sweetBerry.item"; + break; + default: + deathMessage.first = "death.attack.generic.item"; + break; + } + return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true); + } + } + if (mHardCodedDeathMessage.contains(cause)) { + if (directKiller.empty()) { + directKiller = "empty"; + } + if (mHardCodedDeathMessage[cause].contains(directKiller)) { + deathMessage.first = std::string(mHardCodedDeathMessage[cause][directKiller]); + return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true); + } else if (mHardCodedDeathMessage[cause].contains("all")) { + deathMessage.first = std::string(mHardCodedDeathMessage[cause]["all"]); + return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true); + } + } + return {}; +} + +DeathMessageResult translateDeathMessage(DeathMessageResult origin, std::string name, Actor* dead, ActorDamageSource* ads) { + name = getResourcePackKey(name, dead); + if (origin.first.length() > 65565) { + return {"death.attack.even_more_magic", {name}}; + } + auto damageCause = ads->mCause; // 伤害类型 + Actor* killer = nullptr; // 击杀者 + std::string directKiller; // 直接击杀实体 + std::string weaponName; // 是否持有武器 + bool isEscaping = false; + int64 uid = dead->getOrCreateUniqueID().rawID; + if (ads->isEntitySource()) { + directKiller = getDamagingEntity(ads)->getTypeName(); + if (ads->isChildEntitySource()) { + killer = getDamagingEntity(ads)->getOwner(); + } else { + killer = getDamagingEntity(ads); + } + } + if (killer == nullptr && mHurtByEntityMap.count(uid)) { + killer = ll::service::getLevel()->fetchEntity(mHurtByEntityMap[uid],true); + isEscaping = true; + } + if (killer != nullptr) { + weaponName = killer->getCarriedItem().getCustomName(); + } + // Vanilla的硬编码死亡信息类型 + auto result = + tryTranslateHardCodedDeathMessage(damageCause, origin, name, killer, directKiller, weaponName, isEscaping, uid); + if (result.has_value()) { + return result.value(); + } + return makeDeathMessage((int)damageCause, origin, name, killer, weaponName, isEscaping); +} + +LL_AUTO_TYPE_INSTANCE_HOOK( + DeathMessageHook1, + HookPriority::Lowest, + ActorDamageSource, + &ActorDamageSource::$getDeathMessage, + + + DeathMessageResult, + + std::string a1, + Actor* a2 +) { + + + + auto originl = origin(a1, a2); + logger->info("原消息name为 {}", a1); + logger->info("原消息为 {}", originl.first); + auto res = translateDeathMessage(originl, a1, a2, this); + return res; +} + +LL_AUTO_TYPE_INSTANCE_HOOK( + DeathMessageHook2, + HookPriority::Lowest, + ActorDamageByActorSource, + &ActorDamageByActorSource::$getDeathMessage, + DeathMessageResult, + std::string a1, + Actor* a2 +) { + auto originl = origin(a1, a2); + logger->info("原消息name为 {}", a1); + logger->info("原消息为 {}", originl.first); + auto res = translateDeathMessage(originl, a1, a2, this); + return res; +} + +LL_AUTO_TYPE_INSTANCE_HOOK( + DeathMessageHook3, + HookPriority::Lowest, + ActorDamageByBlockSource, + &ActorDamageByBlockSource::$getDeathMessage, + + DeathMessageResult, + std::string a1, + Actor* a2 +) { + auto originl = origin(a1, a2); + logger->info("原消息name为 {}", a1); + logger->info("原消息为 {}", originl.first); + auto res = translateDeathMessage(originl, a1, a2, this); + return res; +} + +LL_AUTO_TYPE_INSTANCE_HOOK( + DeathMessageHook4, + HookPriority::Lowest, + ActorDamageByChildActorSource, + &ActorDamageByChildActorSource::$getDeathMessage, + + + DeathMessageResult, + std::string a1, + Actor* a2 +) { + auto originl = origin(a1, a2); + logger->info("原消息name为 {}", a1); + logger->info("原消息为 {}", originl.first); + auto res = translateDeathMessage(originl, a1, a2, this); + return res; +} +int getNextCauseId() { + mMaxCauseId++; + return mMaxCauseId; +} + +bool registerDamageCause(std::string const& causeName) { + if (!isCustomCauseExist(causeName)) { + auto id = getNextCauseId(); + mCustomCauseMap.push_back({causeName, id}); + return true; + } + return false; +} + +bool setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause cause, std::string_view msg) { + auto id = (int)cause; + if (!mVanillaCauseMessage.count(id)) { + mVanillaCauseMessage[id] = msg; + return true; + } + return false; +} + +bool registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause cause, + std::string_view message, + std::string_view killerType +) { + if (mHardCodedDeathMessage.contains(cause)) { + if (mHardCodedDeathMessage[cause].contains(killerType)) { + return false; + } + } + mHardCodedDeathMessage[cause][killerType] = message; + return true; +} void RegisterDamageDefinition() { - GMLIB::Mod::DamageCause::DamageCause::setCustomDamageCauseEnabled(); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Anvil, "anvil"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::EntityAttack, "mob"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::RamAttack, "mob"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Drowning, "drown"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FallingBlock, "fallingBlock"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Fire, "inFire"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FireTick, "onFire"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Fireworks, "fireworks"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FlyIntoWall, "flyIntoWall"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Freezing, "freeze"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Lava, "lava"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Lightning, "lightningBolt"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Wither, "wither"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Magic, "indirectMagic"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Magma, "hotFloor"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Stalactite, "stalactite"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Stalagmite, "stalagmite"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Starve, "starve"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Suffocation, "inWall"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::SonicBoom, "sonicBoom"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Void, "outOfWorld"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::SelfDestruct, "genericKill"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Projectile, "thrown"); - GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Thorns, "thorns"); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Anvil, "anvil"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::EntityAttack, "mob"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::RamAttack, "mob"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Drowning, "drown"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FallingBlock, "fallingBlock"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Fire, "inFire"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FireTick, "onFire"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Fireworks, "fireworks"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FlyIntoWall, "flyIntoWall"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Freezing, "freeze"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Lava, "lava"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Lightning, "lightningBolt"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Wither, "wither"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Magic, "indirectMagic"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Magma, "hotFloor"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Stalactite, "stalactite"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Stalagmite, "stalagmite"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Starve, "starve"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Suffocation, "inWall"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::SonicBoom, "sonicBoom"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Void, "outOfWorld"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::SelfDestruct, "genericKill"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Projectile, "thrown"); + setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Thorns, "thorns"); + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.fireball.item", "minecraft:small_fireball" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.trident.item", "minecraft:thrown_trident" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.spit", "minecraft:llama_spit" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.bullet", "minecraft:shulker_bullet" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.arrow.item", "minecraft:arrow" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.explosion.player", "minecraft:fireball" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Projectile, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Projectile, "death.attack.mob", "minecraft:breeze_wind_charge_projectile" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Magic, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Magic, "death.attack.magic", "empty" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::SonicBoom, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::SonicBoom, "death.attack.sonicBoom", "minecraft:warden" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::Thorns, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::Thorns, "death.attack.generic", "empty" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::EntityExplosion, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::EntityExplosion, "death.attack.explosion.player", "all" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::EntityExplosion, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::EntityExplosion, "minecraft:wither_skull", "death.attack.witherSkull.item" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::EntityExplosion, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::EntityExplosion, "minecraft:wither_skull_dangerous", "death.attack.witherSkull.item" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::EntityAttack, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::EntityAttack, "minecraft:player", "death.attack.player.item" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::EntityAttack, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::EntityAttack, "minecraft:bee", "death.attack.sting.item" ); - GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage( - ActorDamageCause::RamAttack, + registerCustomDeathMessage( + SharedTypes::Legacy::ActorDamageCause::RamAttack, "minecraft:player", "death.attack.player.item" ); } - +/* void ListenEvents() { auto& config = DeathMessages::Entry::getInstance().getConfig(); auto& eventBus = ll::event::EventBus::getInstance(); if (config.ConsoleLog.JoinMessage) { eventBus.emplaceListener([](ll::event::player::PlayerConnectEvent& ev) { - infoLogger->info(fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.joined", {ev.self().getName()})) + infoLogger->info(fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.joined", {ev.self().getRealName()})) ); }); } @@ -125,7 +555,7 @@ void ListenEvents() { eventBus.emplaceListener( [](ll::event::player::PlayerDisconnectEvent& ev) { infoLogger->info( - fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.left", {ev.self().getName()})) + fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.left", {ev.self().getRealName()})) ); } ); @@ -140,4 +570,4 @@ void ListenEvents() { } ); } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/Entry.cpp b/src/Entry.cpp index 8f04364..b54b96b 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -1,6 +1,16 @@ #include "Entry.h" #include "Global.h" #include "Language.h" +#include "ll/api/mod/Mod.h" +#include "ll/api/Config.h" +#include "ll/api/io/PatternFormatter.h" +#include "ll/api/io/Logger.h" +#include "ll/api/io/LoggerRegistry.h" +#include "ll/api/io/FileSink.h" +#include "ll/api/mod/RegisterHelper.h" +#include "ll/api/data/IndirectValue.h" +#include "gmlib/gm/i18n/LangI18n.h" +#include "gmlib/gm/i18n/ResourceI18n.h" ll::io::LoggerRegistry& loggerRegistry = ll::io::LoggerRegistry::getInstance(); std::shared_ptr logger = loggerRegistry.getOrCreate(MOD_NAME); @@ -35,8 +45,8 @@ bool Entry::load() { } bool Entry::enable() { - RegisterDamageDefinition(); - ListenEvents(); + /* RegisterDamageDefinition(); + ListenEvents();*/ return true; } @@ -51,10 +61,10 @@ bool Entry::unload() { Config& Entry::getConfig() { return mConfig.value(); } -std::optional Entry::getI18n() { return mI18n; } +std::unique_ptr Entry::getI18n() { return std::move(mI18n); } void Entry::loadI18n() { - mI18n.emplace(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language); + mI18n= std::make_unique(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language); mI18n->updateOrCreateLanguage("en_US", en_US); mI18n->updateOrCreateLanguage("zh_CN", zh_CN); mI18n->loadAllLanguages(); @@ -62,8 +72,7 @@ void Entry::loadI18n() { } void Entry::loadResourcePack() { - GMLIB::Mod::VanillaFix::setFixI18nEnabled(); - auto resource = GMLIB::Files::ResourceLanguage(getSelf().getModDir() / u8"resource", MOD_NAME, 0, 8, 0); + auto resource = gmlib::i18n::ResourceI18n(getSelf().getModDir() / u8"resource", MOD_NAME, 0, 8, 0); resource.addLanguage("en_US", en_US); resource.addLanguage("zh_CN", zh_CN); } @@ -72,9 +81,13 @@ void Entry::loadResourcePack() { LL_REGISTER_MOD(DeathMessages::Entry, DeathMessages::Entry::getInstance()); -std::string tr(std::string const& key, std::vector const& params) { +/*std::string tr(std::string const& key, std::vector const& params) { if (auto i18n = DeathMessages::Entry::getInstance().getI18n()) { return i18n->get(key, params); } - return ::I18nAPI::get(key, params); -} \ No newline at end of file + auto i18n = DeathMessages::Entry::getI18n(); + + return i18n->get(key, params); + + +}*/ \ No newline at end of file diff --git a/src/Entry.h b/src/Entry.h index 2ba2001..73cf400 100644 --- a/src/Entry.h +++ b/src/Entry.h @@ -1,6 +1,11 @@ #pragma once #include "Config.h" #include "Global.h" +#include "ll/api/mod/Mod.h" + +#include + +#include namespace DeathMessages { @@ -27,7 +32,7 @@ public: Config& getConfig(); - std::optional getI18n(); + std::unique_ptr getI18n(); void loadI18n(); @@ -36,7 +41,7 @@ public: private: ll::mod::NativeMod& mSelf; std::optional mConfig; - std::optional mI18n; + std::unique_ptr mI18n; }; } // namespace DeathMessages diff --git a/src/Global.h b/src/Global.h index 4df6d70..55c481c 100644 --- a/src/Global.h +++ b/src/Global.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #define MOD_NAME "DeathMessages" @@ -7,7 +7,7 @@ extern std::shared_ptr logger; extern std::shared_ptr deathLogger; extern std::shared_ptr infoLogger; -extern std::string tr(std::string const& key, std::vector const& data = {}); +/*extern std::string tr(std::string const& key, std::vector const& data = {}); extern void RegisterDamageDefinition(); -extern void ListenEvents(); \ No newline at end of file +extern void ListenEvents();*/ \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 841da63..9fd647e 100644 --- a/xmake.lua +++ b/xmake.lua @@ -7,45 +7,20 @@ if not has_config("vs_runtime") then set_runtimes("MD") end -add_requires("levilamina 1.0.0") -add_requires("levibuildscript 0.3.0") -add_requires("gmlib 0.13.10") +add_requires("levilamina 26.10.5",{configs = {target_type = "server"}}) +add_requires("levibuildscript") +add_requires("gmlib 26.10.0") target("DeathMessages") -- Change this to your mod name. - add_cxflags( - "/EHa", - "/utf-8" - ) - add_files( - "src/**.cpp" - ) - add_includedirs( - "src" - ) - add_packages( - "levilamina", - "gmlib" - ) - add_defines( - "NOMINMAX", - "UNICODE", - "_HAS_CXX17", - "_HAS_CXX20", - "_HAS_CXX23" - ) add_rules("@levibuildscript/linkrule") - set_exceptions("none") + add_rules("@levibuildscript/modpacker") + add_cxflags( "/EHa", "/utf-8", "/W4", "/w44265", "/w44289", "/w44296", "/w45263", "/w44738", "/w45204") + add_defines("NOMINMAX", "UNICODE") + add_packages("levilamina","gmlib") + set_exceptions("none") -- To avoid conflicts with /EHa. set_kind("shared") - set_languages("cxx20") + set_languages("c++23") set_symbols("debug") - - after_build(function (target) - local mod_packer = import("scripts.after_build") - - local mod_define = { - modName = target:name(), - modFile = path.filename(target:targetfile()), - } - - mod_packer.pack_mod(target,mod_define) - end) + add_headerfiles("src/**.h") + add_files("src/**.cpp") + add_includedirs("src")