Compare commits

..

5 Commits

9 changed files with 88 additions and 36 deletions
+12 -3
View File
@@ -19,17 +19,26 @@ That allows players to freely switch languages on their own.
## Death Messages Translation
By default, this plugin uses resource packs for translation to ensure perfect compatibility with various addons. <br> `This requires ModAPI to be enabled.`
### Resource Pack Translation
By default, this plugin uses resource packs for translation to ensure perfect compatibility with various addons. <br>
<br>(The plugin automatically builds the resource pack and sends it to players upon joining. Using resource pack-based translation is recommended.)
>[!IMPORTANT]
>If you wnt to use Resource Pack Translation<br>
>This requires ModAPI to be enabled.<br>
>You can configure language for console in `server.properties` like `language=en_US`
### Server-Side Translation
If you prefer not to use resource packs, you can enable server-side translation in the configuration file.<br> This way, all translations are handled entirely on the server without requiring any client-side resource packs.
>[!IMPORTANT]
>You can configure language for Server-Side Translation in `./plugins/DeathMessages/config/config.json` like `Language=en_US`
#### For issues, please report them via GitHub Issues!!!
#### Pull Requests are also welcome!
You can also customize death messages by editing the language files.<br>
(The resource pack will be generated in the ./plugins/DeathMessages/log directory; feel free to modify it as needed.)
<br> `This requires ModAPI to be enabled.`
(The language files will be generated in the ./plugins/DeathMessages/lang directory; feel free to modify it as needed.)
>[!WARNING]
> DO NOT modify files in directory `./plugins/DeathMessages/resource`, unless you know what you are doing
High performance: Implemented using native functions with no additional data storage, resulting in minimal performance overhead.
Uses native death message broadcasting, preserving the vanilla showdeathmessages game rule behavior.
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "${modName}",
"entry": "${modFile}",
"type": "native",
"version": "0.14.0",
"version": "0.14.1",
"author": "GroupMountain",
"description": "Better Death Messages",
"dependencies": [
+14 -1
View File
@@ -10,6 +10,8 @@
#include "mc/world/actor/Mob.h"
#include "mc/world/level/Level.h"
#include <gmlib/mc/locale/I18nAPI.h>
//===============GMLIB 0.13.5 ActorDamageCause.cc===============
phmap::flat_hash_map<int64, float> mFallHeightMap;
@@ -83,10 +85,21 @@ DeathMessageResult makeDeathMessage(
// 如果没有击杀者和试图逃离,那么不可能使用 .player 结尾
ll::utils::string_utils::replaceAll(res.first, ".player", "");
}
if (!DeathMessages::Entry::getInstance().isResourceI18nLoaded) {
res.first=tr(res.first, res.second);
auto translatedMessage=tr(res.first, res.second);
res.first = translatedMessage;
res.second = {};
}
auto& config = DeathMessages::Entry::getInstance().getConfig();
if (config.ConsoleLog.DeathMessage) {
auto translatedMessage=tr(res.first, res.second);
deathLogger->info(translatedMessage);
}
return res;
}
// 未定义返回vanilla值
+50 -13
View File
@@ -12,9 +12,12 @@
#include "ll/api/mod/ModManagerRegistry.h"
#include "ll/api/mod/RegisterHelper.h"
#include "ll/api/service/Bedrock.h"
#include "ll/api/io/FileUtils.h"
#include <filesystem>
#include "gmlib/gm/i18n/LangI18n.h"
#include "gmlib/gm/i18n/ResourceI18n.h"
#include "gmlib/mc/locale/I18nAPI.h"
ll::io::LoggerRegistry& loggerRegistry = ll::io::LoggerRegistry::getInstance();
std::shared_ptr<ll::io::Logger> logger = loggerRegistry.getOrCreate(MOD_NAME);
@@ -33,8 +36,13 @@ Entry& Entry::getInstance() {
}
bool Entry::load() {
isResourceI18nLoaded=false;
isResourceI18nLoaded=false;
if (!ll::file_utils::readFile(getSelf().getLangDir() / u8"en_US.lang").has_value()) {
ll::file_utils::writeFile(getSelf().getLangDir() / u8"en_US.lang", en_US);
}
if (!ll::file_utils::readFile(getSelf().getLangDir() / u8"zh_CN.lang").has_value()) {
ll::file_utils::writeFile(getSelf().getLangDir() / u8"zh_CN.lang", zh_CN);
}
mConfig.emplace();
if (!ll::config::loadConfig(*mConfig, getSelf().getConfigDir() / u8"config.json")) {
ll::config::saveConfig(*mConfig, getSelf().getConfigDir() / u8"config.json");
@@ -46,9 +54,11 @@ bool Entry::load() {
ll::makePolymorphic<ll::io::PatternFormatter>("[{3:.3%F %T.} {2}][{1}] {0}", false);
deathLogger->addSink(std::make_shared<ll::io::FileSink>(path, polymorphicFormatter));
}
loadI18n();
if ((!getConfig().ServerSideTranslation.Enabled)&&ll::mod::ModManagerRegistry::getInstance().hasMod("ModAPI")) {
loadResourcePack();
}else {
loadI18n();
}
return true;
}
@@ -82,19 +92,38 @@ gmlib::i18n::LangI18n& Entry::getI18n() {
}
void Entry::loadI18n() {
const std::string custom_zh_CN = ll::file_utils::readFile(
getSelf().getLangDir() / u8"zh_CN.lang",
false
)
.value_or(zh_CN);
const std::string custom_en_US = ll::file_utils::readFile(
getSelf().getLangDir() / u8"en_US.lang",
false
)
.value_or(en_US);
mI18n= std::make_unique<gmlib::i18n::LangI18n>(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language);
mI18n->updateOrCreateLanguage("en_US", en_US);
mI18n->updateOrCreateLanguage("zh_CN", zh_CN);
mI18n->updateOrCreateLanguage("en_US", custom_en_US);
mI18n->updateOrCreateLanguage("zh_CN", custom_zh_CN);
mI18n->loadAllLanguages();
mI18n->setDefaultLanguage("zh_CN");
mI18n->setDefaultLanguage(getConfig().ServerSideTranslation.Language);
}
void Entry::loadResourcePack() {
auto mResource = std::make_unique<gmlib::i18n::ResourceI18n>(getSelf().getModDir() / u8"lang", MOD_NAME, 0, 16, 1);
mResource->addLanguage("en_US", en_US);
mResource->addLanguage("zh_CN", zh_CN);
if (
ll::file_utils::readFile(getSelf().getLangDir() / u8"en_US.lang")!=
ll::file_utils::readFile(getSelf().getModDir() / u8"resource/language_pack/texts/en_US.lang")
||ll::file_utils::readFile(getSelf().getLangDir() / u8"zh_CN.lang")!=
ll::file_utils::readFile(getSelf().getModDir() / u8"resource/language_pack/texts/zh_CN.lang")
)
std::filesystem::remove_all(getSelf().getModDir() / u8"resource");
auto mResource = std::make_unique<gmlib::i18n::ResourceI18n>(getSelf().getModDir() / u8"resource", MOD_NAME, 0, 16, 1);
mResource->addLanguageFromPath("zh_CN",getSelf().getLangDir() / u8"zh_CN.lang");
mResource->addLanguageFromPath("en_US",getSelf().getLangDir() / u8"en_US.lang");
mResource->loadAllLanguages();
isResourceI18nLoaded=true;
}
@@ -107,11 +136,19 @@ void Entry::loadResourcePack() {
LL_REGISTER_MOD(DeathMessages::Entry, DeathMessages::Entry::getInstance());
std::string tr(std::string const& key, std::vector<std::string> const& params) {
std::string tr(std::string const& key, std::vector<std::string> params) {
if (DeathMessages::Entry::getInstance().isResourceI18nLoaded) {
return gmlib::I18nAPI::get(key, params);
}
auto& i18n = DeathMessages::Entry::getInstance().getI18n();
return i18n.get(key, params);
logger->info(DeathMessages::Entry::getInstance().isResourceI18nLoaded ? "ResourceI18nLoaded" : "LangI18nLoaded");
if (params.size() > 1)
params.at(1) = gmlib::I18nAPI::get(
params.at(1),
{},
DeathMessages::Entry::getInstance().getConfig().ServerSideTranslation.Language
);
return i18n.get(key, params);
return key;
}
+1 -1
View File
@@ -17,4 +17,4 @@ extern bool isCrystal;
using DeathMessageResult = std::pair<std::string, std::vector<std::string>>;
extern DeathMessageResult translateDeathMessage(DeathMessageResult origin, std::string name, Actor* dead, ActorDamageSource* ads);
extern std::string tr(std::string const& key, std::vector<std::string> const& params = {});
extern std::string tr(std::string const& key, std::vector<std::string> params = {});
+5 -5
View File
@@ -87,8 +87,8 @@ LL_AUTO_TYPE_INSTANCE_HOOK(
auto res = translateDeathMessage(originl, a1, a2, this);
return res;
}
LL_AUTO_TYPE_INSTANCE_HOOK(
//
/*LL_AUTO_TYPE_INSTANCE_HOOK(
ActorDamageByActorHook,
HookPriority::Lowest,
ActorDamageByActorSource,
@@ -128,13 +128,13 @@ LL_AUTO_TYPE_INSTANCE_HOOK(
auto originl = origin(a1, a2);
auto res = translateDeathMessage(originl, a1, a2, this);
return res;
}
}*/
void uninstallHooks() {
MobDieHook::unhook();
CryatslHurtHook::unhook();
ActorDamageHook::unhook();
ActorDamageByActorHook::unhook();
/*ActorDamageByActorHook::unhook();
ActorDamageByBlockHook::unhook();
ActorDamageByChildHook::unhook();
ActorDamageByChildHook::unhook();*/
}
+3 -11
View File
@@ -8,7 +8,6 @@
#include "ll/api/event/EventBus.h"
ll::event::ListenerPtr playerConnectEventListener;
ll::event::ListenerPtr playerDieEventListener;
ll::event::ListenerPtr playerDisconnectEventListener;
void ListenEvents() {
auto& config = DeathMessages::Entry::getInstance().getConfig();
@@ -30,20 +29,13 @@ void ListenEvents() {
}
);
}
if (config.ConsoleLog.DeathMessage) {
playerDieEventListener=eventBus.emplaceListener<ll::event::player::PlayerDieEvent>(
[](ll::event::player::PlayerDieEvent& ev) {
auto [key, params] = ev.source().getDeathMessage(ev.self().getRealName(), &ev.self());
auto info = tr(key, params);
deathLogger->info(info);
}
);
}
//Die Message move to DeathMessage.cpp 93L
}
void uninstallEventListeners() {
auto& eventBus = ll::event::EventBus::getInstance();
eventBus.removeListener(playerDieEventListener);
eventBus.removeListener(playerConnectEventListener);
eventBus.removeListener(playerDisconnectEventListener);
}
+1
View File
@@ -4,3 +4,4 @@
#define LL_MEMORY_OPERATORS
#include "ll/api/memory/MemoryOperators.h" // IWYU pragma: keep
+1 -1
View File
@@ -2,7 +2,7 @@
"format_version": 3,
"format_uuid": "289f771f-2c9a-4d73-9f3f-8492495a924d",
"tooth": "github.com/GroupMountain/DeathMessages",
"version": "0.14.0",
"version": "0.14.1",
"info": {
"name": "DeathMessages",
"description": "Better Death Messages on MCBE",