Compare commits
2 Commits
8aaef54548
..
main
@@ -19,17 +19,26 @@ That allows players to freely switch languages on their own.
|
|||||||
|
|
||||||
## Death Messages Translation
|
## 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.)
|
<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.
|
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!!!
|
#### For issues, please report them via GitHub Issues!!!
|
||||||
#### Pull Requests are also welcome!
|
#### Pull Requests are also welcome!
|
||||||
|
|
||||||
You can also customize death messages by editing the language files.<br>
|
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.)
|
(The language files will be generated in the ./plugins/DeathMessages/lang directory; feel free to modify it as needed.)
|
||||||
<br> `This requires ModAPI to be enabled.`
|
>[!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.
|
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.
|
Uses native death message broadcasting, preserving the vanilla showdeathmessages game rule behavior.
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "${modName}",
|
"name": "${modName}",
|
||||||
"entry": "${modFile}",
|
"entry": "${modFile}",
|
||||||
"type": "native",
|
"type": "native",
|
||||||
"version": "0.14.0",
|
"version": "0.14.1",
|
||||||
"author": "GroupMountain",
|
"author": "GroupMountain",
|
||||||
"description": "Better Death Messages",
|
"description": "Better Death Messages",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|||||||
+14
-1
@@ -10,6 +10,8 @@
|
|||||||
#include "mc/world/actor/Mob.h"
|
#include "mc/world/actor/Mob.h"
|
||||||
#include "mc/world/level/Level.h"
|
#include "mc/world/level/Level.h"
|
||||||
|
|
||||||
|
#include <gmlib/mc/locale/I18nAPI.h>
|
||||||
|
|
||||||
//===============GMLIB 0.13.5 ActorDamageCause.cc===============
|
//===============GMLIB 0.13.5 ActorDamageCause.cc===============
|
||||||
|
|
||||||
phmap::flat_hash_map<int64, float> mFallHeightMap;
|
phmap::flat_hash_map<int64, float> mFallHeightMap;
|
||||||
@@ -83,10 +85,21 @@ DeathMessageResult makeDeathMessage(
|
|||||||
// 如果没有击杀者和试图逃离,那么不可能使用 .player 结尾
|
// 如果没有击杀者和试图逃离,那么不可能使用 .player 结尾
|
||||||
ll::utils::string_utils::replaceAll(res.first, ".player", "");
|
ll::utils::string_utils::replaceAll(res.first, ".player", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DeathMessages::Entry::getInstance().isResourceI18nLoaded) {
|
if (!DeathMessages::Entry::getInstance().isResourceI18nLoaded) {
|
||||||
res.first=tr(res.first, res.second);
|
auto translatedMessage=tr(res.first, res.second);
|
||||||
|
res.first = translatedMessage;
|
||||||
res.second = {};
|
res.second = {};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
auto& config = DeathMessages::Entry::getInstance().getConfig();
|
||||||
|
|
||||||
|
if (config.ConsoleLog.DeathMessage) {
|
||||||
|
auto translatedMessage=tr(res.first, res.second);
|
||||||
|
deathLogger->info(translatedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
// 未定义返回vanilla值
|
// 未定义返回vanilla值
|
||||||
|
|||||||
+48
-11
@@ -12,9 +12,12 @@
|
|||||||
#include "ll/api/mod/ModManagerRegistry.h"
|
#include "ll/api/mod/ModManagerRegistry.h"
|
||||||
#include "ll/api/mod/RegisterHelper.h"
|
#include "ll/api/mod/RegisterHelper.h"
|
||||||
#include "ll/api/service/Bedrock.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/LangI18n.h"
|
||||||
#include "gmlib/gm/i18n/ResourceI18n.h"
|
#include "gmlib/gm/i18n/ResourceI18n.h"
|
||||||
|
#include "gmlib/mc/locale/I18nAPI.h"
|
||||||
|
|
||||||
ll::io::LoggerRegistry& loggerRegistry = ll::io::LoggerRegistry::getInstance();
|
ll::io::LoggerRegistry& loggerRegistry = ll::io::LoggerRegistry::getInstance();
|
||||||
std::shared_ptr<ll::io::Logger> logger = loggerRegistry.getOrCreate(MOD_NAME);
|
std::shared_ptr<ll::io::Logger> logger = loggerRegistry.getOrCreate(MOD_NAME);
|
||||||
@@ -34,7 +37,12 @@ Entry& Entry::getInstance() {
|
|||||||
|
|
||||||
bool Entry::load() {
|
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();
|
mConfig.emplace();
|
||||||
if (!ll::config::loadConfig(*mConfig, getSelf().getConfigDir() / u8"config.json")) {
|
if (!ll::config::loadConfig(*mConfig, getSelf().getConfigDir() / u8"config.json")) {
|
||||||
ll::config::saveConfig(*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);
|
ll::makePolymorphic<ll::io::PatternFormatter>("[{3:.3%F %T.} {2}][{1}] {0}", false);
|
||||||
deathLogger->addSink(std::make_shared<ll::io::FileSink>(path, polymorphicFormatter));
|
deathLogger->addSink(std::make_shared<ll::io::FileSink>(path, polymorphicFormatter));
|
||||||
}
|
}
|
||||||
loadI18n();
|
|
||||||
if ((!getConfig().ServerSideTranslation.Enabled)&&ll::mod::ModManagerRegistry::getInstance().hasMod("ModAPI")) {
|
if ((!getConfig().ServerSideTranslation.Enabled)&&ll::mod::ModManagerRegistry::getInstance().hasMod("ModAPI")) {
|
||||||
loadResourcePack();
|
loadResourcePack();
|
||||||
|
}else {
|
||||||
|
loadI18n();
|
||||||
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -82,19 +92,38 @@ gmlib::i18n::LangI18n& Entry::getI18n() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Entry::loadI18n() {
|
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= std::make_unique<gmlib::i18n::LangI18n>(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language);
|
||||||
mI18n->updateOrCreateLanguage("en_US", en_US);
|
mI18n->updateOrCreateLanguage("en_US", custom_en_US);
|
||||||
mI18n->updateOrCreateLanguage("zh_CN", zh_CN);
|
mI18n->updateOrCreateLanguage("zh_CN", custom_zh_CN);
|
||||||
mI18n->loadAllLanguages();
|
mI18n->loadAllLanguages();
|
||||||
mI18n->setDefaultLanguage("zh_CN");
|
mI18n->setDefaultLanguage(getConfig().ServerSideTranslation.Language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Entry::loadResourcePack() {
|
void Entry::loadResourcePack() {
|
||||||
auto mResource = std::make_unique<gmlib::i18n::ResourceI18n>(getSelf().getModDir() / u8"lang", MOD_NAME, 0, 16, 1);
|
if (
|
||||||
mResource->addLanguage("en_US", en_US);
|
ll::file_utils::readFile(getSelf().getLangDir() / u8"en_US.lang")!=
|
||||||
mResource->addLanguage("zh_CN", zh_CN);
|
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();
|
mResource->loadAllLanguages();
|
||||||
isResourceI18nLoaded=true;
|
isResourceI18nLoaded=true;
|
||||||
}
|
}
|
||||||
@@ -107,11 +136,19 @@ void Entry::loadResourcePack() {
|
|||||||
|
|
||||||
LL_REGISTER_MOD(DeathMessages::Entry, DeathMessages::Entry::getInstance());
|
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();
|
auto& i18n = DeathMessages::Entry::getInstance().getI18n();
|
||||||
|
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 i18n.get(key, params);
|
||||||
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -17,4 +17,4 @@ extern bool isCrystal;
|
|||||||
using DeathMessageResult = std::pair<std::string, std::vector<std::string>>;
|
using DeathMessageResult = std::pair<std::string, std::vector<std::string>>;
|
||||||
|
|
||||||
extern DeathMessageResult translateDeathMessage(DeathMessageResult origin, std::string name, Actor* dead, ActorDamageSource* ads);
|
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
@@ -87,8 +87,8 @@ LL_AUTO_TYPE_INSTANCE_HOOK(
|
|||||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
/*LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||||
ActorDamageByActorHook,
|
ActorDamageByActorHook,
|
||||||
HookPriority::Lowest,
|
HookPriority::Lowest,
|
||||||
ActorDamageByActorSource,
|
ActorDamageByActorSource,
|
||||||
@@ -128,13 +128,13 @@ LL_AUTO_TYPE_INSTANCE_HOOK(
|
|||||||
auto originl = origin(a1, a2);
|
auto originl = origin(a1, a2);
|
||||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||||
return res;
|
return res;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void uninstallHooks() {
|
void uninstallHooks() {
|
||||||
MobDieHook::unhook();
|
MobDieHook::unhook();
|
||||||
CryatslHurtHook::unhook();
|
CryatslHurtHook::unhook();
|
||||||
ActorDamageHook::unhook();
|
ActorDamageHook::unhook();
|
||||||
ActorDamageByActorHook::unhook();
|
/*ActorDamageByActorHook::unhook();
|
||||||
ActorDamageByBlockHook::unhook();
|
ActorDamageByBlockHook::unhook();
|
||||||
ActorDamageByChildHook::unhook();
|
ActorDamageByChildHook::unhook();*/
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-11
@@ -8,7 +8,6 @@
|
|||||||
#include "ll/api/event/EventBus.h"
|
#include "ll/api/event/EventBus.h"
|
||||||
|
|
||||||
ll::event::ListenerPtr playerConnectEventListener;
|
ll::event::ListenerPtr playerConnectEventListener;
|
||||||
ll::event::ListenerPtr playerDieEventListener;
|
|
||||||
ll::event::ListenerPtr playerDisconnectEventListener;
|
ll::event::ListenerPtr playerDisconnectEventListener;
|
||||||
void ListenEvents() {
|
void ListenEvents() {
|
||||||
auto& config = DeathMessages::Entry::getInstance().getConfig();
|
auto& config = DeathMessages::Entry::getInstance().getConfig();
|
||||||
@@ -30,20 +29,13 @@ void ListenEvents() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (config.ConsoleLog.DeathMessage) {
|
|
||||||
playerDieEventListener=eventBus.emplaceListener<ll::event::player::PlayerDieEvent>(
|
//Die Message move to DeathMessage.cpp 93L
|
||||||
[](ll::event::player::PlayerDieEvent& ev) {
|
|
||||||
auto [key, params] = ev.source().getDeathMessage(ev.self().getRealName(), &ev.self());
|
|
||||||
auto info = tr(key, params);
|
|
||||||
deathLogger->info(info);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstallEventListeners() {
|
void uninstallEventListeners() {
|
||||||
auto& eventBus = ll::event::EventBus::getInstance();
|
auto& eventBus = ll::event::EventBus::getInstance();
|
||||||
eventBus.removeListener(playerDieEventListener);
|
|
||||||
eventBus.removeListener(playerConnectEventListener);
|
eventBus.removeListener(playerConnectEventListener);
|
||||||
eventBus.removeListener(playerDisconnectEventListener);
|
eventBus.removeListener(playerDisconnectEventListener);
|
||||||
}
|
}
|
||||||
@@ -4,3 +4,4 @@
|
|||||||
#define LL_MEMORY_OPERATORS
|
#define LL_MEMORY_OPERATORS
|
||||||
|
|
||||||
#include "ll/api/memory/MemoryOperators.h" // IWYU pragma: keep
|
#include "ll/api/memory/MemoryOperators.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"format_version": 3,
|
"format_version": 3,
|
||||||
"format_uuid": "289f771f-2c9a-4d73-9f3f-8492495a924d",
|
"format_uuid": "289f771f-2c9a-4d73-9f3f-8492495a924d",
|
||||||
"tooth": "github.com/GroupMountain/DeathMessages",
|
"tooth": "github.com/GroupMountain/DeathMessages",
|
||||||
"version": "0.14.0",
|
"version": "0.14.1",
|
||||||
"info": {
|
"info": {
|
||||||
"name": "DeathMessages",
|
"name": "DeathMessages",
|
||||||
"description": "Better Death Messages on MCBE",
|
"description": "Better Death Messages on MCBE",
|
||||||
|
|||||||
Reference in New Issue
Block a user