mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-22 14:34:59 +01:00
Add Translation support (#504)
Adds full multi-language support to any Bedrock-supported language. Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
This commit is contained in:
parent
d1e5960d69
commit
cfaf4051b7
51 changed files with 504 additions and 191 deletions
5
.gitmodules
vendored
5
.gitmodules
vendored
|
@ -1,4 +1,7 @@
|
|||
[submodule "connector/src/main/resources/mappings"]
|
||||
path = connector/src/main/resources/mappings
|
||||
url = https://github.com/GeyserMC/mappings.git
|
||||
branch = feature/1.16
|
||||
branch = feature/1.16
|
||||
[submodule "connector/src/main/resources/languages"]
|
||||
path = connector/src/main/resources/languages
|
||||
url = https://github.com/GeyserMC/languages.git
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.geysermc.connector.dump.BootstrapDumpInfo;
|
|||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor;
|
||||
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager;
|
||||
|
||||
|
@ -71,7 +72,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
|||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
|
||||
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml"));
|
||||
} catch (IOException ex) {
|
||||
getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
||||
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -93,7 +94,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
|||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||
|
||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) {
|
||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
||||
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ import net.md_5.bungee.api.plugin.TabExecutor;
|
|||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -52,7 +54,14 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
|
|||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + "You do not have permission to execute this command!"));
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||
}
|
||||
|
||||
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + message));
|
||||
return;
|
||||
}
|
||||
getCommand(args[0]).execute(new BungeeCommandSender(sender), args);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.geysermc.connector.network.translators.world.WorldManager;
|
|||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor;
|
||||
import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager;
|
||||
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
|
||||
|
@ -68,15 +69,15 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||
getDataFolder().mkdir();
|
||||
File bukkitConfig = new File("plugins/Geyser-Bukkit/config.yml");
|
||||
if (bukkitConfig.exists()) { // Copy over old configs
|
||||
getLogger().log(Level.INFO, "Existing config found in the Geyser-Bukkit folder; copying over...");
|
||||
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copy_bukkit_config"));
|
||||
Files.copy(bukkitConfig.toPath(), new File(getDataFolder().toString() + "/config.yml").toPath());
|
||||
getLogger().log(Level.INFO, "Copied!");
|
||||
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copied_bukkit_config"));
|
||||
}
|
||||
}
|
||||
File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class);
|
||||
} catch (IOException ex) {
|
||||
getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
||||
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -92,7 +93,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||
|
||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") == null) {
|
||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
||||
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||
this.getPluginLoader().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -26,13 +26,14 @@
|
|||
package org.geysermc.platform.spigot.command;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -48,7 +49,14 @@ public class GeyserSpigotCommandExecutor implements TabExecutor {
|
|||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!");
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.RED + message);
|
||||
return true;
|
||||
}
|
||||
getCommand(args[0]).execute(new SpigotCommandSender(sender), args);
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.geysermc.connector.dump.BootstrapDumpInfo;
|
|||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor;
|
||||
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -80,7 +81,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
|
|||
try {
|
||||
configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Failed to copy config.yml from jar path!");
|
||||
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -90,7 +91,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
|
|||
config = loader.load();
|
||||
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Failed to load config.yml!");
|
||||
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
package org.geysermc.platform.sponge.command;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.spongepowered.api.command.CommandCallable;
|
||||
import org.spongepowered.api.command.CommandException;
|
||||
import org.spongepowered.api.command.CommandResult;
|
||||
|
@ -55,7 +55,8 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
|
|||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
source.sendMessage(Text.of(ChatColor.RED + "You do not have permission to execute this command!"));
|
||||
// Not ideal to use log here but we dont get a session
|
||||
source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
|
||||
return CommandResult.success();
|
||||
}
|
||||
getCommand(args[0]).execute(new SpongeCommandSender(source), args);
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.geysermc.connector.dump.BootstrapDumpInfo;
|
|||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.standalone.command.GeyserCommandManager;
|
||||
import org.geysermc.platform.standalone.gui.GeyserStandaloneGUI;
|
||||
|
||||
|
@ -107,7 +108,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||
File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
|
||||
} catch (IOException ex) {
|
||||
geyserLogger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
||||
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||
System.exit(0);
|
||||
}
|
||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package org.geysermc.platform.standalone;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
|
||||
public class LoopbackUtil {
|
||||
private static final String checkExemption = "powershell -Command \"CheckNetIsolation LoopbackExempt -s\""; // Java's Exec feature runs as CMD, NetIsolation is only accessible from PowerShell.
|
||||
private static final String loopbackCommand = "powershell -Command \"CheckNetIsolation LoopbackExempt -a -n='Microsoft.MinecraftUWP_8wekyb3d8bbwe'\"";
|
||||
|
@ -31,12 +32,12 @@ public class LoopbackUtil {
|
|||
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]);
|
||||
process = Runtime.getRuntime().exec(startScript);
|
||||
|
||||
geyserLogger.info(ChatColor.AQUA + "Added loopback exemption to Windows!");
|
||||
geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
geyserLogger.error("Couldn't auto add loopback exemption to Windows!");
|
||||
geyserLogger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.failed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ package org.geysermc.platform.standalone.gui;
|
|||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.standalone.GeyserStandaloneLogger;
|
||||
import org.geysermc.platform.standalone.command.GeyserCommandManager;
|
||||
|
||||
|
@ -52,7 +53,9 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
public class GeyserStandaloneGUI {
|
||||
|
||||
private static final String[] playerTableHeadings = new String[] {"IP", "Username"};
|
||||
private static final String[] playerTableHeadings = new String[] {
|
||||
LanguageUtils.getLocaleStringLog("geyser.gui.table.ip"),
|
||||
LanguageUtils.getLocaleStringLog("geyser.gui.table.username")};
|
||||
private static final List<Integer> ramValues = new ArrayList<>();
|
||||
|
||||
private static final ColorPane consolePane = new ColorPane();
|
||||
|
@ -67,7 +70,7 @@ public class GeyserStandaloneGUI {
|
|||
|
||||
public GeyserStandaloneGUI() {
|
||||
// Create the frame and setup basic settings
|
||||
JFrame frame = new JFrame("Geyser Standalone");
|
||||
JFrame frame = new JFrame(LanguageUtils.getLocaleStringLog("geyser.gui.title"));
|
||||
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
frame.setSize(800, 400);
|
||||
frame.setMinimumSize(frame.getSize());
|
||||
|
@ -82,8 +85,8 @@ public class GeyserStandaloneGUI {
|
|||
@Override
|
||||
public void windowClosing(WindowEvent we)
|
||||
{
|
||||
String[] buttons = {"Yes", "No"};
|
||||
int result = JOptionPane.showOptionDialog(frame, "Are you sure you want to exit?", frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]);
|
||||
String[] buttons = {LanguageUtils.getLocaleStringLog("geyser.gui.exit.confirm"), LanguageUtils.getLocaleStringLog("geyser.gui.exit.deny")};
|
||||
int result = JOptionPane.showOptionDialog(frame, LanguageUtils.getLocaleStringLog("geyser.gui.exit.message"), frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]);
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
System.exit(0);
|
||||
}
|
||||
|
@ -124,12 +127,12 @@ public class GeyserStandaloneGUI {
|
|||
JMenuBar menuBar = new JMenuBar();
|
||||
|
||||
// Create 'File'
|
||||
JMenu fileMenu = new JMenu("File");
|
||||
JMenu fileMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file"));
|
||||
fileMenu.setMnemonic(KeyEvent.VK_F);
|
||||
menuBar.add(fileMenu);
|
||||
|
||||
// 'Open Geyser folder' button
|
||||
JMenuItem openButton = new JMenuItem("Open Geyser folder", KeyEvent.VK_O);
|
||||
JMenuItem openButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.open_folder"), KeyEvent.VK_O);
|
||||
openButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
|
||||
openButton.addActionListener(e -> {
|
||||
try {
|
||||
|
@ -141,40 +144,40 @@ public class GeyserStandaloneGUI {
|
|||
fileMenu.addSeparator();
|
||||
|
||||
// 'Exit' button
|
||||
JMenuItem exitButton = new JMenuItem("Exit", KeyEvent.VK_X);
|
||||
JMenuItem exitButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.exit"), KeyEvent.VK_X);
|
||||
exitButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK));
|
||||
exitButton.addActionListener(e -> System.exit(0));
|
||||
fileMenu.add(exitButton);
|
||||
|
||||
// Create 'Commands'
|
||||
commandsMenu = new JMenu("Commands");
|
||||
commandsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.commands"));
|
||||
commandsMenu.setMnemonic(KeyEvent.VK_C);
|
||||
menuBar.add(commandsMenu);
|
||||
|
||||
// Create 'View'
|
||||
JMenu viewMenu = new JMenu("View");
|
||||
JMenu viewMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view"));
|
||||
viewMenu.setMnemonic(KeyEvent.VK_V);
|
||||
menuBar.add(viewMenu);
|
||||
|
||||
// 'Zoom in' button
|
||||
JMenuItem zoomInButton = new JMenuItem("Zoom In");
|
||||
JMenuItem zoomInButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_in"));
|
||||
zoomInButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK));
|
||||
zoomInButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() + 1)));
|
||||
viewMenu.add(zoomInButton);
|
||||
|
||||
// 'Zoom in' button
|
||||
JMenuItem zoomOutButton = new JMenuItem("Zoom Out");
|
||||
JMenuItem zoomOutButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_out"));
|
||||
zoomOutButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK));
|
||||
zoomOutButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() - 1)));
|
||||
viewMenu.add(zoomOutButton);
|
||||
|
||||
// 'Reset Zoom' button
|
||||
JMenuItem resetZoomButton = new JMenuItem("Reset Zoom");
|
||||
JMenuItem resetZoomButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.reset_zoom"));
|
||||
resetZoomButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), originalFontSize)));
|
||||
viewMenu.add(resetZoomButton);
|
||||
|
||||
// create 'Options'
|
||||
optionsMenu = new JMenu("Options");
|
||||
optionsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options"));
|
||||
viewMenu.setMnemonic(KeyEvent.VK_O);
|
||||
menuBar.add(optionsMenu);
|
||||
|
||||
|
@ -195,7 +198,7 @@ public class GeyserStandaloneGUI {
|
|||
ramValues.add(0);
|
||||
}
|
||||
ramGraph.setValues(ramValues);
|
||||
ramGraph.setXLabel("Loading...");
|
||||
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.loading"));
|
||||
rightContentPane.add(ramGraph);
|
||||
|
||||
JScrollPane playerScrollPane = new JScrollPane(playerTable);
|
||||
|
@ -270,7 +273,7 @@ public class GeyserStandaloneGUI {
|
|||
}
|
||||
|
||||
// 'Debug Mode' toggle
|
||||
JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem("Debug Mode");
|
||||
JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options.toggle_debug_mode"));
|
||||
debugMode.setSelected(geyserStandaloneLogger.isDebug());
|
||||
debugMode.addActionListener(e -> geyserStandaloneLogger.setDebug(!geyserStandaloneLogger.isDebug()));
|
||||
optionsMenu.add(debugMode);
|
||||
|
@ -305,7 +308,7 @@ public class GeyserStandaloneGUI {
|
|||
final int freePercent = (int)(freeMemory * 100.0 / totalMemory + 0.5);
|
||||
ramValues.add(100 - freePercent);
|
||||
|
||||
ramGraph.setXLabel("Usage: " + String.format("%,d", (totalMemory - freeMemory) / MEGABYTE) + "mb (" + freePercent + "% free)");
|
||||
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.usage", String.format("%,d", (totalMemory - freeMemory) / MEGABYTE), freePercent));
|
||||
|
||||
// Trim the list
|
||||
int k = ramValues.size();
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.geysermc.connector.dump.BootstrapDumpInfo;
|
|||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor;
|
||||
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -85,7 +86,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
|||
File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
||||
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
|||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||
|
||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) {
|
||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
||||
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import net.kyori.text.TextComponent;
|
|||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class GeyserVelocityCommandExecutor implements Command {
|
||||
|
@ -46,7 +47,8 @@ public class GeyserVelocityCommandExecutor implements Command {
|
|||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
source.sendMessage(TextComponent.of(ChatColor.RED + "You do not have permission to execute this command!"));
|
||||
// Not ideal to use log here but we dont get a session
|
||||
source.sendMessage(TextComponent.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
|
||||
return;
|
||||
}
|
||||
getCommand(args[0]).execute(new VelocityCommandSender(source), args);
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Oops! You attempted to run a plugin version of Geyser directly!
|
||||
|
||||
This jar file is a plugin for ${plugin_type}. You can run this file as a
|
||||
plugin by dropping the jar file into the "${plugin_folder}" directory.
|
||||
|
||||
There is also a standalone version available that doesn't need to
|
||||
be installed as a plugin, you can find it on our build server:
|
||||
|
||||
http://ci.geysermc.org/
|
||||
|
||||
If you need more help, you should check out our discord:
|
||||
|
||||
http://discord.geysermc.org/
|
||||
|
||||
--------------------------------------------------------------------------------
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
package org.geysermc.connector;
|
||||
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
@ -37,13 +38,13 @@ public class FloodgateKeyLoader {
|
|||
if (floodgate != null) {
|
||||
Path autoKey = floodgateFolder.resolve("public-key.pem");
|
||||
if (Files.exists(autoKey)) {
|
||||
logger.info("Auto-loaded floodgate key");
|
||||
logger.info(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.auto_loaded"));
|
||||
floodgateKey = autoKey;
|
||||
} else {
|
||||
logger.error("Auth-type set to floodgate and the public key is missing!");
|
||||
logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.missing_key"));
|
||||
}
|
||||
} else {
|
||||
logger.error("Auth-type set to floodgate but floodgate is not installed!");
|
||||
logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.geysermc.connector.network.translators.item.ItemTranslator;
|
|||
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
|
||||
import org.geysermc.connector.network.translators.sound.SoundRegistry;
|
||||
import org.geysermc.connector.network.translators.world.WorldManager;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.connector.utils.DimensionUtils;
|
||||
|
@ -107,7 +108,7 @@ public class GeyserConnector {
|
|||
|
||||
logger.info("******************************************");
|
||||
logger.info("");
|
||||
logger.info("Loading " + NAME + " version " + VERSION);
|
||||
logger.info(LanguageUtils.getLocaleStringLog("geyser.core.load", NAME, VERSION));
|
||||
logger.info("");
|
||||
logger.info("******************************************");
|
||||
|
||||
|
@ -143,9 +144,9 @@ public class GeyserConnector {
|
|||
bedrockServer.setHandler(new ConnectorServerEventHandler(this));
|
||||
bedrockServer.bind().whenComplete((avoid, throwable) -> {
|
||||
if (throwable == null) {
|
||||
logger.info("Started Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());
|
||||
logger.info(LanguageUtils.getLocaleStringLog("geyser.core.start", config.getBedrock().getAddress(), String.valueOf(config.getBedrock().getPort())));
|
||||
} else {
|
||||
logger.severe("Failed to start Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());
|
||||
logger.severe(LanguageUtils.getLocaleStringLog("geyser.core.fail", config.getBedrock().getAddress(), config.getBedrock().getPort()));
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}).join();
|
||||
|
@ -168,24 +169,24 @@ public class GeyserConnector {
|
|||
}
|
||||
|
||||
double completeTime = (System.currentTimeMillis() - startupTime) / 1000D;
|
||||
String message = String.format("Done (%ss)!", new DecimalFormat("#.###").format(completeTime));
|
||||
String message = LanguageUtils.getLocaleStringLog("geyser.core.finish.done", new DecimalFormat("#.###").format(completeTime)) + " ";
|
||||
if (isGui) {
|
||||
message += " Run Commands -> help for help!";
|
||||
message += LanguageUtils.getLocaleStringLog("geyser.core.finish.gui");
|
||||
} else {
|
||||
message += " Run /geyser help for help!";
|
||||
message += LanguageUtils.getLocaleStringLog("geyser.core.finish.console");
|
||||
}
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
bootstrap.getGeyserLogger().info("Shutting down Geyser.");
|
||||
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown"));
|
||||
shuttingDown = true;
|
||||
|
||||
if (players.size() >= 1) {
|
||||
bootstrap.getGeyserLogger().info("Kicking " + players.size() + " player(s)");
|
||||
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.log", players.size()));
|
||||
|
||||
for (GeyserSession playerSession : players.values()) {
|
||||
playerSession.disconnect("Geyser Proxy shutting down.");
|
||||
playerSession.disconnect(LanguageUtils.getPlayerLocaleString("geyser.core.shutdown.kick.message", playerSession.getClientData().getLanguageCode()));
|
||||
}
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {
|
||||
|
@ -209,7 +210,7 @@ public class GeyserConnector {
|
|||
// Block and wait for the future to complete
|
||||
try {
|
||||
future.get();
|
||||
bootstrap.getGeyserLogger().info("Kicked all players");
|
||||
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.done"));
|
||||
} catch (Exception e) {
|
||||
// Quietly fail
|
||||
}
|
||||
|
@ -222,7 +223,7 @@ public class GeyserConnector {
|
|||
authType = null;
|
||||
this.getCommandManager().getCommands().clear();
|
||||
|
||||
bootstrap.getGeyserLogger().info("Geyser shutdown successfully.");
|
||||
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done"));
|
||||
}
|
||||
|
||||
public void addPlayer(GeyserSession player) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import lombok.Getter;
|
|||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.defaults.*;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -44,17 +45,17 @@ public abstract class CommandManager {
|
|||
public CommandManager(GeyserConnector connector) {
|
||||
this.connector = connector;
|
||||
|
||||
registerCommand(new HelpCommand(connector, "help", "Shows help for all registered commands.", "geyser.command.help"));
|
||||
registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list"));
|
||||
registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload"));
|
||||
registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop"));
|
||||
registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand"));
|
||||
registerCommand(new DumpCommand(connector, "dump", "Dumps Geyser debug infomation for bug reports.", "geyser.command.dump"));
|
||||
registerCommand(new HelpCommand(connector, "help", LanguageUtils.getLocaleStringLog("geyser.commands.help.desc"), "geyser.command.help"));
|
||||
registerCommand(new ListCommand(connector, "list", LanguageUtils.getLocaleStringLog("geyser.commands.list.desc"), "geyser.command.list"));
|
||||
registerCommand(new ReloadCommand(connector, "reload", LanguageUtils.getLocaleStringLog("geyser.commands.reload.desc"), "geyser.command.reload"));
|
||||
registerCommand(new StopCommand(connector, "stop", LanguageUtils.getLocaleStringLog("geyser.commands.stop.desc"), "geyser.command.stop"));
|
||||
registerCommand(new OffhandCommand(connector, "offhand", LanguageUtils.getLocaleStringLog("geyser.commands.offhand.desc"), "geyser.command.offhand"));
|
||||
registerCommand(new DumpCommand(connector, "dump", LanguageUtils.getLocaleStringLog("geyser.commands.dump.desc"), "geyser.command.dump"));
|
||||
}
|
||||
|
||||
public void registerCommand(GeyserCommand command) {
|
||||
commands.put(command.getName(), command);
|
||||
connector.getLogger().debug("Registered command " + command.getName());
|
||||
connector.getLogger().debug(LanguageUtils.getLocaleStringLog("geyser.commands.registered", command.getName()));
|
||||
|
||||
if (command.getAliases().isEmpty())
|
||||
return;
|
||||
|
@ -82,7 +83,7 @@ public abstract class CommandManager {
|
|||
|
||||
GeyserCommand cmd = commands.get(label);
|
||||
if (cmd == null) {
|
||||
connector.getLogger().error("Invalid Command! Try /geyser help for a list of commands.");
|
||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.invalid"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.geysermc.connector.GeyserConnector;
|
|||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.dump.DumpInfo;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.connector.utils.WebUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -57,37 +58,37 @@ public class DumpCommand extends GeyserCommand {
|
|||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
sender.sendMessage("Collecting dump info");
|
||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collecting"));
|
||||
String dumpData = "";
|
||||
try {
|
||||
dumpData = MAPPER.writeValueAsString(new DumpInfo());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(ChatColor.RED + "Failed to collect dump info, check console for more information");
|
||||
connector.getLogger().error("Failed to collect dump info", e);
|
||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error"));
|
||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage("Uploading dump");
|
||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.uploading"));
|
||||
String response;
|
||||
JsonNode responseNode;
|
||||
try {
|
||||
response = WebUtils.post(DUMP_URL + "documents", dumpData);
|
||||
responseNode = MAPPER.readTree(response);
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(ChatColor.RED + "Failed to upload dump, check console for more information");
|
||||
connector.getLogger().error("Failed to upload dump", e);
|
||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error"));
|
||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!responseNode.has("key")) {
|
||||
sender.sendMessage(ChatColor.RED + "Failed to upload dump: " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
|
||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short") + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
|
||||
return;
|
||||
}
|
||||
|
||||
String uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
|
||||
sender.sendMessage("We've made a dump with useful information, report your issue and provide this url: " + ChatColor.DARK_AQUA + uploadedDumpUrl);
|
||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.message") + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
|
||||
if (!sender.isConsole()) {
|
||||
connector.getLogger().info(sender.getName() + " created a GeyserDump at " + uploadedDumpUrl);
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), uploadedDumpUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import org.geysermc.connector.common.ChatColor;
|
|||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -48,7 +50,17 @@ public class HelpCommand extends GeyserCommand {
|
|||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----");
|
||||
int page = 1;
|
||||
int maxPage = 1;
|
||||
String header = "";
|
||||
|
||||
if (sender instanceof GeyserSession) {
|
||||
header = LanguageUtils.getPlayerLocaleString("geyser.commands.help.header", ((GeyserSession) sender).getClientData().getLanguageCode(), page, maxPage);
|
||||
} else {
|
||||
header = LanguageUtils.getLocaleStringLog("geyser.commands.help.header", page, maxPage);
|
||||
}
|
||||
|
||||
sender.sendMessage(header);
|
||||
Map<String, GeyserCommand> cmds = connector.getCommandManager().getCommands();
|
||||
List<String> commands = connector.getCommandManager().getCommands().keySet().stream().sorted().collect(Collectors.toList());
|
||||
commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()));
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.connector.command.defaults;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -45,6 +45,13 @@ public class ListCommand extends GeyserCommand {
|
|||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
sender.sendMessage(ChatColor.YELLOW + "Online Players (" + connector.getPlayers().size() + "): " + ChatColor.WHITE + connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", ((GeyserSession) sender).getClientData().getLanguageCode(), connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.commands.list.message", connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||
}
|
||||
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.connector.command.defaults;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.common.PlatformType;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
public class ReloadCommand extends GeyserCommand {
|
||||
|
||||
|
@ -46,9 +46,18 @@ public class ReloadCommand extends GeyserCommand {
|
|||
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
|
||||
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.commands.reload.message", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.commands.reload.message");
|
||||
}
|
||||
|
||||
sender.sendMessage(message);
|
||||
|
||||
for (GeyserSession session : connector.getPlayers().values()) {
|
||||
session.disconnect("Geyser has been reloaded... sorry for the inconvenience!");
|
||||
session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getClientData().getLanguageCode()));
|
||||
}
|
||||
connector.reload();
|
||||
}
|
||||
|
|
|
@ -28,24 +28,39 @@ package org.geysermc.connector.common.main;
|
|||
|
||||
import javax.swing.*;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Locale;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class IGeyserMain {
|
||||
|
||||
/**
|
||||
* Displays the run help message in the console and a message box if running with a gui
|
||||
*/
|
||||
public void displayMessage() {
|
||||
String message = createMessage();
|
||||
|
||||
if (System.console() == null) {
|
||||
if (System.console() == null && !isHeadless()) {
|
||||
JOptionPane.showMessageDialog(null, message, "GeyserMC Plugin: " + this.getPluginType(), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
printMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and format the run help text
|
||||
*
|
||||
* @return The formatted message
|
||||
*/
|
||||
private String createMessage() {
|
||||
String message = "";
|
||||
|
||||
InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("help.txt");
|
||||
InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/" + Locale.getDefault().toString() + ".txt");
|
||||
|
||||
if (helpStream == null) {
|
||||
helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/en_US.txt");
|
||||
}
|
||||
|
||||
Scanner help = new Scanner(helpStream).useDelimiter("\\Z");
|
||||
String line = "";
|
||||
while (help.hasNext()) {
|
||||
|
@ -60,14 +75,44 @@ public class IGeyserMain {
|
|||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we are in a headless environment
|
||||
*
|
||||
* @return Are we in a headless environment?
|
||||
*/
|
||||
private boolean isHeadless() {
|
||||
try {
|
||||
Class<?> graphicsEnvironment = Class.forName("java.awt.GraphicsEnvironment");
|
||||
Method isHeadless = graphicsEnvironment.getDeclaredMethod("isHeadless");
|
||||
return (Boolean)isHeadless.invoke(null);
|
||||
} catch (Exception ex) { }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply print a message to console
|
||||
*
|
||||
* @param message The message to print
|
||||
*/
|
||||
private void printMessage(String message) {
|
||||
System.out.print(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform the plugin is for
|
||||
*
|
||||
* @return The string representation of the plugin platforms name
|
||||
*/
|
||||
public String getPluginType() {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the folder name the plugin should go into
|
||||
*
|
||||
* @return The string representation of the folder
|
||||
*/
|
||||
public String getPluginFolder() {
|
||||
return "unknown";
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ package org.geysermc.connector.configuration;
|
|||
|
||||
import org.geysermc.connector.GeyserLogger;
|
||||
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -111,9 +113,9 @@ public interface GeyserConfiguration {
|
|||
|
||||
static void checkGeyserConfiguration(GeyserConfiguration geyserConfig, GeyserLogger geyserLogger) {
|
||||
if (geyserConfig.getConfigVersion() < CURRENT_CONFIG_VERSION) {
|
||||
geyserLogger.warning("Your Geyser config is out of date! Please regenerate your config when possible.");
|
||||
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.outdated"));
|
||||
} else if (geyserConfig.getConfigVersion() > CURRENT_CONFIG_VERSION) {
|
||||
geyserLogger.warning("Your Geyser config is too new! Errors may occur.");
|
||||
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.too_new"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.geysermc.connector.configuration.GeyserConfiguration;
|
|||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
|
@ -50,13 +51,13 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
|||
|
||||
@Override
|
||||
public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) {
|
||||
connector.getLogger().info(inetSocketAddress + " tried to connect!");
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.attempt_connect", inetSocketAddress));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BedrockPong onQuery(InetSocketAddress inetSocketAddress) {
|
||||
connector.getLogger().debug(inetSocketAddress + " has pinged you!");
|
||||
connector.getLogger().debug(LanguageUtils.getLocaleStringLog("geyser.network.pinged", inetSocketAddress));
|
||||
|
||||
GeyserConfiguration config = connector.getConfig();
|
||||
|
||||
|
@ -108,7 +109,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
|||
bedrockServerSession.setLogging(true);
|
||||
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession)));
|
||||
bedrockServerSession.addDisconnectHandler(disconnectReason -> {
|
||||
connector.getLogger().info("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconnected for reason " + disconnectReason);
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.disconnect", bedrockServerSession.getAddress().getAddress(), disconnectReason));
|
||||
|
||||
GeyserSession player = connector.getPlayers().get(bedrockServerSession.getAddress());
|
||||
if (player != null) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.geysermc.connector.GeyserConnector;
|
|||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
||||
import org.geysermc.connector.utils.LoginEncryptionUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
|
@ -47,10 +48,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
@Override
|
||||
public boolean handle(LoginPacket loginPacket) {
|
||||
if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
session.disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.outdated.server", session.getClientData().getLanguageCode(), GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()));
|
||||
return true;
|
||||
} else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
session.disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.outdated.client", session.getClientData().getLanguageCode(), GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
switch (packet.getStatus()) {
|
||||
case COMPLETED:
|
||||
session.connect(connector.getRemoteServer());
|
||||
connector.getLogger().info("Player connected with username " + session.getAuthData().getName());
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.connect", session.getAuthData().getName()));
|
||||
break;
|
||||
case HAVE_ALL_PACKS:
|
||||
ResourcePackStackPacket stack = new ResourcePackStackPacket();
|
||||
|
@ -97,7 +98,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
GeyserConfiguration.IUserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername);
|
||||
|
||||
if (info != null) {
|
||||
connector.getLogger().info("using stored credentials for bedrock user " + session.getAuthData().getName());
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.stored_credentials", session.getAuthData().getName()));
|
||||
session.authenticate(info.getEmail(), info.getPassword());
|
||||
|
||||
// TODO send a message to bedrock user telling them they are connected (if nothing like a motd
|
||||
|
@ -111,6 +112,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
|
||||
@Override
|
||||
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
||||
LanguageUtils.loadGeyserLocale(session.getClientData().getLanguageCode());
|
||||
|
||||
if (!session.isLoggedIn() && !session.isLoggingIn() && session.getConnector().getAuthType() == AuthType.ONLINE) {
|
||||
// TODO it is safer to key authentication on something that won't change (UUID, not username)
|
||||
if (!couldLoginUserByName(session.getAuthData().getName())) {
|
||||
|
@ -124,7 +127,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
@Override
|
||||
public boolean handle(MovePlayerPacket packet) {
|
||||
if (session.isLoggingIn()) {
|
||||
session.sendMessage("Please wait until you are logged in...");
|
||||
session.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.auth.login.wait", session.getClientData().getLanguageCode()));
|
||||
}
|
||||
|
||||
return translateAndDefault(packet);
|
||||
|
|
|
@ -258,12 +258,11 @@ public class GeyserSession implements CommandSender {
|
|||
|
||||
public void login() {
|
||||
if (connector.getAuthType() != AuthType.ONLINE) {
|
||||
connector.getLogger().info(
|
||||
"Attempting to login using " + connector.getAuthType().name().toLowerCase() + " mode... " +
|
||||
(connector.getAuthType() == AuthType.OFFLINE ?
|
||||
"authentication is disabled." : "authentication will be encrypted"
|
||||
)
|
||||
);
|
||||
if (connector.getAuthType() == AuthType.OFFLINE) {
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.offline"));
|
||||
} else {
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.floodgate"));
|
||||
}
|
||||
authenticate(authData.getName());
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +273,7 @@ public class GeyserSession implements CommandSender {
|
|||
|
||||
public void authenticate(String username, String password) {
|
||||
if (loggedIn) {
|
||||
connector.getLogger().severe(username + " is already logged in!");
|
||||
connector.getLogger().severe(LanguageUtils.getLocaleStringLog("geyser.auth.already_loggedin", username));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -299,13 +298,13 @@ public class GeyserSession implements CommandSender {
|
|||
PublicKey.class
|
||||
);
|
||||
} catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
connector.getLogger().error("Error while reading Floodgate key file", e);
|
||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.bad_key"), e);
|
||||
}
|
||||
publicKey = key;
|
||||
} else publicKey = null;
|
||||
|
||||
if (publicKey != null) {
|
||||
connector.getLogger().info("Loaded Floodgate key!");
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.loaded_key"));
|
||||
}
|
||||
|
||||
downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory());
|
||||
|
@ -326,7 +325,7 @@ public class GeyserSession implements CommandSender {
|
|||
upstream.getSession().getAddress().getAddress().getHostAddress()
|
||||
));
|
||||
} catch (Exception e) {
|
||||
connector.getLogger().error("Failed to encrypt message", e);
|
||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.encrypt_fail"), e);
|
||||
}
|
||||
|
||||
HandshakePacket handshakePacket = event.getPacket();
|
||||
|
@ -343,7 +342,7 @@ public class GeyserSession implements CommandSender {
|
|||
public void connected(ConnectedEvent event) {
|
||||
loggingIn = false;
|
||||
loggedIn = true;
|
||||
connector.getLogger().info(authData.getName() + " (logged in as: " + protocol.getProfile().getName() + ")" + " has connected to remote java server on address " + remoteServer.getAddress());
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.connect", authData.getName(), protocol.getProfile().getName(), remoteServer.getAddress()));
|
||||
playerEntity.setUuid(protocol.getProfile().getId());
|
||||
playerEntity.setUsername(protocol.getProfile().getName());
|
||||
|
||||
|
@ -352,6 +351,7 @@ public class GeyserSession implements CommandSender {
|
|||
// Let the user know there locale may take some time to download
|
||||
// as it has to be extracted from a JAR
|
||||
if (locale.toLowerCase().equals("en_us") && !LocaleUtils.LOCALE_MAPPINGS.containsKey("en_us")) {
|
||||
// This should probably be left hardcoded as it will only show for en_us clients
|
||||
sendMessage("Downloading your locale (en_us) this may take some time");
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ public class GeyserSession implements CommandSender {
|
|||
public void disconnected(DisconnectedEvent event) {
|
||||
loggingIn = false;
|
||||
loggedIn = false;
|
||||
connector.getLogger().info(authData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason());
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.disconnect", authData.getName(), remoteServer.getAddress(), event.getReason()));
|
||||
if (event.getCause() != null) {
|
||||
event.getCause().printStackTrace();
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ public class GeyserSession implements CommandSender {
|
|||
|
||||
@Override
|
||||
public void packetError(PacketErrorEvent event) {
|
||||
connector.getLogger().warning("Downstream packet error! " + event.getCause().getMessage());
|
||||
connector.getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.network.downstream_error", event.getCause().getMessage()));
|
||||
if (connector.getConfig().isDebugMode())
|
||||
event.getCause().printStackTrace();
|
||||
event.setSuppress(true);
|
||||
|
@ -412,8 +412,8 @@ public class GeyserSession implements CommandSender {
|
|||
downstream.getSession().connect();
|
||||
connector.addPlayer(this);
|
||||
} catch (InvalidCredentialsException | IllegalArgumentException e) {
|
||||
connector.getLogger().info("User '" + username + "' entered invalid login info, kicking.");
|
||||
disconnect("Invalid/incorrect login info");
|
||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.invalid", username));
|
||||
disconnect(LanguageUtils.getPlayerLocaleString("geyser.auth.login.invalid.kick", getClientData().getLanguageCode()));
|
||||
} catch (RequestException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ public class GeyserSession implements CommandSender {
|
|||
}
|
||||
|
||||
public void close() {
|
||||
disconnect("Server closed.");
|
||||
disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.close", getClientData().getLanguageCode()));
|
||||
}
|
||||
|
||||
public void setAuthenticationData(AuthData authData) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.nukkitx.nbt.NbtMap;
|
|||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -59,7 +60,7 @@ public class BiomeTranslator {
|
|||
biomesTag = (NbtMap) biomenbtInputStream.readTag();
|
||||
BIOMES = biomesTag;
|
||||
} catch (Exception ex) {
|
||||
GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?");
|
||||
GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.biome_read"));
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.nukkitx.nbt.NBTInputStream;
|
|||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class EntityIdentifierRegistry {
|
|||
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
|
||||
ENTITY_IDENTIFIERS = (NbtMap) nbtInputStream.readTag();
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to get entities from entity identifiers", e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.entity"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacket;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -66,10 +67,10 @@ public class PacketTranslatorRegistry<T> {
|
|||
|
||||
BEDROCK_TRANSLATOR.translators.put(targetPacket, translator);
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet.");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.invalid_target", clazz.getCanonicalName()));
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated translator " + clazz.getCanonicalName() + ".");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.failed", clazz.getCanonicalName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +98,7 @@ public class PacketTranslatorRegistry<T> {
|
|||
GeyserConnector.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not translate packet " + packet.getClass().getSimpleName(), ex);
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ public class BedrockPacketViolationWarningTranslator extends PacketTranslator<Pa
|
|||
|
||||
@Override
|
||||
public void translate(PacketViolationWarningPacket packet, GeyserSession session) {
|
||||
// Not translated since this is something that the developers need to know
|
||||
session.getConnector().getLogger().error("Packet violation warning sent from client! " + packet.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||
import lombok.NonNull;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
@ -80,7 +81,7 @@ public class EffectRegistry {
|
|||
+ entry.getValue().asText()
|
||||
+ ", it will take effect.");
|
||||
} catch (IllegalArgumentException e2){
|
||||
GeyserConnector.getInstance().getLogger().warning("Fail to map particle " + entry.getKey() + "=>" + entry.getValue().asText());
|
||||
GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.particle.failed_map", entry.getKey(), entry.getValue().asText()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||
import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
private static final ItemData UNUSUABLE_CRAFTING_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(
|
||||
"The creative crafting grid is\nunavailable in Java Edition");
|
||||
private static final ItemData UNUSUABLE_CRAFTING_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.creative"));
|
||||
|
||||
public PlayerInventoryTranslator() {
|
||||
super(46);
|
||||
|
|
|
@ -34,11 +34,11 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class ChestInventoryUpdater extends InventoryUpdater {
|
||||
private static final ItemData UNUSUABLE_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(
|
||||
"This slot does not exist in the inventory\non Java Edition, as there is less\nrows than possible in Bedrock");
|
||||
private static final ItemData UNUSUABLE_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.slot"));
|
||||
|
||||
private final int paddedSize;
|
||||
|
||||
|
|
|
@ -37,16 +37,12 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Registry for anything item related.
|
||||
|
@ -82,7 +78,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
itemEntries = GeyserConnector.JSON_MAPPER.readValue(stream, itemEntriesType);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_bedrock"), e);
|
||||
}
|
||||
|
||||
for (JsonNode entry : itemEntries) {
|
||||
|
@ -95,7 +91,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
items = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e);
|
||||
}
|
||||
|
||||
int itemIndex = 0;
|
||||
|
@ -144,7 +140,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load creative items", e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
||||
}
|
||||
|
||||
List<ItemData> creativeItems = new ArrayList<>();
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.geysermc.connector.GeyserConnector;
|
|||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.ItemRemapper;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -88,14 +89,13 @@ public abstract class ItemTranslator {
|
|||
for (ItemEntry item : appliedItems) {
|
||||
ItemTranslator registered = ITEM_STACK_TRANSLATORS.get(item.getJavaId());
|
||||
if (registered != null) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "." +
|
||||
" Item translator " + registered.getClass().getCanonicalName() + " is already registered for the item " + item.getJavaIdentifier());
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.already_registered", clazz.getCanonicalName(), registered.getClass().getCanonicalName(), item.getJavaIdentifier()));
|
||||
continue;
|
||||
}
|
||||
ITEM_STACK_TRANSLATORS.put(item.getJavaId(), itemStackTranslator);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + ".");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.failed", clazz.getCanonicalName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.geysermc.connector.network.session.cache.TeleportCache;
|
|||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.utils.ChunkUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
@Translator(packet = ServerPlayerPositionRotationPacket.class)
|
||||
public class JavaPlayerPositionRotationTranslator extends PacketTranslator<ServerPlayerPositionRotationPacket> {
|
||||
|
@ -90,7 +91,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||
|
||||
ChunkUtils.updateChunkPosition(session, pos.toInt());
|
||||
|
||||
session.getConnector().getLogger().info("Spawned player at " + packet.getX() + " " + packet.getY() + " " + packet.getZ());
|
||||
session.getConnector().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.entity.player.spawn", packet.getX(), packet.getY(), packet.getZ()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.utils.EntityUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -52,7 +53,7 @@ public class JavaSpawnEntityTranslator extends PacketTranslator<ServerSpawnEntit
|
|||
|
||||
org.geysermc.connector.entity.type.EntityType type = EntityUtils.toBedrockEntity(packet.getType());
|
||||
if (type == null) {
|
||||
session.getConnector().getLogger().warning("Entity type " + packet.getType() + " was null.");
|
||||
session.getConnector().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.entity.type_null", packet.getType()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.utils.EntityUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -48,7 +49,7 @@ public class JavaSpawnLivingEntityTranslator extends PacketTranslator<ServerSpaw
|
|||
|
||||
EntityType type = EntityUtils.toBedrockEntity(packet.getType());
|
||||
if (type == null) {
|
||||
session.getConnector().getLogger().warning("Entity type " + packet.getType() + " was null.");
|
||||
session.getConnector().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.entity.type_null", packet.getType()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.geysermc.connector.entity.PlayerEntity;
|
|||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
@Translator(packet = ServerSpawnPlayerPacket.class)
|
||||
|
@ -44,7 +45,7 @@ public class JavaSpawnPlayerTranslator extends PacketTranslator<ServerSpawnPlaye
|
|||
|
||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
||||
if (entity == null) {
|
||||
GeyserConnector.getInstance().getLogger().error("Haven't received PlayerListEntry packet before spawning player! We ignore the player " + packet.getUuid());
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.scoreboard;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerTeamPacket;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -35,11 +34,11 @@ import org.geysermc.connector.network.translators.Translator;
|
|||
import org.geysermc.connector.scoreboard.Scoreboard;
|
||||
import org.geysermc.connector.scoreboard.Team;
|
||||
import org.geysermc.connector.scoreboard.UpdateType;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerTeamPacket;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
@Translator(packet = ServerTeamPacket.class)
|
||||
public class JavaTeamTranslator extends PacketTranslator<ServerTeamPacket> {
|
||||
|
@ -66,21 +65,21 @@ public class JavaTeamTranslator extends PacketTranslator<ServerTeamPacket> {
|
|||
.setSuffix(MessageUtils.getBedrockMessage(packet.getSuffix()))
|
||||
.setUpdateType(UpdateType.UPDATE);
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered.");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName()));
|
||||
}
|
||||
break;
|
||||
case ADD_PLAYER:
|
||||
if(team != null){
|
||||
team.addEntities(packet.getPlayers());
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered.");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName()));
|
||||
}
|
||||
break;
|
||||
case REMOVE_PLAYER:
|
||||
if(team != null){
|
||||
team.removeEntities(packet.getPlayers());
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered.");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName()));
|
||||
}
|
||||
break;
|
||||
case REMOVE:
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.geysermc.connector.scoreboard.Scoreboard;
|
|||
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
@Translator(packet = ServerUpdateScorePacket.class)
|
||||
public class JavaUpdateScoreTranslator extends PacketTranslator<ServerUpdateScorePacket> {
|
||||
|
@ -45,7 +46,7 @@ public class JavaUpdateScoreTranslator extends PacketTranslator<ServerUpdateScor
|
|||
|
||||
Objective objective = scoreboard.getObjective(packet.getObjective());
|
||||
if (objective == null && packet.getAction() != ScoreboardAction.REMOVE) {
|
||||
GeyserConnector.getInstance().getLogger().info("Tried to update score without the existence of its requested objective '" + packet.getObjective() + '\'');
|
||||
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.translator.score.failed_objective", packet.getObjective()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.nukkitx.nbt.NbtMapBuilder;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -72,7 +73,7 @@ public abstract class BlockEntityTranslator {
|
|||
try {
|
||||
BLOCK_ENTITY_TRANSLATORS.put(clazz.getAnnotation(BlockEntity.class).name(), (BlockEntityTranslator) clazz.newInstance());
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated block entity " + clazz.getCanonicalName() + ".");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_entity.failed", clazz.getCanonicalName()));
|
||||
}
|
||||
}
|
||||
for (Class<?> clazz : ref.getSubTypesOf(RequiresBlockState.class)) {
|
||||
|
@ -81,7 +82,7 @@ public abstract class BlockEntityTranslator {
|
|||
try {
|
||||
REQUIRES_BLOCK_STATE_LIST.add((RequiresBlockState) clazz.newInstance());
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate required block state " + clazz.getCanonicalName() + ".");
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_state.failed", clazz.getCanonicalName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|||
import lombok.Getter;
|
||||
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
@ -78,7 +79,7 @@ public class Scoreboard {
|
|||
|
||||
public Team registerNewTeam(String teamName, Set<String> players) {
|
||||
if (teams.containsKey(teamName)) {
|
||||
session.getConnector().getLogger().info("Ignoring team " + teamName + ". It overrides without removing old team.");
|
||||
session.getConnector().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_overrides", teamName));
|
||||
return getTeam(teamName);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ public class DockerCheck {
|
|||
String output = new String(Files.readAllBytes(Paths.get("/proc/1/cgroup")));
|
||||
|
||||
if (output.contains("docker")) {
|
||||
bootstrap.getGeyserLogger().warning("You are most likely in a Docker container, this may cause connection issues from Geyser to the Java server");
|
||||
bootstrap.getGeyserLogger().warning("We recommended using the following IP as the remote address: " + ipAddress);
|
||||
bootstrap.getGeyserLogger().warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.docker_warn.line1"));
|
||||
bootstrap.getGeyserLogger().warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.docker_warn.line2", ipAddress));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied
|
||||
|
|
|
@ -135,7 +135,7 @@ public class FileUtils {
|
|||
public static InputStream getResource(String resource) {
|
||||
InputStream stream = FileUtils.class.getClassLoader().getResourceAsStream(resource);
|
||||
if (stream == null) {
|
||||
throw new AssertionError("Unable to find resource: " + resource);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.resource", resource));
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,8 @@ public class InventoryUtils {
|
|||
NbtMapBuilder root = NbtMap.builder();
|
||||
NbtMapBuilder display = NbtMap.builder();
|
||||
|
||||
display.putString("Name", ChatColor.RESET + "Unusable inventory space");
|
||||
// Not ideal to use log here but we dont get a session
|
||||
display.putString("Name", ChatColor.RESET + LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.name"));
|
||||
display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description));
|
||||
|
||||
root.put("display", display.build());
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class LanguageUtils {
|
||||
|
||||
/**
|
||||
* If we determine the locale that the user wishes to use, use that locale
|
||||
*/
|
||||
private static String CACHED_LOCALE;
|
||||
|
||||
private static final Map<String, Properties> LOCALE_MAPPINGS = new HashMap<>();
|
||||
|
||||
static {
|
||||
// Load it as a backup in case something goes really wrong
|
||||
if (!"en_US".equals(formatLocale(getDefaultLocale()))) { // getDefaultLocale() loads the locale automatically
|
||||
loadGeyserLocale("en_US");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Geyser locale from resources, if the file doesn't exist it just logs a warning
|
||||
*
|
||||
* @param locale Locale to load
|
||||
*/
|
||||
public static void loadGeyserLocale(String locale) {
|
||||
locale = formatLocale(locale);
|
||||
|
||||
InputStream localeStream = GeyserConnector.class.getClassLoader().getResourceAsStream("languages/texts/" + locale + ".properties");
|
||||
|
||||
// Load the locale
|
||||
if (localeStream != null) {
|
||||
Properties localeProp = new Properties();
|
||||
try {
|
||||
localeProp.load(new InputStreamReader(localeStream, StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(getLocaleStringLog("geyser.language.load_failed", locale), e);
|
||||
}
|
||||
|
||||
// Insert the locale into the mappings
|
||||
LOCALE_MAPPINGS.put(locale, localeProp);
|
||||
} else {
|
||||
if (!locale.toLowerCase().equals(getDefaultLocale().toLowerCase())) { // The default locale was invalid fallback to en_us
|
||||
GeyserConnector.getInstance().getLogger().warning(getLocaleStringLog("geyser.language.missing_file", locale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formatted language string with the default locale for Geyser
|
||||
*
|
||||
* @param key Language string to translate
|
||||
* @param values Values to put into the string
|
||||
* @return Translated string or the original message if it was not found in the given locale
|
||||
*/
|
||||
public static String getLocaleStringLog(String key, Object... values) {
|
||||
return getPlayerLocaleString(key, getDefaultLocale(), values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formatted language string with the given locale for Geyser
|
||||
*
|
||||
* @param key Language string to translate
|
||||
* @param locale Locale to translate to
|
||||
* @param values Values to put into the string
|
||||
* @return Translated string or the original message if it was not found in the given locale
|
||||
*/
|
||||
public static String getPlayerLocaleString(String key, String locale, Object... values) {
|
||||
locale = formatLocale(locale);
|
||||
|
||||
Properties properties = LOCALE_MAPPINGS.get(locale);
|
||||
String formatString = properties.getProperty(key);
|
||||
|
||||
// Try and get the key from the default locale
|
||||
if (formatString == null) {
|
||||
properties = LOCALE_MAPPINGS.get(formatLocale(getDefaultLocale()));
|
||||
formatString = properties.getProperty(key);
|
||||
}
|
||||
|
||||
// Try and get the key from en_US (this should only ever happen in development)
|
||||
if (formatString == null) {
|
||||
properties = LOCALE_MAPPINGS.get("en_US");
|
||||
formatString = properties.getProperty(key);
|
||||
}
|
||||
|
||||
// Final fallback
|
||||
if (formatString == null) {
|
||||
formatString = key;
|
||||
}
|
||||
|
||||
return MessageFormat.format(formatString.replace("&", "\u00a7"), values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up and formats a locale string
|
||||
*
|
||||
* @param locale The locale to format
|
||||
* @return The formatted locale
|
||||
*/
|
||||
private static String formatLocale(String locale) {
|
||||
try {
|
||||
String[] parts = locale.toLowerCase().split("_");
|
||||
String newLocale = parts[0] + "_" + parts[1].toUpperCase();
|
||||
switch (newLocale) { // Fallback to the closest language if we don't support it but Bedrock does.
|
||||
case "es_MX":
|
||||
return "es_ES";
|
||||
case "pt_BR":
|
||||
return "pt_PT";
|
||||
case "fr_CA":
|
||||
return "fr_FR";
|
||||
default:
|
||||
return newLocale;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default locale that Geyser should use
|
||||
* @return the current default locale
|
||||
*/
|
||||
public static String getDefaultLocale() {
|
||||
if (CACHED_LOCALE != null) return CACHED_LOCALE; // We definitely know the locale the user is using
|
||||
String locale;
|
||||
boolean isValid = true;
|
||||
if (GeyserConnector.getInstance() != null &&
|
||||
GeyserConnector.getInstance().getConfig() != null &&
|
||||
GeyserConnector.getInstance().getConfig().getDefaultLocale() != null) { // If the config option for getDefaultLocale does not equal null, use that
|
||||
locale = formatLocale(GeyserConnector.getInstance().getConfig().getDefaultLocale());
|
||||
if (isValidLanguage(locale)) {
|
||||
CACHED_LOCALE = locale;
|
||||
return locale;
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
locale = formatLocale(Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry());
|
||||
if (!isValidLanguage(locale)) { // Bedrock does not support this language
|
||||
locale = "en_US";
|
||||
}
|
||||
if (GeyserConnector.getInstance() != null &&
|
||||
GeyserConnector.getInstance().getConfig() != null && (GeyserConnector.getInstance().getConfig().getDefaultLocale() == null || !isValid)) { // Means we should use the system locale for sure
|
||||
CACHED_LOCALE = locale;
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the given locale is supported by Bedrock
|
||||
* @param locale the locale to validate
|
||||
* @return true if the given locale is supported by Bedrock and by extension Geyser
|
||||
*/
|
||||
private static boolean isValidLanguage(String locale) {
|
||||
boolean result = true;
|
||||
if (FileUtils.class.getResource("/languages/texts/" + locale + ".properties") == null) {
|
||||
result = false;
|
||||
if (GeyserConnector.getInstance() != null && GeyserConnector.getInstance().getLogger() != null) { // Could be too early for these to be initialized
|
||||
GeyserConnector.getInstance().getLogger().warning(locale + " is not a valid Bedrock language."); // We can't translate this since we just loaded an invalid language
|
||||
}
|
||||
} else {
|
||||
if (!LOCALE_MAPPINGS.containsKey(locale)) {
|
||||
loadGeyserLocale(locale);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// no-op
|
||||
}
|
||||
}
|
|
@ -48,8 +48,6 @@ public class LocaleUtils {
|
|||
|
||||
private static final Map<String, Asset> ASSET_MAP = new HashMap<>();
|
||||
|
||||
private static final String DEFAULT_LOCALE = (GeyserConnector.getInstance().getConfig().getDefaultLocale() != null ? GeyserConnector.getInstance().getConfig().getDefaultLocale() : "en_us");
|
||||
|
||||
private static String smallestURL = "";
|
||||
|
||||
static {
|
||||
|
@ -60,7 +58,7 @@ public class LocaleUtils {
|
|||
|
||||
// Download the latest asset list and cache it
|
||||
generateAssetCache();
|
||||
downloadAndLoadLocale(DEFAULT_LOCALE);
|
||||
downloadAndLoadLocale(LanguageUtils.getDefaultLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,7 +80,7 @@ public class LocaleUtils {
|
|||
|
||||
// Make sure we definitely got a version
|
||||
if (latestInfoURL.isEmpty()) {
|
||||
throw new Exception("Unable to get latest Minecraft version");
|
||||
throw new Exception(LanguageUtils.getLocaleStringLog("geyser.locale.fail.latest_version"));
|
||||
}
|
||||
|
||||
// Get the individual version manifest
|
||||
|
@ -105,7 +103,7 @@ public class LocaleUtils {
|
|||
ASSET_MAP.put(entry.getKey(), asset);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
GeyserConnector.getInstance().getLogger().info("Failed to load locale asset cache: " + (!e.getMessage().isEmpty() ? e.getMessage() : e.getStackTrace()));
|
||||
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.locale.fail.asset_cache", (!e.getMessage().isEmpty() ? e.getMessage() : e.getStackTrace())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@ public class LocaleUtils {
|
|||
|
||||
// Check the locale isn't already loaded
|
||||
if (!ASSET_MAP.containsKey("minecraft/lang/" + locale + ".json") && !locale.equals("en_us")) {
|
||||
GeyserConnector.getInstance().getLogger().warning("Invalid locale requested to download and load: " + locale);
|
||||
GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.locale.fail.invalid", locale));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -170,7 +168,7 @@ public class LocaleUtils {
|
|||
try {
|
||||
localeStream = new FileInputStream(localeFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new AssertionError("Unable to load locale: " + locale + " (" + e.getMessage() + ")");
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.file", locale, e.getMessage()));
|
||||
}
|
||||
|
||||
// Parse the file as json
|
||||
|
@ -178,7 +176,7 @@ public class LocaleUtils {
|
|||
try {
|
||||
localeObj = GeyserConnector.JSON_MAPPER.readTree(localeStream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java edition lang map for " + locale, e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.json", locale), e);
|
||||
}
|
||||
|
||||
// Parse all the locale fields
|
||||
|
@ -192,7 +190,7 @@ public class LocaleUtils {
|
|||
// Insert the locale into the mappings
|
||||
LOCALE_MAPPINGS.put(locale.toLowerCase(), langMap);
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().warning("Missing locale file: " + locale);
|
||||
GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.locale.fail.missing", locale));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +202,7 @@ public class LocaleUtils {
|
|||
private static void downloadEN_US(File localeFile) {
|
||||
try {
|
||||
// Let the user know we are downloading the JAR
|
||||
GeyserConnector.getInstance().getLogger().info("Downloading Minecraft JAR to extract en_us locale, please wait... (this may take some time depending on the speed of your internet connection)");
|
||||
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.locale.download.en_us"));
|
||||
GeyserConnector.getInstance().getLogger().debug("Download URL: " + smallestURL);
|
||||
|
||||
// Download the smallest JAR (client or server)
|
||||
|
@ -233,7 +231,7 @@ public class LocaleUtils {
|
|||
// Delete the nolonger needed client/server jar
|
||||
Files.delete(tmpFilePath);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to download and extract en_us locale!", e);
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.en_us"), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +245,7 @@ public class LocaleUtils {
|
|||
public static String getLocaleString(String messageText, String locale) {
|
||||
Map<String, String> localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(locale.toLowerCase());
|
||||
if (localeStrings == null)
|
||||
localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(DEFAULT_LOCALE);
|
||||
localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(LanguageUtils.getDefaultLocale());
|
||||
|
||||
return localeStrings.getOrDefault(messageText, messageText);
|
||||
}
|
||||
|
|
|
@ -156,18 +156,20 @@ public class LoginEncryptionUtils {
|
|||
private static int AUTH_DETAILS_FORM_ID = 1337;
|
||||
|
||||
public static void showLoginWindow(GeyserSession session) {
|
||||
SimpleFormWindow window = new SimpleFormWindow("Login", "You need a Java Edition account to play on this server.");
|
||||
window.getButtons().add(new FormButton("Login with Minecraft"));
|
||||
window.getButtons().add(new FormButton("Disconnect"));
|
||||
String userLanguage = session.getClientData().getLanguageCode();
|
||||
SimpleFormWindow window = new SimpleFormWindow(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.title", userLanguage), LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.desc", userLanguage));
|
||||
window.getButtons().add(new FormButton(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.btn_login", userLanguage)));
|
||||
window.getButtons().add(new FormButton(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.btn_disconnect", userLanguage)));
|
||||
|
||||
session.sendForm(window, AUTH_FORM_ID);
|
||||
}
|
||||
|
||||
public static void showLoginDetailsWindow(GeyserSession session) {
|
||||
CustomFormWindow window = new CustomFormBuilder("Login Details")
|
||||
.addComponent(new LabelComponent("Enter the credentials for your Minecraft: Java Edition account below."))
|
||||
.addComponent(new InputComponent("Email/Username", "account@geysermc.org", ""))
|
||||
.addComponent(new InputComponent("Password", "123456", ""))
|
||||
String userLanguage = session.getClientData().getLanguageCode();
|
||||
CustomFormWindow window = new CustomFormBuilder(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.title", userLanguage))
|
||||
.addComponent(new LabelComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.desc", userLanguage)))
|
||||
.addComponent(new InputComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.email", userLanguage), "account@geysermc.org", ""))
|
||||
.addComponent(new InputComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.pass", userLanguage), "123456", ""))
|
||||
.build();
|
||||
|
||||
session.sendForm(window, AUTH_DETAILS_FORM_ID);
|
||||
|
@ -203,8 +205,8 @@ public class LoginEncryptionUtils {
|
|||
if (response != null) {
|
||||
if (response.getClickedButtonId() == 0) {
|
||||
showLoginDetailsWindow(session);
|
||||
} else if (response.getClickedButtonId() == 1) {
|
||||
session.disconnect("Login is required");
|
||||
} else if(response.getClickedButtonId() == 1) {
|
||||
session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.getClientData().getLanguageCode()));
|
||||
}
|
||||
} else {
|
||||
showLoginWindow(session);
|
||||
|
|
|
@ -246,7 +246,7 @@ public class SkinUtils {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Failed getting skin for " + entity.getUuid(), e);
|
||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e);
|
||||
}
|
||||
|
||||
if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape);
|
||||
|
@ -257,7 +257,7 @@ public class SkinUtils {
|
|||
public static void handleBedrockSkin(PlayerEntity playerEntity, BedrockClientData clientData) {
|
||||
GameProfileData data = GameProfileData.from(playerEntity.getProfile());
|
||||
|
||||
GeyserConnector.getInstance().getLogger().info("Registering bedrock skin for " + playerEntity.getUsername() + " (" + playerEntity.getUuid() + ")");
|
||||
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.skin.bedrock.register", playerEntity.getUsername(), playerEntity.getUuid()));
|
||||
|
||||
try {
|
||||
byte[] skinBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getSkinData().getBytes("UTF-8"));
|
||||
|
@ -270,7 +270,7 @@ public class SkinUtils {
|
|||
SkinProvider.storeBedrockSkin(playerEntity.getUuid(), data.getSkinUrl(), skinBytes);
|
||||
SkinProvider.storeBedrockGeometry(playerEntity.getUuid(), geometryNameBytes, geometryBytes);
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().info("Unable to load bedrock skin for '" + playerEntity.getUsername() + "' as they are likely using a customised skin");
|
||||
GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.skin.bedrock.fail", playerEntity.getUsername()));
|
||||
GeyserConnector.getInstance().getLogger().debug("The size of '" + playerEntity.getUsername() + "' skin is: " + clientData.getSkinImageWidth() + "x" + clientData.getSkinImageHeight());
|
||||
}
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ allow-third-party-ears: false
|
|||
# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat
|
||||
show-cooldown: true
|
||||
|
||||
# The default locale if we dont have the one the client requested
|
||||
default-locale: en_us
|
||||
# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.
|
||||
# default-locale: en_us
|
||||
|
||||
# Configures if chunk caching should be enabled or not. This keeps an individual
|
||||
# record of each block the client loads in. While this feature does allow for a few
|
||||
|
|
1
connector/src/main/resources/languages
Submodule
1
connector/src/main/resources/languages
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 08be7fdd7bd3c1ade46fa8968c04d3d67bb0d378
|
Loading…
Reference in a new issue