From 1aec8de03cc34658d0128079b2c64c6ef9a81fd4 Mon Sep 17 00:00:00 2001 From: OmerBenGera Date: Fri, 11 Mar 2022 18:53:52 +0200 Subject: [PATCH] Added automatic detection of player languages --- .../api/config/SettingsManager.java | 5 +++++ .../config/SettingsContainer.java | 2 ++ .../config/SettingsHandler.java | 5 +++++ .../superiorskyblock/lang/PlayerLocales.java | 2 +- .../listeners/PlayersListener.java | 10 ++++++++++ .../superiorskyblock/nms/NMSPlayers.java | 6 ++++++ src/main/resources/config.yml | 7 ++++++- .../nms/v1_12_R1/NMSPlayersImpl.java | 13 +++++++++++++ .../nms/v1_16_R3/NMSPlayersImpl.java | 18 ++++++++++++++++++ .../nms/v1_17_R1/NMSPlayersImpl.java | 18 ++++++++++++++++++ .../nms/v1_18_R1/NMSPlayersImpl.java | 18 ++++++++++++++++++ .../nms/v1_18_R2/NMSPlayersImpl.java | 18 ++++++++++++++++++ .../nms/v1_8_R3/NMSPlayersImpl.java | 13 +++++++++++++ 13 files changed, 133 insertions(+), 2 deletions(-) diff --git a/API/src/main/java/com/bgsoftware/superiorskyblock/api/config/SettingsManager.java b/API/src/main/java/com/bgsoftware/superiorskyblock/api/config/SettingsManager.java index 4bb04b67c..65a1a4ff2 100644 --- a/API/src/main/java/com/bgsoftware/superiorskyblock/api/config/SettingsManager.java +++ b/API/src/main/java/com/bgsoftware/superiorskyblock/api/config/SettingsManager.java @@ -543,6 +543,11 @@ public interface SettingsManager { */ long getRecalcTaskTimeout(); + /** + * Whether to detect the player's language automatically when he first joins the server. + * Config-path: auto-language-detection + */ + boolean isAutoLanguageDetection(); interface Database { diff --git a/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsContainer.java b/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsContainer.java index d7a98bf9d..6ffa9f0c0 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsContainer.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsContainer.java @@ -182,6 +182,7 @@ public final class SettingsContainer { public final double chargeOnWarp; public final boolean publicWarps; public final long recalcTaskTimeout; + public final boolean autoLanguageDetection; public SettingsContainer(SuperiorSkyblockPlugin plugin, YamlConfiguration config) throws HandlerLoadException { databaseType = config.getString("database.type"); @@ -471,6 +472,7 @@ else if (sections.length == 3) chargeOnWarp = config.getDouble("charge-on-warp", 0D); publicWarps = config.getBoolean("public-warps"); recalcTaskTimeout = config.getLong("recalc-task-timeout"); + autoLanguageDetection = config.getBoolean("auto-language-detection", true); } private List loadInteractables(SuperiorSkyblockPlugin plugin) { diff --git a/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsHandler.java b/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsHandler.java index 805f20b7b..7475df646 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsHandler.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/config/SettingsHandler.java @@ -513,6 +513,11 @@ public long getRecalcTaskTimeout() { return this.container.recalcTaskTimeout; } + @Override + public boolean isAutoLanguageDetection() { + return this.container.autoLanguageDetection; + } + public void updateValue(String path, Object value) throws IOException { SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin(); File file = new File(plugin.getDataFolder(), "config.yml"); diff --git a/src/main/java/com/bgsoftware/superiorskyblock/lang/PlayerLocales.java b/src/main/java/com/bgsoftware/superiorskyblock/lang/PlayerLocales.java index 87c8b62be..9172834b7 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/lang/PlayerLocales.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/lang/PlayerLocales.java @@ -19,7 +19,7 @@ public final class PlayerLocales { private static final Pattern RTL_LOCALE_PATTERN = Pattern.compile( "^(ar|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)"); - private static final Pattern LOCALE_PATTERN = Pattern.compile("^[a-z]{2}[_|-][A-Z]{2}$"); + private static final Pattern LOCALE_PATTERN = Pattern.compile("^[a-zA-Z]{2}[_|-][a-zA-Z]{2}$"); private static final Set locales = new HashSet<>(); private static final Set noInteractMessages = new HashSet<>(); diff --git a/src/main/java/com/bgsoftware/superiorskyblock/listeners/PlayersListener.java b/src/main/java/com/bgsoftware/superiorskyblock/listeners/PlayersListener.java index 0ce97a3cd..2991bf8a6 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/listeners/PlayersListener.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/listeners/PlayersListener.java @@ -70,6 +70,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.UUID; @@ -149,6 +150,15 @@ public void onPlayerJoin(PlayerJoinEvent e) { } }, 10L); + if (plugin.getSettings().isAutoLanguageDetection() && !e.getPlayer().hasPlayedBefore()) { + Executor.sync(() -> superiorPlayer.runIfOnline(player -> { + Locale playerLocale = plugin.getNMSPlayers().getPlayerLocale(player); + if (playerLocale != null && PlayerLocales.isValidLocale(playerLocale)) { + superiorPlayer.setUserLocale(playerLocale); + } + }), 2L); + } + Executor.async(() -> superiorPlayer.runIfOnline(player -> { java.util.Locale locale = superiorPlayer.getUserLocale(); if (!Message.GOT_INVITE.isEmpty(locale)) { diff --git a/src/main/java/com/bgsoftware/superiorskyblock/nms/NMSPlayers.java b/src/main/java/com/bgsoftware/superiorskyblock/nms/NMSPlayers.java index e3315147b..73e4256e8 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/nms/NMSPlayers.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/nms/NMSPlayers.java @@ -6,6 +6,9 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; + public interface NMSPlayers { void clearInventory(OfflinePlayer offlinePlayer); @@ -20,4 +23,7 @@ public interface NMSPlayers { boolean wasThrownByPlayer(Item item, Player player); + @Nullable + Locale getPlayerLocale(Player player); + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0acf3a0d6..d2a9ef790 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -738,4 +738,9 @@ public-warps: false # Timeout for the recalculate task, in seconds. # If you want to disable the timeout, set this to 0 or below. -recalc-task-timeout: 10 \ No newline at end of file +recalc-task-timeout: 10 + +# Detect the player's language automatically when he first joins the server. +# The language will only get changed if there is a valid translation available, +# otherwise the default language will be chosen for the player. +auto-language-detection: true \ No newline at end of file diff --git a/v1_12_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_12_R1/NMSPlayersImpl.java b/v1_12_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_12_R1/NMSPlayersImpl.java index 94ae99b11..077bc7049 100644 --- a/v1_12_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_12_R1/NMSPlayersImpl.java +++ b/v1_12_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_12_R1/NMSPlayersImpl.java @@ -2,6 +2,7 @@ import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -22,6 +23,8 @@ import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { @@ -87,4 +90,14 @@ public boolean wasThrownByPlayer(org.bukkit.entity.Item item, Player player) { return entity instanceof EntityItem && player.getName().equals(((EntityItem) entity).n()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + try { + return PlayerLocales.getLocale(player.getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + } diff --git a/v1_16_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_16_R3/NMSPlayersImpl.java b/v1_16_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_16_R3/NMSPlayersImpl.java index 860d02d03..5566fc29c 100644 --- a/v1_16_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_16_R3/NMSPlayersImpl.java +++ b/v1_16_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_16_R3/NMSPlayersImpl.java @@ -1,7 +1,9 @@ package com.bgsoftware.superiorskyblock.nms.v1_16_R3; +import com.bgsoftware.common.reflection.ReflectMethod; import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -24,10 +26,13 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { + private static final ReflectMethod PLAYER_LOCALE = new ReflectMethod<>(Player.class, "locale"); private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin(); @Override @@ -92,4 +97,17 @@ public boolean wasThrownByPlayer(Item item, Player player) { return entity instanceof EntityItem && player.getUniqueId().equals(((EntityItem) entity).getThrower()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + if (PLAYER_LOCALE.isValid()) { + return player.locale(); + } else try { + //noinspection deprecation + return PlayerLocales.getLocale(player.getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + } diff --git a/v1_17_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_17_R1/NMSPlayersImpl.java b/v1_17_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_17_R1/NMSPlayersImpl.java index bccfcac10..0342ed431 100644 --- a/v1_17_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_17_R1/NMSPlayersImpl.java +++ b/v1_17_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_17_R1/NMSPlayersImpl.java @@ -1,7 +1,9 @@ package com.bgsoftware.superiorskyblock.nms.v1_17_R1; +import com.bgsoftware.common.reflection.ReflectMethod; import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -23,10 +25,13 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { + private static final ReflectMethod PLAYER_LOCALE = new ReflectMethod<>(Player.class, "locale"); private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin(); @Override @@ -91,4 +96,17 @@ public boolean wasThrownByPlayer(Item item, Player player) { return entity instanceof EntityItem && player.getUniqueId().equals(((EntityItem) entity).getThrower()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + if (PLAYER_LOCALE.isValid()) { + return player.locale(); + } else try { + //noinspection deprecation + return PlayerLocales.getLocale(player.getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + } diff --git a/v1_18_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R1/NMSPlayersImpl.java b/v1_18_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R1/NMSPlayersImpl.java index 7fea95815..499044dec 100644 --- a/v1_18_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R1/NMSPlayersImpl.java +++ b/v1_18_R1/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R1/NMSPlayersImpl.java @@ -1,7 +1,9 @@ package com.bgsoftware.superiorskyblock.nms.v1_18_R1; +import com.bgsoftware.common.reflection.ReflectMethod; import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.bgsoftware.superiorskyblock.nms.v1_18_R1.mapping.level.WorldServer; import com.bgsoftware.superiorskyblock.nms.v1_18_R1.mapping.world.entity.Entity; @@ -22,10 +24,13 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { + private static final ReflectMethod PLAYER_LOCALE = new ReflectMethod<>(Player.class, "locale"); private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin(); @Override @@ -92,4 +97,17 @@ public boolean wasThrownByPlayer(Item item, Player player) { return entity.getHandle() instanceof EntityItem && player.getUniqueId().equals(entity.getThrower()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + if (PLAYER_LOCALE.isValid()) { + return player.locale(); + } else try { + //noinspection deprecation + return PlayerLocales.getLocale(player.getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + } diff --git a/v1_18_R2/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R2/NMSPlayersImpl.java b/v1_18_R2/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R2/NMSPlayersImpl.java index 4ea13de89..44f3129d8 100644 --- a/v1_18_R2/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R2/NMSPlayersImpl.java +++ b/v1_18_R2/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_18_R2/NMSPlayersImpl.java @@ -1,7 +1,9 @@ package com.bgsoftware.superiorskyblock.nms.v1_18_R2; +import com.bgsoftware.common.reflection.ReflectMethod; import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.bgsoftware.superiorskyblock.nms.v1_18_R2.mapping.level.WorldServer; import com.bgsoftware.superiorskyblock.nms.v1_18_R2.mapping.world.entity.Entity; @@ -22,10 +24,13 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { + private static final ReflectMethod PLAYER_LOCALE = new ReflectMethod<>(Player.class, "locale"); private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin(); @Override @@ -92,4 +97,17 @@ public boolean wasThrownByPlayer(Item item, Player player) { return entity.getHandle() instanceof EntityItem && player.getUniqueId().equals(entity.getThrower()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + if (PLAYER_LOCALE.isValid()) { + return player.locale(); + } else try { + //noinspection deprecation + return PlayerLocales.getLocale(player.getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + } diff --git a/v1_8_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_8_R3/NMSPlayersImpl.java b/v1_8_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_8_R3/NMSPlayersImpl.java index 47a18fda2..c3c9ed802 100644 --- a/v1_8_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_8_R3/NMSPlayersImpl.java +++ b/v1_8_R3/src/main/java/com/bgsoftware/superiorskyblock/nms/v1_8_R3/NMSPlayersImpl.java @@ -2,6 +2,7 @@ import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; +import com.bgsoftware.superiorskyblock.lang.PlayerLocales; import com.bgsoftware.superiorskyblock.nms.NMSPlayers; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -24,6 +25,8 @@ import org.bukkit.craftbukkit.v1_8_R3.util.CraftChatMessage; import org.bukkit.entity.Player; +import javax.annotation.Nullable; +import java.util.Locale; import java.util.Optional; public final class NMSPlayersImpl implements NMSPlayers { @@ -103,4 +106,14 @@ public boolean wasThrownByPlayer(org.bukkit.entity.Item item, Player player) { return entity instanceof EntityItem && player.getName().equals(((EntityItem) entity).n()); } + @Nullable + @Override + public Locale getPlayerLocale(Player player) { + try { + return PlayerLocales.getLocale(player.spigot().getLocale()); + } catch (IllegalArgumentException error) { + return null; + } + } + }