Skip to content

feat: i18n locale support with zh_CN, en, ja_JP - #64

Open
windy664 wants to merge 2 commits into
ikafly144:masterfrom
windy664:feat/i18n-locale-support
Open

feat: i18n locale support with zh_CN, en, ja_JP#64
windy664 wants to merge 2 commits into
ikafly144:masterfrom
windy664:feat/i18n-locale-support

Conversation

@windy664

@windy664 windy664 commented Jul 19, 2026

Copy link
Copy Markdown

Summary

Add internationalization (i18n) support for MailBox, allowing server operators to customize all user-facing messages in their preferred language.

Features

LocaleManager

  • Loads locale overrides from plugins/MailBox/locales/{locale}.yml
  • Automatic fallback to en.yml if selected locale not found
  • Logs warnings for unknown locale keys (debug level)

Built-in Locale Files

  • en.yml - English (default)
  • zh_CN.yml - Simplified Chinese (简体中文)
  • ja_JP.yml - Japanese (日本語)

Config Changes

  • New locale field in config.yml (default: "en")
  • Messages class no longer extends BaseConfig (uses locale files instead)
  • Automatic migration: warns if old messages block detected in config.yml

Usage

# config.yml
locale: "zh_CN"
# locales/zh_CN.yml (auto-generated on first run)
system-name: 系统
read: <green>已读</green>
unread: <red>未读</red>
# ... customize as needed

Technical Details

  • Locale keys use kebab-case (e.g., click-action-delete)
  • Config.Messages fields use camelCase (e.g., clickActionDelete)
  • Reflection-based mapping with graceful error handling
  • Preserves existing config.yml structure

Testing

Tested with:

  • English (default)
  • Simplified Chinese (zh_CN)
  • Japanese (ja_JP)
  • Missing locale file fallback
  • Invalid locale key handling

Summary by CodeRabbit

  • 新機能

    • 英語・日本語・簡体字中国語に対応し、設定したロケールでメールボックスの表示文言を利用できるようになりました。
    • メニュー、ダイアログ、通知、テンプレート操作など、主要な表示メッセージをロケール別にカスタマイズできます。
    • メール通知の有効・無効を設定できる項目を追加しました。
  • 改善

    • 既存設定のメッセージ情報を新しいロケール形式へ自動移行します。
    • ロケールファイルがない場合は英語へ自動的に切り替わります。

Add internationalization support for MailBox:

- New LocaleManager loads locale overrides from plugins/MailBox/locales/{locale}.yml
- Built-in locale files: en.yml (English), zh_CN.yml (Simplified Chinese), ja_JP.yml (Japanese)
- Config.locale setting to select active locale (default: "en")
- Locale keys use kebab-case matching Config.Messages field names
- Automatic migration: old messages block in config.yml detected and warned
- Fallback to en.yml if selected locale file not found

Usage:
1. Set locale: "zh_CN" in config.yml
2. Edit plugins/MailBox/locales/zh_CN.yml to customize messages
3. Restart server or reload config
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

ロケール設定と Messages 管理を追加し、英語・日本語・中国語の文言をYAMLから読み込めるようにしました。既存のメニュー、コマンド、通知の文言参照をロケール管理経由へ移行し、ShadowJar設定も変更しました。

Changes

ローカライズ基盤

Layer / File(s) Summary
メッセージ契約とロケール定義
paper/src/main/java/net/sabafly/mailBox/configuration/*, paper/src/main/java/net/sabafly/mailBox/MailBox.java
locale設定、Locale enum、Messagesフィールド群、現在のメッセージを返す静的アクセサを追加。
ロケール読み込みと移行
paper/src/main/java/net/sabafly/mailBox/configuration/ConfigLoader.java, LocaleManager.java, paper/src/main/java/net/sabafly/mailBox/Bootstrapper.java
messages設定の削除、ロケールYAMLの確保・読み込み、kebab-caseキーの反映、ダイアログ登録への適用を追加。

表示文言参照の移行

Layer / File(s) Summary
コマンドと通知の参照移行
paper/src/main/java/net/sabafly/mailBox/commands/*, mail/*, schedule/*
コマンド返信、システム名、添付表示、未読・新着通知の文言取得元をMailBox.messages()へ変更。
作成・入力・添付メニュー
paper/src/main/java/net/sabafly/mailBox/menu/{CreateMailMenu,SendMailMenu,StringInputMenu,Attachment*}*
メール作成、送信、入力、添付操作で使用する表示文言をロケール管理のMessagesへ変更。
受信箱・テンプレート・閲覧メニュー
paper/src/main/java/net/sabafly/mailBox/menu/{InboxMenu,MailTemplate*,MailViewerMenu}.java
受信箱、テンプレート、メール閲覧画面のタイトル、ロア、ボタン、確認文言をMessagesへ変更。

ロケールリソースと成果物

Layer / File(s) Summary
言語ファイルとビルド設定
paper/src/main/resources/locales/*, paper/build.gradle.kts
英語・日本語・簡体中文のメッセージ定義を追加し、ShadowJarでplugin.ymlを除外しない設定へ変更。

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConfigLoader
  participant LocaleManager
  participant LocaleYAML
  participant Messages
  ConfigLoader->>LocaleManager: localeを指定してloadLocale
  LocaleManager->>LocaleYAML: locales/{locale}.ymlを読み込む
  LocaleYAML-->>LocaleManager: ロケーションキーと文言
  LocaleManager->>Messages: camelCaseフィールドへ反映
  Messages-->>ConfigLoader: 現在のメッセージを提供
Loading

Suggested reviewers: ikafly144

Poem

うさぎが言葉をぴょんと替え
英語も日本語も花ひらく
中国語の月も照らされて
メニューは軽やか跳ねまわる
Localeの巣箱で、にんじん乾杯! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.02% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PRの主要変更であるロケール対応と en/zh_CN/ja_JP の追加を適切に要約しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a localization system to the plugin, migrating the configuration's messages section to separate locale files managed by a new LocaleManager. Feedback on these changes highlights several key improvements: addressing a potential path traversal vulnerability by validating the locale string, fixing a reflection bug where null-initialized fields would not be populated, preventing a potential NullPointerException when loading empty or corrupted configuration files, and translating a warning log from Chinese to English for consistency.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +41 to +45
public void applyLocale(Config config) {
this.currentLocale = config.locale;
if (currentLocale == null || currentLocale.isBlank()) {
this.currentLocale = "en";
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

To prevent potential path traversal vulnerabilities and handle potential null configurations gracefully, we should validate that the locale string only contains alphanumeric characters, underscores, or hyphens, and add a null check for the config object.

Suggested change
public void applyLocale(Config config) {
this.currentLocale = config.locale;
if (currentLocale == null || currentLocale.isBlank()) {
this.currentLocale = "en";
}
public void applyLocale(Config config) {
if (config == null) {
return;
}
this.currentLocale = config.locale;
if (currentLocale == null || currentLocale.isBlank() || !currentLocale.matches("[a-zA-Z0-9_-]+")) {
this.currentLocale = "en";
}

Comment on lines +112 to +117
Field field = Config.Messages.class.getDeclaredField(fieldName);
field.setAccessible(true);
Object current = field.get(messages);
if (current instanceof String) {
field.set(messages, value);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using current instanceof String will fail to populate any locale fields that are initialized to null (since null instanceof String is false). Checking the field's declared type with field.getType() == String.class is safer, more robust, and avoids an unnecessary reflection get call.

                Field field = Config.Messages.class.getDeclaredField(fieldName);
                field.setAccessible(true);
                if (field.getType() == String.class) {
                    field.set(messages, value);
                }

this.config = loader.load().get(Config.class);
loader.save(loader.createNode(loader.defaultOptions()).set(Config.class, this.config));
var root = loader.load();
this.config = root.get(Config.class);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the config.yml file is empty or corrupted, root.get(Config.class) can return null. We should add a null check and fallback to a new Config instance to prevent subsequent NullPointerExceptions.

                this.config = root.get(Config.class);
                if (this.config == null) {
                    this.config = new Config();
                }

this.config = root.get(Config.class);
// 兼容旧配置:移除已废弃的 messages 区块
if (root.node("messages").virtual() == false) {
logger.warn("config.yml 中的 messages 区块已废弃,请改用 locales/*.yml 语言文件。已自动忽略该区块。");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The warning message is hardcoded in Chinese, whereas the rest of the plugin's logs, comments, and default messages are in English. For consistency and better maintainability, it is recommended to use English for all system log messages.

Suggested change
logger.warn("config.yml 中的 messages 区块已废弃,请改用 locales/*.yml 语言文件。已自动忽略该区块。");
logger.warn("The 'messages' section in config.yml is deprecated. Please use 'locales/*.yml' instead. This section has been automatically ignored and removed.");

@ikafly144

Copy link
Copy Markdown
Owner

I'll check out other changes later though. Please unify comments and console output in English.

@ikafly144 ikafly144 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the overall LocaleManager needs to be reviewed from the design.
There are issues with log messages and comments.


public boolean enableGameMenuShortcut = true;
public boolean enableQuickAction = true;
public boolean enableMailNotification = false;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#66 changes are mixed in


@ConfigSerializable
public static class Messages extends BaseConfig {
public static class Messages {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should no longer be an inner class.
A new method of LocaleManager providing Messages should be introduced.

loader.save(loader.createNode(loader.defaultOptions()).set(Config.class, this.config));
var root = loader.load();
this.config = root.get(Config.class);
// 兼容旧配置:移除已废弃的 messages 区块

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that comments and log messages in the code are unified in English.

* Load locale file and apply overrides to Config.Messages.
* Call this after Config is loaded.
*/
public void applyLocale(Config config) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design of having a Messages instance in a Config instance is not good. You should keep the instance within LocaleManager.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LocaleManager and Config should be separated. If it remains mixed, it becomes a debt.

// 兼容旧配置:移除已废弃的 messages 区块
if (root.node("messages").virtual() == false) {
logger.warn("config.yml 中的 messages 区块已废弃,请改用 locales/*.yml 语言文件。已自动忽略该区块。");
root.node("messages").set(null);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous message definitions should be migrated to the new LocaleManager as a custom locale, etc.

return;
}

copyResourceIfMissing("/locales/en.yml", localesDir.resolve("en.yml"));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Language and file definitions should be enumerated. That's more scalable.

…ndalone class

- Create Locale enum for supported locales (EN, ZH_CN, JA_JP)
- Extract Messages from Config inner class to standalone Messages.java
- LocaleManager now owns Messages instance via messages() getter
- LocaleManager.loadLocale(Locale) replaces applyLocale(Config)
- Config no longer holds Messages instance
- Add MailBox.messages() static accessor
- Update all 16 files to use messages() instead of config().messages
- Translate Chinese comments/logs to English in ConfigLoader
- Use Locale enum for file enumeration in ensureLocaleFilesExist()

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@paper/src/main/java/net/sabafly/mailBox/commands/MailCommands.java`:
- Around line 166-172: In the subject-edit flow around template.setSubject and
database().updateMailTemplate, capture template.subject() in a separate
old-subject value before applying newSubject. Use that preserved value for the
old_subject placeholder, while continuing to pass newSubject for new_subject.

In `@paper/src/main/java/net/sabafly/mailBox/configuration/LocaleManager.java`:
- Around line 75-78: Update the Exception handling in LocaleManager’s
locale-loading flow so that after a load failure it sets the fallback locale to
Locale.EN and explicitly loads dataDir/locales/en.yml through the existing
locale-loading mechanism. Preserve the error log and ensure the customized
English fallback file is applied rather than only changing the in-memory locale
enum.

In `@paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java`:
- Around line 60-63: CreateMailMenu コンストラクタで、フィールド代入より前に super(...)
を最初の文として移動してください。player とメニュータイトルを使う既存のスーパークラス初期化は維持し、その後に target と nextMenu
を代入してください。

In `@paper/src/main/resources/locales/en.yml`:
- Around line 1-3: Update the header comments in
paper/src/main/resources/locales/en.yml lines 1-3,
paper/src/main/resources/locales/ja_JP.yml lines 1-3, and
paper/src/main/resources/locales/zh_CN.yml lines 1-3 to use English wording
consistently; in all three files, replace the outdated Config.Messages reference
with Messages while preserving the kebab-case key-name guidance.

In `@paper/src/main/resources/locales/zh_CN.yml`:
- Line 30: Update the content-info translation in the zh_CN locale so the
<length> value is labeled as a character count, replacing the email-count unit
“封信” with the appropriate character unit such as “个字符”.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c5eabc83-c087-4a45-8364-e0b77b48116d

📥 Commits

Reviewing files that changed from the base of the PR and between de9adac and 01c086f.

📒 Files selected for processing (27)
  • paper/build.gradle.kts
  • paper/src/main/java/net/sabafly/mailBox/Bootstrapper.java
  • paper/src/main/java/net/sabafly/mailBox/MailBox.java
  • paper/src/main/java/net/sabafly/mailBox/commands/MailCommands.java
  • paper/src/main/java/net/sabafly/mailBox/configuration/Config.java
  • paper/src/main/java/net/sabafly/mailBox/configuration/ConfigLoader.java
  • paper/src/main/java/net/sabafly/mailBox/configuration/Locale.java
  • paper/src/main/java/net/sabafly/mailBox/configuration/LocaleManager.java
  • paper/src/main/java/net/sabafly/mailBox/configuration/Messages.java
  • paper/src/main/java/net/sabafly/mailBox/mail/DummyMailUser.java
  • paper/src/main/java/net/sabafly/mailBox/mail/attachments/VaultValueAttachment.java
  • paper/src/main/java/net/sabafly/mailBox/menu/AttachmentCommandMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/AttachmentItemMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/AttachmentVaultValueMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/ContentMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/InboxMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/ItemSetterMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/MailTemplateEditMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/MailTemplateMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/MailViewerMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/SendMailMenu.java
  • paper/src/main/java/net/sabafly/mailBox/menu/StringInputMenu.java
  • paper/src/main/java/net/sabafly/mailBox/schedule/ScheduleManager.java
  • paper/src/main/resources/locales/en.yml
  • paper/src/main/resources/locales/ja_JP.yml
  • paper/src/main/resources/locales/zh_CN.yml
💤 Files with no reviewable changes (1)
  • paper/build.gradle.kts

Comment on lines 166 to 172
template.setSubject(newSubject);
database().updateMailTemplate(template);
context.getSource().getSender().sendMessage(miniMessage().deserialize(
config().messages.templateEditSubjectSuccess,
messages().templateEditSubjectSuccess,
Placeholder.component("template", miniMessage().deserialize(newSubject)),
Placeholder.component("old_subject", miniMessage().deserialize(template.subject())),
Placeholder.component("new_subject", miniMessage().deserialize(newSubject))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

更新前の件名を変更前に保持してください。

Line 166 で件名を更新した後に Line 171 の template.subject()old_subject に渡しているため、更新前・更新後が同じ件名になります。

修正案
+String oldSubject = template.subject();
 template.setSubject(newSubject);
 database().updateMailTemplate(template);
 context.getSource().getSender().sendMessage(miniMessage().deserialize(
         messages().templateEditSubjectSuccess,
         Placeholder.component("template", miniMessage().deserialize(newSubject)),
-        Placeholder.component("old_subject", miniMessage().deserialize(template.subject())),
+        Placeholder.component("old_subject", miniMessage().deserialize(oldSubject)),
         Placeholder.component("new_subject", miniMessage().deserialize(newSubject))
 ));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
template.setSubject(newSubject);
database().updateMailTemplate(template);
context.getSource().getSender().sendMessage(miniMessage().deserialize(
config().messages.templateEditSubjectSuccess,
messages().templateEditSubjectSuccess,
Placeholder.component("template", miniMessage().deserialize(newSubject)),
Placeholder.component("old_subject", miniMessage().deserialize(template.subject())),
Placeholder.component("new_subject", miniMessage().deserialize(newSubject))
String oldSubject = template.subject();
template.setSubject(newSubject);
database().updateMailTemplate(template);
context.getSource().getSender().sendMessage(miniMessage().deserialize(
messages().templateEditSubjectSuccess,
Placeholder.component("template", miniMessage().deserialize(newSubject)),
Placeholder.component("old_subject", miniMessage().deserialize(oldSubject)),
Placeholder.component("new_subject", miniMessage().deserialize(newSubject))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@paper/src/main/java/net/sabafly/mailBox/commands/MailCommands.java` around
lines 166 - 172, In the subject-edit flow around template.setSubject and
database().updateMailTemplate, capture template.subject() in a separate
old-subject value before applying newSubject. Use that preserved value for the
old_subject placeholder, while continuing to pass newSubject for new_subject.

Comment on lines +75 to +78
} catch (Exception e) {
logger.error("Failed to load locale: {}", currentLocale.fileName(), e);
this.currentLocale = Locale.EN;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

読み込み失敗時も実際の en.yml を読み込んでください。

ここでは Locale を EN に変えるだけで、dataDir/locales/en.yml を再読み込みしません。例えば壊れた ja_JP.yml では、管理者がカスタマイズした英語フォールバックが無視されます。

修正例
 } catch (Exception e) {
     logger.error("Failed to load locale: {}", currentLocale.fileName(), e);
-    this.currentLocale = Locale.EN;
+    if (locale != Locale.EN) {
+        loadLocale(Locale.EN);
+    } else {
+        this.currentLocale = Locale.EN;
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (Exception e) {
logger.error("Failed to load locale: {}", currentLocale.fileName(), e);
this.currentLocale = Locale.EN;
}
} catch (Exception e) {
logger.error("Failed to load locale: {}", currentLocale.fileName(), e);
if (locale != Locale.EN) {
loadLocale(Locale.EN);
} else {
this.currentLocale = Locale.EN;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@paper/src/main/java/net/sabafly/mailBox/configuration/LocaleManager.java`
around lines 75 - 78, Update the Exception handling in LocaleManager’s
locale-loading flow so that after a load failure it sets the fallback locale to
Locale.EN and explicitly loads dataDir/locales/en.yml through the existing
locale-loading mechanism. Preserve the error log and ensure the customized
English fallback file is applied rather than only changing the in-memory locale
enum.

Comment on lines 60 to +63
public CreateMailMenu(@NotNull Player player, @Nullable User target, @Nullable InventoryMenu<?> nextMenu) {
this.target = target;
this.nextMenu = nextMenu;
super(player, 9, miniMessage().deserialize(config().messages.createMailMenuTitle));
super(player, 9, miniMessage().deserialize(messages().createMailMenuTitle));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '56,66p' paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java

Repository: ikafly144/MailBox

Length of output: 555


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the relevant class hierarchy without running repository code.
if [ -f paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java ]; then
  lines=$(wc -l < paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java)
  echo "== CreateMailMenu.java outline/headers =="
  sed -n '1,90p' paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java | nl -ba
fi

echo "== candidate parent classes =="
rg -n "class InventoryMenu|class .*Menu|InventoryMenu<" . --glob '*.java' | head -80

Repository: ikafly144/MailBox

Length of output: 237


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== CreateMailMenu.java =="
sed -n '1,110p' paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java

echo
echo "== candidate parent classes =="
rg -n "class InventoryMenu|class .*Menu|InventoryMenu<" . --glob '*.java' | head -80

Repository: ikafly144/MailBox

Length of output: 10528


super(...) をコンストラクタの先頭へ移動してください。

Java では super(...) は明示的なコンストラクタ呼び出しで最初に評価されるため、Line 61-62 より先に実行されるこの書き方はコンパイルできません。

修正案
 public CreateMailMenu(`@NotNull` Player player, `@Nullable` User target, `@Nullable` InventoryMenu<?> nextMenu) {
+    super(player, 9, miniMessage().deserialize(messages().createMailMenuTitle));
     this.target = target;
     this.nextMenu = nextMenu;
-    super(player, 9, miniMessage().deserialize(messages().createMailMenuTitle));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public CreateMailMenu(@NotNull Player player, @Nullable User target, @Nullable InventoryMenu<?> nextMenu) {
this.target = target;
this.nextMenu = nextMenu;
super(player, 9, miniMessage().deserialize(config().messages.createMailMenuTitle));
super(player, 9, miniMessage().deserialize(messages().createMailMenuTitle));
public CreateMailMenu(`@NotNull` Player player, `@Nullable` User target, `@Nullable` InventoryMenu<?> nextMenu) {
super(player, 9, miniMessage().deserialize(messages().createMailMenuTitle));
this.target = target;
this.nextMenu = nextMenu;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@paper/src/main/java/net/sabafly/mailBox/menu/CreateMailMenu.java` around
lines 60 - 63, CreateMailMenu コンストラクタで、フィールド代入より前に super(...)
を最初の文として移動してください。player とメニュータイトルを使う既存のスーパークラス初期化は維持し、その後に target と nextMenu
を代入してください。

Comment on lines +1 to +3
# MailBox English locale
# Key names correspond to Config.Messages fields in kebab-case.
# e.g. "new-mail" -> Config.Messages.newMail

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

ロケール YAML のヘッダーコメントを英語と現行型名に統一してください。

Messages は独立クラスになっています。また、PR 要件ではコメントを英語へ統一するため、日本語・中国語のヘッダーコメントも更新してください。

  • paper/src/main/resources/locales/en.yml#L1-L3: Config.MessagesMessages に修正してください。
  • paper/src/main/resources/locales/ja_JP.yml#L1-L3: コメントを英語化し、Config.MessagesMessages に修正してください。
  • paper/src/main/resources/locales/zh_CN.yml#L1-L3: コメントを英語化し、Config.MessagesMessages に修正してください。
📍 Affects 3 files
  • paper/src/main/resources/locales/en.yml#L1-L3 (this comment)
  • paper/src/main/resources/locales/ja_JP.yml#L1-L3
  • paper/src/main/resources/locales/zh_CN.yml#L1-L3
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@paper/src/main/resources/locales/en.yml` around lines 1 - 3, Update the
header comments in paper/src/main/resources/locales/en.yml lines 1-3,
paper/src/main/resources/locales/ja_JP.yml lines 1-3, and
paper/src/main/resources/locales/zh_CN.yml lines 1-3 to use English wording
consistently; in all three files, replace the outdated Config.Messages reference
with Messages while preserving the kebab-case key-name guidance.

read: <green>已读</green>
unread: <red>未读</red>
content: 内容
content-info: '内容: <bold><length> 封信</bold>'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

文字数の単位を修正してください。

content-info には content.length() が渡されますが、「封信」はメール件数を表します。个字符 など文字数の単位にしてください。

修正例
-content-info: '内容: <bold><length> 封信</bold>'
+content-info: '内容: <bold><length> 个字符</bold>'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
content-info: '内容: <bold><length> 封信</bold>'
content-info: '内容: <bold><length> 个字符</bold>'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@paper/src/main/resources/locales/zh_CN.yml` at line 30, Update the
content-info translation in the zh_CN locale so the <length> value is labeled as
a character count, replacing the email-count unit “封信” with the appropriate
character unit such as “个字符”.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants