From 4dafb5cd974ce58546ced27fc55e4e11c3cc2113 Mon Sep 17 00:00:00 2001 From: CiroZDP Date: Mon, 18 Mar 2024 22:27:51 +0100 Subject: [PATCH] Update to 24r04 --- .idea/.gitignore | 3 + .idea/compiler.xml | 15 +++ .idea/jarRepositories.xml | 20 ++++ .idea/libraries/JOSL.xml | 9 ++ .idea/misc.xml | 17 ++++ .idea/vcs.xml | 6 ++ opcraft/logs/latest.log | 3 +- src/main/java/net/opencraft/client/Game.java | 53 +++++------ .../java/net/opencraft/config/GameConfig.java | 1 + .../net/opencraft/config/GameExperiments.java | 2 +- .../java/net/opencraft/config/Workspace.java | 77 ---------------- .../net/opencraft/data/packs/DefaultPack.java | 30 ++++++ .../java/net/opencraft/data/packs/Pack.java | 4 +- .../opencraft/data/packs/ResourcePack.java | 2 +- .../net/opencraft/language/Translator.java | 56 ++++++++---- .../net/opencraft/renderer/Renderizable.java | 12 +-- .../java/net/opencraft/renderer/Screen.java | 10 +- .../java/net/opencraft/renderer/Texture.java | 14 +++ .../renderer/display/DisplayManager.java | 12 ++- .../opencraft/renderer/scenes/LoadScene.java | 7 +- .../net/opencraft/renderer/scenes/Scene.java | 9 -- .../opencraft/renderer/scenes/TitleScene.java | 59 +++++------- src/main/java/net/opencraft/sound/Sound.java | 59 +++++++----- .../net/opencraft/sound/SoundManager.java | 15 ++- src/main/java/net/opencraft/util/Assets.java | 86 ++++++------------ src/main/java/net/opencraft/util/Fonts.java | 26 +----- .../java/net/opencraft/util/Resource.java | 50 ++++++---- src/main/java/net/opencraft/util/Utils.java | 22 ++++- .../java/net/opencraft/util/ZipUtils.java | 16 ---- target/classes/META-INF/MANIFEST.MF | 2 +- .../maven/net/OpenCraft/pom.properties | 6 +- .../classes/net/opencraft/client/Game.class | Bin 4623 -> 4587 bytes .../net/opencraft/config/GameConfig.class | Bin 609 -> 681 bytes .../opencraft/config/GameExperiments.class | Bin 451 -> 451 bytes .../net/opencraft/config/Workspace.class | Bin 2548 -> 0 bytes .../net/opencraft/language/Translator.class | Bin 1924 -> 2325 bytes .../net/opencraft/renderer/Renderizable.class | Bin 749 -> 181 bytes .../renderer/display/DisplayManager.class | Bin 2145 -> 2486 bytes .../classes/net/opencraft/util/Assets.class | Bin 4051 -> 3078 bytes target/classes/net/opencraft/util/Fonts.class | Bin 2433 -> 1476 bytes .../classes/net/opencraft/util/Resource.class | Bin 2623 -> 2946 bytes target/classes/net/opencraft/util/Utils.class | Bin 912 -> 1728 bytes 42 files changed, 356 insertions(+), 347 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/libraries/JOSL.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml delete mode 100644 src/main/java/net/opencraft/config/Workspace.java create mode 100644 src/main/java/net/opencraft/data/packs/DefaultPack.java delete mode 100644 src/main/java/net/opencraft/util/ZipUtils.java delete mode 100644 target/classes/net/opencraft/config/Workspace.class diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..32fac45 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/JOSL.xml b/.idea/libraries/JOSL.xml new file mode 100644 index 0000000..9b3a2dd --- /dev/null +++ b/.idea/libraries/JOSL.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e6cb064 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/opcraft/logs/latest.log b/opcraft/logs/latest.log index f9f7243..72622fa 100644 --- a/opcraft/logs/latest.log +++ b/opcraft/logs/latest.log @@ -1,2 +1 @@ -[12:50:33] [main/INFO]: Initializing the game... -[12:50:33] [main/INFO]: Game initializated! +[22:25:35] [main/INFO]: OpenCraft 24r03 started! diff --git a/src/main/java/net/opencraft/client/Game.java b/src/main/java/net/opencraft/client/Game.java index f4ced21..9a32872 100644 --- a/src/main/java/net/opencraft/client/Game.java +++ b/src/main/java/net/opencraft/client/Game.java @@ -4,7 +4,6 @@ import static net.opencraft.LoggerConfig.handle; import static net.opencraft.renderer.display.DisplayManager.destroyDisplay; -import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Locale; @@ -12,7 +11,7 @@ import net.opencraft.config.GameConfig; import net.opencraft.config.GameExperiments; -import net.opencraft.config.Workspace; +import net.opencraft.data.packs.DefaultPack; import net.opencraft.data.packs.Pack; import net.opencraft.renderer.RenderDragon; import net.opencraft.renderer.Screen; @@ -22,17 +21,17 @@ public class Game implements Runnable { public static final String NAME = "OpenCraft"; - public static final String VERSION = "24r03"; - public static final String TITLE = NAME + ' ' + VERSION; + public static final String VERSION = "24r04"; + public static final String TITLE = NAME + ((char) 0x20) + VERSION; public static final int NANOSECONDS = 1000000000; - public static final double NANO_PER_TICK = NANOSECONDS / GameConfig.TICK_RATE; - - private static Game instance; - private static Pack selected_pack; + public static final double NANO_PER_TICK = (double) NANOSECONDS / GameConfig.TICK_RATE; + private static final Game instance = new Game(); private static final Logger logger = Logger.getLogger("main"); + private static Pack selected_pack = DefaultPack.getDefaultPack(); + private boolean running = false; private Screen screen; @@ -41,12 +40,21 @@ public class Game implements Runnable { System.setProperty("java.util.logging.SimpleFormatter.format", LOG_FORMAT); handle(logger); } + + public void init() { + Thread.currentThread().setName("main"); + + RenderDragon.init(); + this.screen = RenderDragon.getScreen(); + Scene.setCurrent(Scene.LOAD_SCENE); + + running = true; + } @Override public void run() { - logger.info("Initializing the game..."); init(); - logger.info("Game initializated!"); + logger.info(Game.TITLE + " started!"); long lastUpdate = System.nanoTime(); @@ -74,8 +82,8 @@ public void run() { } public void render() { - Graphics g = this.screen.getGraphics(); - Scene.renderCurrent(g); + BufferedImage img = this.screen.getImage(); + Scene.renderCurrent(img); RenderDragon.update(); } @@ -91,18 +99,6 @@ public void stop() { destroyDisplay(); } - public void init() { - Thread.currentThread().setName("main"); - - Workspace.create(); - - RenderDragon.init(); - screen = RenderDragon.getScreen(); - Scene.setCurrent(Scene.LOAD_SCENE); - - running = true; - } - public static Locale getLanguage() { return GameConfig.LANGUAGE; } @@ -132,7 +128,7 @@ public static void selectPack(Pack pack) { } public static void useDefaultPack() { - selectPack(null); + selectPack(DefaultPack.getDefaultPack()); } public static Pack getResourcePack() { @@ -144,15 +140,14 @@ public static Game getInstance() { } public static boolean isDefaultPackSelected() { - return selected_pack == null; + return selected_pack instanceof DefaultPack; } public static BufferedImage screenshot() { - Game game = getInstance(); - return game.screen.screenshot(); + return getInstance().screen.screenshot(); } public static void main(String[] args) throws IOException { - new Thread(instance = new Game()).start(); + new Thread(instance).start(); } } diff --git a/src/main/java/net/opencraft/config/GameConfig.java b/src/main/java/net/opencraft/config/GameConfig.java index 86ca5bf..3ba5ed6 100644 --- a/src/main/java/net/opencraft/config/GameConfig.java +++ b/src/main/java/net/opencraft/config/GameConfig.java @@ -10,5 +10,6 @@ public class GameConfig { public static byte TICK_RATE = 60; public static boolean UNICODE = false; public static Pack PACK_SELECTED = null; + public static String GAME_DIR = "opcraft"; } diff --git a/src/main/java/net/opencraft/config/GameExperiments.java b/src/main/java/net/opencraft/config/GameExperiments.java index 3ef8b19..bd76065 100644 --- a/src/main/java/net/opencraft/config/GameExperiments.java +++ b/src/main/java/net/opencraft/config/GameExperiments.java @@ -43,6 +43,6 @@ private GameExperiments() { * This experiment skip completly the load screen.
* Recommended for developers! * */ - public static final boolean SKIP_LOAD_SCENE = false; + public static final boolean SKIP_LOAD_SCENE = true; } \ No newline at end of file diff --git a/src/main/java/net/opencraft/config/Workspace.java b/src/main/java/net/opencraft/config/Workspace.java deleted file mode 100644 index d753d2c..0000000 --- a/src/main/java/net/opencraft/config/Workspace.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.opencraft.config; - -import java.io.File; - -public class Workspace { - - public static String GAME_DIR = "opcraft"; - - public static String ASSETS_DIR = GAME_DIR + "/assets"; - public static String WORLDS_DIR = GAME_DIR + "/worlds"; - public static String LOGS_DIR = GAME_DIR + "/logs"; - - private Workspace() { - } - - public static void createFolders() { - File gameDir = new File(GAME_DIR); - File logsDir = new File(LOGS_DIR); - File assetsDir = new File(ASSETS_DIR); - File worldsDir = new File(WORLDS_DIR); - - gameDir.mkdirs(); - logsDir.mkdirs(); - assetsDir.mkdirs(); - worldsDir.mkdirs(); - } - - private static void create(String gameDir, String assetsDir, String worldsDir, String logsDir) { - GAME_DIR = gameDir; - ASSETS_DIR = assetsDir; - WORLDS_DIR = worldsDir; - LOGS_DIR = logsDir; - createFolders(); - } - - private static void create(String gameDir, String assetsDir) { - create(gameDir, assetsDir, autoWorldsDir(), autoLogsDir()); - } - - private static void create(String gameDir) { - create(gameDir, autoAssetsDir()); - } - - public static void create() { - create(autoGameDir()); - } - - public static void create(String... dirs) { - int len = dirs.length; - if (len == 0) { - create(); - } else if (len == 1) { - create(dirs[0]); - } else if (len > 1 && len < 4) { - create(dirs[0], dirs[1]); - } else if (len > 3) { - create(dirs[0], dirs[1], dirs[2], dirs[3]); - } - } - - private static String autoGameDir() { - return "opcraft"; - } - - private static String autoAssetsDir() { - return GAME_DIR + "/assets"; - } - - private static String autoWorldsDir() { - return GAME_DIR + "/worlds"; - } - - private static String autoLogsDir() { - return GAME_DIR + "/logs"; - } - -} diff --git a/src/main/java/net/opencraft/data/packs/DefaultPack.java b/src/main/java/net/opencraft/data/packs/DefaultPack.java new file mode 100644 index 0000000..331f23d --- /dev/null +++ b/src/main/java/net/opencraft/data/packs/DefaultPack.java @@ -0,0 +1,30 @@ +package net.opencraft.data.packs; + +import java.io.FileInputStream; +import java.io.InputStream; + +public final class DefaultPack extends Pack { + + private static final DefaultPack defaultPack = new DefaultPack(); + + public DefaultPack() { + } + + public static Pack getDefaultPack() { + return DefaultPack.defaultPack; + } + + @Override + public InputStream getResource(String resource) { + InputStream in = InputStream.nullInputStream(); + + System.out.println("Resource adquired: " + resource); + try { + in = new FileInputStream(resource); + } catch (Exception ignored) { + } + + return in; + } + +} diff --git a/src/main/java/net/opencraft/data/packs/Pack.java b/src/main/java/net/opencraft/data/packs/Pack.java index 3dda626..0d5ee18 100644 --- a/src/main/java/net/opencraft/data/packs/Pack.java +++ b/src/main/java/net/opencraft/data/packs/Pack.java @@ -2,6 +2,6 @@ import java.io.InputStream; -public interface Pack { - InputStream getResource(String resource); +public abstract class Pack { + public abstract InputStream getResource(String resource); } diff --git a/src/main/java/net/opencraft/data/packs/ResourcePack.java b/src/main/java/net/opencraft/data/packs/ResourcePack.java index e9a0a13..7e5033e 100644 --- a/src/main/java/net/opencraft/data/packs/ResourcePack.java +++ b/src/main/java/net/opencraft/data/packs/ResourcePack.java @@ -6,7 +6,7 @@ import java.util.zip.ZipException; import java.util.zip.ZipFile; -public class ResourcePack implements Pack { +public class ResourcePack extends Pack { private ZipFile zfile; diff --git a/src/main/java/net/opencraft/language/Translator.java b/src/main/java/net/opencraft/language/Translator.java index b771ebd..f1f5268 100644 --- a/src/main/java/net/opencraft/language/Translator.java +++ b/src/main/java/net/opencraft/language/Translator.java @@ -1,43 +1,59 @@ package net.opencraft.language; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import net.opencraft.config.GameConfig; import net.opencraft.util.Resource; public class Translator { + + private static final Map ENGLISH = new HashMap<>(); + private static final Map GALICIAN = new HashMap<>(); + private static final Map SPANISH = new HashMap<>(); + + static { + + // English translation + ENGLISH.put("opencraft.button:singleplayer", "Singleplayer"); + ENGLISH.put("opencraft.button:multiplayer", "Multiplayer"); + ENGLISH.put("opencraft.button:settings", "Settings"); + ENGLISH.put("opencraft.button:quit", "Quit Game"); + + // Galician translation + GALICIAN.put("opencraft.button:singleplayer", "Un xogador"); + GALICIAN.put("opencraft.button:multiplayer", "Multixogador"); + GALICIAN.put("opencraft.button:settings", "Configuración"); + GALICIAN.put("opencraft.button:quit", "Saír"); + + // Spanish translation + SPANISH.put("opencraft.button:singleplayer", "Un jugador"); + SPANISH.put("opencraft.button:multiplayer", "Multijugador"); + SPANISH.put("opencraft.button:settings", "Configuración"); + SPANISH.put("opencraft.button:quit", "Salir"); + + } public static String translate(String property, Locale language) { - if (language.equals(Locale.forLanguageTag("es-ES"))) { - return switch(property) { - case "opencraft.buttons:singleplayer" -> "Un jugador"; - case "opencraft.buttons:multiplayer" -> "Multijugador"; - case "opencraft.buttons:config" -> "Configuración"; - case "opencraft.buttons:quit" -> "Salir"; - - default -> property; - }; - } - return switch(property) { - case "opencraft.buttons:singleplayer" -> "Singleplayer"; - case "opencraft.buttons:multiplayer" -> "Multiplayer"; - case "opencraft.buttons:config" -> "Settings"; - case "opencraft.buttons:quit" -> "Quit Game"; + if (language.equals(Languages.get("es-ES"))) + return SPANISH.getOrDefault(property, property); + else if (language.equals(Languages.get("gl-GL"))) + return GALICIAN.getOrDefault(property, property); + else + return ENGLISH.getOrDefault(property, property); - default -> property; - }; } - public static String translate(String property) { return Translator.translate(property, GameConfig.LANGUAGE); } - + public static String translate(Resource resource, Locale language) { return Translator.translate(resource.toString(), language); } - + public static String translate(Resource resource) { return Translator.translate(resource, GameConfig.LANGUAGE); } diff --git a/src/main/java/net/opencraft/renderer/Renderizable.java b/src/main/java/net/opencraft/renderer/Renderizable.java index 93db56c..20f6027 100644 --- a/src/main/java/net/opencraft/renderer/Renderizable.java +++ b/src/main/java/net/opencraft/renderer/Renderizable.java @@ -1,18 +1,8 @@ package net.opencraft.renderer; -import java.awt.Graphics; import java.awt.image.BufferedImage; public interface Renderizable { - - void render(Graphics g); - - public default void render(Graphics g, int width, int height) { - render(g); - } - - public default void render(BufferedImage bi) { - render(bi.getGraphics(), bi.getWidth(), bi.getHeight()); - } + public void render(BufferedImage bi); } diff --git a/src/main/java/net/opencraft/renderer/Screen.java b/src/main/java/net/opencraft/renderer/Screen.java index ceb66e4..16a956c 100644 --- a/src/main/java/net/opencraft/renderer/Screen.java +++ b/src/main/java/net/opencraft/renderer/Screen.java @@ -1,7 +1,6 @@ package net.opencraft.renderer; -import java.awt.Graphics; -import java.awt.Image; +import java.awt.*; import java.awt.image.BufferedImage; public class Screen implements Renderizable { @@ -10,6 +9,10 @@ public class Screen implements Renderizable { public Screen(final int width, final int height) { screenImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = screenImg.getGraphics(); + g.setColor(Color.BLACK); + g.fillRect(0, 0, width, height); + g.dispose(); } public BufferedImage getImage() { @@ -20,17 +23,14 @@ public Graphics getGraphics() { return getImage().getGraphics(); } - @Override public void render(Graphics g, final int width, final int height) { g.drawImage(getImage(), 0, 0, width, height, null); } - @Override public void render(Graphics g) { g.drawImage(getImage(), 0, 0, null); } - @Override public void render(BufferedImage bi) { if (bi.equals(screenImg)) return; diff --git a/src/main/java/net/opencraft/renderer/Texture.java b/src/main/java/net/opencraft/renderer/Texture.java index 713f10e..8636543 100644 --- a/src/main/java/net/opencraft/renderer/Texture.java +++ b/src/main/java/net/opencraft/renderer/Texture.java @@ -3,8 +3,11 @@ import java.awt.Color; import java.awt.Image; import java.awt.image.BufferedImage; +import java.io.InputStream; import java.util.Optional; +import javax.imageio.ImageIO; + public class Texture { public final Optional img; @@ -21,6 +24,17 @@ public Texture(int width, int height, boolean alpha) { this(new BufferedImage(width, height, (alpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB))); } + public static Texture of(InputStream in) { + Image img = null; + + try { + img = ImageIO.read(in); + } catch (Exception ignored) { + } + + return Texture.of(img); + } + public static Texture of(Image img) { return new Texture(img); } diff --git a/src/main/java/net/opencraft/renderer/display/DisplayManager.java b/src/main/java/net/opencraft/renderer/display/DisplayManager.java index bdc8a63..ce4fb8e 100644 --- a/src/main/java/net/opencraft/renderer/display/DisplayManager.java +++ b/src/main/java/net/opencraft/renderer/display/DisplayManager.java @@ -2,12 +2,13 @@ import java.awt.BorderLayout; import java.awt.Cursor; +import java.awt.Point; +import java.awt.Rectangle; import net.opencraft.client.Game; import net.opencraft.util.Assets; public class DisplayManager { - public static Display display = null; private DisplayManager() { @@ -24,6 +25,7 @@ public static void createDisplay() { display.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); display.setIconImage(Assets.getIcon()); display.pack(); + } public static void showDisplay() { @@ -55,6 +57,14 @@ public static int getDisplayHeight() { return display.getHeight(); } + public static Point getDisplayLocation() { + return display.getLocation(); + } + + public static Rectangle getDisplayRect() { + return new Rectangle(display.getLocation().x, display.getLocation().y, display.getWidth(), display.getHeight()); + } + public static void updateDisplay() { display.repaint(); } diff --git a/src/main/java/net/opencraft/renderer/scenes/LoadScene.java b/src/main/java/net/opencraft/renderer/scenes/LoadScene.java index 5b690de..1e084c4 100644 --- a/src/main/java/net/opencraft/renderer/scenes/LoadScene.java +++ b/src/main/java/net/opencraft/renderer/scenes/LoadScene.java @@ -6,6 +6,7 @@ import java.awt.Color; import java.awt.Font; import java.awt.Graphics; +import java.awt.image.BufferedImage; import java.util.logging.Logger; import net.opencraft.config.GameExperiments; @@ -35,7 +36,9 @@ public LoadScene() { super(RESOURCE, SOUND); } - public void render(Graphics g) { + @Override + public void render(BufferedImage img) { + Graphics g = img.getGraphics(); if (GameExperiments.SKIP_LOAD_SCENE) { changeScreen(0); return; @@ -51,7 +54,7 @@ public void render(Graphics g) { public void classicLS(Graphics g) { if (i == Display.HEIGHT - 1) - g.drawImage(Assets.getLoadscreen(), 0, 0, Display.WIDTH, Display.HEIGHT, null); + g.drawImage(Assets.getLoadscene(), 0, 0, Display.WIDTH, Display.HEIGHT, null); i--; diff --git a/src/main/java/net/opencraft/renderer/scenes/Scene.java b/src/main/java/net/opencraft/renderer/scenes/Scene.java index 36b3db2..806d14c 100644 --- a/src/main/java/net/opencraft/renderer/scenes/Scene.java +++ b/src/main/java/net/opencraft/renderer/scenes/Scene.java @@ -1,6 +1,5 @@ package net.opencraft.renderer.scenes; -import java.awt.Graphics; import java.awt.image.BufferedImage; import net.opencraft.config.GameExperiments; @@ -34,14 +33,6 @@ public static void renderCurrent(BufferedImage bi) { getCurrent().render(bi); } - public static void renderCurrent(Graphics g, int width, int height) { - getCurrent().render(g, width, height); - } - - public static void renderCurrent(Graphics g) { - getCurrent().render(g); - } - public static Scene getCurrent() { return current; } diff --git a/src/main/java/net/opencraft/renderer/scenes/TitleScene.java b/src/main/java/net/opencraft/renderer/scenes/TitleScene.java index a126868..817bba1 100644 --- a/src/main/java/net/opencraft/renderer/scenes/TitleScene.java +++ b/src/main/java/net/opencraft/renderer/scenes/TitleScene.java @@ -1,7 +1,11 @@ package net.opencraft.renderer.scenes; +import static net.opencraft.util.Assets.LOGO; +import static net.opencraft.util.Assets.PANORAMAS; +import static net.opencraft.util.Assets.WIDGETS; +import static net.opencraft.util.Utils.BUTTON; + import java.awt.Color; -import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; @@ -11,25 +15,25 @@ import net.opencraft.language.Translator; import net.opencraft.renderer.display.Display; import net.opencraft.sound.Sound; -import net.opencraft.util.Assets; import net.opencraft.util.Fonts; import net.opencraft.util.Resource; +import net.opencraft.util.Utils; import net.opencraft.util.coords.Coordinates; -import net.opencraft.util.coords.Vec2; public class TitleScene extends Scene { - + public static final Resource RESOURCE = Resource.format("opencraft.scene:title"); public static final Sound SOUND = Sound.MOOG_CITY; - private static TitleScene instance = new TitleScene(); + private static final TitleScene instance = new TitleScene(); public TitleScene() { super(RESOURCE, SOUND); } @Override - public void render(Graphics g) { + public void render(BufferedImage bi) { + Graphics g = bi.getGraphics(); final int width = Display.WIDTH; final int height = Display.HEIGHT; @@ -41,23 +45,24 @@ public void render(Graphics g) { // Set font g.setFont(Fonts.MOJANGLES.deriveFont(Font.PLAIN, 18)); - // Draw panoramas - g.drawImage(Assets.getPanoramas(), 0, 0, height * 3, height, null); + // Draw background + g.drawImage(PANORAMAS, 0, 0, height * 3, height, null); // Draw Logo - g.drawImage(Assets.getLogo(), (width - 583) / 2, 30, 583, 166, null); + g.drawImage(LOGO, (width - 583) / 2, 30, 583, 166, null); // Draw buttons - int[] b1 = Coordinates.XYWHtoP4(Vec2.newTemp((width - 400) / 2, height / 2 - 50), new Dimension(400, 45)); - int[] b2 = Coordinates.XYWHtoP4(Vec2.newTemp((width - 390) / 2, height / 2), new Dimension(190, 45)); - int[] b3 = Coordinates.XYWHtoP4(Vec2.newTemp((width) / 2, height / 2), new Dimension(190, 45)); + int[] b1 = Coordinates.XYWHtoP4((width - 400) / 2, height / 2 - 50, 400, 45); + int[] b2 = Coordinates.XYWHtoP4((width - 390) / 2, height / 2, 190, 45); + int[] b3 = Coordinates.XYWHtoP4((width) / 2, height / 2, 190, 45); + + int[] bb = Utils.getButton(BUTTON).getBounds(); - int[] bb = Assets.getButton(0).getBounds(); - g.drawImage(Assets.bindTexture("/gui/widgets.png").getImage(), b1[0], b1[1], b1[2], b1[3], bb[0], bb[1], bb[2], + g.drawImage(WIDGETS, b1[0], b1[1], b1[2], b1[3], bb[0], bb[1], bb[2], bb[3], null); - g.drawImage(Assets.bindTexture("/gui/widgets.png").getImage(), b2[0], b2[1], b2[2], b2[3], bb[0], bb[1], bb[2], + g.drawImage(WIDGETS, b2[0], b2[1], b2[2], b2[3], bb[0], bb[1], bb[2], bb[3], null); - g.drawImage(Assets.bindTexture("/gui/widgets.png").getImage(), b3[0], b3[1], b3[2], b3[3], bb[0], bb[1], bb[2], + g.drawImage(WIDGETS, b3[0], b3[1], b3[2], b3[3], bb[0], bb[1], bb[2], bb[3], null); // Legal terms @@ -67,26 +72,12 @@ public void render(Graphics g) { g.drawString(COPYLEFT, width - 425, height - 70); - // Draw Game Info + // Draw GameInfo g.drawString(Game.TITLE, 15, height - 70); - g.drawString(Translator.translate("opencraft.buttons:singleplayer"), width / 2 - 69, height / 2 - 23); - - g.drawString(Translator.translate("opencraft.buttons:config"), (width - 300) / 2, (height + 55) / 2); - g.drawString(Translator.translate("opencraft.buttons:quit"), (width + 90) / 2, (height + 55) / 2); - } - - @Override - public void render(Graphics g, int width, int height) { - render(g); - } - - @Override - public void render(BufferedImage bi) { - render(bi.getGraphics(), bi.getWidth(), bi.getHeight()); - } + g.drawString(Translator.translate("opencraft.button:singleplayer"), width / 2 - 69, height / 2 - 23); - public static TitleScene renewInstance() { - return instance = new TitleScene(); + g.drawString(Translator.translate("opencraft.button:settings"), (width - 300) / 2, (height + 55) / 2); + g.drawString(Translator.translate("opencraft.button:quit"), (width + 90) / 2, (height + 55) / 2); } public static TitleScene getInstance() { diff --git a/src/main/java/net/opencraft/sound/Sound.java b/src/main/java/net/opencraft/sound/Sound.java index 0d5c5bb..d64b21a 100644 --- a/src/main/java/net/opencraft/sound/Sound.java +++ b/src/main/java/net/opencraft/sound/Sound.java @@ -4,7 +4,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Objects; +import java.util.Optional; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; @@ -12,12 +12,11 @@ import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; -import net.opencraft.config.Workspace; +import net.opencraft.config.GameConfig; import net.opencraft.util.Resource; public enum Sound { - NONE("opencraft.sounds", "none", null), - MOOG_CITY("opencraft.sound", "title.moog_city", "MoogCity.wav"), + NONE("opencraft.sounds", "none", null), MOOG_CITY("opencraft.sound", "title.moog_city", "MoogCity.wav"), ARIA_MATH("opencraft.sound", "ambient.aria_math", "AriaMath.wav"); public static Sound PLAYING = null; @@ -44,15 +43,18 @@ public String getSoundId() { return soundId; } - public String getRelativePath() { - return path; + public Optional getRelativePath() { + return Optional.ofNullable(path); } - public String getPath() { - if (Objects.isNull(path)) - return null; - - return Workspace.ASSETS_DIR + "/opencraft/sounds/" + path; + public Optional getPath() { + + Optional relativePath = getRelativePath(); + + if (relativePath.isEmpty()) + return Optional.empty(); + + return Optional.of(GameConfig.GAME_DIR + "/assets/opencraft/sounds/" + path); } public static Sound getCurrent() { @@ -61,28 +63,43 @@ public static Sound getCurrent() { public Sound fromResource(Resource res) { return switch (res.toString()) { - case "opencraft.sound:title.moog_city" -> MOOG_CITY; - case "opencraft.sound:ambient.aria_math" -> ARIA_MATH; - default -> null; + case "opencraft.sound:title.moog_city" -> MOOG_CITY; + case "opencraft.sound:ambient.aria_math" -> ARIA_MATH; + default -> NONE; }; } - public static void play(Clip player, Sound sound) - throws LineUnavailableException, IOException, UnsupportedAudioFileException { + public static void play(Clip player, Sound sound) { if (player == null) return; - AudioInputStream audioStream = AudioSystem.getAudioInputStream(getSound(sound)); - player.open(audioStream); - player.loop(Clip.LOOP_CONTINUOUSLY); + try { + AudioInputStream audioStream = AudioSystem.getAudioInputStream(getSound(sound).get()); + player.open(audioStream); + player.loop(Clip.LOOP_CONTINUOUSLY); + } catch (Exception ignored) { + } } public void play(Clip player) throws LineUnavailableException, IOException, UnsupportedAudioFileException { play(player, this); } - public static InputStream getSound(Sound snd) throws IOException { - return new BufferedInputStream(new FileInputStream(snd.getPath())); + public static Optional getSound(Sound snd) { + Optional path = snd.getPath(); + + if (path.isEmpty()) + return Optional.empty(); + + BufferedInputStream bis; + try { + var fis = new FileInputStream(path.get()); + bis = new BufferedInputStream(fis); + } catch (Exception ignored) { + return Optional.empty(); + } + + return Optional.of(bis); } public Resource toResource() { diff --git a/src/main/java/net/opencraft/sound/SoundManager.java b/src/main/java/net/opencraft/sound/SoundManager.java index e7f4528..34e0811 100644 --- a/src/main/java/net/opencraft/sound/SoundManager.java +++ b/src/main/java/net/opencraft/sound/SoundManager.java @@ -5,7 +5,6 @@ import static net.opencraft.sound.Sound.getCurrent; import static net.opencraft.sound.Sound.setCurrent; -import java.util.Objects; import java.util.logging.Logger; import javax.sound.sampled.AudioSystem; @@ -21,10 +20,11 @@ public class SoundManager { public static final boolean SUPPORTED; static { - // Set logging format + /* Set logging format */ System.setProperty("java.util.logging.SimpleFormatter.format", LOG_FORMAT); handle(logger); + // Create clip instance Clip clip = null; boolean supported = true; try { @@ -43,17 +43,14 @@ private SoundManager() { public static void update() { Sound sound = Scene.getCurrent().getSound(); - if (!isSupported() || Objects.isNull(sound.getPath())) + if (!isSupported()) return; if (getCurrent() != sound) { resetPlayer(); - try { - Sound.play(player, sound); - } catch (Exception e) { - logger.severe(e.getMessage()); - } - setCurrent(sound); + + Sound.play(player, sound); + setCurrent(sound); } } diff --git a/src/main/java/net/opencraft/util/Assets.java b/src/main/java/net/opencraft/util/Assets.java index aa06c30..990c4ed 100644 --- a/src/main/java/net/opencraft/util/Assets.java +++ b/src/main/java/net/opencraft/util/Assets.java @@ -5,93 +5,61 @@ import java.awt.Image; import java.awt.image.BufferedImage; -import javax.imageio.ImageIO; - -import net.opencraft.client.Game; -import net.opencraft.config.Workspace; -import net.opencraft.data.ButtonInfo; +import net.opencraft.config.GameConfig; import net.opencraft.renderer.Texture; public class Assets { + + public final static Image LOGO; + public final static Image WIDGETS; + public final static Image PANORAMAS; + + public static String TEXTURE_DIR = GameConfig.GAME_DIR + "/assets/opencraft/textures"; - private Assets() { - } - - public static ButtonInfo getButton(int button) { - return switch (button) { - case 0 -> ButtonInfo.of().vertices(new int[] { 0, 66, 200, 86 }).build(); - default -> ButtonInfo.EMPTY; - }; + static { + LOGO = getLogo().getImage(); + WIDGETS = getWidgets().getImage(); + PANORAMAS = getPanoramas().getImage(); } - public static Image getLogo() { - return bindTexture("/gui/title/minecraft.png").getImage(); + private Assets() { } - public static Image getLoadscreen() { - return bindTexture("/gui/title/background/loadscreen.jpg").getImage(); + private static Texture getLogo() { + return bindTexture("/gui/title/minecraft.png"); } - public static Image getPanorama(int index) { + private static Image getPanorama(int index) { return bindTexture(String.format("/gui/title/background/panorama_%d.png", index)).getImage(); } - public static Image getPanoramas() { + private static Texture getPanoramas() { BufferedImage bi = new BufferedImage(3072, 1024, BufferedImage.TYPE_INT_RGB); Graphics g = bi.getGraphics(); - g.setColor(Color.BLACK); + g.setColor(Color.PINK); g.fillRect(0, 0, 3072, 1024); g.drawImage(getPanorama(0), 0, 0, null); g.drawImage(getPanorama(1), 1024, 0, null); g.drawImage(getPanorama(2), 2048, 0, null); g.dispose(); - return bi; - } - - public static Image getIcon() { - return bindInternalTexture("/icon.png").getImage(); + return Texture.of(bi); } - public static Texture bindExternalTexture(String path) { - Image img = null; - try { - img = ImageIO.read(Resource.bindExternalResource(path)); - } catch (Exception ignored) { - } - - return Texture.of(img); + private static Texture getWidgets() { + return bindTexture("/gui/widgets.png"); } - public static Texture bindInternalTexture(String path) { - Image img = null; - try { - img = ImageIO.read(Resource.bindInternalResource(path)); - } catch (Exception ignored) { - } - - return Texture.of(img); - + public static Image getIcon() { + return Texture.of(Resource.bindInternalResource("/icon.png")).getImage(); } - - public static Texture bindPackTexture(String path) { - Image img = null; - try { - img = ImageIO.read(Game.getResourcePack().getResource(path)); - } catch (Exception ignored) { - } - - return Texture.of(img); - + + public static Image getLoadscene() { + return bindTexture("/gui/title/background/loadscreen.jpg").getImage(); } public static Texture bindTexture(String path) { - if (!Game.isDefaultPackSelected()) - return bindPackTexture("assets/opencraft/textures" + path); - - return bindExternalTexture(Workspace.ASSETS_DIR + "/opencraft/textures" + path); + return Texture.of(Resource.bindResource(Assets.TEXTURE_DIR + path)); } - - -} +} \ No newline at end of file diff --git a/src/main/java/net/opencraft/util/Fonts.java b/src/main/java/net/opencraft/util/Fonts.java index bd270f8..4312c6f 100644 --- a/src/main/java/net/opencraft/util/Fonts.java +++ b/src/main/java/net/opencraft/util/Fonts.java @@ -1,38 +1,18 @@ package net.opencraft.util; -import static net.opencraft.LoggerConfig.LOG_FORMAT; -import static net.opencraft.LoggerConfig.handle; - import java.awt.Font; import java.io.InputStream; -import java.util.logging.Logger; -import net.opencraft.client.Game; -import net.opencraft.config.Workspace; +import net.opencraft.config.GameConfig; public class Fonts { - - private static final Logger logger = Logger.getLogger("fontManager"); public static final Font MOJANGLES; static { - // Set logging format - System.setProperty("java.util.logging.SimpleFormatter.format", LOG_FORMAT); - handle(logger); - Font mojangles; - InputStream mojanglesIn = InputStream.nullInputStream(); - - if (!Game.isDefaultPackSelected()) - mojanglesIn = Game.getResourcePack().getResource("assets/opencraft/fonts/Mojangles.ttf"); - else { - try { - mojanglesIn = Resource.bindExternalResource(Workspace.ASSETS_DIR + "/opencraft/fonts/Mojangles.ttf"); - } catch (Exception ignored) { - logger.warning("Resource 'opencraft.font:mojangles' not found!"); - } - } + InputStream mojanglesIn = Resource.bindResource(GameConfig.GAME_DIR + "/assets/opencraft/fonts/Mojangles.ttf"); + try { mojangles = Font.createFont(Font.TRUETYPE_FONT, mojanglesIn); diff --git a/src/main/java/net/opencraft/util/Resource.java b/src/main/java/net/opencraft/util/Resource.java index 981a677..15e5935 100644 --- a/src/main/java/net/opencraft/util/Resource.java +++ b/src/main/java/net/opencraft/util/Resource.java @@ -1,72 +1,84 @@ package net.opencraft.util; -import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.net.URL; +import net.opencraft.client.Game; + public class Resource { private final String origin; private final String name; - + public Resource(String origin, String name) { this.origin = origin; this.name = name; } - + public Resource(Resource other) { this.origin = other.origin; this.name = other.name; } - + public Resource(String complete_name) { this(Resource.format(complete_name)); } - + public static Resource of(String origin, String name) { return new Resource(origin, name); } - + public static Resource of(Resource other) { return new Resource(other); } - + public static Resource of(String complete_name) { return Resource.of(Resource.format(complete_name)); } - + public static Resource format(String complete_name) { String[] sources = complete_name.split(":"); String origin = sources[0]; String name = sources[1]; - + return Resource.of(origin, name); } - + public static InputStream bindInternalResource(String respath) { - return Resource.class.getResourceAsStream(respath); + InputStream in = InputStream.nullInputStream(); + try { + in = Resource.class.getResourceAsStream(respath); + } catch (Exception ignored) { + } + + return in; } - + public static URL getResourceURL(String respath) { return Resource.class.getResource(respath); } + + public static InputStream bindResource(String respath) { + InputStream in = InputStream.nullInputStream(); + try { + in = Game.getResourcePack().getResource(respath); + } catch (Exception ignored) { + } - public static InputStream bindExternalResource(String respath) throws IOException { - return new FileInputStream(respath); + return in; } - + public String getOrigin() { return origin; } - + public String getName() { return name; } - + @Override public String toString() { return origin + ":" + name; } - + } diff --git a/src/main/java/net/opencraft/util/Utils.java b/src/main/java/net/opencraft/util/Utils.java index 859ae5f..061e880 100644 --- a/src/main/java/net/opencraft/util/Utils.java +++ b/src/main/java/net/opencraft/util/Utils.java @@ -1,14 +1,32 @@ package net.opencraft.util; -import net.opencraft.config.Workspace; +import net.opencraft.config.GameConfig; +import net.opencraft.data.ButtonInfo; public class Utils { + public static final int BUTTON = 0; + public static final int BUTTON_SELECTED = 1; + public static final int BUTTON_DISABLED = 2; + private Utils() { } + public static ButtonInfo getButton(int button) { + return switch (button) { + case BUTTON -> ButtonInfo.of().vertices(new int[] { 0, 66, 200, 86 }).build(); + case BUTTON_SELECTED -> ButtonInfo.of().vertices(new int[] { 0, 86, 200, 106 }).build(); + case BUTTON_DISABLED -> ButtonInfo.of().vertices(new int[] { 0, 45, 200, 66 }).build(); + default -> ButtonInfo.EMPTY; + }; + } + + public static String getGameDir() { + return GameConfig.GAME_DIR; + } + public static String getLatestFile() { - return Workspace.LOGS_DIR + "/latest.log"; + return GameConfig.GAME_DIR + "/logs/latest.log"; } } diff --git a/src/main/java/net/opencraft/util/ZipUtils.java b/src/main/java/net/opencraft/util/ZipUtils.java deleted file mode 100644 index 7e36642..0000000 --- a/src/main/java/net/opencraft/util/ZipUtils.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.opencraft.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipFile; - -public class ZipUtils { - - private ZipUtils() { - } - - public static InputStream getResource(String name, ZipFile zfile) throws IOException { - return zfile.getInputStream(zfile.getEntry(name)); - } - -} diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF index b55046a..9bdf3b1 100644 --- a/target/classes/META-INF/MANIFEST.MF +++ b/target/classes/META-INF/MANIFEST.MF @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Build-Jdk-Spec: 17 +Build-Jdk-Spec: 21 Created-By: Maven Integration for Eclipse diff --git a/target/classes/META-INF/maven/net/OpenCraft/pom.properties b/target/classes/META-INF/maven/net/OpenCraft/pom.properties index 45f56f3..a32aa39 100644 --- a/target/classes/META-INF/maven/net/OpenCraft/pom.properties +++ b/target/classes/META-INF/maven/net/OpenCraft/pom.properties @@ -1,7 +1,7 @@ #Generated by Maven Integration for Eclipse -#Sat Mar 16 12:13:12 CET 2024 +#Mon Mar 18 18:28:14 CET 2024 +artifactId=OpenCraft +groupId=net m2e.projectLocation=D\:\\dev\\OpenCraft m2e.projectName=OpenCraft -groupId=net -artifactId=OpenCraft version=24RXX diff --git a/target/classes/net/opencraft/client/Game.class b/target/classes/net/opencraft/client/Game.class index 930ab912acc201b87b55d6def647c47b31d875bc..0e59637a21cf3e56eb300b6877e99f689e26f7ec 100644 GIT binary patch literal 4587 zcma)8`F|8=9e##nGrP+WAV8p0AV4TdfGmMvfy9=u39z^%X*LN^q;c4tYz8*7+nGrL zTYK0l+G=a9O2v8~^{Cn=C2UKr)>{;<_kG{L`Ue=F_npaRSdx#D5Bt9JzVG+>-p7^y zy!bMJcKl1lJOwvch8xQl3@dHx!)`2{GY!j)?bk;Q6_pAWoz(BrV>#W*#(GYiG}5k$ zDg`w&r+s6VrJu+d3M#uh4t4P^IdhqEZPUuODOeECTaK$+?x3C@_v4VxAw{`yI{O*qKo>W)7r@J$yKuJ`zUAO}B z5ywNlU429SiTLYz(WxM8O4ezLcw=%-Z7F0`E}zXBwt|(O3S+LBi-|Mp5KGECp^9VV zXa^%RRM69>6s#%3%;>Hj6IV{Gm%pS?ZQ6(!6z6twaniP7Sl1KUhLtgF!;Yoo0}_VY z=?=?uZ&6Uu&^SmF$MYGZs^jWagC0Z#8_}qufly^?<*i{eE1gKYbE}~Vn`m-jl%c+k ze!5B78=<|nXjq2YD0eXpTd|JfwM&lTa+`+bSP=$&Q8}ucRur$rP8ByRSRq|Ji+wcg z!frCk8m?zB1Kxx)w_!)Uvw`M2h@=WeWgw|iXC2oV)o=*i z3g$b8+iNo!ZTGB#owFEjPE*PZ_0uhiUi7KBje&fv;XId2heQhfboYpEWkmL_^1038 z)HV@%3zMd0bdQamFzkLW-)oZjw4NK(ZBu;9!zd~c6XrasVHH+0Zrl;m;UZ!xisKkk zamO|K_m9|yp3(3|=uEBjn9VG3y+Z{{>AIO>;+?h$n6!orD6~q0b+c3{ST>8X8V94u z!c;M$VEwh0DCJt8Ou9~6&*m)+$FNS2FqU!{^}^Uo#@WKCgyH9_&^xbT4eBDe6OIa2 zlDXJAX~QxcW;z!QF2)o@lRX`sL#cRIH?wm?S;&@n1qo@2J8@dW88BL+G)3GqpMqq= z|3zP(7_)O>@nHcIHNp(z%}oBXVqC|m%$Xt<@1G<5RHMwHGS%kUhqS=%F{H8^Z0;@CmH>7 zgoo!^4Hxi1s=(5c7}c}nS~ne;`e`?2inG|>vEgBs?~HsQUGpIgAI3+>-Q!mB&RRcK z=c4uE_G218E(`LQuW5xj$`-QP%ZRyXg&9As;eA*a#%GvmDO$3?-cy%lnlv{z3za{o z;q!Qg<%as~xAnq^nP!eI3#v4IOg+AcXH|Sj!D5+-g75UDhUbKUYQ}U5dB=!i0vA<0 z&#p3uHO0f6em2(Wt%r1rhO;$H3YhAQ;kb7Gtbgf=m*n6vCM{m71+qZN(qpuV4)~&m z%Xo?2Np^JaAL!WMRT@EpFTLVA12>$W+7owMNuBUtKo{s`uTFmnNE8q zv6wAHJ5#W(Jc$E+PfiwcA}GkW)nkqk=z1awUe)kDe4mAzUhXrT{Ft3)jtF4k_e5zX zT6JB249tKWLYA3M06FCkKQfCs%|snJtT-ci)^`QJ)bL~cLM)mKn?dh zl+5C;GijsXnj8#O{9eHl8DC~Tmgp(nh+6+gF_`>G!SY~*pPo9|n#7yGX!xs$p^z*^ zEEKw(Wk@fXg*8P^Nn7kQMca#rNw-!T%vdIew@Jb06WDHBWwPf$s&pUl{ma z#P1p`DZO9HZ;n-@T`49gxpJW48WmH9#AJJvE87Lvr9@kcbwpUtual_cFR*PX>c?@@ zx%>n+Uxsq@5}GH_QnS5?9TR9P;&l^<*L2nFFCuYxTpaW~N2+-k;O}Z`0P>p8-7+?% zRm5M925dqjS~w04%9kKVj(tAgcG4<5k2YPx;iigl3;6!% zRVCiT5Wr74cLNAD!`Ujf}YgI$)409%g(Wk>b{RbiTM@-hTq0B$^_6w~xME zegh#|?o%_6QAv7?z;^_E7%KUYz1{~%`r%S5{P#5d=ZX2*NqnJ*@fk!Rq`||X@yxL_%dGhDQ1+JzzZ|1J!MW&nOuNn z2w%ZV65y+N)Cbt~=m;lTQ>a;ukXAepSxwi2z+Ie#3zIEs-lp_dD4D+L_%V pZmTcj_|b8+T*4nF@#k{WoW}w@DUrNFT#dis@1#=j4=LwA{|i2d0>uCT literal 4623 zcma)8`Ck<08UK##GP~<|p%P55=leX*_c`A8 z+J9et4L}qAtzvn+2LrZa|>u=PPVnn;<3-XY-*p?sZIW#$DUAh8h(tYDrs;t6Ofrp2`{_EL0HgqS6+j zRDs&x))S9)b%wB5L2z4xy=6Pc-dJx(TL{Y(EXkj(@HZEBHg|T#+giFhTjL6pSV`l# zYoH#nJkZ_NGte7rImnGx1tC+aPSC^~I_C9O80i=(dT1mEGJ0Y}!P=tJN!`_>V#|qk z^Oq8(sr1m0VJleeIh}RQR8*|d>u87E<0;i9M_i#f$0*|@Y{Rf-!`p_HG;G6;#^nJD zhME`-%XDv3P*PLdPl{X8Nh6GEY*29%5sJJ?TZ871j2-Fbr-mBTl4-%kKu>coqoeE# zlctRtR-!zF&4e7)O)G*ZwyM~oV3iEs9DZon1_mWOWVoJV3hHZShq`utB81|bHQa!= zgs?+FjnGstG}Zfz)yK`zOv>1wwnuf>HSGF9`4z%01+~Ykw^q5g?-sv@qXdmG{n(MA=4U6D_A)P8@2rrqW5b!f=YSNbVE3*V7cfL6~Yh+uCsF1 z3HFa`xC1AczLsvKd(Bb0&Gc;-AOjlSE2xOU>NW)zaZHRH(lb+xdF3T| z%4k@NiU@45n~|tBGs9O@hZ?fDi%G-8KVa*bVKYIIl{J2%>vywR`pbC_tH{NVN2HL2Q4r6Lofqc#Nd8BsNw+y>*oRQkqxBP)`!xThKB^L zrP(RYNa=Dft!Lnh7(AlELS+b#vSi{6Lq?=YK1CkKdsIB3V43U;g~A%16gt$T>15K5 z5yAWLl#2H&*gTJc;$TWY6K(azL%OB2dun)Ez${K0j%%mS_?r=&#RpY9Goy@qhiyYo zYWNVIC2t9jF>g`9im8~$BK1}olCyYT!#R=SD(k+JDI38HcuB>J3T~WfXu@ltN7D9) z!#>Yc{D>rx{g{a-0wAOCaSflqC%s1vE=7{^7ngO29T1AWa0=!*YFC_L%4nuW0zH=#6S$XRM{Gl{PG9Hj0kwA7VJ25i=9Bn1f-~ z@i#PlQ?S2KzCs547?4o$L=e}%g34k-iysKJ{i5A`N5l14%~mF!4%C};n`_btiuaKEdRt=Gb<4bo^*_df;Tl>hgIxhrc+=? z+<*JXUd?Ap#CxVV!)dmpimB2P*aIkr}nrcdcP^|<*>NR>V|GAz%ZU%@%wS(J?k%H_yZ;J8{mgCr(zY&r5q;<$on>rhFA z^_(51PVu*{Y{eL=Qjd6As7|ATS>bK712p6s||=E+bY~atQ~gaTb#T(C7dQILuMVYu;%blCCJ|oI+C8 zqf}CKjOLVeP2h0d1p37HTlt;CvAv6T1z$##Upv%tb*=G4d%3!IRj_spb?JoIT10`j ztqLv~+7;yQvoB2kr|u#So|}A=>v~BJNnu%u^st?N0b5AaR$8=;lr_+v9VB!Y{oYN# zn^22e>GK}kf@ZGn?qg^r}HJcFgx`6;BVtq^GqE#3}MwLgYOd zk<6~g2Bf&FVw5&)MqrXEgDRAOunv=?Th2;KxDcKsE7O~VY+z|KQiFXlA0UuUA`gS=7f@JUEX~>8a z?IrM$f_Mh=@#I6y2k7uKqg=%B-6EcznG<*{hxbk+dPW|j5yu&oJDBVz3Xse5$b2~Z z$Vnf$GKUY8ZJNMyIea*WkJjbzu}esg;Zr$${zzS5MlRk+zCrgwIEjTwVlfPA8e{ZDYzrlhP0L>QMa;Y&=@H;xO_&U*A^NZ*|W zDucL;ixMD*As=9;?_^~4GECn8^f;=DQCup_7NA7%W%dnW#;bX%YJJ0lfpJ_Z1~^SK z&J@9d^fK;@2HZ)_lf}?Bf#SYdcTh!_<9Qhd$l;QPZmhu8nV?DSV~_UIKTM=#?KN5}ETW&Cjhe<`N# YMOMm7d2De%{2l)wo`Qe!cLDzOKk%mswg3PC diff --git a/target/classes/net/opencraft/config/GameConfig.class b/target/classes/net/opencraft/config/GameConfig.class index a74171a7105ed11fd8abd3b07b31e88166bdd144..587e905b31c0ba8691d8188612047ef7bfe8755d 100644 GIT binary patch delta 375 zcmXYs&rZTX5XQd&`VSVZs3?je{w-+Ii#Hn+qsEY6NWgF<4I-&&z>w;dvq#gX(3|#P z;=u>-EqoEFr2Jh_k4i<8Uq-dUqfC^T>V z2j30-(a`NglVCJFBA8x33`Rk8Oh`MmE+KO|z8+YZ$D)A+f~|V)qabvfDhpW1O0~{12Vr7^V2tnj6aOZX`Ava5X5um(>U#n^u;VUu zNQ+;nI<;hpS4qLdENphq@vFg6p3)l%36^XxK`EVJl@hEKDhaBuTufn$?;`&Q`~w|X u9-d=};C=GgRt_+T2mWJSjuNcZ-?6I@j$-I4Yp5Ra=YWG6I|+5g+5ZI;H8OGl delta 319 zcmYL@%}&Bl5QV=BZK34~SW(13#J{MUz5p>MZiysH*ca@grk2EjTb{s$=~K8d(Jo9} z_yE2IFJhcl6K64VGIP#%@3XluoUiYXPoT@ulk+m~j-xORr)P@d@ySqOTug2Pn`Kr? zxQhC%|KNMGX&8CE$=HtqO#@48SN;CLMzN+bu`;!;DN)YUhQ`Lp)Rv}#R@8c799+)s zM#25SA4P$}&2hsdRxPWeX;V!e)wME`h3d=;lv$!GfSUaDTxM2{H|i;?^=?YDn9@=y zo3FAjur1xikZxn)$eR^OYIgD~k{A9T&6An&%+q&v|KnD^Eaj1={&ld&zBm;JIp^>P DnwTq% diff --git a/target/classes/net/opencraft/config/GameExperiments.class b/target/classes/net/opencraft/config/GameExperiments.class index 739e3b6528453cbd8b3bb5944dc07ca15ec50864..3138e87e62c00eb376c8d251ff939ced3a4384e6 100644 GIT binary patch delta 13 UcmX@ie3*GdDI+7tPZ|BIN{l0 z(QnvZHLxCq#j5W;a<+;aeo${Vtg4+vT;R}S>xor#EpMy1y7}0yh61Ujxs}C-3(I!} zvgN(MD`DVxTQdTgxk_bmt)e9|8>@HA3(+H0UR`=k&Q@K=bHZx^vGKyXKz!b>*(n?p zNcs)sP#QFEpa+R8oz5CKjGVyGj#ankeXnYT8&0@Qsu@~d*c2EW@ARh7$&#>x29gq% z5yNFyQ8Uv@nE&hE~p9jsZKt}WyBtCqWN1&(}2%*3n;B!d`644gzS zg9*1CdNf>qdxn{;zG`4wpy+ z2_$yvH7B5D=JY-@xn=Fx3r-+#Q0E~6rQM|KZ#C6lX{*_^!-)RY58Rrj6WTL@+g;3d zruAJo1v)D*ZQzVd(%E;y)jC%Vd<2;;Yd7@Sp|73Hjd!WAH1e^5Yf_`kmXEO{N12x%Z^|%+ar2TwhE`@hVO^XFt8dc zcDU`=ni<^3mq|PjII}mPj`zf`+eJO6dV)$;HS~k0a$ABV-BzZ)U$0V8mouUVDoTqFD z&_oXn9U@?!kSEl?Qi5wIGH{W%Aiu|af#E&%jI!HDkb_Fi&_Xzc(-cn2k&FO-VO-MG z++P^IM^|3p>}^fvNtQJ^KypQsM@Zf=|Ae_QA&*IUOvz)<_!tdP~7ZZ~*Kw{s@* zI>CfaGLutGVGEb`JUOOHa-5PUSeBD4$uP4yLZ42xtrLURW$7e!o|MdIjy4l2i8*?d zh^$|ZtS=Bz7S=E)TDa1}Yzv?4S=GrOWn5#*%Al5QTQMRlGM++&I87O8H)Xak*TTY^ zXa)9ysnB#OQxRHP?wtr@LLsngS}3)!{3gT{!#JlPr0d^N@ph#6E89%+O6IHC{0~UC zP=1D)eEdfS7`s5IXPC;ze?~5!{0aSJnQ?L#o?$4T_!(KvFncbT39?lpVycNvmJAFw z#$+aGFT?U>afvN3&Cl3ndUJ);RV=b4WOM68m2d~Ee8sr2KgDPC@h)F!#Q#B`=o>gp z7_RBa_0v(zv25ROl+weaOL(mvYew$=NTHx2C7v3)3h<`djeTnT3UyUm>r^Z4Q{%U& stJ>$CYPZ^IF|4ZqHt+@SF&67j!jwlje3M_JjT)g0ENZk2LJ#7 diff --git a/target/classes/net/opencraft/language/Translator.class b/target/classes/net/opencraft/language/Translator.class index 4edf97b42a2550c25181166c709a4cc8f22e218c..e941ab2e7fd4f09a441244bb562af14ce3303b6d 100644 GIT binary patch literal 2325 zcmah~T~pge6g_JLl8yKhF_e!45>jI9f*YEo6i8Y_h(l{2L69_Q+H^6(hzQxpQm6cZ zK6j>1ed`~{OhRVzIn(J(-uk0Dy(`I<94LLU_wL@k_uRARUj6;g+dl!!!;uhUIB)4r zu2R*llFfIVoXM@S%gcIh!{%1aM(6PcJzP($Z?7xUAh~=qh@r zu49mSmn9nJ2xnXT*w!f7nk#^luEmkU-eSS z^Ci=;4Ce+zJUwxbp=GhMtxM=)=m|mG=Cxe{l0+wZ6sS-b+UC7$2{4>d(26#(>Qj*L zS05=zqD{si!`TKKQ(La%RIJ$=fi(51$q#i~#xR4TMRwY84x#Vg*cr++Z3|tU7F;iMM{)IgEW_A$u#mMSZolZ7Jbq-v8kZ0At0AI^XPEuGf~ zM&mpJkGSs89A0`t-4HzCDK$qYLIOWxO9E#YX{NN~i7O}c=<7^D36BUzF~3^a%omoD z)YiI!1uQZwra#bwhizT2Rb0EI2mKetd%`;>v5P$k2E$M@lBQS+p1>p&PQ_=2hD`c| zVB}#3*=f$43Xb9O>F7@gFKRy!weL`$XSWzW(VbjqjH#DH$HO>KCCAxzn#^)j9v<*1ixVve-NEdaRF~}5jVVO z#Ekgr_#`1m|BUuqGq3Pvm`<7DMe{eFP<1 literal 1924 zcma)7K~vjC6#f<*BpU^&5->C&fzVPTY*dmqr7@u)gb-5WBp8@UZi^#~sE~{-Wrpb` z?M#0}d+61NT+(*N$@Gv*W_sxF=%trldTBG6q;Dmeh}fl-$J*VuZ{PR5?>(=7ef9G* z0JGST(7`Zj8=me|4ZG~}El;<&UGaIv(AQjU*DUTiu7m_b-wuDkgI)dB=8jSJ7`kRn z+w|rbIx`a+42cEjzL7#Fk_wKYi=nq*+D6ge-89@azG)c@YQZUUYlFL{SVzW$w{6xK z#tQ#QB+roaB3cw}CR2Drs^qz*UCDga*L%DPM}}H$!3DF zlL`iqX6V^++(IPE8m};nw}Fj7VyE*W@{odeaf*~O_Iz$plKt_sp^o{9dnpX#tb{X7 z5~2orn2>@Ij55gEytXa$4a8oSF~)G_plDN@zUMi1?NW^-u#Bq3_YGGB9g;E5Fxcu? zcI+*)A|t~v+`7B#Tb>z4k)bgRw7Ts1rY9rIkXpA#cKiyz@3=Ci7?c%p_`vcZ3Ahk| z`7SS;&wsLIoG0;1+%oCFM|7YRBQ4`1Lw69Oi9bWxmkiG%ubPZY)B<-1dt{04k{EK; zC2p>_FM6w`8EC)R&IkMP5-}VvdA$6^3a>`JctmYuMad^|71tyzFq}Qyw4tuLAQxt> zU=j2Skqh(1rS zBC+tCu&WqOX4?EN$it1$sV|Ns$1r^~`!?Z4?j@1?4QiWGkmPk!TnoK#?wTo4M2wPW zC*4t?i-ej5UG$b{rPIiSReJ*Y2by#sMQ^bU$mpiG5<1X$oK{JpG+F2{Ymje(Y%eC& zzNb(d82lFd+TE1~PCp_uZ2Bf1eZPEd0r+_k($+4n3=W5X{qcjAhk{VBTLxTAi%pgqo|PN7d^{s?&8Ow8z@rViOgpQrsqP zHo~2WaIZzUw{tPvTnslC!_CEUF9_U^1@0#T_tOBEkU9g!=13KgUJ89IQfiNMdO)@> z(T9gn@fF#>ru*+Vr13ij@dt+RC*5U#;WYjxyHI+7)F(BOr@s>MyufA5k=CEl{3iNe zVphU%H$4e@UX!td))L){j7Gf1G!l_Ptnsg&qJ~$(8sa=*2DR3H#QalSe=Nerdf;5F z2jqyEIDaELf0?`m>!jAe@?@I;!bl8j6s-g6 F{{ROS!Dj#f diff --git a/target/classes/net/opencraft/renderer/Renderizable.class b/target/classes/net/opencraft/renderer/Renderizable.class index c1ebf878d812fef6aa45bd5fd54aa701cc0b7e60..24aadcbba12ace427ca20bcbb4462a638ba780ba 100644 GIT binary patch delta 46 zcmaFMx|NaZ)W2Q(7#J9A7&s?#c}nwfj1cRTmYyuH7?0@y*-fTQZW7bD9A4AetR%!6X!~ z#GPb@cb$ zZs{RdeL{v`1(4yZ=Idajt;Ktm@i`2bY_s*vXABv5WNaYMdyXv_S+My7>iswjV}wtf zfdYzLMWa!SCDB=w7-fqLF`|~$&gZGAnF!I6A zZC<@5Qur3g`k_{~QV#D{mm4*|IbARLVYMCz*}?qug1_pI`fK6n{dzSBCsOqC*dt(3 zII2DS;>^CoY`GK){hi$rA*+TJA=75#p&n~I6(ovcqr zqepKqXXs;qelBsGE1cjKCz;_C4>-*{XKmFTcg|rrZ$G&=(-*WFAWe>AT(mpxTyjXA zhE+RaXUx1@wx3Nw#_hH#bX`{+Bs7vNuxNKoU#s>dhCIzKqIt4IRHva>Qqd`8qm%o^ z(!;N$wy1q)`G3)ji&C5`KX`G_^LB@4iz9oU!}^XzrY3HDy{TnFmxolm8U>Y-Sp==-p&*Hl(Xmb*7V1!$E@V{K-XMk^qk{z= z3VMK!y+JP$O+qsa-v{%X4`!JA&SXA+-add`5{qNlc#JE9?WQr&Yu7xC6~de3H13}r zoL?uM_oPMRzEa`#Ojd2h{3NXy%DL&lkuTkolwCCwB$?RkaE-O;}H3))F2O#lD@ diff --git a/target/classes/net/opencraft/util/Assets.class b/target/classes/net/opencraft/util/Assets.class index 84c03c86dfbd541b9d56cca3f833703cb1bc9b77..1d1f3c79c3655bbce635879dd78eaefeff5834e5 100644 GIT binary patch literal 3078 zcma)8X;%|h7=A7Z*_aAMgyLGQAOU4sv2}^nMns$%mI8`PtDPj5Fff@(Clk;vcHj5i z?%UUXX!RV-v8Vk3{ZT!A@121J$kD<%xp(e;*XKU(d+$I0-uWBAQT!T414F09UDYmf zE9>Ypu3B~tQ%#jh+%1I>WN4Yw7j)Ist-Lyxnd4cPA($Q;9;2PK+|n0aRV(Ouo@5A5 zYbS??rY0Gp?O)$hgHED6ubqp&{ijkvP)36Np7(<{Z zagKZp+BqIYGg`xFVc4-c$gFM67h84R&eE*p>Xut#=u$6Mnb2n}0ZH8SviS+9D9B$>f z!yR>sUviK#Ykt` z$kA^}2qYAQJ%K(2dxd~PTjRQAJ9 z@$D~$j>;p7A%Fn|4@042a%T+!a?6_hYen~b)k-%XE zM?fTK${1G8M~vY>-NU&%dcsIek_;Prv~}o3aGas5CZLR-ozFXV*~+O!AD$~+IWM{t z2E#bP&{{16&2o93I|@!>h-k2&n`J&W!_dCsOLE&6qoW^&7RKpSrQ{J`!4o*c5Sp=_ zf=-2XxK7HKYWV0CV6qNH85#*YewBfdFDlNhE0i%rZK@~AGc&}JZg7e{= zQ7YOcE^7K&1r7+L2AiVUzs~SI`vPfZ3~CB%{jWMMVl~SX7*(NV#HhHg5y+Cui(csq z+Ir1Nqb?c23zWQS(A4Aeb-WzLOH{F|3rQC21TWcTC(9MQf>#;ZL^%o;JC;r$dwbMZ z>X6iDq+zR?RV=&2Zmt(((|cV2^ajI0Uu%uX{{TpIt+cJ@N?C642;QdFSHE^mDdcc& z_0JXaacV5@iW}fPhC_8i_Q0&Yh3b@54A=32f)528ih!dEL$Ij3v($7aC1j@z(KVaA zd$V6u1Rcu>+jdJX719WIXYE`mhR^Y37++8Z)ox-~3-&x$y@uf3Qm6E+YdhCO@Lw_9 zs14qi_6(lZt(?hAyVJHkUoIxsXH>JYN^$C1k=GHwN2~Eo4C2xw|N}F%JZ~J?RBO zmwynQ;(nxAr?>{?NOv8LQE`#WF@h#2B!3@$O{0N+fju{|;SM$ex6n~R=MuKv!h;ob z$w^NIy>hbe4-##FO26&o252QyZS=nh+i0a59e7Ae2r0TKeJ2AnGFor!y^Z}<6EW$# zlVaX1)r2?+;Q$_?F(#fHzJYGJ1BBv_R&eNd=|Th%lIz=6oW?}|^L0{WN!aU%9}E74 zz=go(3Lc-V;1pS)WY!wlSrbAB(io8;(EGtR_ZyiLP@Vr1qZe8gv<4Bpjqx)C%w)Rn zCZ?D0bYCFg?JObN7pNc~2(Tp>(|tjjlY;-%D83@gUrQ+TR#2?Q(@h5jbkQ5In~?1x z7!vf*>BRv0kfImO81`Y3&OjjDPBAq@gNrhKwb9kQfJKTpCZ0xqmc#B1vZ{Dfc7`5*2$ B?~4Ec literal 4051 zcmbVP>3+MYO}Y`<8ig!fKlIl>s_l6*qszq>P|z=MsMYGGg(`Mqk3ff$7Z@Gc#_I4? z#k6vUOY1|}r(mzZ(YLi;+n{1U4hVFw8Lnq$4LUnMa(O!+YMcGj4yibddjvW&5`w^y z?XV_dWZ;O3`|u9#nwdMlxGZqbHmotEnUG_V6xf;e^z7=KUJ3)HFa{~7;4qFn-q(YE z&C`-ay9P1+4t3wM!{cj35#cMBYD4Z!A=Do$X8%oDi}lTP_g=(%#%H4M8O zCk2L^P-p0I!F4KjPP3fas)?(m0&#QadEItgy{HQeND*$~;89AVy|q%f^UBd&K*(u4 zuHZ3&zD8mtZO*}QyGs}F~(=4dkFg2XU1qF)&yXq%RJC;L+mT-~Crc#sB z=jeVT5dJioS;l1rmul=vnbxeTcrTu#Bv{$}#WIwe_e-eDxT50yV5qzEre!VoB~Ou# z_?`%4Rh+`Za-pFj4=N;yhQ#P4Y0Fe`RTfVr zXO>G&nHkcNF{$&-dt10>ffPJ{ps}dtEoWrfCbJH;{sBVNOup7qvaG_BDLEihQp(D; zb*rA5{^-nl%V-?ea9siAaG*8w{C=@ul%0y3B_AKe^8&l2*_wgcoGi2f&eoLoBWyZa z(k@jziqFuCjN^y#Q3W5NK;-ng=JO^ONxdbhrH|p`>^xk|qWDl~caxE(G!1BPrB2q8 zPs%>1**Ylk0km$OIH}XIKGZ=D)`2huAa3_!)7k%MaJk`_%@p~)loAf zE!?%YlsH+|7ay|q>HEhT$wfH&1gq()tZn}p)RHz$18g*k8_5%;^fM4{1F=p{={b05R+-I zIje>iXe!`mR?m8ldtJi3E%0J9%y4yJ@JZdySw?v{|(75tTy~-Q${yD$g z)w?vmfx!(Nyn(J;xc4SkM*JiDc^I&Vb!?ERhH#SajiXOt7)LpOjDOvT>^?lD5MB)L z#7GEa)Q3TE{i9WkZ$Oi#18=0Wz(L=f^ecu3+iZKN{kD6Xwy|A?r%i@#5A{D1eG`%8 z$o?u4=_)4M8yRkLWe8_|S7Lawj^bsSlgKW-j^uKmioPhKw{h;=*an_Xjo-q;2A&;{ zM1q+Oyl*^GMJ5sv8^~Q8kMf-x!mm#GMT&yC4Xlhch&V>q!9#m6N}k7Y0QZx@2gvsX zCZS=Ttt8D5O5O(vs0XuHg~hMkoG-$r_c1ti*bUB0Rk&?9KiNbcYeq<($6qPN0g)Q3 zVy%h~rEVZPH(tdjZgNTnZ6`k6qKij4dYa>pQF>3*@zDf6ix+6BgKGF3KF{4!Ap_|6 z4^4C^piI61q0kzE^QzDm!I%CQ1ZQ~0ED@X~f~Wpp1gzj8g6lLVIoK;wReWviHGHQ7 zTVeDt|5}Nd=e}ncm<2j{p$W#`IuV1LiRj-#1pkc*VLVF^GC2-a@%@*ubLtFx? diff --git a/target/classes/net/opencraft/util/Fonts.class b/target/classes/net/opencraft/util/Fonts.class index beb3e972392e23ca33f952327c66e6b1d603d3d3..eef20cfdb078869fc2381c3cf5ae7dc0070dd182 100644 GIT binary patch delta 588 zcmXX?&rcIk5dPl2?!N8v3UmuCrM7?tS{7yfQL7+|h;22{lP8ZWwuDBvMmLZclg2-R zyo*;)9u0bcVB*Px;Uxcy@hHwdJxu1CnQvykeD5;fhn&+tC*J_9;?aRqKj_x#Nem$+ zAQ`5@PUQDrcEasfK{xWZ`(bx?$8QBMIvW~F3}b}BZmqW)>Wmkyw1kU{`o$a8IC276 zwU(H6CXi>4Pj|y-s>^Fd2L%)bE-<8e!Cv48`;p)5hmk}HQ|fnOIXAcrUiMpI} z^)s9ki~`3P+v1DInB4q`bo(m`PuyufDvxk+)BA$?L)wdN8Ap}&JldSpSBG_%>_Qe} zC?kgoCa_3z4+*#fB45(PGL`?3Br7gsi4JCwf{!aC?J6x4VVu)_gH&Dv6R4ik*bpeh zHHc28{8#T&X4EsiBh(HF7+R90o3?&0HTF%^agzufw=``TE0p6q_bAq}L6t-30h)M- F{9mfbRXqRz literal 2433 zcmaJ?dsh=j6#oq<8{#4upMZ~06A3=DwPI_D(kk+ZCO};ZRZ8uUOv1uuH{G46^kqLr zPrrbFtLN0zp3@J|4^?|-l6Vpgo}BE?&b@c;y}$drcmDnF^*;cv<2M663@1DxEx#(f zLcmMXs!7MS=6p|v2KF%wZSzOma=BNwmNvIVK{E8Yez`0HhLM~WY74dJkWx;|G7SCs zr8_ql=X0|*!(c;^KbHDrl18o&YvL&`M4wE=`6TQ}N{0M40rV7{w_A zCp$2;cS9*ECQjoFWgZH-98f6&xyx{^OBQ?P)t+h;V>oNzBPvj5X&d;=_+H5=n@Au@ zwcO%f(G?7*n%=qTYSuhZ$6PTniL2zC z>VHp!ek~{nrO7Zx&O1*pa>=bK2}4V%WFq*CA;Cj}J#6a$#lO(X``bi%SA=OPO9${d zG6tpyrw<-!QdixeLbe4%6zNjP?zr^h3*0pDCBx}XHw9fYYt0XKLP~(ZxrG^q=uO+6 zU9lhD&fa5)y-$u9wfU@xIm}ZnDtt#!?F(G4IdY3uq2!b(!@0fV>!ei{cMaTO80`#B zQ>KNziJU^<$fn~JXP;2Bc-(EtB3Pv6Y<M($>5&v4(F5tpbr%QX6|T#Ku$E243$_vssvy zDRJb1nq{rfl#6doY~VZUo$JjBcDze8+3dus8Z6(NFc2}Y*=ijP>Fkq&s7lB8)NFJ- zu~@5YieQCrs#c8U`~r7ZdElt;=4Ss}bckMW*I7E?XxBUlEvM}Hf$Ei}MyF>Q!UMLX zHpug;_7O!dT$Ngsrm@^|h#4dAG?1>e!Y?H2sI8lA&QUQ(^=?|hPV?=S@5@jIyqXts z%P)pegs2%H*b}-iIugfwfjqOLJo4J+2^oe267CHVn>jgeI8ZN|(x z4!*>Z*s<7&I!4xB;7A?uI?m~kUWlQ%4iPf$Zj0VND(J5ko`pz$#Rl%$kACs=eL1<&D99zQ9_wA zohHc^9ExBW1I^VoS)RrIH{_y+pcw}i4e-bUJ>HN~kAW4vOXk!74Y**@n~~xE^RKY; uoEAMggFd}EprbJx3aG#%c`tmeRmBhVj*#pz{h#1R`cjAfgkSI!!~X-Gkd+Gn diff --git a/target/classes/net/opencraft/util/Resource.class b/target/classes/net/opencraft/util/Resource.class index 455a4bff914be768c015b4034991f31dcc7d9274..ac687b759d0e9a6d5c2850a12af0d4620040e5cc 100644 GIT binary patch delta 937 zcmZ`$&2AD=7(JK2;b#gJicO80n7Amo7_De3U@f+lVnN$dt<_e&z%5Q02Eq)+#07~P zA7D1d7jTQwn5GNs+DGseOniju$AE^Cy0~-ix%YhEIp>?hi8qt}??(q;0i@CR=s)A^ zME3YguBZ(qr#IVX(QFA`mvIA0hLGOYw4rN;$>~`B1b)g-?dBxhq#FBK<9bzD(70j9 zxP=5mq$H6$u%JmA<}Ru=J`dnx@*&8Kjmln%sQB;7|!hPgG?XE1JAq zEAZw9FKNQsa?WkJxjXumY~M=ZTDM z>{tcYTTclU31#btE9TvXV0bs3w|=?LTQT?Rv)l`siIXK6CCcf#XxUR1hJ>2+%^hd; zPe0vVN2dh`ob;DZ?c-WL%;H~=%71{XaH$Ih7Xk=ko(N&0gb4$e={rOBR}sQ>MCj%; zwV(#L4G--uj9~$bRJ}wf0>^J^;gArQh|VPH1|RMqO9VgA!4;}z#FT9DaL@lf@)TfwIDkwxj|Z3|i}R3?!8jIELkYtF5(GyRghmoD zJjAB83%F@Y#mIPuh; Y#4|jn-Ai3|X;q;T^3!P#8gxwk0X*fq$N&HU delta 615 zcmZvYJ5L)y6ot?A;$820>?BaDWNe^oB+nWVoX>b=9Q2*FIdb7jLh2FT@W1- zP0AG03)PHo4(i8nBgmnK5! zAm|%Hp0)I;vnC3dlZoJG^%a&iyq4dBPqYHw5WYT^57Z8M6+Gx%3gI0=p$rjB%W;I8 ztJt0=_#qz&-Lh4UvoE4*SRp*DAGM#S>X(4L)FVC5zVjCa(8g5-aqUHvt9jjP$nY(o zV-Q(+p||f3HQUqo+DDOQ=opW-Fz5vg?w&%qhU&jDUhMgWiDp!P14^$a6DDEt*ndC@ zBoB>bBHQ2#B8GO>2ve}+xzUvvy;q%PH5pD8W`O3{e8WJbj#Dtt&;S;&$a{$KZ+R8* Oo=*mMAMgpQNc;nt-D-LO diff --git a/target/classes/net/opencraft/util/Utils.class b/target/classes/net/opencraft/util/Utils.class index 9c8c821d5baba4be90b1b0444f6c9e45e01f53a5..41dfc5c3fe2e5c5e33db18835810a3f2691b2264 100644 GIT binary patch literal 1728 zcmah}TXWM!6#h28D0Y>`3AE5aoQ68oh7uL%6$fZ!JHf4uJJ`76^1!U+jiW@7JkmPT z%#{Dpf6$pewLDOU>F~_7|EbfnvST}!l80UGxqat5M`!o%e_y=@u!gFJDTa%#kcQV2 zuI2MBY4oM-7>{WSG(;IvJA9uT4tKjot-T{G$q+XmHyX8v46MvBQ}EnCa#uFF(-#rK z1;gyX<7vHADHR%}qEfT5x>&BSo0Wl@2*lTH*OvDfBH3J%AzJV{B8dp*bj;vg3ai+z zc-Y@-3%|kJj$oLtcouh>+_#lHR7T~t9WX3Z{;!@qL!v9B*_YCD8Lni@xnsT^F1azV zm)$KdpTq~aq+x+!@hIpqM;({3$S~z?G32smpk~az?R11s=u24E@FBy>ThR{#bX>tl z4Ac9Ii(`$mgl>5Q(? zA8ikNJX4q4+O6{5@E;|q|C@YI6m6g3JY^qGS6%wH+ogmzaa+SJN^`U+mgjEST|-6F z$k9>9XZW1jvAJF?JuQ|Wsj)Z#M*~VJD_n{|ZrF~Pr%C)u$Je;SaAA+{DlCi3A8fgO zILOr3tJ#xCr*LIR*1f)O3585TcxzS_2f8<==gC0&yjK-++v@~L+{e0xZx}LTmbSa^ z?FwU1`+&*@x1{GED2^t>FOy7$-UGk~-0e6b$W%OUx8KX3Bs`%x64*HCiBsI4O!yCO zdVaFxAw+>YPTiIwKO4urX_Oe|nBjQcfSw4|<5fB{=w;Uxe!<~EAm|x+KofqV=F_Us z@GV37?XEOkgOVAv;Z4Fay*cWQiO{sh5GP3^X$sRMCnjWdpWm5~bwtUF9vO<5rHI?~ zW%P|*`xB`@LI^c5Npb>|^9;^~r_c%K@g7MDypIb*fPW~lvOQb)jdtLta931-OSJCL zYQ4lo?XP4jnlfvx*c{%}TJcn~_5$e_$oz`p$lM&8cSh!wk@?2hY>v$F=g9s}Ng`0h z7pPVsMX%Ew@}&8Z=pPX6pGh|^49Ywstm%#C`#Zg#<$SHs|+@&+r4l0k$G#FN(_9oQe#x(evq`V2jYS zLJ@?=Jx4HD1ZfJBox7)Lg3(vm} z`c_A%C}Ea?n`bBO%cIsgL-GH#B3UV`sG!OabE%)LVMWGrd?)F=f;z*4X2wtHTKp~D zYD*mJ3@Rf(Ba=IhXA^C?uJ8{XD+oj&W0RpVZjdDzdi