Language system implementation, commands still not translatable yet, finish up configs system

This commit is contained in:
mohammed jasem alaajel 2023-10-01 14:31:49 +04:00
parent 32b5e829ba
commit 983693b929
13 changed files with 304 additions and 81 deletions

View File

@ -11,6 +11,7 @@
package com.imaginarycode.minecraft.redisbungee.api;
import com.imaginarycode.minecraft.redisbungee.AbstractRedisBungeeAPI;
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.events.EventsPlatform;
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
@ -54,6 +55,8 @@ public interface RedisBungeePlugin<P> extends EventsPlatform {
RedisBungeeConfiguration configuration();
LangConfiguration langConfiguration();
Summoner<?> getSummoner();
RedisBungeeMode getRedisBungeeMode();

View File

@ -1,4 +1,142 @@
/*
* Copyright (c) 2013-present RedisBungee contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.imaginarycode.minecraft.redisbungee.api.config;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class LangConfiguration {
public static class Messages {
private final Map<Locale, Component> LOGGED_IN_FROM_OTHER_LOCATION;
private final Map<Locale, Component> ALREADY_LOGGED_IN;
private final Map<Locale, String> SERVER_CONNECTING;
private final Map<Locale, String> SERVER_NOT_FOUND;
private final Locale defaultLocale;
public Messages(Locale defaultLocale) {
LOGGED_IN_FROM_OTHER_LOCATION = new HashMap<>();
ALREADY_LOGGED_IN = new HashMap<>();
SERVER_CONNECTING = new HashMap<>();
SERVER_NOT_FOUND = new HashMap<>();
this.defaultLocale = defaultLocale;
}
public void register(String id, Locale locale, String miniMessage) {
switch (id) {
case "server-not-found" -> SERVER_NOT_FOUND.put(locale, miniMessage);
case "server-connecting" -> SERVER_CONNECTING.put(locale, miniMessage);
case "logged-in-other-location" -> LOGGED_IN_FROM_OTHER_LOCATION.put(locale, MiniMessage.miniMessage().deserialize(miniMessage));
case "already-logged-in" -> ALREADY_LOGGED_IN.put(locale, MiniMessage.miniMessage().deserialize(miniMessage));
}
}
public Component alreadyLoggedIn(Locale locale) {
if (ALREADY_LOGGED_IN.containsKey(locale)) return ALREADY_LOGGED_IN.get(locale);
return ALREADY_LOGGED_IN.get(defaultLocale);
}
// there is no way to know whats client locale during login so just default to use default locale MESSAGES.
public Component alreadyLoggedIn() {
return this.alreadyLoggedIn(this.defaultLocale);
}
public Component loggedInFromOtherLocation(Locale locale) {
if (LOGGED_IN_FROM_OTHER_LOCATION.containsKey(locale)) return LOGGED_IN_FROM_OTHER_LOCATION.get(locale);
return LOGGED_IN_FROM_OTHER_LOCATION.get(defaultLocale);
}
// there is no way to know what's client locale during login so just default to use default locale MESSAGES.
public Component loggedInFromOtherLocation() {
return this.loggedInFromOtherLocation(this.defaultLocale);
}
public Component serverConnecting(Locale locale, String server) {
String miniMessage;
if (SERVER_CONNECTING.containsKey(locale)) {
miniMessage = SERVER_CONNECTING.get(locale);
} else {
miniMessage = SERVER_CONNECTING.get(defaultLocale);
}
return MiniMessage.miniMessage().deserialize(miniMessage, Placeholder.parsed("server", server));
}
public Component serverConnecting(String server) {
return this.serverConnecting(this.defaultLocale, server);
}
public Component serverNotFound(Locale locale, String server) {
String miniMessage;
if (SERVER_NOT_FOUND.containsKey(locale)) {
miniMessage = SERVER_NOT_FOUND.get(locale);
} else {
miniMessage = SERVER_NOT_FOUND.get(defaultLocale);
}
return MiniMessage.miniMessage().deserialize(miniMessage, Placeholder.parsed("server", server));
}
public Component serverNotFound(String server) {
return this.serverNotFound(this.defaultLocale, server);
}
// tests locale if set CORRECTLY or just throw if not
public void test(Locale locale) {
if (!(LOGGED_IN_FROM_OTHER_LOCATION.containsKey(locale) && ALREADY_LOGGED_IN.containsKey(locale) && SERVER_CONNECTING.containsKey(locale) && SERVER_NOT_FOUND.containsKey(locale))) {
throw new IllegalStateException("Language system in `messages` found missing entries for " + locale.toString());
}
}
}
private final Component redisBungeePrefix;
private final Locale defaultLanguage;
private final boolean useClientLanguage;
private final Messages messages;
public LangConfiguration(Component redisBungeePrefix, Locale defaultLanguage, boolean useClientLanguage, Messages messages) {
this.redisBungeePrefix = redisBungeePrefix;
this.defaultLanguage = defaultLanguage;
this.useClientLanguage = useClientLanguage;
this.messages = messages;
}
public Component redisBungeePrefix() {
return redisBungeePrefix;
}
public Locale defaultLanguage() {
return defaultLanguage;
}
public boolean useClientLanguage() {
return useClientLanguage;
}
public Messages messages() {
return messages;
}
}

View File

@ -34,7 +34,6 @@ public interface ConfigLoader extends GenericConfigLoader {
int CONFIG_VERSION = 2;
@Override
default void loadConfig(RedisBungeePlugin<?> plugin, Path dataFolder) throws IOException {
Path configFile = createConfigFile(dataFolder, "config.yml", "config.yml");
final YAMLConfigurationLoader yamlConfigurationFileLoader = YAMLConfigurationLoader.builder().setPath(configFile).build();

View File

@ -1,29 +1,31 @@
/*
* Copyright (c) 2013-present RedisBungee contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.imaginarycode.minecraft.redisbungee.api.config.loaders;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import org.jetbrains.annotations.Nullable;
import java.io.File;
;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.util.UUID;
public interface GenericConfigLoader {
// CHANGES on every reboot
String RANDOM_OLD = "backup-" + Instant.now().getEpochSecond();
default void loadConfig(RedisBungeePlugin<?> plugin, File dataFolder) throws IOException {
loadConfig(plugin, dataFolder.toPath());
}
void loadConfig(RedisBungeePlugin<?> plugin, Path path) throws IOException;
default Path createConfigFile(Path dataFolder, String configFile, @Nullable String defaultResourceID) throws IOException {
if (Files.notExists(dataFolder)) {
Files.createDirectory(dataFolder);

View File

@ -1,4 +1,55 @@
/*
* Copyright (c) 2013-present RedisBungee contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.imaginarycode.minecraft.redisbungee.api.config.loaders;
public interface LangConfigLoader {
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Locale;
public interface LangConfigLoader extends GenericConfigLoader {
int CONFIG_VERSION = 1;
default void loadLangConfig(RedisBungeePlugin<?> plugin, Path dataFolder) throws IOException {
Path configFile = createConfigFile(dataFolder, "lang.yml", "lang.yml");
final YAMLConfigurationLoader yamlConfigurationFileLoader = YAMLConfigurationLoader.builder().setPath(configFile).build();
ConfigurationNode node = yamlConfigurationFileLoader.load();
if (node.getNode("config-version").getInt(0) != CONFIG_VERSION) {
handleOldConfig(dataFolder, "lang.yml", "lang.yml");
node = yamlConfigurationFileLoader.load();
}
// MINI message serializer
MiniMessage miniMessage = MiniMessage.miniMessage();
Component prefix = miniMessage.deserialize(node.getNode("prefix").getString("<color:red>[<color:yellow>Redis<color:red>Bungee]"));
Locale defaultLocale = Locale.forLanguageTag(node.getNode("default-locale").getString("en-us"));
System.out.println(node.getNode("default-locale").getString());
boolean useClientLocale = node.getNode("use-client-locale").getBoolean(true);
LangConfiguration.Messages messages = new LangConfiguration.Messages(defaultLocale);
node.getNode("messages").getChildrenMap().forEach((key, childNode) -> childNode.getChildrenMap().forEach((childKey, childChildNode) -> {
messages.register(key.toString(), Locale.forLanguageTag(childKey.toString()), childChildNode.getString());
}));
messages.test(defaultLocale);
onLangConfigLoad(new LangConfiguration(prefix, defaultLocale, useClientLocale, messages));
}
void onLangConfigLoad(LangConfiguration langConfiguration);
}

View File

@ -61,9 +61,8 @@ compatibility-max-connections: 3
# if this disabled override-bungee-commands will be ignored
register-commands: false
# THIS IS BUNGEECORD ONLY OPTION!
# Whether or not RedisBungee should install its version of regular BungeeCord commands.
# Whether RedisBungee should install its version of regular BungeeCord commands.
# Often, the RedisBungee commands are desired, but in some cases someone may wish to
# override the commands using another plugin.
#
@ -75,23 +74,24 @@ register-commands: false
# ignored on velocity
override-bungee-commands: false
# A list of IP addresses for which RedisBungee will not modify the response for, useful for automatic
# restart scripts.
exempt-ip-addresses: []
# restore old login behavior before 0.9.0 update
# enabled by default
# when true: when player login and there is old player with same uuid it will get disconnected as result and new player will login
# when true: when player login and there is old player with same uuid it will get disconnected as result and new player will log in
# when false: when a player login but login will fail because old player is still connected.
kick-when-online: true
# enabled by default
# this option tells redis-bungee handle motd and set online count, when motd is requested
# this option tells RedisBungee handle motd and set online count, when motd is requested
# you can disable this when you want to handle motd yourself, use RedisBungee api to get total players when needed :)
handle-motd: true
# A list of IP addresses for which RedisBungee will not modify the response for, useful for automatic
# restart scripts.
# Ignored if handle-motd is disabled.
exempt-ip-addresses: []
# disabled by default
# Redis-bungee will attempt to connect player to last server that was stored.
# RedisBungee will attempt to connect player to last server that was stored.
reconnect-to-last-server: false
# Config version DO NOT CHANGE!!!!

View File

@ -1,71 +1,80 @@
# this config file is for messages / Languages
# Note 1: use MiniMessage format https://docs.advntr.dev/minimessage/format.html
# use MiniMessage format https://docs.advntr.dev/minimessage/format.html
# for colors etc... Legacy chat color is not supported.
# Note 2:
# Language codes used in minecraft from the minecraft wiki
# example: en_us for american english and ar_sa for arabic
# example: en-us for american english and ar-sa for arabic
# all codes can be obtained from link below
# from the colum Locale Code -> In-game
# NOTE: minecraft wiki shows languages like this `en_us` in config it should be `en-us`
# https://minecraft.wiki/w/Language
# example:
# lets assume we want to add arabic language.
# errors:
# messages:
# logged-in-other-location:
# en_us: "<color:red>You logged in from another location!"
# ar_sa: "<color:red>لقد اتصلت من مكان اخر"
# en-us: "<color:red>You logged in from another location!"
# ar-sa: "<color:red>لقد اتصلت من مكان اخر"
# RedisBungee Prefix if ever used.
redis-bungee-prefix: "<color:red>[<color:yellow>Redis<color:red>Bungee]"
prefix: "<color:red>[<color:yellow>Redis<color:red>Bungee]"
# us_en is american English, Which is the default language used when a language for a message isn't defined.
# Warning: IF THE set default language wasn't defined in the config for all messages, plugin will not load.
# set the default language
default-language: en_us
# en-us is american English, Which is the default language used when a language for a message isn't defined.
# Warning: IF THE set default locale wasn't defined in the config for all messages, plugin will not load.
# set the Default locale
default-locale: en-us
# send language based on client sent settings
# if you don't have languages configured for client it will
# default to language that has been set above
use-client-language: true
# if you don't have languages configured For client Language
# it will default to language that has been set above
# NOTE: due minecraft protocol not sending player settings during login,
# some of the messages like logged-in-other-location will
# skip translation and use default locale that has been set in default-locale.
use-client-locale: true
# messages
# messages that are used during login, and connecting to Last server
messages:
logged-in-other-location:
en_us: "<color:red>You logged in from another location!"
ar_sa: "<color:red>لقد اتصلت من مكان اخر"
en-us: "<color:red>You logged in from another location!"
ar-sa: "<color:red>لقد اتصلت من مكان اخر"
already-logged-in:
en_us: "<color:red>You are already logged in!"
ar_sa: "<color:red>انت متصل بالفعل"
en-us: "<color:red>You are already logged in!"
ar-sa: "<color:red>انت متصل بالفعل"
server-not-found:
# placeholder <server> displays server name in the message.
en_us: "<color:red>unable to connect you to the last server, because server <server> was not found."
ar_sa: "<color:red>فشل الاتصال بالخادم السابق لان الخادم غير موجود (<server>)"
server-found:
en-us: "<color:red>unable to connect you to the last server, because server <server> was not found."
ar-sa: "<color:red>فشل الاتصال بالخادم السابق لان الخادم غير موجود (<server>)"
server-connecting:
# placeholder <server> displays server name in the message.
en_us: "<color:green>Connecting you to <server>..."
ar_sa: "<color:green>جاري الاتصال بخادم <server>"
en-us: "<color:green>Connecting you to <server>..."
ar-sa: "<color:green>جاري الاتصال بخادم <server>"
# commands common messages:
# commands common messages
commands-common:
player-not-found:
en_us: "<color:red>Player not found."
ar_sa: "<color:red>اللاعب غير موجود"
en-us: "<color:red>Player not found."
ar-sa: "<color:red>اللاعب غير موجود"
player-not-specified:
en_us: "<color:red>You must specify a player name."
ar_sa: "<color:red>أدخل اسم اللاعب مطلوب"
en-us: "<color:red>You must specify a player name."
ar-sa: "<color:red>أدخل اسم اللاعب مطلوب"
command-not-specified:
en_us: "<color:red>You must specify a command to be run."
ar_sa: "<color:red>ادخل الأمر المطلوب"
en-us: "<color:red>You must specify a command to be run."
ar-sa: "<color:red>ادخل الأمر المطلوب"
# commands
commands:
glist:
single-player:
en-us: "<color:yellow><players> player is currently online"
players:
en-us: "<color:yellow><players> players are currently online"
notice:
en-us: "<color:yellow>To see all players online, use /glist showall."
# DO NOT CHANGE!!!!!
config-version: 1

View File

@ -12,15 +12,11 @@ package com.imaginarycode.minecraft.redisbungee;
import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
@ -30,14 +26,11 @@ import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, PostLoginEvent, PlayerDisconnectEvent, PubSubMessageEvent, PlayerChangedServerNetworkEvent, PlayerLeftNetworkEvent, ServerConnectedEvent> implements Listener {
private final BungeeComponentSerializer BUNGEECORD_SERIALIZER = BungeeComponentSerializer.get();
public BungeePlayerDataManager(RedisBungeePlugin<ProxiedPlayer> plugin) {
super(plugin);
}
@ -74,12 +67,12 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, Po
// check if online
if (getLastOnline(event.getConnection().getUniqueId()) == 0) {
if (plugin.configuration().kickWhenOnline()) {
kickPlayer(event.getConnection().getUniqueId(), Component.empty());
kickPlayer(event.getConnection().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
// wait 3 seconds before releasing the event
plugin.executeAsyncAfter(() -> event.completeIntent((Plugin) plugin), TimeUnit.SECONDS, 3);
} else {
event.setCancelled(true);
event.setCancelReason(BUNGEECORD_SERIALIZER.serialize(Component.empty()));
event.setCancelReason(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().alreadyLoggedIn()));
event.completeIntent((Plugin) plugin);
}
} else {

View File

@ -14,8 +14,10 @@ import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
import com.imaginarycode.minecraft.redisbungee.api.ProxyDataManager;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.ConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.LangConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerChangedServerNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerJoinedNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerLeftNetworkEvent;
@ -45,6 +47,8 @@ import redis.clients.jedis.JedisPool;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.sql.Date;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@ -52,7 +56,7 @@ import java.util.concurrent.*;
import java.util.logging.Level;
public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlayer>, ConfigLoader {
public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlayer>, ConfigLoader, LangConfigLoader {
private static RedisBungeeAPI apiStatic;
private AbstractRedisBungeeAPI api;
@ -64,6 +68,7 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
private Summoner<?> summoner;
private UUIDTranslator uuidTranslator;
private RedisBungeeConfiguration configuration;
private LangConfiguration langConfiguration;
private OkHttpClient httpClient;
private final Logger logger = LoggerFactory.getLogger("RedisBungee");
@ -74,6 +79,10 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
return this.configuration;
}
@Override
public LangConfiguration langConfiguration() {
return this.langConfiguration;
}
@Override
public AbstractRedisBungeeAPI getAbstractRedisBungeeApi() {
@ -184,7 +193,7 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
public void initialize() {
logInfo("Initializing RedisBungee.....");
logInfo("Version: {}", Constants.VERSION);
logInfo("Build date: {}", Constants.BUILD_DATE);
logInfo("Build date: {}", Date.from(Instant.ofEpochSecond(Constants.BUILD_DATE)));
ThreadFactory factory = ((ThreadPoolExecutor) getExecutorService()).getThreadFactory();
ScheduledExecutorService service = Executors.newScheduledThreadPool(24, factory);
try {
@ -198,7 +207,8 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
getLogger().log(Level.WARNING, "skipping replacement.....");
}
try {
loadConfig(this, getDataFolder());
loadConfig(this, getDataFolder().toPath());
loadLangConfig(this, getDataFolder().toPath());
} catch (IOException e) {
throw new RuntimeException("Unable to load/save config", e);
}
@ -350,4 +360,8 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
}
@Override
public void onLangConfigLoad(LangConfiguration langConfiguration) {
this.langConfiguration = langConfiguration;
}
}

View File

@ -18,6 +18,7 @@ import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
@ -152,12 +153,13 @@ public class RedisBungeeListener implements Listener {
@EventHandler
public void onServerConnectEvent(ServerConnectEvent event) {
if (event.getReason() == ServerConnectEvent.Reason.JOIN_PROXY && plugin.configuration().handleReconnectToLastServer()) {
ProxiedPlayer player = event.getPlayer();
String lastServer = plugin.playerDataManager().getLastServerFor(event.getPlayer().getUniqueId());
if (lastServer == null) return;
// sending connect message, todo: IMPLEMENT once lang system is finalized
player.sendMessage(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().serverConnecting(player.getLocale(), lastServer)));
ServerInfo serverInfo = ProxyServer.getInstance().getServerInfo(lastServer);
if (serverInfo == null) {
// sending failure message, todo: IMPLEMENT once lang system is finalized
player.sendMessage(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().serverNotFound(player.getLocale(), lastServer)));
return;
}
event.setTarget(serverInfo);

View File

@ -155,12 +155,13 @@ public class RedisBungeeListener {
@Subscribe
public void onPlayerChooseInitialServerEvent(PlayerChooseInitialServerEvent event) {
if (plugin.configuration().handleReconnectToLastServer()) {
String lastServer = plugin.playerDataManager().getLastServerFor(event.getPlayer().getUniqueId());
Player player = event.getPlayer();
String lastServer = plugin.playerDataManager().getLastServerFor(player.getUniqueId());
if (lastServer == null) return;
// sending connect message, todo: IMPLEMENT once lang system is finalized
player.sendMessage(plugin.langConfiguration().messages().serverConnecting(player.getPlayerSettings().getLocale(), lastServer));
Optional<RegisteredServer> optionalRegisteredServer = ((RedisBungeeVelocityPlugin) plugin).getProxy().getServer(lastServer);
if (optionalRegisteredServer.isEmpty()) {
// sending failure message, todo: IMPLEMENT once lang system is finalized
player.sendMessage(plugin.langConfiguration().messages().serverNotFound(player.getPlayerSettings().getLocale(), lastServer));
return;
}
RegisteredServer server = optionalRegisteredServer.get();

View File

@ -15,8 +15,10 @@ import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
import com.imaginarycode.minecraft.redisbungee.api.ProxyDataManager;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.ConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.LangConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerChangedServerNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerJoinedNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerLeftNetworkEvent;
@ -52,7 +54,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.nio.file.Path;
import java.sql.Date;
import java.time.Duration;
import java.time.Instant;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -61,7 +65,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Plugin(id = "redisbungee", name = "RedisBungee", version = Constants.VERSION, url = "https://github.com/ProxioDev/RedisBungee", authors = {"astei", "ProxioDev"})
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, ConfigLoader {
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, ConfigLoader, LangConfigLoader {
private final ProxyServer server;
private final Logger logger;
private final Path dataFolder;
@ -70,6 +74,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
private RedisBungeeMode redisBungeeMode;
private final UUIDTranslator uuidTranslator;
private RedisBungeeConfiguration configuration;
private LangConfiguration langConfiguration;
private final OkHttpClient httpClient;
private final ProxyDataManager proxyDataManager;
@ -92,9 +97,10 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
this.logger = logger;
this.dataFolder = dataDirectory;
logInfo("Version: {}", Constants.VERSION);
logInfo("Build date: {}", Constants.BUILD_DATE);
logInfo("Build date: {}", Date.from(Instant.ofEpochSecond(Constants.BUILD_DATE)));
try {
loadConfig(this, dataDirectory);
loadLangConfig(this, dataDirectory);
} catch (IOException e) {
throw new RuntimeException("Unable to load/save config", e);
} catch (JedisConnectionException e) {
@ -206,6 +212,11 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
return this.configuration;
}
@Override
public LangConfiguration langConfiguration() {
return this.langConfiguration;
}
@Override
public Player getPlayer(UUID uuid) {
return this.getProxy().getPlayer(uuid).orElse(null);
@ -311,6 +322,10 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
this.redisBungeeMode = mode;
}
@Override
public void onLangConfigLoad(LangConfiguration langConfiguration) {
this.langConfiguration = langConfiguration;
}
@Override
public RedisBungeeMode getRedisBungeeMode() {

View File

@ -25,10 +25,7 @@ import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLoginEvent, DisconnectEvent, PubSubMessageEvent, PlayerChangedServerNetworkEvent, PlayerLeftNetworkEvent, ServerConnectedEvent> {
@ -69,15 +66,14 @@ public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLog
@Subscribe
public void onLoginEvent(LoginEvent event, Continuation continuation) {
System.out.println(event.getPlayer().getPlayerSettings().getLocale().getDisplayLanguage());
// check if online
if (getLastOnline(event.getPlayer().getUniqueId()) == 0) {
if (plugin.configuration().kickWhenOnline()) {
kickPlayer(event.getPlayer().getUniqueId(), Component.empty());
kickPlayer(event.getPlayer().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
// wait 3 seconds before releasing the event
plugin.executeAsyncAfter(continuation::resume, TimeUnit.SECONDS, 3);
} else {
event.setResult(ResultedEvent.ComponentResult.denied(Component.empty()));
event.setResult(ResultedEvent.ComponentResult.denied(plugin.langConfiguration().messages().alreadyLoggedIn()));
continuation.resume();
}
} else {