A Minecraft server-side mod that adds various teleportation related commands
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "WIP 1.4.0, Started implementation of config file"

This reverts commit 5b11df654b25d89a6da33b8790c7b85fbf1cf56b.

+311 -568
-11
CHANGELOG.md
··· 4 4 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), 5 5 and this project kind of adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 6 7 - ### WIP [1.4.0] 8 - #### Changed 9 - - The loading logic of the storage file 10 - 11 - #### Added 12 - - **a config file!** 13 - - The config file starts at **version 0**! 14 - - versioning to the storage file for better handling of migrations. 15 - - We start at **version 1**, all previous version are version 0. 16 - 17 - 18 7 ### [1.3.4] 19 8 - Updated Italian translations (Thanks to [Jump-333](https://github.com/Jump-333)!) 20 9 - Turned DeathLocation into a Hashmap
+14 -17
README.md
··· 4 4 5 5 Here is the [Changelog](https://github.com/MrSn0wy/TeleportCommands/blob/main/CHANGELOG.md) 6 6 7 - ## Currently available commands: 7 + ### Currently available commands: 8 8 9 9 - `/worldspawn [<Disable Safety>]` - Teleports you to the world spawn (in the overworld), if given true it will not do safety checks 10 10 - `/back [<Disable Safety>]` - Teleports you to the location where you last died, if given true it will not do safety checks ··· 32 32 33 33 <br> 34 34 35 - ## TODO: 36 - ### Planned commands: 35 + ### TODO: 36 + #### Planned commands: 37 37 - [ ] `/wild` - Teleports you to a random location in the Overworld 38 38 - [x] `/worldspawn` - Teleports you to the worldspawn 39 - - [ ] `/spawn <dimension>` - Teleports you to your spawn point in a dimension, defaults to your current dimension 39 + - [ ] `/spawn <dimension>` - Teleports you to your spawnpoint in a dimension, defaults to your current dimension 40 40 - [ ] `/previous` - Go to the last teleported location 41 41 42 - ### Improvements: 42 + #### Improvements: 43 43 - [ ] Look into changing the mod into the more safe and sane kotlin (I love java) 44 44 - [ ] Add game tests 45 45 - [ ] Find the easiest way to backport the mod to older version (help) ··· 56 56 - [x] Add Quilt support and NeoForge 57 57 58 58 59 - ## Want to help? 59 + ### Want to help? 60 60 1. You can create a translation file so other people can use the mod in their native language: [translations.md](./common/src/main/resources/assets/teleport_commands/lang/translations.md) 61 61 62 62 63 - ## How to build 64 - ### Getting the correct environment 65 - #### Nixos 63 + ### How to build 64 + #### Getting the correct environment 66 65 If you are on nixos you can simply go into the folder of where you cloned the repo, and run `nix develop .`. This will give you the environment I use (apart from the IDE) :3. 67 66 68 - #### Generic linux 69 67 On any other linux distro, just install the jetbrains jdk, or try openjdk21. 70 68 71 - #### Windows 72 - On windows probably go to the openjdk website and install the 21 version? Idk goodluck. 69 + On windows probably go to the openjdk website and install the 21 version? idk goodluck. 73 70 74 - ### Building 75 - Then on linux just run `./gradlew build`. To make it into a single mod jar just run `./gradlew mergeJars`. 71 + #### Building 72 + Then on linux just do `./gradlew build` and to make it in a single mod jar `./gradlew mergeJars`. 76 73 77 74 Or on windows, just do `.\gradlew.bat build` and `.\gradlew.bat mergeJars`. 78 75 Note that this isn't tested for windows, but I think that is how it works. 79 76 80 - ### Getting the jars 77 + #### Getting the jars 81 78 Then you can find your jars in `fabric/build/libs/` (for fabric), `neoforge/build/libs/` (for neoforge) or `merged/build/libs/` (if you made the merged jar file). 82 79 83 80 If you have any issues just make an issue or contact me on Discord `@mrsnowy_` 84 81 85 - ## Random notes lol 86 - Text Colors: 82 + ### Notes 83 + Colors: 87 84 - Green = When something succeeds and an action will happen 88 85 - Aqua = When something needs attention 89 86 - White = When something is done
+1 -1
common/build.gradle
··· 37 37 artifacts { 38 38 commonJava sourceSets.main.java.sourceDirectories.singleFile 39 39 commonResources sourceSets.main.resources.sourceDirectories.singleFile 40 - } 40 + }
+181 -5
common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
··· 5 5 import dev.mrsnowy.teleport_commands.storage.StorageManager; 6 6 import dev.mrsnowy.teleport_commands.commands.*; 7 7 import dev.mrsnowy.teleport_commands.storage.DeathLocationStorage; 8 - import dev.mrsnowy.teleport_commands.storage.ConfigManager; 9 8 import net.minecraft.commands.CommandSourceStack; 9 + import net.minecraft.commands.Commands; 10 10 import net.minecraft.server.MinecraftServer; 11 11 import net.minecraft.server.level.ServerPlayer; 12 12 import net.minecraft.world.level.storage.LevelResource; 13 - import net.minecraft.core.BlockPos; 13 + 14 14 import java.io.*; 15 + import java.nio.file.Files; 15 16 import java.nio.file.Path; 16 17 import java.nio.file.Paths; 18 + import java.nio.file.StandardOpenOption; 19 + 20 + import net.minecraft.core.BlockPos; 21 + 22 + import static dev.mrsnowy.teleport_commands.storage.StorageManager.*; 17 23 18 24 public class TeleportCommands { 19 25 public static String MOD_LOADER; ··· 30 36 CONFIG_DIR = Paths.get(System.getProperty("user.dir")).resolve("config"); // Construct the game directory path 31 37 SERVER = server; 32 38 33 - StorageManager.StorageInit(); // Initialize the storage file 34 - ConfigManager.ConfigInit(); 39 + StorageManager.STORAGE = storageValidator(); // Initialize the storage file 35 40 DeathLocationStorage.clearDeathLocations(); // Clear data of death locations. 41 + 36 42 } 37 43 38 44 // initialize commands, also allows me to easily disable any when there is a config ··· 42 48 tpa.register(dispatcher); 43 49 warp.register(dispatcher); 44 50 worldspawn.register(dispatcher); 45 - main.register(dispatcher); 46 51 } 47 52 48 53 // Runs when the playerDeath mixin calls it, updates the /back command position ··· 53 58 54 59 DeathLocationStorage.setDeathLocation(uuid, pos, world); 55 60 } 61 + 62 + // cleans and updates Storage to the newest "version". This is painful 63 + private static StorageClass storageValidator() { 64 + Constants.LOGGER.info("Cleaning and updating Storage!"); 65 + 66 + try { 67 + StorageInit(); 68 + 69 + long startFileSize = Files.size(StorageManager.STORAGE_FILE); 70 + 71 + FileReader reader = new FileReader(StorageManager.STORAGE_FILE.toString()); 72 + JsonElement jsonElement = JsonParser.parseReader(reader); 73 + 74 + if (jsonElement.isJsonObject()) { 75 + 76 + JsonObject mainJsonObject = jsonElement.getAsJsonObject(); 77 + JsonArray newWarpsArray = new JsonArray(); 78 + JsonArray newPlayersArray = new JsonArray(); 79 + 80 + // get the Warps list 81 + if (mainJsonObject.has("Warps") && mainJsonObject.get("Warps").isJsonArray()) { 82 + 83 + // Warps 84 + for (JsonElement warpElement : mainJsonObject.get("Warps").getAsJsonArray()) { 85 + 86 + // Warp 87 + if (warpElement.isJsonObject()) { 88 + JsonObject warp = warpElement.getAsJsonObject(); 89 + 90 + String warpName = warp.has("name") ? warp.get("name").getAsString() : ""; 91 + Integer warpX = warp.has("x") ? warp.get("x").getAsInt() : null; 92 + Integer warpY = warp.has("y") ? warp.get("y").getAsInt() : null; 93 + Integer warpZ = warp.has("z") ? warp.get("z").getAsInt() : null; 94 + String warpWorld = warp.has("world") ? warp.get("world").getAsString() : ""; 95 + 96 + // check if it is valid 97 + if (!warpName.isBlank() && !warpWorld.isBlank() && warpX != null && warpY != null && warpZ != null) { 98 + JsonObject newWarp = new JsonObject(); 99 + 100 + newWarp.addProperty("name", warpName); 101 + newWarp.addProperty("x", warpX); 102 + newWarp.addProperty("y", warpY); 103 + newWarp.addProperty("z", warpZ); 104 + newWarp.addProperty("world", warpWorld); 105 + 106 + newWarpsArray.add(newWarp); 107 + } 108 + } 109 + } 110 + } 111 + 112 + 113 + // get the Players list 114 + if (mainJsonObject.has("Players") && mainJsonObject.get("Players").isJsonArray()) { 115 + 116 + // players 117 + for (JsonElement playerElement : mainJsonObject.get("Players").getAsJsonArray()) { 118 + 119 + // player 120 + if (playerElement.isJsonObject()) { 121 + 122 + JsonObject player = playerElement.getAsJsonObject(); 123 + boolean hasInformation = false; 124 + 125 + String UUID = player.has("Player_UUID") 126 + ? player.get("Player_UUID").getAsString() : (player.has("UUID") 127 + ? player.get("UUID").getAsString() : null); 128 + 129 + String DefaultHome = player.has("DefaultHome") 130 + ? player.get("DefaultHome").getAsString() : ""; 131 + 132 + JsonArray homes = new JsonArray(); 133 + 134 + if (player.has("Homes") && player.get("Homes").isJsonArray() ) { 135 + JsonArray tempHomes = player.get("Homes").getAsJsonArray(); 136 + boolean defaultHomeFound = false; 137 + 138 + 139 + for (JsonElement homeElement : tempHomes) { 140 + if (homeElement.isJsonObject()) { 141 + JsonObject home = homeElement.getAsJsonObject(); 142 + 143 + String homeName = home.has("name") 144 + ? home.get("name").getAsString() : ""; 145 + 146 + // upgrade doubles to int 147 + Integer homeX = home.has("x") && home.get("x").isJsonPrimitive() && home.get("x").getAsJsonPrimitive().isNumber() 148 + ? (int) Math.floor(home.get("x").getAsDouble()) : null; 149 + 150 + Integer homeY = home.has("y") && home.get("y").isJsonPrimitive() && home.get("y").getAsJsonPrimitive().isNumber() 151 + ? (int) Math.floor(home.get("y").getAsDouble()) : null; 152 + 153 + Integer homeZ = home.has("z") && home.get("z").isJsonPrimitive() && home.get("z").getAsJsonPrimitive().isNumber() 154 + ? (int) Math.floor(home.get("z").getAsDouble()) : null; 155 + 156 + String homeWorld = home.has("world") 157 + ? home.get("world").getAsString() : ""; 158 + 159 + // check if it is valid 160 + if (!homeName.isBlank() && !homeWorld.isBlank() && homeX != null && homeY != null && homeZ != null) { 161 + 162 + // check if it is the default home 163 + if (!DefaultHome.isBlank() && homeName.equals(DefaultHome)) { 164 + defaultHomeFound = true; 165 + } 166 + 167 + JsonObject newHome = new JsonObject(); 168 + 169 + newHome.addProperty("name", homeName); 170 + newHome.addProperty("x", homeX); 171 + newHome.addProperty("y", homeY); 172 + newHome.addProperty("z", homeZ); 173 + newHome.addProperty("world", homeWorld); 174 + 175 + homes.add(newHome); 176 + hasInformation = true; 177 + } 178 + } 179 + } 180 + 181 + // clean DefaultHome if there is no home with the name 182 + if (!defaultHomeFound) { 183 + DefaultHome = ""; 184 + } 185 + } 186 + 187 + // if it isn't empty it gets added to the newPlayersArray 188 + if ((UUID != null && !UUID.isBlank()) && hasInformation) { 189 + 190 + JsonObject newPlayer = new JsonObject(); 191 + 192 + newPlayer.addProperty("UUID", UUID); 193 + newPlayer.addProperty("DefaultHome", DefaultHome); 194 + newPlayer.add("Homes", homes); 195 + 196 + newPlayersArray.add(newPlayer); 197 + } 198 + } 199 + } 200 + } 201 + 202 + // save the cleaned and updated file 203 + mainJsonObject.remove("Warps"); 204 + mainJsonObject.add("Warps", newWarpsArray); 205 + 206 + mainJsonObject.remove("Players"); 207 + mainJsonObject.add("Players", newPlayersArray); 208 + 209 + // save the cleaned database 210 + Gson gson = new GsonBuilder().create(); 211 + byte[] json = gson.toJson(mainJsonObject).getBytes(); 212 + Files.write(StorageManager.STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); 213 + 214 + // Only show amount cleaned when it isn't 0B lool 215 + int diff = Math.round(( startFileSize - Files.size(StorageManager.STORAGE_FILE) )); 216 + 217 + if (diff > 0) { 218 + Constants.LOGGER.info("Success! Cleaned: {}B", diff); 219 + } else { 220 + Constants.LOGGER.info("Success!"); 221 + } 222 + 223 + return gson.fromJson(mainJsonObject, StorageManager.StorageClass.class); 224 + } 225 + 226 + } catch (IOException e) { 227 + Constants.LOGGER.error("Error while cleaning the database!", e); 228 + } 229 + 230 + return null; 231 + } 56 232 }
+76 -138
common/src/main/java/dev/mrsnowy/teleport_commands/commands/main.java
··· 1 - package dev.mrsnowy.teleport_commands.commands; 2 - 3 - import com.mojang.brigadier.CommandDispatcher; 4 - import com.mojang.brigadier.arguments.StringArgumentType; 5 - import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; 6 - import com.mojang.brigadier.suggestion.SuggestionProvider; 7 - import dev.mrsnowy.teleport_commands.Constants; 8 - import dev.mrsnowy.teleport_commands.TeleportCommands; 9 - import dev.mrsnowy.teleport_commands.storage.ConfigManager; 10 - import net.minecraft.ChatFormatting; 11 - import net.minecraft.commands.CommandSourceStack; 12 - import net.minecraft.commands.Commands; 13 - import net.minecraft.commands.SharedSuggestionProvider; 14 - import net.minecraft.network.chat.Component; 15 - import net.minecraft.network.chat.MutableComponent; 16 - import net.minecraft.server.level.ServerPlayer; 17 - 18 - import java.util.Arrays; 19 - 20 - import static dev.mrsnowy.teleport_commands.utils.tools.*; 21 - 22 - public class main { 23 - 24 - // TODO! Make this automatically generate based on the commands we have 25 - private static final String[] available_commands = { 26 - "back", 27 - "home", 28 - "tpa", 29 - "warp", 30 - "worldspawn" 31 - }; 32 - 33 - // sum lists 34 - private static final String[] enabled_commands = available_commands; // TODO! get enabled commands 35 - private static final String[] disabled_commands = available_commands; // TODO! get disabled commands 36 - 37 - // Create sum suggestion providers 38 - private static final SuggestionProvider<CommandSourceStack> disabled_commands_suggester = (context, builder) -> SharedSuggestionProvider.suggest(disabled_commands, builder); 39 - private static final SuggestionProvider<CommandSourceStack> enabled_commands_suggester = (context, builder) -> SharedSuggestionProvider.suggest(enabled_commands, builder); 40 - 41 - 42 - public static void register(CommandDispatcher<CommandSourceStack> dispatcher) { 43 - 44 - dispatcher.register(Commands.literal("teleportcommands") 45 - .then(Commands.literal("reloadConfig") 46 - .executes(context -> { 47 - try { 48 - ConfigManager.ConfigLoader(); 49 - } catch (Exception e) { 50 - Constants.LOGGER.error("Failed to reload config!", e); 51 - throw new SimpleCommandExceptionType(Component.literal(e.toString())).create(); 52 - } 53 - return 0; 54 - })) 55 - .then(Commands.literal("disable") 56 - .then(Commands.argument("command", StringArgumentType.word()) 57 - .suggests(enabled_commands_suggester) 58 - .requires(source -> source.hasPermission(4)) // Require OP 59 - .requires(source -> source.getPlayer() != null) 60 - .executes(context -> { 61 - final ServerPlayer player = context.getSource().getPlayerOrException(); 62 - final String string = StringArgumentType.getString(context, "command"); 63 - 64 - // todo! maybe move this check outside for reusability? 65 - if (!Arrays.asList(enabled_commands).contains(string)) { 66 - // TODO! make this translatable 67 - throw new SimpleCommandExceptionType(Component.literal("\"" + string + "\" is not available as an command!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 68 - } 69 - 70 - try { 71 - player.displayClientMessage(Component.literal("meow " + string), true); 72 - 73 - } catch (Exception e) { 74 - Constants.LOGGER.error("Error while disabling a command! => ", e); 75 - // TODO replace the error below with something normal? 76 - throw new SimpleCommandExceptionType(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 77 - } 78 - return 0; 79 - }) 80 - )) 81 - .then(Commands.literal("enable") 82 - .then(Commands.argument("command", StringArgumentType.word()) 83 - .suggests(disabled_commands_suggester) 84 - .requires(source -> source.hasPermission(4)) // Require OP 85 - .requires(source -> source.getPlayer() != null) 86 - .executes(context -> { 87 - final ServerPlayer player = context.getSource().getPlayerOrException(); 88 - final String string = StringArgumentType.getString(context, "command"); 89 - 90 - // todo! maybe move this check outside for reusability? 91 - if (!Arrays.asList(disabled_commands).contains(string)) { 92 - // TODO! make this translatable 93 - throw new SimpleCommandExceptionType(Component.literal("\"" + string + "\" is not available as an command!")).create(); 94 - } 95 - 96 - try { 97 - player.displayClientMessage(Component.literal("meow " + string), true); 98 - 99 - } catch (Exception e) { 100 - Constants.LOGGER.error("Error while disabling a command! => ", e); 101 - // TODO replace the error below with something normal? 102 - throw new SimpleCommandExceptionType(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 103 - } 104 - return 0; 105 - }) 106 - )) 107 - // Todo! Is this still needed? 108 - .then(Commands.literal("reload") 109 - .requires(source -> source.hasPermission(4)) // Require OP 110 - .executes(context -> { 111 - TeleportCommands.registerCommands(context.getSource().dispatcher()); 112 - return 0; 113 - })) 114 - 115 - .then(Commands.literal("help") 116 - .executes(context -> { 117 - context.getSource().sendSuccess(main::printCommands, false); 118 - return 0; 119 - })) 120 - ); 121 - } 122 - 123 - 124 - // ----- 125 - 126 - 127 - private static MutableComponent printCommands() { 128 - MutableComponent message = Component.empty(); 129 - 130 - message.append(Component.literal("Thank you for using Teleport Commands (V" + Constants.VERSION + ")!").withStyle(ChatFormatting.AQUA)); 131 - message.append(Component.literal("Teleport Commands is a server-side mod that adds various teleportation related commands").withStyle(ChatFormatting.AQUA)); 132 - 133 - message.append(Component.literal("----").withStyle(ChatFormatting.AQUA)); 134 - message.append(Component.literal("Usage:").withStyle(ChatFormatting.AQUA)); 135 - 136 - return message; 137 - } 138 - } 1 + //package dev.mrsnowy.teleport_commands.commands; 2 + // 3 + //import com.mojang.brigadier.arguments.BoolArgumentType; 4 + //import dev.mrsnowy.teleport_commands.TeleportCommands; 5 + //import dev.mrsnowy.teleport_commands.common.DeathLocation; 6 + //import dev.mrsnowy.teleport_commands.storage.DeathLocationStorage; 7 + //import net.minecraft.ChatFormatting; 8 + //import net.minecraft.commands.Commands; 9 + //import net.minecraft.core.BlockPos; 10 + //import net.minecraft.network.chat.ClickEvent; 11 + //import net.minecraft.network.chat.Component; 12 + //import net.minecraft.server.level.ServerLevel; 13 + //import net.minecraft.server.level.ServerPlayer; 14 + //import net.minecraft.world.phys.Vec3; 15 + // 16 + //import java.util.Optional; 17 + // 18 + //import static dev.mrsnowy.teleport_commands.utils.tools.*; 19 + //import static net.minecraft.commands.Commands.argument; 20 + // 21 + //// TODO! add option to reload registered commands! 22 + // 23 + //public class main { 24 + // 25 + // public static void register(Commands commandManager) { 26 + // 27 + // commandManager.getDispatcher().register(Commands.literal("teleportcommands") 28 + // .then(Commands.literal("help") 29 + // .requires(source -> source.getPlayer() != null) 30 + // .executes(context -> { 31 + // final ServerPlayer player = context.getSource().getPlayerOrException(); 32 + // 33 + // try { 34 + // printCommands(player); 35 + // 36 + // } catch (Exception e) { 37 + // TeleportCommands.LOGGER.error("Error while going back! => ", e); 38 + // player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 39 + // return 1; 40 + // } 41 + // return 0; 42 + // })) 43 + // .then(argument("Disable Safety", BoolArgumentType.bool()) 44 + // .requires(source -> source.getPlayer() != null) 45 + // .executes(context -> { 46 + // final boolean safety = BoolArgumentType.getBool(context, "Disable Safety"); 47 + // final ServerPlayer player = context.getSource().getPlayerOrException(); 48 + // 49 + // try { 50 + //// ToDeathLocation(player, safety); 51 + // 52 + // } catch (Exception e) { 53 + // TeleportCommands.LOGGER.error("Error while going back! => ", e); 54 + // player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 55 + // return 1; 56 + // } 57 + // return 0; 58 + // })) 59 + // ); 60 + // } 61 + // 62 + // 63 + // // ----- 64 + // 65 + // 66 + // // Gets the DeathLocation of the player and teleports the player to it 67 + // private static void printCommands(ServerPlayer player) throws Exception { 68 + // 69 + // player.displayClientMessage(Component.literal("Thank you for using Teleport Commands (V)!").withStyle(ChatFormatting.AQUA), false); 70 + // player.displayClientMessage(Component.literal("Teleport Commands is a server-side mod that adds various teleportation related commands").withStyle(ChatFormatting.AQUA), false); 71 + // 72 + // player.displayClientMessage(Component.literal("----").withStyle(ChatFormatting.AQUA), false); 73 + // 74 + // player.displayClientMessage(Component.literal("Usage:").withStyle(ChatFormatting.AQUA), false); 75 + // } 76 + //}
-9
common/src/main/java/dev/mrsnowy/teleport_commands/common/ModCommand.java
··· 1 - package dev.mrsnowy.teleport_commands.common; 2 - 3 - public enum ModCommand { 4 - back, 5 - home, 6 - tpa, 7 - warp, 8 - worldspawn, 9 - }
+1
common/src/main/java/dev/mrsnowy/teleport_commands/common/Player.java
··· 1 1 package dev.mrsnowy.teleport_commands.common; 2 2 3 3 import dev.mrsnowy.teleport_commands.storage.StorageManager; 4 + import net.minecraft.core.BlockPos; 4 5 5 6 import java.util.ArrayList; 6 7 import java.util.List;
-252
common/src/main/java/dev/mrsnowy/teleport_commands/storage/ConfigManager.java
··· 1 - package dev.mrsnowy.teleport_commands.storage; 2 - 3 - import com.google.gson.*; 4 - import dev.mrsnowy.teleport_commands.Constants; 5 - import dev.mrsnowy.teleport_commands.TeleportCommands; 6 - 7 - import java.io.FileReader; 8 - import java.nio.file.Files; 9 - import java.nio.file.Path; 10 - import java.nio.file.StandardOpenOption; 11 - 12 - public class ConfigManager { 13 - public static Path CONFIG_FILE; 14 - public static ConfigClass CONFIG; 15 - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); 16 - private static final int defaultVersion = new ConfigClass().getVersion(); 17 - 18 - public static void ConfigInit() { 19 - CONFIG_FILE = TeleportCommands.CONFIG_DIR.resolve("teleport_commands.json"); 20 - 21 - try { 22 - ConfigLoader(); 23 - 24 - } catch (Exception e) { 25 - // crashing is probably better here, otherwise the whole mod will be broken 26 - Constants.LOGGER.error("Error while initializing the config file! Exiting! => ", e); 27 - throw new RuntimeException("Error while initializing the config file! Exiting! => ", e); 28 - } 29 - } 30 - 31 - public static void ConfigLoader() throws Exception { 32 - if (!CONFIG_FILE.toFile().exists() || CONFIG_FILE.toFile().length() == 0) { 33 - Files.createDirectories(TeleportCommands.CONFIG_DIR); 34 - 35 - Constants.LOGGER.warn("Config file was not found or was empty! Initializing config"); 36 - CONFIG = new ConfigClass(); 37 - ConfigSaver(); 38 - Constants.LOGGER.info("Config created successfully!"); 39 - } 40 - 41 - ConfigMigrator(); 42 - 43 - FileReader reader = new FileReader(CONFIG_FILE.toFile()); 44 - CONFIG = GSON.fromJson(reader, ConfigClass.class); 45 - if (CONFIG == null) { 46 - Constants.LOGGER.warn("Config file was empty! Loading defaults..."); 47 - CONFIG = new ConfigClass(); 48 - ConfigSaver(); 49 - } 50 - 51 - ConfigSaver(); // Save it so any missing values get added to the file. 52 - Constants.LOGGER.info("Config loaded successfully!"); 53 - } 54 - 55 - /// This function checks what version the config file is and migrates it to the current version of the mod. 56 - public static void ConfigMigrator() throws Exception { 57 - FileReader reader = new FileReader(CONFIG_FILE.toFile()); 58 - JsonObject jsonObject = GSON.fromJson(reader, JsonObject.class); 59 - 60 - int version = jsonObject.has("version") ? jsonObject.get("version").getAsInt() : 0; 61 - 62 - if (version < defaultVersion) { 63 - // Constants.LOGGER.warn("Config file is v{}, migrating to v{}!", version, defaultVersion); 64 - // 65 - // // Save the storage :3 66 - // byte[] json = GSON.toJson(jsonObject, JsonArray.class).getBytes(); 67 - // Files.write(CONFIG_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); 68 - // 69 - // Constants.LOGGER.info("Config file migrated to v{} successfully!", defaultVersion); 70 - } else if (version > defaultVersion) { 71 - String message = String.format("Teleport Commands: The config file's version is newer than the supported version, found v%s, expected <= v%s.\n" + 72 - "If you intentionally backported then you can attempt to downgrade the config file located at this location: \"%s\".\n", 73 - version, defaultVersion, CONFIG_FILE.toAbsolutePath()); 74 - 75 - throw new IllegalStateException(message); 76 - } 77 - } 78 - 79 - public static void ConfigSaver() throws Exception { 80 - // todo! maybe throttle saves? 81 - byte[] json = GSON.toJson( ConfigManager.CONFIG ).getBytes(); 82 - 83 - Files.write(CONFIG_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); 84 - } 85 - 86 - public static class ConfigClass { 87 - private final int version = 0; 88 - public Teleporting teleporting = new Teleporting(); 89 - public Back back = new Back(); 90 - public Home home = new Home(); 91 - public Tpa tpa = new Tpa(); 92 - public Warp warp = new Warp(); 93 - public WorldSpawn worldSpawn = new WorldSpawn(); 94 - 95 - public int getVersion() { 96 - return version; 97 - } 98 - 99 - public static final class Teleporting { 100 - private int delay = 5; 101 - private boolean whileMoving = true; 102 - private boolean whileFighting = false; 103 - private int fightCooldown = 10; 104 - 105 - public int getDelay() { 106 - return delay; 107 - } 108 - 109 - public void setDelay(int delay) { 110 - this.delay = delay; 111 - } 112 - 113 - public boolean isWhileMoving() { 114 - return whileMoving; 115 - } 116 - 117 - public void setWhileMoving(boolean whileMoving) { 118 - this.whileMoving = whileMoving; 119 - } 120 - 121 - public boolean isWhileFighting() { 122 - return whileFighting; 123 - } 124 - 125 - public void setWhileFighting(boolean whileFighting) { 126 - this.whileFighting = whileFighting; 127 - } 128 - 129 - public int getFightCooldown() { 130 - return fightCooldown; 131 - } 132 - 133 - public void setFightCooldown(int fightCooldown) { 134 - this.fightCooldown = fightCooldown; 135 - } 136 - } 137 - 138 - public final class Back { 139 - private boolean enabled = true; 140 - private boolean deleteAfterTeleport = false; 141 - 142 - public boolean isEnabled() { 143 - return enabled; 144 - } 145 - 146 - public void setEnabled(boolean enabled) { 147 - this.enabled = enabled; 148 - } 149 - 150 - public boolean isDeleteAfterTeleport() { 151 - return deleteAfterTeleport; 152 - } 153 - 154 - public void setDeleteAfterTeleport(boolean deleteAfterTeleport) { 155 - this.deleteAfterTeleport = deleteAfterTeleport; 156 - } 157 - } 158 - 159 - public final class Home { 160 - private boolean enabled = true; 161 - private int playerMaximum = 20; 162 - private boolean deleteInvalid = false; 163 - 164 - public boolean isEnabled() { 165 - return enabled; 166 - } 167 - 168 - public void setEnabled(boolean enabled) { 169 - this.enabled = enabled; 170 - } 171 - 172 - public int getPlayerMaximum() { 173 - return playerMaximum; 174 - } 175 - 176 - public void setPlayerMaximum(int playerMaximum) { 177 - this.playerMaximum = playerMaximum; 178 - } 179 - 180 - public boolean isDeleteInvalid() { 181 - return deleteInvalid; 182 - } 183 - 184 - public void setDeleteInvalid(boolean deleteInvalid) { 185 - this.deleteInvalid = deleteInvalid; 186 - } 187 - } 188 - 189 - public final class Tpa { 190 - private boolean enabled = true; 191 - 192 - public boolean isEnabled() { 193 - return enabled; 194 - } 195 - 196 - public void setEnabled(boolean enabled) { 197 - this.enabled = enabled; 198 - } 199 - } 200 - 201 - public final class Warp { 202 - private boolean enabled = true; 203 - private boolean deleteInvalid = false; 204 - 205 - public boolean isEnabled() { 206 - return enabled; 207 - } 208 - 209 - public void setEnabled(boolean enabled) { 210 - this.enabled = enabled; 211 - } 212 - 213 - public boolean isDeleteInvalid() { 214 - return deleteInvalid; 215 - } 216 - 217 - public void setDeleteInvalid(boolean deleteInvalid) { 218 - this.deleteInvalid = deleteInvalid; 219 - } 220 - } 221 - 222 - public final class WorldSpawn { 223 - private boolean enabled = true; 224 - private String world_id = "minecraft:overworld"; 225 - 226 - public boolean isEnabled() { 227 - return enabled; 228 - } 229 - 230 - public void setEnabled(boolean enabled) { 231 - this.enabled = enabled; 232 - } 233 - 234 - public String getWorld_id() { 235 - return world_id; 236 - } 237 - 238 - public void setWorld_id(String world_id) { 239 - this.world_id = world_id; 240 - } 241 - } 242 - } 243 - 244 - // --- Ideas! --- 245 - // Make config options for disabling certain commands 246 - // Make config options for renaming certain commands 247 - // Make config option for changing required permission level for certain commands 248 - // Make config for setting max homes 249 - // Make config that adds a delay between teleports and when fighting. (in teleport function?) 250 - // Make config that automatically deletes namedLocations (warps/homes) with invalid world id's 251 - // Make config for setting the world_id for /worldspawn ? 252 - }
+23 -123
common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
··· 1 1 package dev.mrsnowy.teleport_commands.storage; 2 2 3 - import com.google.gson.*; 3 + import com.google.gson.Gson; 4 + import com.google.gson.GsonBuilder; 4 5 import dev.mrsnowy.teleport_commands.Constants; 5 6 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 7 import dev.mrsnowy.teleport_commands.common.NamedLocation; 7 8 import dev.mrsnowy.teleport_commands.common.Player; 8 9 9 - import java.io.FileReader; 10 + import java.io.File; 10 11 import java.nio.file.Files; 11 12 import java.nio.file.Path; 12 13 import java.nio.file.StandardOpenOption; ··· 21 22 public static Path STORAGE_FOLDER; 22 23 public static Path STORAGE_FILE; 23 24 public static StorageClass STORAGE; 24 - private static final Gson GSON = new GsonBuilder().create(); 25 - private static final int defaultVersion = new StorageClass().getVersion(); 26 25 27 - /// Initializes the StorageManager class and loads the storage from the filesystem. 28 26 public static void StorageInit() { 29 27 STORAGE_FOLDER = TeleportCommands.SAVE_DIR.resolve("TeleportCommands/"); 30 28 STORAGE_FILE = STORAGE_FOLDER.resolve("storage.json"); 31 29 32 30 try { 33 - StorageLoader(); 34 - 35 - } catch (Exception e) { 36 - // crashing is probably better here, otherwise the whole mod will be broken 37 - Constants.LOGGER.error("Error while initializing the storage file! Exiting! => ", e); 38 - throw new RuntimeException("Error while initializing the storage file! Exiting! => ", e); 39 - } 40 - } 41 - 42 - /// Loads the storage from the filesystem 43 - public static void StorageLoader() throws Exception { 44 - 45 - if (!STORAGE_FILE.toFile().exists() || STORAGE_FILE.toFile().length() == 0) { 46 - Constants.LOGGER.warn("Storage file was not found or was empty! Initializing storage"); 47 - 48 - Files.createDirectories(STORAGE_FOLDER); 49 - STORAGE = new StorageClass(); 50 - StorageSaver(); 51 - Constants.LOGGER.info("Storage created successfully!"); 52 - } 53 - 54 - StorageMigrator(); 55 - 56 - FileReader reader = new FileReader(STORAGE_FILE.toFile()); 57 - STORAGE = GSON.fromJson(reader, StorageClass.class); 58 - if (STORAGE == null) { 59 - Constants.LOGGER.warn("Storage file was empty! Initializing storage"); 60 - STORAGE = new StorageClass(); 61 - StorageSaver(); 62 - } 63 - 64 - STORAGE.cleanup(); 65 - 66 - StorageSaver(); // Save it so any missing values get added to the file. 67 - Constants.LOGGER.info("Storage loaded successfully!"); 68 - } 69 - 70 - /// This function checks what version the storage file is and migrates it to the current version of the mod. 71 - public static void StorageMigrator() throws Exception { 72 - FileReader reader = new FileReader(STORAGE_FILE.toFile()); 73 - JsonObject jsonObject = GSON.fromJson(reader, JsonObject.class); 74 - 75 - int version = jsonObject.has("version") ? jsonObject.get("version").getAsInt() : 0; 76 - 77 - if (version < defaultVersion) { 78 - Constants.LOGGER.warn("Storage file is v{}, migrating to v{}!", version, defaultVersion); 79 - 80 - // In v1.1.0 "Player_UUID" got renamed to "UUID". Since the storage file didn't have a version yet, it is set to version 0. 81 - if (version == 0) { 82 - 83 - if (jsonObject.has("Players") && jsonObject.get("Players").isJsonArray()) { 84 - 85 - JsonArray players = jsonObject.get("Players").getAsJsonArray(); 86 - 87 - for (JsonElement playerElement : players) { 88 - JsonObject player = playerElement.getAsJsonObject(); 89 - 90 - String UUID = player.has("Player_UUID") 91 - ? player.get("Player_UUID").getAsString() : (player.has("UUID") 92 - ? player.get("UUID").getAsString() : null); 93 - 94 - if (UUID == null || UUID.isBlank()) { 95 - // remove it then, it's an invalid entry 0.0 96 - players.remove(player); // may return true or false for success, but idc 97 - 98 - } else { 99 - player.remove("Player_UUID"); 100 - player.addProperty("UUID", UUID); 101 - } 102 - } 103 - } 31 + // check if the folder exists and create it 32 + if (!Files.exists(STORAGE_FOLDER)) { 33 + Files.createDirectories(STORAGE_FOLDER); 34 + } 104 35 105 - jsonObject.addProperty("version", 1); 36 + // check if the file exists and create it 37 + if (!Files.exists(STORAGE_FILE)) { 38 + Files.createFile(STORAGE_FILE); 106 39 } 107 40 108 - // Save the storage :3 109 - byte[] json = GSON.toJson(jsonObject, JsonArray.class).getBytes(); 110 - Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); 111 - 112 - Constants.LOGGER.info("Storage file migrated to v{} successfully!", defaultVersion); 113 - } else if (version > defaultVersion) { 114 - String message = String.format("Teleport Commands: The storage file's version is newer than the supported version, found v%s, expected <= v%s.\n" + 115 - "If you intentionally backported then you can attempt to downgrade the storage file located at this location: \"%s\".\n", 116 - version, defaultVersion, STORAGE_FILE.toAbsolutePath()); 41 + // create the basic storage if it is empty 42 + if (new File(String.valueOf(STORAGE_FILE)).length() == 0) { 43 + StorageManager.STORAGE = new StorageClass(); 44 + StorageSaver(); // todo! verify that it creates em correctly 45 + } 117 46 118 - throw new IllegalStateException(message); 47 + } catch (Exception e) { 48 + Constants.LOGGER.error("Error while creating the storage file! Exiting! => ", e); 49 + // crashing is probably better here, otherwise the whole mod will be broken 50 + System.exit(1); 119 51 } 120 52 } 121 53 122 - /// Saves the storage to the filesystem 123 54 public static void StorageSaver() throws Exception { 124 55 // todo! maybe throttle saves? 125 - byte[] json = GSON.toJson( StorageManager.STORAGE ).getBytes(); 56 + Gson gson = new GsonBuilder().create(); 57 + byte[] json = gson.toJson( StorageManager.STORAGE ).getBytes(); 126 58 127 - Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); 59 + Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); 128 60 } 129 61 130 62 131 63 public static class StorageClass { 132 - private final int version = 1; 133 64 private final ArrayList<NamedLocation> Warps = new ArrayList<>(); 134 65 private final ArrayList<Player> Players = new ArrayList<>(); 135 66 136 - /// Cleans up any values in the storage class 137 - public void cleanup() throws Exception { 138 - for (Player player : Players) { 139 - // Remove players with invalid UUID's 140 - if (player.getUUID().isBlank()) { 141 - Players.remove(player); 142 - } 143 - 144 - List<NamedLocation> homes = player.getHomes(); 145 - 146 - // Delete any homes with an invalid world_id (if enabled in config) 147 - if (ConfigManager.CONFIG.home.isDeleteInvalid()) { 148 - homes.removeIf(home -> home.getWorld().isEmpty()); 149 - } 150 - 151 - // Remove players with no homes 152 - if (homes.isEmpty()) { 153 - Players.remove(player); 154 - } 155 - } 156 - 157 - // Delete any warps with an invalid world_id (if enabled in config) 158 - if (ConfigManager.CONFIG.warp.isDeleteInvalid()) { 159 - Warps.removeIf(warp -> warp.getWorld().isEmpty()); 160 - } 161 - 162 - StorageSaver(); 163 - } 164 - 165 - public int getVersion() { 166 - return version; 167 - } 67 + // ----- 168 68 169 69 // returns all warps 170 70 public List<NamedLocation> getWarps() {
+14
common/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
··· 1 + package dev.mrsnowy.teleport_commands.storage; 2 + 3 + public class configManager { 4 + // Currently nothing to see here... yet 5 + 6 + // --- Ideas! --- 7 + // Make config options for disabling certain commands 8 + // Make config options for renaming certain commands 9 + // Make config option for changing required permission level for certain commands 10 + // Make config for setting max homes 11 + // Make config that adds a delay between teleports and when fighting. (in teleport function?) 12 + // Make config that automatically deletes namedLocations (warps/homes) with invalid world id's 13 + // Make config for setting the world_id for /worldspawn ? 14 + }
-1
flake.nix
··· 22 22 default = pkgs.mkShell { 23 23 packages = with pkgs; [ 24 24 jetbrains.jdk-no-jcef # Jetbrains jdk 25 - just # for the justfile 26 25 flite # Make mc not complain 27 26 28 27 # Took these from https://github.com/NixOS/nixpkgs/blob/nixos-25.05/pkgs/by-name/pr/prismlauncher/package.nix#L123
+1 -11
justfile
··· 1 - # A justfile :3 2 - 3 - build: 4 - ./gradlew build 5 - 6 - clean: 7 - ./gradlew clean 8 - 9 - mergeJars: 10 - ./gradlew mergeJars 11 1 12 2 ide: 13 - nohup idea ./ >/dev/null 2>&1 & 3 + nohup idea-ultimate ./ >/dev/null 2>&1 &