9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-20 07:19:16 +00:00

Merge remote-tracking branch 'origin/master'

This commit is contained in:
William278
2025-06-13 19:25:31 +01:00
12 changed files with 60 additions and 22 deletions

View File

@@ -8,7 +8,7 @@ plugins {
dependencies { dependencies {
implementation project(path: ':common') implementation project(path: ':common')
implementation 'net.william278.uniform:uniform-bukkit:1.3.3' implementation 'net.william278.uniform:uniform-bukkit:1.3.4'
implementation 'net.william278.uniform:uniform-paper:1.3.4' implementation 'net.william278.uniform:uniform-paper:1.3.4'
implementation 'net.william278.toilet:toilet-bukkit:1.0.13' implementation 'net.william278.toilet:toilet-bukkit:1.0.13'
implementation 'net.william278:mpdbdataconverter:1.0.1' implementation 'net.william278:mpdbdataconverter:1.0.1'
@@ -18,14 +18,14 @@ dependencies {
implementation 'net.kyori:adventure-platform-bukkit:4.4.0' implementation 'net.kyori:adventure-platform-bukkit:4.4.0'
implementation 'dev.triumphteam:triumph-gui:3.1.12' implementation 'dev.triumphteam:triumph-gui:3.1.12'
implementation 'space.arim.morepaperlib:morepaperlib:0.4.4' implementation 'space.arim.morepaperlib:morepaperlib:0.4.4'
implementation 'de.tr7zw:item-nbt-api:2.15.0' implementation 'de.tr7zw:item-nbt-api:2.15.1-SNAPSHOT'
compileOnly "io.papermc.paper:paper-api:${paper_api_version}" compileOnly "io.papermc.paper:paper-api:${paper_api_version}"
compileOnly 'com.github.retrooper:packetevents-spigot:2.7.0' compileOnly 'com.github.retrooper:packetevents-spigot:2.8.0'
compileOnly 'com.github.dmulloy2:ProtocolLib:5.3.0' compileOnly 'com.github.dmulloy2:ProtocolLib:5.3.0'
compileOnly 'org.projectlombok:lombok:1.18.38' compileOnly 'org.projectlombok:lombok:1.18.38'
compileOnly 'commons-io:commons-io:2.19.0' compileOnly 'commons-io:commons-io:2.19.0'
compileOnly 'org.json:json:20250107' compileOnly 'org.json:json:20250517'
compileOnly 'net.william278:minedown:1.8.2' compileOnly 'net.william278:minedown:1.8.2'
compileOnly 'de.exlll:configlib-yaml:4.6.1' compileOnly 'de.exlll:configlib-yaml:4.6.1'
compileOnly 'com.zaxxer:HikariCP:6.3.0' compileOnly 'com.zaxxer:HikariCP:6.3.0'

View File

@@ -7,8 +7,8 @@ dependencies {
api 'org.apache.commons:commons-text:1.13.1' api 'org.apache.commons:commons-text:1.13.1'
api 'net.william278:minedown:1.8.2' api 'net.william278:minedown:1.8.2'
api 'net.william278:mapdataapi:2.0' api 'net.william278:mapdataapi:2.0'
api 'org.json:json:20250107' api 'org.json:json:20250517'
api 'com.google.code.gson:gson:2.13.0' api 'com.google.code.gson:gson:2.13.1'
api 'com.fatboyindustrial.gson-javatime-serialisers:gson-javatime-serialisers:1.1.2' api 'com.fatboyindustrial.gson-javatime-serialisers:gson-javatime-serialisers:1.1.2'
api 'de.exlll:configlib-yaml:4.6.1' api 'de.exlll:configlib-yaml:4.6.1'
api 'net.william278:paginedown:1.1.2' api 'net.william278:paginedown:1.1.2'
@@ -19,7 +19,7 @@ dependencies {
compileOnlyApi 'net.william278.toilet:toilet-common:1.0.13' compileOnlyApi 'net.william278.toilet:toilet-common:1.0.13'
compileOnly 'net.william278.uniform:uniform-common:1.3.3' compileOnly 'net.william278.uniform:uniform-common:1.3.4'
compileOnly 'com.mojang:brigadier:1.1.8' compileOnly 'com.mojang:brigadier:1.1.8'
compileOnly 'org.projectlombok:lombok:1.18.38' compileOnly 'org.projectlombok:lombok:1.18.38'
compileOnly 'org.jetbrains:annotations:26.0.2' compileOnly 'org.jetbrains:annotations:26.0.2'

View File

@@ -159,7 +159,9 @@ public class Settings {
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class RedisSettings { public static class RedisSettings {
@Comment("Specify the credentials of your Redis server here. Set \"password\" to '' if you don't have one") @Comment({"Specify the credentials of your Redis server here.",
"Set \"user\" to '' if you don't have one or would like to use the default user.",
"Set \"password\" to '' if you don't have one."})
private RedisCredentials credentials = new RedisCredentials(); private RedisCredentials credentials = new RedisCredentials();
@Getter @Getter
@@ -168,6 +170,9 @@ public class Settings {
public static class RedisCredentials { public static class RedisCredentials {
private String host = "localhost"; private String host = "localhost";
private int port = 6379; private int port = 6379;
@Comment("Only change the database if you know what you are doing. The default is 0.")
private int database = 0;
private String user = "";
private String password = ""; private String password = "";
private boolean useSsl = false; private boolean useSsl = false;
} }

View File

@@ -65,9 +65,11 @@ public class RedisManager extends JedisPubSub {
@Blocking @Blocking
public void initialize() throws IllegalStateException { public void initialize() throws IllegalStateException {
final Settings.RedisSettings.RedisCredentials credentials = plugin.getSettings().getRedis().getCredentials(); final Settings.RedisSettings.RedisCredentials credentials = plugin.getSettings().getRedis().getCredentials();
final String user = credentials.getUser();
final String password = credentials.getPassword(); final String password = credentials.getPassword();
final String host = credentials.getHost(); final String host = credentials.getHost();
final int port = credentials.getPort(); final int port = credentials.getPort();
final int database = credentials.getDatabase();
final boolean useSSL = credentials.isUseSsl(); final boolean useSSL = credentials.isUseSsl();
// Create the jedis pool // Create the jedis pool
@@ -79,9 +81,20 @@ public class RedisManager extends JedisPubSub {
final Settings.RedisSettings.RedisSentinel sentinel = plugin.getSettings().getRedis().getSentinel(); final Settings.RedisSettings.RedisSentinel sentinel = plugin.getSettings().getRedis().getSentinel();
Set<String> redisSentinelNodes = new HashSet<>(sentinel.getNodes()); Set<String> redisSentinelNodes = new HashSet<>(sentinel.getNodes());
if (redisSentinelNodes.isEmpty()) { if (redisSentinelNodes.isEmpty()) {
this.jedisPool = password.isEmpty() DefaultJedisClientConfig.Builder clientConfigBuilder = DefaultJedisClientConfig.builder()
? new JedisPool(config, host, port, 0, useSSL) .ssl(useSSL)
: new JedisPool(config, host, port, 0, password, useSSL); .database(database)
.timeoutMillis(0);
if (!user.isEmpty()) {
clientConfigBuilder.user(user);
}
if (!password.isEmpty()) {
clientConfigBuilder.password(password);
}
this.jedisPool = new JedisPool(config, new HostAndPort(host, port), clientConfigBuilder.build());
} else { } else {
final String sentinelPassword = sentinel.getPassword(); final String sentinelPassword = sentinel.getPassword();
this.jedisPool = new JedisSentinelPool(sentinel.getMaster(), redisSentinelNodes, password.isEmpty() this.jedisPool = new JedisSentinelPool(sentinel.getMaster(), redisSentinelNodes, password.isEmpty()

View File

@@ -100,6 +100,8 @@ public interface DumpProvider {
Map.entry("Redis Version", StatusLine.REDIS_VERSION.getValue(getPlugin())), Map.entry("Redis Version", StatusLine.REDIS_VERSION.getValue(getPlugin())),
Map.entry("Redis Latency", StatusLine.REDIS_LATENCY.getValue(getPlugin())), Map.entry("Redis Latency", StatusLine.REDIS_LATENCY.getValue(getPlugin())),
Map.entry("Redis Sentinel", StatusLine.USING_REDIS_SENTINEL.getValue(getPlugin())), Map.entry("Redis Sentinel", StatusLine.USING_REDIS_SENTINEL.getValue(getPlugin())),
Map.entry("Redis Database", StatusLine.REDIS_DATABASE.getValue(getPlugin())),
Map.entry("Redis User", StatusLine.USING_REDIS_USER.getValue(getPlugin())),
Map.entry("Redis Password", StatusLine.USING_REDIS_PASSWORD.getValue(getPlugin())), Map.entry("Redis Password", StatusLine.USING_REDIS_PASSWORD.getValue(getPlugin())),
Map.entry("Redis SSL", StatusLine.REDIS_USING_SSL.getValue(getPlugin())), Map.entry("Redis SSL", StatusLine.REDIS_USING_SSL.getValue(getPlugin())),
Map.entry("Redis Local", StatusLine.IS_REDIS_LOCAL.getValue(getPlugin())) Map.entry("Redis Local", StatusLine.IS_REDIS_LOCAL.getValue(getPlugin()))

View File

@@ -60,6 +60,10 @@ public enum StatusLine {
USING_REDIS_SENTINEL(plugin -> getBoolean( USING_REDIS_SENTINEL(plugin -> getBoolean(
!plugin.getSettings().getRedis().getSentinel().getMaster().isBlank() !plugin.getSettings().getRedis().getSentinel().getMaster().isBlank()
)), )),
REDIS_DATABASE(plugin -> Component.text(plugin.getSettings().getRedis().getCredentials().getDatabase())),
USING_REDIS_USER(plugin -> getBoolean(
!plugin.getSettings().getRedis().getCredentials().getUser().isBlank()
)),
USING_REDIS_PASSWORD(plugin -> getBoolean( USING_REDIS_PASSWORD(plugin -> getBoolean(
!plugin.getSettings().getRedis().getCredentials().getPassword().isBlank() !plugin.getSettings().getRedis().getCredentials().getPassword().isBlank()
)), )),

View File

@@ -23,7 +23,7 @@ locales:
data_list_title: '[%1% 的玩家資料快照:](#00fb9a) [(%2%-%3% 共](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n' data_list_title: '[%1% 的玩家資料快照:](#00fb9a) [(%2%-%3% 共](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
data_list_item: '[%1%](gray show_text=&7玩家資料快照 %2%\n&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7已標記:\n&8標記的快照將不會自動輪換。 run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7版本時間戳:\n&8資料儲存時間\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7儲存原因:\n&8觸發儲存的原因 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7快照大小:\n&8快照的預估檔案大小KiB run_command=/userdata view %2% %3%)' data_list_item: '[%1%](gray show_text=&7玩家資料快照 %2%\n&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7已標記:\n&8標記的快照將不會自動輪換。 run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7版本時間戳:\n&8資料儲存時間\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7儲存原因:\n&8觸發儲存的原因 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7快照大小:\n&8快照的預估檔案大小KiB run_command=/userdata view %2% %3%)'
data_list_item_invalid: '[%1%](dark_gray show_text=&7玩家資料快照 %2%\n&8⚡ %4% suggest_command=/userdata delete %2% %3%) [%5%](dark_gray show_text=&7已標記:\n&8標記的快照將不會自動輪換。 suggest_command=/userdata delete %2% %3%) [%6% ⚑ %8% ⏏ %9%](gray strikethrough show_text=&#ff3300&無效的資料快照\n&#ff7e5e&點擊刪除\n\n&7⚠ %10% suggest_command=/userdata delete %2% %3%)' data_list_item_invalid: '[%1%](dark_gray show_text=&7玩家資料快照 %2%\n&8⚡ %4% suggest_command=/userdata delete %2% %3%) [%5%](dark_gray show_text=&7已標記:\n&8標記的快照將不會自動輪換。 suggest_command=/userdata delete %2% %3%) [%6% ⚑ %8% ⏏ %9%](gray strikethrough show_text=&#ff3300&無效的資料快照\n&#ff7e5e&點擊刪除\n\n&7⚠ %10% suggest_command=/userdata delete %2% %3%)'
data_saved: '[Successfully saved a snapshot of %1%''s current user data.](#00fb9a)' data_saved: '[✅ 成功儲存 %1% 的目前使用者資料快照。](#00fb9a)'
data_deleted: '[❌ 成功刪除:](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)' data_deleted: '[❌ 成功刪除:](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
data_restored: '[⏪ 成功將玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&8%2%)[的資料恢復為 快照:](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)' data_restored: '[⏪ 成功將玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&8%2%)[的資料恢復為 快照:](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
data_pinned: '[※ 成功標記](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)' data_pinned: '[※ 成功標記](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
@@ -41,8 +41,8 @@ locales:
save_cause_world_save: '世界儲存' save_cause_world_save: '世界儲存'
save_cause_death: '死亡' save_cause_death: '死亡'
save_cause_server_shutdown: '伺服器關閉' save_cause_server_shutdown: '伺服器關閉'
save_cause_save_command: 'save command' save_cause_save_command: '儲存指令'
save_cause_dump_command: 'dump command' save_cause_dump_command: '導出指令'
save_cause_inventory_command: '背包指令' save_cause_inventory_command: '背包指令'
save_cause_enderchest_command: '終界箱指令' save_cause_enderchest_command: '終界箱指令'
save_cause_backup_restore: '備份還原' save_cause_backup_restore: '備份還原'
@@ -54,9 +54,9 @@ locales:
update_available: '[HuskSync](#ff7e5e bold) [| 發現可用的新版本: v%1% (running: v%2%).](#ff7e5e)' update_available: '[HuskSync](#ff7e5e bold) [| 發現可用的新版本: v%1% (running: v%2%).](#ff7e5e)'
reload_complete: '[HuskSync](#00fb9a bold) [| 配置和語言文件已重新加載。](#00fb9a)\n[⚠ 確保所有伺服器上的配置文件都是最新的!](#00fb9a)\n[重啟後配置變更才會生效。](#00fb9a italic)' reload_complete: '[HuskSync](#00fb9a bold) [| 配置和語言文件已重新加載。](#00fb9a)\n[⚠ 確保所有伺服器上的配置文件都是最新的!](#00fb9a)\n[重啟後配置變更才會生效。](#00fb9a italic)'
system_status_header: '[HuskSync](#00fb9a bold) [| 系統狀態報告:](#00fb9a)' system_status_header: '[HuskSync](#00fb9a bold) [| 系統狀態報告:](#00fb9a)'
system_dump_confirm: '[HuskSync](#00fb9a bold) [| Prepare a system dump? This will include:](#00fb9a)\n[• Your latest server logs and HuskSync config files](gray)\n[• Current plugin system status information](gray)\n[• Information about your Java & Minecraft server environment](gray)\n[• A list of other currently installed plugins](gray)\n[To confirm, use:](#00fb9a) [/husksync dump confirm](#00fb9a italic show_text=&7Click to prepare dump run_command=/husksync dump confirm)' system_dump_confirm: '[HuskSync](#00fb9a bold) [| 要產生系統狀態紀錄檔嗎?這將包含以下內容:](#00fb9a)\n[• 最近的伺服器日誌與 HuskSync 設定檔](gray)\n[• 插件目前的系統狀態資訊](gray)\n[• 有關您的 Java Minecraft 伺服器環境的資訊](gray)\n[• 目前已安裝的其他插件清單](gray)\n[若要確認,請輸入:](#00fb9a) [/husksync dump confirm](#00fb9a italic show_text=&7點擊以產生紀錄檔 run_command=/husksync dump confirm)'
system_dump_started: '[HuskSync](#00fb9a bold) [| Preparing system status dump, please wait…](#00fb9a)' system_dump_started: '[HuskSync](#00fb9a bold) [| 正在產生系統狀態紀錄檔,請稍候…](#00fb9a)'
system_dump_ready: '[HuskSync](#00fb9a bold) [| System status dump prepared! Click to view:](#00fb9a)' system_dump_ready: '[HuskSync](#00fb9a bold) [| 系統狀態紀錄檔已完成!點擊以下連結以查看:](#00fb9a)'
error_invalid_syntax: '[錯誤:](#ff3300) [語法不正確,用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=&#ff7e5e&點擊建議 suggest_command=%1%)' error_invalid_syntax: '[錯誤:](#ff3300) [語法不正確,用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=&#ff7e5e&點擊建議 suggest_command=%1%)'
error_invalid_player: '[錯誤:](#ff3300) [找不到這位玩家](#ff7e5e)' error_invalid_player: '[錯誤:](#ff3300) [找不到這位玩家](#ff7e5e)'
error_invalid_data: '[錯誤:](#ff3300) [無法解壓使用者資料,因為快照無效或已損壞。](#ff7e5e) [(詳細資訊…)](gray show_text=&7⚠ %1%)' error_invalid_data: '[錯誤:](#ff3300) [無法解壓使用者資料,因為快照無效或已損壞。](#ff7e5e) [(詳細資訊…)](gray show_text=&7⚠ %1%)'

View File

@@ -65,10 +65,15 @@ database:
user_data: husksync_user_data user_data: husksync_user_data
# Redis settings # Redis settings
redis: redis:
# Specify the credentials of your Redis server here. Set "password" to '' if you don't have one # Specify the credentials of your Redis server here.
# Set "user" to '' if you don't have one or would like to use the default user.
# Set "password" to '' if you don't have one.
credentials: credentials:
host: localhost host: localhost
port: 6379 port: 6379
# Only change the database if you know what you are doing. The default is 0.
database: 0
user: ''
password: '' password: ''
use_ssl: false use_ssl: false
# Options for if you're using Redis sentinel. Don't modify this unless you know what you're doing! # Options for if you're using Redis sentinel. Don't modify this unless you know what you're doing!

View File

@@ -16,10 +16,15 @@ To configure Redis, navigate to your [`config.yml`](Config-File) file and modify
```yaml ```yaml
# Redis settings # Redis settings
redis: redis:
# Specify the credentials of your Redis server here. Set "password" to '' if you don't have one # Specify the credentials of your Redis server here.
# Set "user" to '' if you don't have one or would like to use the default user.
# Set "password" to '' if you don't have one.
credentials: credentials:
host: localhost host: localhost
port: 6379 port: 6379
# Only change the database if you know what you are doing. The default is 0.
database: 0
user: ''
password: '' password: ''
use_ssl: false use_ssl: false
# Options for if you're using Redis sentinel. Don't modify this unless you know what you're doing! # Options for if you're using Redis sentinel. Don't modify this unless you know what you're doing!
@@ -33,8 +38,9 @@ redis:
</details> </details>
### Credentials ### Credentials
Enter the hostname, port, and default user password of your Redis server. Enter the hostname, port, user, and password of your Redis server.
If you don't have a Redis user, just use the default user password and leave the user field empty (`user: ''`).
If your Redis default user doesn't have a password, leave the password field blank (`password: ''`') and the plugin will attempt to connect without a password. If your Redis default user doesn't have a password, leave the password field blank (`password: ''`') and the plugin will attempt to connect without a password.
### Default user password ### Default user password

View File

@@ -14,7 +14,7 @@ dependencies {
modImplementation include("net.kyori:adventure-platform-fabric:${fabric_adventure_platform_version}") modImplementation include("net.kyori:adventure-platform-fabric:${fabric_adventure_platform_version}")
modImplementation include("me.lucko:fabric-permissions-api:${fabric_permissions_api_version}") modImplementation include("me.lucko:fabric-permissions-api:${fabric_permissions_api_version}")
modImplementation include("eu.pb4:sgui:${fabric_sgui_version}") modImplementation include("eu.pb4:sgui:${fabric_sgui_version}")
modImplementation include("net.william278.uniform:uniform-fabric:1.3.3+${project.name}") modImplementation include("net.william278.uniform:uniform-fabric:1.3.4+${project.name}")
modImplementation include("net.william278.toilet:toilet-fabric:1.0.13+${project.name}") modImplementation include("net.william278.toilet:toilet-fabric:1.0.13+${project.name}")
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}"

View File

@@ -4,7 +4,7 @@ org.gradle.daemon=true
javaVersion=21 javaVersion=21
# Plugin metadata # Plugin metadata
plugin_version=3.8.3 plugin_version=3.8.4
plugin_archive=husksync plugin_archive=husksync
plugin_description=A modern, cross-server player data synchronization system plugin_description=A modern, cross-server player data synchronization system

View File

@@ -66,6 +66,9 @@ redis:
credentials: credentials:
host: localhost host: localhost
port: 6379 port: 6379
# Only change the database if you know what you are doing. The default is 0.
database: 0
user: ''
password: '' password: ''
use_ssl: false use_ssl: false