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.

Revamped translation file loading + other stuffz

MrSnowy 8c56645d 6745e07e

+442 -413
+3 -2
CHANGELOG.md
··· 8 8 #### Changed 9 9 - the loading logic of the storage file. 10 10 - most static classes to non-static, should prevent leaks. 11 - - Changed out java Timers for a tick-based timer. 11 + - changed out java Timers for a tick-based timer (so that it follows the server tick speed). 12 + - fixed the before-teleportation effects not being sent into the correct dimension when switching dimension. 12 13 13 14 #### Added 14 15 - **a config file!** 15 16 - The config file starts at **version 0**! 16 17 - versioning to the storage file for better handling of migrations. 17 18 - We start at **version 1**, all previous version are version 0. 18 - 19 + - caching for loading the translation files! 19 20 20 21 ### [1.3.4] 21 22 - Updated Italian translations (Thanks to [Jump-333](https://github.com/Jump-333)!)
+1 -1
common/src/main/java/dev/mrsnowy/teleport_commands/Constants.java
··· 6 6 public class Constants { 7 7 public static final String MOD_ID = "teleport_commands"; 8 8 public static final String MOD_NAME = "Teleport Commands"; 9 - public static final String VERSION = "1.3.4"; 9 + public static final String VERSION = "1.4.0"; 10 10 11 11 public static final Logger LOGGER = LoggerFactory.getLogger(MOD_NAME); 12 12 }
+10 -10
common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
··· 4 4 import dev.mrsnowy.teleport_commands.storage.StorageManager; 5 5 import dev.mrsnowy.teleport_commands.commands.*; 6 6 import dev.mrsnowy.teleport_commands.storage.DeathLocationStorage; 7 - import dev.mrsnowy.teleport_commands.storage.configManager; 8 - import dev.mrsnowy.teleport_commands.utils.teleporter; 7 + import dev.mrsnowy.teleport_commands.storage.ConfigManager; 8 + import dev.mrsnowy.teleport_commands.utils.Teleporter; 9 9 import net.minecraft.commands.CommandSourceStack; 10 10 import net.minecraft.server.MinecraftServer; 11 11 import net.minecraft.server.level.ServerPlayer; ··· 22 22 public Path configDir; 23 23 public MinecraftServer server; 24 24 public StorageManager storageManager; 25 - public configManager config; 25 + public ConfigManager config; 26 26 public DeathLocationStorage deathLocationStorage; 27 - public teleporter teleporter; 27 + public Teleporter teleporter; 28 28 29 - // Gets ran when the server starts, initializes the mod :3 29 + /// Gets ran when the server starts, initializes the mod :3 30 30 public void initializeMod(MinecraftServer server) { 31 31 INSTANCE = this; 32 32 Constants.LOGGER.info("Initializing Teleport Commands (V{})! Hello {}!", Constants.VERSION, modLoader); ··· 36 36 this.server = server; 37 37 38 38 storageManager = new StorageManager(this); 39 - config = new configManager(this); 39 + config = new ConfigManager(this); 40 40 deathLocationStorage = new DeathLocationStorage(); 41 - teleporter = new teleporter(this); 41 + teleporter = new Teleporter(this); 42 42 } 43 43 44 - // initialize commands, also allows me to easily disable any when there is a config 44 + /// initialize commands, also allows me to easily disable any when there is a config 45 45 public void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher) { 46 - new back(dispatcher, this); 46 + back.register(dispatcher); 47 47 home.register(dispatcher); 48 48 new tpa(dispatcher, this); 49 49 new warp(dispatcher, this); ··· 51 51 main.register(dispatcher); 52 52 } 53 53 54 - // Runs when the playerDeath mixin calls it, updates the /back command position 54 + /// Runs when the playerDeath mixin calls it, updates the /back command position 55 55 public void onPlayerDeath(ServerPlayer player) { 56 56 BlockPos pos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 57 57 String world = player.serverLevel().dimension().location().toString();
+22 -37
common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java
··· 8 8 9 9 import dev.mrsnowy.teleport_commands.TeleportCommands; 10 10 import dev.mrsnowy.teleport_commands.common.DeathLocation; 11 - import dev.mrsnowy.teleport_commands.utils.tools; 11 + import dev.mrsnowy.teleport_commands.utils.Tools; 12 12 import net.minecraft.ChatFormatting; 13 13 import net.minecraft.commands.CommandSourceStack; 14 14 import net.minecraft.commands.Commands; 15 15 import net.minecraft.core.BlockPos; 16 - import net.minecraft.network.chat.ClickEvent; 17 - import net.minecraft.network.chat.Component; 16 + import net.minecraft.server.MinecraftServer; 18 17 import net.minecraft.server.level.ServerLevel; 19 18 import net.minecraft.server.level.ServerPlayer; 20 19 import net.minecraft.world.phys.Vec3; 21 20 22 - import static dev.mrsnowy.teleport_commands.utils.tools.*; 21 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 22 + import static dev.mrsnowy.teleport_commands.utils.Tools.*; 23 23 import static net.minecraft.commands.Commands.argument; 24 24 25 25 public class back { 26 - TeleportCommands teleportCommands; 27 26 28 - public back(CommandDispatcher<CommandSourceStack> commandDispatcher, TeleportCommands teleportCommands) { 29 - this.teleportCommands = teleportCommands; 27 + public static void register(CommandDispatcher<CommandSourceStack> commandDispatcher) { 30 28 31 29 commandDispatcher.register(Commands.literal("back") 32 30 .requires(source -> source.getPlayer() != null) 33 31 .executes(context -> { 34 - final ServerPlayer player = context.getSource().getPlayerOrException(); 32 + CommandSourceStack source = context.getSource(); 33 + ServerPlayer player = source.getPlayerOrException(); 35 34 36 35 try { 37 - ToDeathLocation(player, false); 36 + ToDeathLocation(player, player.server, false); 38 37 39 38 } catch (Exception e) { 40 39 Constants.LOGGER.error("Error while going back! => ", e); 41 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 40 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 42 41 return 1; 43 42 } 44 43 return 0; ··· 47 46 .requires(source -> source.getPlayer() != null) 48 47 .executes(context -> { 49 48 final boolean safety = BoolArgumentType.getBool(context, "Disable Safety"); 50 - final ServerPlayer player = context.getSource().getPlayerOrException(); 49 + ServerPlayer player = context.getSource().getPlayerOrException(); 51 50 52 51 try { 53 - ToDeathLocation(player, safety); 52 + ToDeathLocation(player, player.server, safety); 54 53 55 54 } catch (Exception e) { 56 55 Constants.LOGGER.error("Error while going back! => ", e); 57 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 56 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 58 57 return 1; 59 58 } 60 59 return 0; ··· 66 65 // ----- 67 66 68 67 // Gets the DeathLocation of the player and teleports the player to it 69 - private void ToDeathLocation(ServerPlayer player, boolean safetyDisabled) throws Exception { 68 + private static void ToDeathLocation(ServerPlayer player, MinecraftServer server, boolean safetyDisabled) throws Exception { 69 + TeleportCommands teleportCommands = TeleportCommands.INSTANCE; 70 + 70 71 DeathLocation deathLocation = teleportCommands.deathLocationStorage 71 72 .getDeathLocation(player.getStringUUID()) 72 73 .orElse(null); 73 74 74 75 if (deathLocation == null) { 75 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player).withStyle(ChatFormatting.RED), true); 76 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.noLocation", player).withStyle(ChatFormatting.RED), true); 76 77 return; 77 78 } 78 79 ··· 83 84 Constants.LOGGER.warn("({}) Error while going back! \nCouldn't find a world with the id: \"{}\" \nAvailable worlds: {}", 84 85 player.getName().getString(), 85 86 deathLocation.getWorldString(), 86 - tools.getWorldIds(teleportCommands.server)); 87 + Tools.getWorldIds(server)); 87 88 88 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.worldNotFound", player) 89 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.worldNotFound", player) 89 90 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 90 91 91 92 return; ··· 95 96 96 97 // Sets the teleportBlockPos based on if it should do safety checking 97 98 if (!safetyDisabled) { 98 - Optional<BlockPos> safeBlockPos = getSafeBlockPos(deathLocation.getBlockPos(), deathLocationWorld); 99 + Optional<BlockPos> safeBlockPos = Tools.getSafeBlockPos(deathLocation.getBlockPos(), deathLocationWorld); 99 100 100 101 // Check if there is a safe BlockPos 101 102 if (safeBlockPos.isEmpty()) { 102 - // asks the player if they want to teleport anyway 103 - player.displayClientMessage( 104 - Component.empty() 105 - .append(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player) 106 - .withStyle(ChatFormatting.RED, ChatFormatting.BOLD) 107 - ) 108 - .append("\n") 109 - .append(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player) 110 - .withStyle(ChatFormatting.WHITE) 111 - ) 112 - .append("\n") 113 - .append(getTranslatedText("commands.teleport_commands.common.forceTeleport", player) 114 - .withStyle(ChatFormatting.DARK_AQUA, ChatFormatting.BOLD) 115 - .withStyle(style -> style.withClickEvent(new ClickEvent.RunCommand("/back true"))) 116 - ) 117 - .append("\n"), false); 103 + Tools.sendSafetyWarning(player, "/back true"); 118 104 return; 119 105 120 106 } else { ··· 126 112 } 127 113 128 114 // check if the player is already at this location (in the same world) 129 - if (player.blockPosition().equals(teleportBlockPos) && player.level() == deathLocationWorld) { 130 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); 115 + if (player.blockPosition().equals(teleportBlockPos) && player.serverLevel() == deathLocationWorld) { 116 + player.displayClientMessage(getTranslation("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); 131 117 132 118 } else { 133 119 // teleport the player! 134 120 Vec3 teleportPos = new Vec3(teleportBlockPos.getX() + 0.5, teleportBlockPos.getY(), teleportBlockPos.getZ() + 0.5); 135 121 136 - // player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); 137 122 teleportCommands.teleporter.queue(player, deathLocationWorld, teleportPos, "commands.teleport_commands.back.go"); 138 123 } 139 124 }
+39 -41
common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java
··· 11 11 import java.util.List; 12 12 import java.util.Optional; 13 13 14 - import dev.mrsnowy.teleport_commands.utils.tools; 14 + import dev.mrsnowy.teleport_commands.utils.Tools; 15 15 import net.minecraft.ChatFormatting; 16 16 import net.minecraft.commands.CommandSourceStack; 17 17 import net.minecraft.commands.Commands; ··· 24 24 import net.minecraft.server.level.ServerPlayer; 25 25 import net.minecraft.world.phys.Vec3; 26 26 27 - import static dev.mrsnowy.teleport_commands.storage.StorageManager.STORAGE; 28 - import static dev.mrsnowy.teleport_commands.utils.tools.getTranslatedText; 27 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 29 28 import static net.minecraft.commands.Commands.argument; 30 - import static dev.mrsnowy.teleport_commands.utils.tools.Teleporter; 31 29 32 30 public class home { 33 31 public static void register(CommandDispatcher<CommandSourceStack> commandDispatcher) { ··· 44 42 45 43 } catch (Exception e) { 46 44 Constants.LOGGER.error("Error while setting a home! => ", e); 47 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 45 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 48 46 return 1; 49 47 } 50 48 return 0; ··· 61 59 62 60 } catch (Exception e) { 63 61 Constants.LOGGER.error("Error while going home! => ", e); 64 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 62 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 65 63 return 1; 66 64 } 67 65 return 0; ··· 78 76 79 77 } catch (Exception e) { 80 78 Constants.LOGGER.error("Error while going to a specific home! => ", e); 81 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 79 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 82 80 return 1; 83 81 } 84 82 return 0; ··· 97 95 98 96 } catch (Exception e) { 99 97 Constants.LOGGER.error("Error while deleting a home! => ", e); 100 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.deleteError", player) 98 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.deleteError", player) 101 99 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 102 100 return 1; 103 101 } ··· 119 117 120 118 } catch (Exception e) { 121 119 Constants.LOGGER.error("Error while renaming a home! => ", e); 122 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.renameError", player) 120 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.renameError", player) 123 121 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 124 122 return 1; 125 123 } ··· 139 137 140 138 } catch (Exception e) { 141 139 Constants.LOGGER.error("Error while setting the default home! => ", e); 142 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.defaultError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 140 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.defaultError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 143 141 return 1; 144 142 } 145 143 return 0; ··· 155 153 156 154 } catch (Exception e) { 157 155 Constants.LOGGER.error("Error while printing the homes! => ", e); 158 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.homes.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 156 + player.displayClientMessage(getTranslation("commands.teleport_commands.homes.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 159 157 return 1; 160 158 } 161 159 return 0; ··· 182 180 183 181 if (homeExists) { 184 182 // Display error message that the home already exists 185 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.exists", player).withStyle(ChatFormatting.RED), true); 183 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.exists", player).withStyle(ChatFormatting.RED), true); 186 184 187 185 } else { 188 186 // Set it as the default if there are no other homes ··· 191 189 } 192 190 193 191 // Display message that the home has been set 194 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.set", player), true); 192 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.set", player), true); 195 193 } 196 194 } 197 195 ··· 202 200 // Get player storage 203 201 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 204 202 if (optionalPlayerStorage.isEmpty()) { 205 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 203 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 206 204 return; 207 205 } 208 206 ··· 214 212 215 213 if (defaultHome.isEmpty()) { 216 214 // No default home set! 217 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.defaultNone", player).withStyle(ChatFormatting.AQUA), true); 215 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.defaultNone", player).withStyle(ChatFormatting.AQUA), true); 218 216 219 217 return; 220 218 } else { ··· 225 223 // Get the home (if it exists) 226 224 Optional<NamedLocation> optionalHome = playerStorage.getHome(homeName); 227 225 if (optionalHome.isEmpty()) { 228 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.AQUA), true); 226 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.AQUA), true); 229 227 return; 230 228 } 231 229 ··· 239 237 player.getName().getString(), 240 238 home.getName(), 241 239 home.getWorldString(), 242 - tools.getWorldIds()); 240 + Tools.getWorldIds()); 243 241 244 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.worldNotFound", player) 242 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.worldNotFound", player) 245 243 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 246 244 247 245 return; ··· 253 251 254 252 // Check if the player is already at this location (in the same world) 255 253 if (player.blockPosition().equals(teleportBlockPos) && player.level() == homeWorld) { 256 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.goSame", player).withStyle(ChatFormatting.AQUA), true); 254 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.goSame", player).withStyle(ChatFormatting.AQUA), true); 257 255 258 256 } else { 259 257 // Teleport the player! 260 258 Vec3 teleportPos = new Vec3(teleportBlockPos.getX() + 0.5, teleportBlockPos.getY(), teleportBlockPos.getZ() + 0.5); 261 259 262 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.go", player), true); 260 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.go", player), true); 263 261 Teleporter(player, homeWorld, teleportPos); 264 262 } 265 263 } ··· 270 268 // Gets player storage 271 269 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 272 270 if (optionalPlayerStorage.isEmpty()) { 273 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 271 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 274 272 return; 275 273 } 276 274 ··· 279 277 // Get the home from the player 280 278 Optional<NamedLocation> optionalHome = playerStorage.getHome(homeName); 281 279 if (optionalHome.isEmpty()) { 282 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 280 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 283 281 return; 284 282 } 285 283 ··· 293 291 // todo! maybe ask the player if they want to set a new default home? :3 294 292 } 295 293 296 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.delete", player), true); 294 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.delete", player), true); 297 295 } 298 296 299 297 private static void RenameHome(ServerPlayer player, String homeName, String newHomeName) throws Exception { ··· 303 301 // Gets player storage 304 302 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 305 303 if (optionalPlayerStorage.isEmpty()) { 306 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 304 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 307 305 return; 308 306 } 309 307 ··· 311 309 312 310 // Check if there already is a home with the new name 313 311 if (playerStorage.getHome(newHomeName).isPresent()) { 314 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.nameExists", player).withStyle(ChatFormatting.RED), true); 312 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.nameExists", player).withStyle(ChatFormatting.RED), true); 315 313 return; 316 314 } 317 315 318 316 // Get the home that needs to be renamed 319 317 Optional<NamedLocation> optionalHome = playerStorage.getHome(homeName); 320 318 if (optionalHome.isEmpty()) { 321 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 319 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 322 320 return; 323 321 } 324 322 ··· 330 328 playerStorage.setDefaultHome(newHomeName); 331 329 } 332 330 333 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.rename", player), true); 331 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.rename", player), true); 334 332 } 335 333 336 334 private static void SetDefaultHome(ServerPlayer player, String homeName) throws Exception { ··· 339 337 // Gets player storage 340 338 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 341 339 if (optionalPlayerStorage.isEmpty()) { 342 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 340 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 343 341 return; 344 342 } 345 343 ··· 347 345 348 346 // Check if the new default home exists 349 347 if ( playerStorage.getHome(homeName).isEmpty() ) { 350 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 348 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 351 349 return; 352 350 } 353 351 354 352 // Check if the home is already the default 355 353 if (playerStorage.getDefaultHome().equals(homeName)) { 356 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.defaultSame", player).withStyle(ChatFormatting.AQUA), true); 354 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.defaultSame", player).withStyle(ChatFormatting.AQUA), true); 357 355 return; 358 356 } 359 357 360 358 // set the new default 361 359 playerStorage.setDefaultHome(homeName); 362 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.default", player), true); 360 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.default", player), true); 363 361 } 364 362 365 363 private static void PrintHomes(ServerPlayer player) throws Exception { 366 364 // Gets player storage, if no storage then the player is homeless! 367 365 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 368 366 if (optionalPlayerStorage.isEmpty()) { 369 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 367 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 370 368 return; 371 369 } 372 370 ··· 376 374 377 375 // Check if there are any homes lol 378 376 if (homes.isEmpty()) { 379 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 377 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 380 378 return; 381 379 } 382 380 383 381 MutableComponent message = Component.empty(); 384 382 385 383 // make da message 386 - message.append(getTranslatedText("commands.teleport_commands.homes.homes", player) 384 + message.append(getTranslation("commands.teleport_commands.homes.homes", player) 387 385 .withStyle(ChatFormatting.YELLOW, ChatFormatting.BOLD) 388 386 ); 389 387 ··· 405 403 if (playerStorage.getDefaultHome().equals(currentHome.getName())) { 406 404 407 405 message.append(" ") 408 - .append(getTranslatedText("commands.teleport_commands.common.default", player) 406 + .append(getTranslation("commands.teleport_commands.common.default", player) 409 407 .withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) 410 408 ); 411 409 } ··· 429 427 .withStyle(style -> 430 428 style.withHoverEvent( 431 429 new HoverEvent.ShowText( 432 - getTranslatedText("commands.teleport_commands.common.hoverCopy", player) 430 + getTranslation("commands.teleport_commands.common.hoverCopy", player) 433 431 ) 434 432 ) 435 433 ) ··· 446 444 .withStyle(style -> 447 445 style.withHoverEvent( 448 446 new HoverEvent.ShowText( 449 - getTranslatedText("commands.teleport_commands.common.hoverCopy", player) 447 + getTranslation("commands.teleport_commands.common.hoverCopy", player) 450 448 ) 451 449 ) 452 450 ) ··· 459 457 message.append(Component.literal(" | ") 460 458 .withStyle(ChatFormatting.AQUA) 461 459 ) 462 - .append(getTranslatedText("commands.teleport_commands.common.tp", player) 460 + .append(getTranslation("commands.teleport_commands.common.tp", player) 463 461 .withStyle(ChatFormatting.GREEN) 464 462 .withStyle(style -> 465 463 style.withClickEvent( ··· 470 468 ) 471 469 ) 472 470 .append(" ") 473 - .append(getTranslatedText("commands.teleport_commands.common.rename", player) 471 + .append(getTranslation("commands.teleport_commands.common.rename", player) 474 472 .withStyle(ChatFormatting.BLUE) 475 473 .withStyle(style -> 476 474 style.withClickEvent( ··· 484 482 485 483 // add set default button if it isn't the default home 486 484 if (!playerStorage.getDefaultHome().equals(currentHome.getName())) { 487 - message.append(getTranslatedText("commands.teleport_commands.common.defaultPrompt", player) 485 + message.append(getTranslation("commands.teleport_commands.common.defaultPrompt", player) 488 486 .withStyle(ChatFormatting.DARK_AQUA) 489 487 .withStyle(style -> 490 488 style.withClickEvent( ··· 497 495 .append(" "); 498 496 } 499 497 500 - message.append(getTranslatedText("commands.teleport_commands.common.delete", player) 498 + message.append(getTranslation("commands.teleport_commands.common.delete", player) 501 499 .withStyle(ChatFormatting.RED) 502 500 .withStyle(style -> 503 501 style.withClickEvent(
+6 -5
common/src/main/java/dev/mrsnowy/teleport_commands/commands/main.java
··· 6 6 import com.mojang.brigadier.suggestion.SuggestionProvider; 7 7 import dev.mrsnowy.teleport_commands.Constants; 8 8 import dev.mrsnowy.teleport_commands.TeleportCommands; 9 - import dev.mrsnowy.teleport_commands.storage.configManager; 10 9 import net.minecraft.ChatFormatting; 11 10 import net.minecraft.commands.CommandSourceStack; 12 11 import net.minecraft.commands.Commands; ··· 16 15 import net.minecraft.server.level.ServerPlayer; 17 16 18 17 import java.util.Arrays; 18 + 19 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 19 20 20 21 public class main { 21 22 ··· 43 44 .then(Commands.literal("reloadConfig") 44 45 .executes(context -> { 45 46 try { 46 - configManager.configLoader(); 47 + // ConfigManager.configLoader(); 47 48 } catch (Exception e) { 48 49 Constants.LOGGER.error("Failed to reload config!", e); 49 50 throw new SimpleCommandExceptionType(Component.literal(e.toString())).create(); ··· 71 72 } catch (Exception e) { 72 73 Constants.LOGGER.error("Error while disabling a command! => ", e); 73 74 // TODO replace the error below with something normal? 74 - throw new SimpleCommandExceptionType(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 75 + throw new SimpleCommandExceptionType(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 75 76 } 76 77 return 0; 77 78 }) ··· 97 98 } catch (Exception e) { 98 99 Constants.LOGGER.error("Error while disabling a command! => ", e); 99 100 // TODO replace the error below with something normal? 100 - throw new SimpleCommandExceptionType(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 101 + throw new SimpleCommandExceptionType(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)).create(); 101 102 } 102 103 return 0; 103 104 }) ··· 106 107 .then(Commands.literal("reload") 107 108 .requires(source -> source.hasPermission(4)) // Require OP 108 109 .executes(context -> { 109 - TeleportCommands.registerCommands(context.getSource().dispatcher()); 110 + TeleportCommands.INSTANCE.registerCommands(context.getSource().dispatcher()); 110 111 return 0; 111 112 })) 112 113
+22 -21
common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java
··· 5 5 import com.mojang.brigadier.CommandDispatcher; 6 6 import dev.mrsnowy.teleport_commands.Constants; 7 7 import dev.mrsnowy.teleport_commands.TeleportCommands; 8 - import dev.mrsnowy.teleport_commands.suggestions.tpaSuggestionProvider; 8 + import dev.mrsnowy.teleport_commands.suggestions.TpaSuggestionProvider; 9 9 10 10 import net.minecraft.ChatFormatting; 11 11 import net.minecraft.commands.CommandSourceStack; ··· 17 17 import net.minecraft.server.level.ServerPlayer; 18 18 import net.minecraft.world.phys.Vec3; 19 19 20 - import static dev.mrsnowy.teleport_commands.utils.tools.*; 20 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 21 + import static dev.mrsnowy.teleport_commands.utils.Tools.*; 21 22 22 23 public class tpa { 23 24 TeleportCommands teleportCommands; ··· 78 79 79 80 commandDispatcher.register(Commands.literal("tpaaccept") 80 81 .requires(source -> source.getPlayer() != null) 81 - .then(Commands.argument("player", EntityArgument.player()).suggests(new tpaSuggestionProvider()) 82 + .then(Commands.argument("player", EntityArgument.player()).suggests(new TpaSuggestionProvider()) 82 83 .executes(context -> { 83 84 final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player"); 84 85 final ServerPlayer player = context.getSource().getPlayerOrException(); ··· 96 97 97 98 commandDispatcher.register(Commands.literal("tpadeny") 98 99 .requires(source -> source.getPlayer() != null) 99 - .then(Commands.argument("player", EntityArgument.player()).suggests(new tpaSuggestionProvider()) 100 + .then(Commands.argument("player", EntityArgument.player()).suggests(new TpaSuggestionProvider()) 100 101 .executes(context -> { 101 102 final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player"); 102 103 final ServerPlayer player = context.getSource().getPlayerOrException(); ··· 106 107 107 108 } catch (Exception e) { 108 109 Constants.LOGGER.error("Error while denying a tpa(here) request! => ", e); 109 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 110 + player.displayClientMessage(getTranslation("commands.teleport_commands.home.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 110 111 return 1; 111 112 } 112 113 ··· 122 123 .count(); 123 124 124 125 if (FromPlayer == ToPlayer) { 125 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); 126 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); 126 127 127 128 } else if (playerTpaList >= 1) { 128 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.alreadySent", FromPlayer, Component.literal(Objects.requireNonNull(ToPlayer.getName().getString(), "ToPlayer name cannot be null")).withStyle(ChatFormatting.BOLD)).withStyle(ChatFormatting.AQUA) 129 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.alreadySent", FromPlayer, Component.literal(Objects.requireNonNull(ToPlayer.getName().getString(), "ToPlayer name cannot be null")).withStyle(ChatFormatting.BOLD)).withStyle(ChatFormatting.AQUA) 129 130 , true 130 131 ); 131 132 ··· 138 139 String ReceivedFromPlayer = Objects.requireNonNull(FromPlayer.getName().getString(), "FromPlayer name cannot be null"); 139 140 String SentToPlayer = Objects.requireNonNull(ToPlayer.getName().getString(), "ToPlayer name cannot be null"); 140 141 141 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.sent", FromPlayer, Component.literal(hereText), Component.literal(SentToPlayer).withStyle(ChatFormatting.BOLD)) 142 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.sent", FromPlayer, Component.literal(hereText), Component.literal(SentToPlayer).withStyle(ChatFormatting.BOLD)) 142 143 // .append(Text.literal("\n[Cancel]").formatted(Formatting.BLUE, Formatting.BOLD)) 143 144 ,true 144 145 ); 145 146 146 - ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.received", ToPlayer, Component.literal(hereText), Component.literal(ReceivedFromPlayer).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD)).withStyle(ChatFormatting.AQUA) 147 + ToPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.received", ToPlayer, Component.literal(hereText), Component.literal(ReceivedFromPlayer).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD)).withStyle(ChatFormatting.AQUA) 147 148 .append("\n") 148 - .append(getTranslatedText("commands.teleport_commands.tpa.accept", ToPlayer) 149 + .append(getTranslation("commands.teleport_commands.tpa.accept", ToPlayer) 149 150 .withStyle(ChatFormatting.GREEN, ChatFormatting.BOLD) 150 151 .withStyle(style -> style 151 152 .withClickEvent( ··· 156 157 ) 157 158 ) 158 159 .append(" ") 159 - .append(getTranslatedText("commands.teleport_commands.tpa.deny", ToPlayer) 160 + .append(getTranslation("commands.teleport_commands.tpa.deny", ToPlayer) 160 161 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD) 161 162 .withStyle(style -> style 162 163 .withClickEvent( ··· 176 177 public void run() { 177 178 boolean successful = tpaList.remove(tpaRequest); 178 179 if (successful) { 179 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.expired", FromPlayer, Component.literal(hereText)).withStyle(ChatFormatting.RED, ChatFormatting.BOLD),true); 180 - ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.expired", ToPlayer, Component.literal(hereText)).withStyle(ChatFormatting.WHITE),true); 180 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.expired", FromPlayer, Component.literal(hereText)).withStyle(ChatFormatting.RED, ChatFormatting.BOLD),true); 181 + ToPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.expired", ToPlayer, Component.literal(hereText)).withStyle(ChatFormatting.WHITE),true); 181 182 } 182 183 // else not needed since it may be denied/cancelled 183 184 } ··· 188 189 189 190 private void tpaAccept(ServerPlayer FromPlayer, ServerPlayer ToPlayer) { 190 191 if (FromPlayer == ToPlayer) { 191 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); 192 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); 192 193 return; 193 194 } 194 195 ··· 216 217 } 217 218 218 219 // if the player teleported then these messages get sent && the request gets removed 219 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", FromPlayer).withStyle(ChatFormatting.WHITE),true); 220 - ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", ToPlayer).withStyle(ChatFormatting.GREEN),true); 220 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.accepted", FromPlayer).withStyle(ChatFormatting.WHITE),true); 221 + ToPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.accepted", ToPlayer).withStyle(ChatFormatting.GREEN),true); 221 222 tpaList.remove(tpaStorage.get()); 222 223 223 224 } else { 224 225 // No request found 225 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); 226 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); 226 227 } 227 228 } 228 229 229 230 private void tpaDeny(ServerPlayer FromPlayer, ServerPlayer ToPlayer) { 230 231 if (FromPlayer == ToPlayer) { 231 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA),true); 232 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA),true); 232 233 233 234 } else { 234 235 Optional<tpaArrayClass> tpaStorage = tpaList.stream() ··· 239 240 if (tpaStorage.isPresent()) { 240 241 tpaList.remove(tpaStorage.get()); 241 242 242 - ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.denied", ToPlayer).withStyle(ChatFormatting.RED, ChatFormatting.BOLD),true); 243 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.denied", FromPlayer).withStyle(ChatFormatting.WHITE),true); 243 + ToPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.denied", ToPlayer).withStyle(ChatFormatting.RED, ChatFormatting.BOLD),true); 244 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.denied", FromPlayer).withStyle(ChatFormatting.WHITE),true); 244 245 245 246 } else { 246 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); 247 + FromPlayer.displayClientMessage(getTranslation("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); 247 248 } 248 249 } 249 250 }
+26 -26
common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java
··· 6 6 import dev.mrsnowy.teleport_commands.TeleportCommands; 7 7 import dev.mrsnowy.teleport_commands.common.NamedLocation; 8 8 import dev.mrsnowy.teleport_commands.suggestions.WarpSuggestionProvider; 9 - import dev.mrsnowy.teleport_commands.utils.tools; 9 + import dev.mrsnowy.teleport_commands.utils.Tools; 10 10 import net.minecraft.ChatFormatting; 11 11 import net.minecraft.commands.CommandSourceStack; 12 12 import net.minecraft.commands.Commands; ··· 22 22 import java.util.List; 23 23 import java.util.Optional; 24 24 25 - import static dev.mrsnowy.teleport_commands.utils.tools.getTranslatedText; 25 + import static dev.mrsnowy.teleport_commands.utils.Tools.getTranslation; 26 26 import static net.minecraft.commands.Commands.argument; 27 27 28 28 public class warp { ··· 46 46 47 47 } catch (Exception e) { 48 48 Constants.LOGGER.error("Error while setting the warp!", e); 49 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 49 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.setError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 50 50 return 1; 51 51 } 52 52 return 0; ··· 65 65 66 66 } catch (Exception e) { 67 67 Constants.LOGGER.error("Error while going to the warp!",e); 68 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 68 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.goError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 69 69 return 1; 70 70 } 71 71 return 0; ··· 86 86 87 87 } catch (Exception e) { 88 88 Constants.LOGGER.error("Error while deleting to the warp!", e); 89 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.deleteError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 89 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.deleteError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 90 90 return 1; 91 91 } 92 92 return 0; ··· 109 109 110 110 } catch (Exception e) { 111 111 Constants.LOGGER.error("Error while renaming the warp!", e); 112 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.renameError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 112 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.renameError", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 113 113 return 1; 114 114 } 115 115 return 0; ··· 125 125 126 126 } catch (Exception e) { 127 127 Constants.LOGGER.error("Error while printing warps!", e); 128 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warps.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 128 + player.displayClientMessage(getTranslation("commands.teleport_commands.warps.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 129 129 return 1; 130 130 } 131 131 return 0; ··· 148 148 149 149 if (warpExists) { 150 150 // Display error message that the warp already exists 151 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.exists", player).withStyle(ChatFormatting.RED), true); 151 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.exists", player).withStyle(ChatFormatting.RED), true); 152 152 153 153 } else { 154 154 // Display message that the home as been set 155 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.set", player), true); 155 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.set", player), true); 156 156 } 157 157 } 158 158 ··· 162 162 // Gets warp 163 163 Optional<NamedLocation> optionalWarp = STORAGE.getWarp(warpName); 164 164 if (optionalWarp.isEmpty()) { 165 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 165 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 166 166 return; 167 167 } 168 168 ··· 176 176 player.getName().getString(), 177 177 warp.getName(), 178 178 warp.getWorldString(), 179 - tools.getWorldIds()); 179 + Tools.getWorldIds()); 180 180 181 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.worldNotFound", player) 181 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.worldNotFound", player) 182 182 .withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 183 183 184 184 return; ··· 190 190 191 191 // Check if the player is already at this location (in the same world) 192 192 if (player.blockPosition().equals(teleportBlockPos) && player.level() == warpWorld) { 193 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.goSame", player).withStyle(ChatFormatting.AQUA), true); 193 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.goSame", player).withStyle(ChatFormatting.AQUA), true); 194 194 195 195 } else { 196 196 // Teleport the player! 197 197 Vec3 teleportPos = new Vec3(teleportBlockPos.getX() + 0.5, teleportBlockPos.getY(), teleportBlockPos.getZ() + 0.5); 198 198 199 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.go", player), true); 199 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.go", player), true); 200 200 Teleporter(player, warpWorld, teleportPos); 201 201 } 202 202 } ··· 211 211 // Delete the warp 212 212 STORAGE.removeWarp(optionalWarp.get()); 213 213 214 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.delete", player), true); 214 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.delete", player), true); 215 215 216 216 } else { 217 217 // the warp is not found 218 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 218 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 219 219 } 220 220 } 221 221 ··· 225 225 226 226 // check if there is no existing warp with the new name 227 227 if (STORAGE.getWarp(newWarpName).isPresent()) { 228 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.nameExists", player).withStyle(ChatFormatting.RED), true); 228 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.nameExists", player).withStyle(ChatFormatting.RED), true); 229 229 return; 230 230 } 231 231 ··· 236 236 237 237 // set the new name 238 238 warpToRename.get().setName(newWarpName); 239 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.rename", player), true); 239 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.rename", player), true); 240 240 241 241 } else { 242 242 // the warp is not found 243 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 243 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.notFound", player).withStyle(ChatFormatting.RED), true); 244 244 } 245 245 } 246 246 ··· 250 250 251 251 // Check if there are any warps lol 252 252 if (warps.isEmpty()) { 253 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.homeless", player).withStyle(ChatFormatting.AQUA), true); 253 + player.displayClientMessage(getTranslation("commands.teleport_commands.warp.homeless", player).withStyle(ChatFormatting.AQUA), true); 254 254 return; 255 255 } 256 256 257 257 MutableComponent message = Component.empty(); 258 258 259 259 // make da message 260 - message.append(getTranslatedText("commands.teleport_commands.warps.warps", player) 260 + message.append(getTranslation("commands.teleport_commands.warps.warps", player) 261 261 .withStyle(ChatFormatting.YELLOW, ChatFormatting.BOLD) 262 262 ); 263 263 ··· 296 296 .withStyle(style -> 297 297 style.withHoverEvent( 298 298 new HoverEvent.ShowText( 299 - getTranslatedText("commands.teleport_commands.common.hoverCopy", player) 299 + getTranslation("commands.teleport_commands.common.hoverCopy", player) 300 300 ) 301 301 ) 302 302 ) ··· 313 313 .withStyle(style -> style 314 314 .withHoverEvent( 315 315 new HoverEvent.ShowText( 316 - getTranslatedText("commands.teleport_commands.common.hoverCopy", player) 316 + getTranslation("commands.teleport_commands.common.hoverCopy", player) 317 317 ) 318 318 ) 319 319 ) ··· 324 324 325 325 // Teleport button 326 326 message.append(Component.literal(" | ").withStyle(ChatFormatting.AQUA)) 327 - .append(getTranslatedText("commands.teleport_commands.common.tp", player) 327 + .append(getTranslation("commands.teleport_commands.common.tp", player) 328 328 .withStyle(ChatFormatting.GREEN) 329 329 .withStyle(style -> 330 330 style.withClickEvent( ··· 338 338 339 339 // Rename and delete buttons if admin 340 340 if (canModify) { 341 - message.append(getTranslatedText("commands.teleport_commands.common.rename", player) 341 + message.append(getTranslation("commands.teleport_commands.common.rename", player) 342 342 .withStyle(ChatFormatting.BLUE) 343 343 .withStyle(style -> style 344 344 .withClickEvent( ··· 349 349 ) 350 350 ) 351 351 .append(" ") 352 - .append(getTranslatedText("commands.teleport_commands.common.delete", player) 352 + .append(getTranslation("commands.teleport_commands.common.delete", player) 353 353 .withStyle(ChatFormatting.RED) 354 354 .withStyle(style -> style 355 355 .withClickEvent(
+12 -33
common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java
··· 4 4 import com.mojang.brigadier.arguments.BoolArgumentType; 5 5 import dev.mrsnowy.teleport_commands.Constants; 6 6 import dev.mrsnowy.teleport_commands.TeleportCommands; 7 + import dev.mrsnowy.teleport_commands.utils.Tools; 7 8 import net.minecraft.ChatFormatting; 8 9 import net.minecraft.commands.CommandSourceStack; 9 10 import net.minecraft.commands.Commands; 10 11 import net.minecraft.core.BlockPos; 11 - import net.minecraft.network.chat.ClickEvent; 12 - import net.minecraft.network.chat.Component; 13 12 import net.minecraft.server.level.ServerLevel; 14 13 import net.minecraft.server.level.ServerPlayer; 15 14 import net.minecraft.world.phys.Vec3; ··· 17 16 import java.util.Objects; 18 17 import java.util.Optional; 19 18 20 - import static dev.mrsnowy.teleport_commands.utils.tools.*; 19 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 20 + import static dev.mrsnowy.teleport_commands.utils.Tools.*; 21 21 import static net.minecraft.commands.Commands.argument; 22 22 23 23 import static net.minecraft.world.level.Level.OVERWORLD; ··· 35 35 36 36 } catch (Exception error) { 37 37 Constants.LOGGER.error("Error while going to the worldspawn! => ", error); 38 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 38 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 39 39 return 1; 40 40 } 41 41 return 0; ··· 51 51 52 52 } catch (Exception error) { 53 53 Constants.LOGGER.error("Error while going to the worldspawn! => ", error); 54 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 54 + player.displayClientMessage(getTranslation("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 55 55 return 1; 56 56 } 57 57 return 0; ··· 62 62 63 63 private static void toWorldSpawn(ServerPlayer player, boolean safetyDisabled) throws NullPointerException { 64 64 // todo! make the dimension customizable 65 - ServerLevel world = TeleportCommands.server.getLevel(OVERWORLD); 65 + ServerLevel world = player.server.getLevel(OVERWORLD); 66 66 BlockPos worldSpawn = Objects.requireNonNull(world,"Overworld cannot be null!").getSharedSpawnPos(); 67 67 68 68 if (!safetyDisabled) { ··· 74 74 // check if the player is already at this location 75 75 if (player.blockPosition().equals(safeBlockPos) && player.level() == world) { 76 76 77 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 77 + player.displayClientMessage(getTranslation("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 78 78 } else { 79 79 Vec3 teleportPos = new Vec3(safeBlockPos.getX() + 0.5, safeBlockPos.getY(), safeBlockPos.getZ() + 0.5); 80 - 81 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.go", player), true); 82 - Teleporter(player, world, teleportPos); 80 + TeleportCommands.INSTANCE.teleporter.queue(player, world, teleportPos, "commands.teleport_commands.worldspawn.go"); 83 81 } 84 82 85 83 } else { 86 - 87 - player.displayClientMessage( 88 - Component.empty() 89 - .append(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player) 90 - .withStyle(ChatFormatting.RED, ChatFormatting.BOLD) 91 - ) 92 - .append("\n") 93 - .append(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player) 94 - .withStyle(ChatFormatting.WHITE) 95 - ) 96 - .append("\n") 97 - .append(getTranslatedText("commands.teleport_commands.common.forceTeleport", player) 98 - .withStyle(ChatFormatting.DARK_AQUA, ChatFormatting.BOLD) 99 - .withStyle(style -> style.withClickEvent( 100 - new ClickEvent.RunCommand("/worldspawn true") 101 - ) 102 - ) 103 - ) 104 - .append("\n"), false); 84 + Tools.sendSafetyWarning(player, "/worldspawn true"); 105 85 } 106 86 107 87 } else { 108 88 109 89 if (player.blockPosition().equals(worldSpawn) && player.level() == world) { 110 90 111 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 91 + player.displayClientMessage(getTranslation("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 112 92 } else { 113 - 114 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.go", player), true); 115 - Teleporter(player, world, new Vec3(worldSpawn.getX() + 0.5, worldSpawn.getY(), worldSpawn.getZ() + 0.5)); 93 + Vec3 teleportPos = new Vec3(worldSpawn.getX() + 0.5, worldSpawn.getY(), worldSpawn.getZ() + 0.5); 94 + TeleportCommands.INSTANCE.teleporter.queue(player, world, teleportPos, "commands.teleport_commands.worldspawn.go"); 116 95 } 117 96 } 118 97 }
+1
common/src/main/java/dev/mrsnowy/teleport_commands/mixin/CommandsMixin.java
··· 20 20 Commands self = (Commands) (Object) this; 21 21 CommandDispatcher<CommandSourceStack> dispatcher = self.getDispatcher(); 22 22 23 + // This re-registers the commands when the server's reloadable resources get reloaded 23 24 TeleportCommands.INSTANCE.registerCommands(dispatcher); 24 25 } 25 26 }
+1 -3
common/src/main/java/dev/mrsnowy/teleport_commands/mixin/PlayerDeathMixin.java common/src/main/java/dev/mrsnowy/teleport_commands/mixin/ServerPlayerMixin.java
··· 1 1 package dev.mrsnowy.teleport_commands.mixin; 2 2 3 3 import dev.mrsnowy.teleport_commands.TeleportCommands; 4 - import net.minecraft.client.renderer.item.properties.numeric.Damage; 5 - import net.minecraft.commands.Commands; 6 4 import net.minecraft.server.level.ServerLevel; 7 5 import net.minecraft.server.level.ServerPlayer; 8 6 import net.minecraft.world.damagesource.DamageSource; ··· 15 13 import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 16 14 17 15 @Mixin(ServerPlayer.class) 18 - public class PlayerDeathMixin { 16 + public class ServerPlayerMixin { 19 17 20 18 @Inject(method = "die", at = @At("HEAD")) 21 19 private void notifyDeath(CallbackInfo info) {
+1 -1
common/src/main/java/dev/mrsnowy/teleport_commands/mixin/ServerStartMixin.java common/src/main/java/dev/mrsnowy/teleport_commands/mixin/MinecraftServerMixin.java
··· 10 10 import java.util.function.BooleanSupplier; 11 11 12 12 @Mixin(MinecraftServer.class) 13 - public class ServerStartMixin { 13 + public class MinecraftServerMixin { 14 14 15 15 @Inject(method = "runServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;buildServerStatus()Lnet/minecraft/network/protocol/status/ServerStatus;", ordinal = 0)) 16 16 private void runServer(CallbackInfo info) {
+5 -5
common/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java common/src/main/java/dev/mrsnowy/teleport_commands/storage/ConfigManager.java
··· 3 3 import com.google.gson.*; 4 4 import dev.mrsnowy.teleport_commands.Constants; 5 5 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 - import dev.mrsnowy.teleport_commands.utils.tools; 6 + import dev.mrsnowy.teleport_commands.utils.Tools; 7 7 8 8 import java.io.FileReader; 9 9 import java.nio.file.Files; 10 10 import java.nio.file.Path; 11 11 import java.nio.file.StandardOpenOption; 12 12 13 - public class configManager { 13 + public class ConfigManager { 14 14 public Path configFile; 15 15 public ConfigClass config; 16 16 ··· 18 18 private final int defaultVersion = new ConfigClass().getVersion(); 19 19 private final TeleportCommands teleportCommands; 20 20 21 - public configManager(TeleportCommands teleportCommands) { 21 + public ConfigManager(TeleportCommands teleportCommands) { 22 22 this.teleportCommands = teleportCommands; 23 23 configFile = teleportCommands.configDir.resolve("teleport_commands.json"); 24 24 ··· 182 182 public void setCommand(String command) throws Exception { 183 183 this.command = command; 184 184 configSaver(); 185 - tools.reloadResources(teleportCommands.server); // Reload the commands 185 + Tools.reloadResources(teleportCommands.server); // Reload the commands 186 186 } 187 187 188 188 public boolean isDeleteAfterTeleport() { ··· 298 298 public void setCommand(String command) throws Exception { 299 299 this.command = command; 300 300 configSaver(); 301 - tools.reloadResources(teleportCommands.server); // Reload the commands 301 + Tools.reloadResources(teleportCommands.server); // Reload the commands 302 302 } 303 303 } 304 304 }
+1 -1
common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/tpaSuggestionProvider.java common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/TpaSuggestionProvider.java
··· 14 14 import java.util.concurrent.CompletableFuture; 15 15 16 16 17 - public class tpaSuggestionProvider implements SuggestionProvider<CommandSourceStack> { 17 + public class TpaSuggestionProvider implements SuggestionProvider<CommandSourceStack> { 18 18 @Override 19 19 public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) { 20 20 try {
+143
common/src/main/java/dev/mrsnowy/teleport_commands/utils/Language.java
··· 1 + package dev.mrsnowy.teleport_commands.utils; 2 + 3 + import com.google.gson.JsonElement; 4 + import com.google.gson.JsonObject; 5 + import com.google.gson.JsonParser; 6 + import dev.mrsnowy.teleport_commands.Constants; 7 + import dev.mrsnowy.teleport_commands.TeleportCommands; 8 + import net.minecraft.network.chat.Component; 9 + import net.minecraft.network.chat.MutableComponent; 10 + import net.minecraft.server.level.ServerPlayer; 11 + 12 + import javax.annotation.Nullable; 13 + import java.io.InputStream; 14 + import java.io.InputStreamReader; 15 + import java.io.Reader; 16 + import java.nio.charset.StandardCharsets; 17 + import java.util.HashMap; 18 + import java.util.Map; 19 + import java.util.regex.Matcher; 20 + import java.util.regex.Pattern; 21 + 22 + public class Language { 23 + record languageObject(@Nullable JsonObject jsonObject, int lastUsedTick) {} 24 + 25 + private static final Map<String, languageObject> LANGUAGE_CACHE = new HashMap<>(); 26 + private static final Pattern NUMBER_PATTERN = Pattern.compile("%(\\d+)%"); 27 + 28 + /// Attempts to retrieve the JSON file for the language, then caches it in memory. 29 + private static @Nullable JsonObject getLanguageJson(String language) { 30 + int currentTick = TeleportCommands.INSTANCE.server.getTickCount(); 31 + 32 + if (LANGUAGE_CACHE.containsKey(language)) { 33 + languageObject cache = LANGUAGE_CACHE.get(language); 34 + LANGUAGE_CACHE.put(language, new languageObject(cache.jsonObject, currentTick)); 35 + return cache.jsonObject; 36 + } 37 + 38 + String filePath = String.format("/assets/%s/lang/%s.json", Constants.MOD_ID, language); 39 + JsonObject value = null; 40 + try { 41 + InputStream stream = TeleportCommands.class.getResourceAsStream(filePath); 42 + if (stream != null) { 43 + Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8); 44 + value = JsonParser.parseReader(reader).getAsJsonObject(); 45 + } 46 + } catch (Exception e) { 47 + Constants.LOGGER.info("Error while reading language {}, maybe it's not available", language); 48 + } 49 + 50 + if (value == null) { 51 + LANGUAGE_CACHE.put(language, new languageObject(null, currentTick)); 52 + } 53 + 54 + return value; 55 + } 56 + 57 + // I love rustifying things 58 + record TranslationResult(@Nullable String value, @Nullable String error) {} 59 + 60 + /// Gets the translation from a key of a language 61 + private static TranslationResult getTranslation(String language, String key) { 62 + try { 63 + JsonObject json = getLanguageJson(language); 64 + if (json == null) { 65 + throw new Exception("Error getting the json file for the translation"); 66 + } 67 + 68 + JsonElement translation = json.get(key); 69 + if (translation == null) { 70 + throw new Exception("Error getting the key for the translation"); 71 + } 72 + String translationString = translation.getAsString(); 73 + if (translationString.isEmpty()) { 74 + throw new Exception("Empty translation key!"); 75 + } 76 + 77 + return new TranslationResult(translationString, null); 78 + 79 + } catch (Exception e) { 80 + return new TranslationResult(null, e.getMessage()); 81 + } 82 + } 83 + 84 + // Gets the translated text for each player based on their language, this is fully server side and actually works (UNLIKE MOJANG'S TRANSLATED KEY'S WHICH ARE CLIENT SIDE) (I'm not mad, I swear!) 85 + public static MutableComponent getTranslation(String key, ServerPlayer player, MutableComponent... args) { 86 + String language = player.clientInformation().language().toLowerCase(); 87 + TranslationResult translationResult = getTranslation(language, key); 88 + 89 + if (translationResult.value == null) { 90 + if (!language.equals("en_us")) { 91 + 92 + translationResult = getTranslation("en_us", key); 93 + if (translationResult.value == null) { 94 + Constants.LOGGER.error("Error while fall-backing to default translation from \"{}\": \"{}\". Returning raw json to user.", language, translationResult.error); 95 + return Component.literal(key); 96 + } 97 + } else { 98 + Constants.LOGGER.error("Error while loading translation: \"{}\". Returning raw json to user.", translationResult.error); 99 + return Component.literal(key); 100 + } 101 + } 102 + 103 + String translationString = translationResult.value; 104 + 105 + if (args.length == 0) { 106 + return Component.literal(translationString); 107 + } 108 + 109 + try { 110 + // Adds the optional MutableComponents in the correct places 111 + Matcher matcher = NUMBER_PATTERN.matcher(translationString); 112 + MutableComponent component = Component.empty(); 113 + int lastIndex = 0; 114 + 115 + while (matcher.find()) { 116 + int index = Integer.parseInt(matcher.group(1)); 117 + 118 + component.append(Component.literal(translationString.substring(lastIndex, matcher.start()))); 119 + component.append(args[index]); 120 + 121 + lastIndex = matcher.end(); 122 + } 123 + 124 + component.append(translationString.substring(lastIndex)); 125 + return component; 126 + 127 + } catch (Exception e) { 128 + Constants.LOGGER.error("Error while replacing dynamic sections in translation: \"{}\". Returning raw string to user.", e.getMessage()); 129 + return Component.literal(translationString); 130 + } 131 + } 132 + 133 + /// Cleans languages out of the cache if they haven't been used for some time. 134 + // TODO! hook this up! 135 + public static void cacheCleaner(int currentTick, int tps) { 136 + LANGUAGE_CACHE.entrySet().removeIf(entry -> { 137 + if (entry.getValue().lastUsedTick + (120 * tps) < currentTick) { 138 + return true; 139 + } 140 + return false; 141 + }); 142 + } 143 + }
+123
common/src/main/java/dev/mrsnowy/teleport_commands/utils/Tools.java
··· 1 + package dev.mrsnowy.teleport_commands.utils; 2 + 3 + import com.google.gson.*; 4 + 5 + import java.io.*; 6 + import java.util.*; 7 + import java.util.stream.StreamSupport; 8 + 9 + import net.minecraft.ChatFormatting; 10 + import net.minecraft.core.BlockPos; 11 + import net.minecraft.network.chat.ClickEvent; 12 + import net.minecraft.network.chat.Component; 13 + import net.minecraft.server.MinecraftServer; 14 + import net.minecraft.server.level.ServerLevel; 15 + import net.minecraft.server.level.ServerPlayer; 16 + 17 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 18 + 19 + 20 + public class Tools { 21 + private static final Set<String> unsafeCollisionFreeBlocks = Set.of("block.minecraft.lava", "block.minecraft.flowing_lava", "block.minecraft.end_portal", "block.minecraft.end_gateway","block.minecraft.fire", "block.minecraft.soul_fire", "block.minecraft.powder_snow", "block.minecraft.nether_portal"); 22 + 23 + // checks a 7x7x7 location around the player in order to find a safe place to teleport them to. 24 + public static Optional<BlockPos> getSafeBlockPos(BlockPos blockPos, ServerLevel world) { 25 + int row = 1; 26 + int rows = 3; 27 + 28 + int blockPosX = blockPos.getX(); 29 + int blockPosY = blockPos.getY(); 30 + int blockPosZ = blockPos.getZ(); 31 + 32 + if (isBlockPosSafe(blockPos, world)) { 33 + return Optional.of(blockPos); // safe location found! 34 + 35 + } else { 36 + // find a safe location in an x row radius 37 + while (row <= rows) { 38 + // TeleportCommands.LOGGER.info("currently doing row " + row + " of " + rows); //debug 39 + for (int z = -row; z <= row; z++) { 40 + for (int x = -row; x <= row; x++) { 41 + for (int y = -row; y <= row; y++) { 42 + 43 + // checks if we are on the outer layer of the row, not on the inside 44 + if ((x == -row || x == row) || (z == -row || z == row) || (y == -row || y == row)) { 45 + 46 + // calculate a new blockPos based on the offset we generated 47 + BlockPos newPos = new BlockPos(blockPosX + x, blockPosY + y, blockPosZ + z); 48 + 49 + if (isBlockPosSafe(newPos, world)) { 50 + // return Optional.of(new Vec3(newPos.getX() + 0.5, newPos.getY(), newPos.getZ() + 0.5)); // safe location found! 51 + return Optional.of(newPos); 52 + } 53 + } 54 + } 55 + } 56 + } 57 + 58 + row++; 59 + } 60 + 61 + // no safe location 62 + return Optional.empty(); // no safe location found! 63 + } 64 + } 65 + 66 + public static void sendSafetyWarning(ServerPlayer player, String command) { 67 + // asks the player if they want to teleport anyway 68 + player.displayClientMessage( 69 + Component.empty() 70 + .append(getTranslation("commands.teleport_commands.common.noSafeLocation", player) 71 + .withStyle(ChatFormatting.RED, ChatFormatting.BOLD) 72 + ) 73 + .append("\n") 74 + .append(getTranslation("commands.teleport_commands.common.safetyIsForLosers", player) 75 + .withStyle(ChatFormatting.WHITE) 76 + ) 77 + .append("\n") 78 + .append(getTranslation("commands.teleport_commands.common.forceTeleport", player) 79 + .withStyle(ChatFormatting.DARK_AQUA, ChatFormatting.BOLD) 80 + .withStyle(style -> style.withClickEvent(new ClickEvent.RunCommand(command))) 81 + ) 82 + .append("\n"), false); 83 + } 84 + 85 + // Gets the ids of all the worlds 86 + public static List<String> getWorldIds(MinecraftServer server) { 87 + return StreamSupport.stream(server.getAllLevels().spliterator(), false) 88 + .map(level -> level.dimension().location().toString()) 89 + .toList(); 90 + } 91 + 92 + 93 + // checks if a BlockPos is safe, used by the teleportSafetyChecker. 94 + private static boolean isBlockPosSafe(BlockPos bottomPlayer, ServerLevel world) { 95 + 96 + // get the block below the player 97 + BlockPos belowPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() -1, bottomPlayer.getZ()); // below the player 98 + String belowPlayerId = world.getBlockState(belowPlayer).getBlock().getDescriptionId(); // below the player 99 + 100 + // get the bottom of the player 101 + String BottomPlayerId = world.getBlockState(bottomPlayer).getBlock().getDescriptionId(); // bottom of player 102 + 103 + // get the top of the player 104 + BlockPos TopPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() + 1, bottomPlayer.getZ()); // top of player 105 + String TopPlayerId = world.getBlockState(TopPlayer).getBlock().getDescriptionId(); // top of player 106 + 107 + 108 + // check if the block position isn't safe 109 + if ((belowPlayerId.equals("block.minecraft.water") || !world.getBlockState(belowPlayer).getCollisionShape(world, belowPlayer).isEmpty()) // check if the player is going to fall on teleport 110 + && (world.getBlockState(bottomPlayer).getCollisionShape(world, bottomPlayer).isEmpty() && !unsafeCollisionFreeBlocks.contains(BottomPlayerId)) // check if it is a collision free block that isn't dangerous 111 + && (!unsafeCollisionFreeBlocks.contains(TopPlayerId))) // check if it is a dangerous collision free block, if it is solid then the player crawls 112 + { 113 + return true; // it's safe 114 + } 115 + return false; // it's not safe! 116 + } 117 + 118 + /// This function reloads "reloadable resources" which includes commands 119 + public static void reloadResources(MinecraftServer server) { 120 + Collection<String> collection = server.getPackRepository().getSelectedIds(); 121 + server.reloadResources(collection); 122 + } 123 + }
+23 -30
common/src/main/java/dev/mrsnowy/teleport_commands/utils/teleporter.java common/src/main/java/dev/mrsnowy/teleport_commands/utils/Teleporter.java
··· 15 15 import javax.annotation.Nullable; 16 16 import java.util.*; 17 17 18 - import static dev.mrsnowy.teleport_commands.utils.tools.getTranslatedText; 18 + import static dev.mrsnowy.teleport_commands.utils.Language.getTranslation; 19 19 import static net.minecraft.sounds.SoundEvents.ENDERMAN_TELEPORT; 20 20 21 - public class teleporter { 21 + public class Teleporter { 22 22 private final TeleportCommands teleportCommands; 23 23 private final Map<UUID, PlayerData> players = new HashMap<>(); 24 24 ··· 58 58 59 59 // ---- 60 60 61 - public teleporter(TeleportCommands teleportCommands) { 61 + public Teleporter(TeleportCommands teleportCommands) { 62 62 this.teleportCommands = teleportCommands; 63 63 } 64 64 ··· 83 83 if (wasOnCooldown && !data.teleportOnCooldown && !data.fightOnCooldown) { 84 84 ServerPlayer player = server.getPlayerList().getPlayer(entry.getKey()); 85 85 if (player != null) { 86 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.ready", player).withStyle(ChatFormatting.WHITE), true); 86 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.ready", player).withStyle(ChatFormatting.WHITE), true); 87 87 } 88 88 } 89 89 ··· 102 102 // check if this is a whole number 103 103 float secondsLeft = (float) (data.pendingTeleport.teleportDelayUntil - currentTick) / data.pendingTeleport.tps; 104 104 if ((secondsLeft % 1) == 0 && player != null) { 105 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.progress", player).withStyle(ChatFormatting.WHITE), true); 105 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.progress", player).withStyle(ChatFormatting.WHITE), true); 106 106 } 107 107 } 108 108 } ··· 137 137 int ticksLeft = data.pendingTeleport.teleportDelayUntil - currentTick; 138 138 int secondsLeft = (int) Math.ceil( (double) ticksLeft / data.pendingTeleport.tps); 139 139 140 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.delay", player, 140 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.delay", player, 141 141 Component.literal(String.valueOf(secondsLeft)), 142 142 Component.literal(String.valueOf(ticksLeft)) 143 143 ).withStyle(ChatFormatting.WHITE), false); ··· 151 151 int ticksLeft = cooldownUntil - currentTick; 152 152 int secondsLeft = (int) Math.ceil( (double) ticksLeft / tps); 153 153 154 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.cooldown", player, 154 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.cooldown", player, 155 155 Component.literal(String.valueOf(secondsLeft)), 156 156 Component.literal(String.valueOf(ticksLeft)) 157 157 ).withStyle(ChatFormatting.WHITE), false); ··· 170 170 // bypass the delay 171 171 teleport(player, world, coords, completionMessage); 172 172 } 173 - 174 - 175 - // save pos and check if they have moved. 176 - 177 - // check if they got hit? whileFighting 178 - 179 - // save when they last got hit and if it exceeds fightCooldown 180 - 181 173 } 182 174 183 175 /// Teleports the player :P 184 - private void teleport(ServerPlayer player, ServerLevel world, Vec3 coords, String completionMessage) { 176 + private void teleport(ServerPlayer player, ServerLevel to_world, Vec3 to_coords, String completionMessage) { 185 177 // teleportation effects & sounds before teleporting 186 - world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() + 1, player.getZ(), 20, 0.0D, 0.0D, 0.0D, 0.01); 187 - world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 1.0D, 0.0D, 0.03); 188 - world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.location()), SoundSource.PLAYERS, 0.4f, 1.0f); 178 + ServerLevel from_world = player.serverLevel(); 179 + from_world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() + 1, player.getZ(), 20, 0.0D, 0.0D, 0.0D, 0.01); 180 + from_world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 1.0D, 0.0D, 0.03); 181 + from_world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.location()), SoundSource.PLAYERS, 0.4f, 1.0f); 189 182 190 183 boolean flying = player.getAbilities().flying; 191 184 192 - player.displayClientMessage(getTranslatedText(completionMessage, player).withStyle(ChatFormatting.WHITE), true); 193 - player.teleportTo(world, coords.x, coords.y, coords.z, Set.of(), player.getYRot(), player.getXRot(), false); 185 + player.displayClientMessage(getTranslation(completionMessage, player).withStyle(ChatFormatting.WHITE), true); 186 + player.teleportTo(to_world, to_coords.x, to_coords.y, to_coords.z, Set.of(), player.getYRot(), player.getXRot(), false); 194 187 195 188 // Restore flying when teleporting trough dimensions 196 189 if (flying) { ··· 199 192 } 200 193 201 194 // teleportation sound && effects after teleport 202 - world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.location()), SoundSource.PLAYERS, 0.4f, 1.0f); 203 - world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() , player.getZ(), 20, 0.0D, 1.0D, 0.0D, 0.01); 204 - world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 0.0D, 0.0D, 0.03); 195 + to_world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.location()), SoundSource.PLAYERS, 0.4f, 1.0f); 196 + to_world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() , player.getZ(), 20, 0.0D, 1.0D, 0.0D, 0.01); 197 + to_world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 0.0D, 0.0D, 0.03); 205 198 } 206 199 207 - 200 + /// This function gets called by the mixin to notify that the player has moved 208 201 public void reportPlayerMoved(ServerPlayer player) { 209 202 if (teleportCommands.config.config.teleporting.isAllowMoving()) { 210 - return; // The config option isn't disabled 203 + return; // The config option is disabled 211 204 } 212 205 213 206 PlayerData data = players.get(player.getUUID()); ··· 217 210 boolean tooFar = data.pendingTeleport.startingCoords.closerThan(pos, 1.5); // Checks if they moved more than one block (1.5 for diagonals) 218 211 219 212 if (tooFar) { 220 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.moving", player).withStyle(ChatFormatting.WHITE), true); 213 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.moving", player).withStyle(ChatFormatting.WHITE), true); 221 214 data.pendingTeleport = null; 222 215 } 223 216 224 217 } 225 218 } 226 219 220 + /// This function gets called by the mixin to notify that the player got damaged 227 221 public void reportPlayerHurt(ServerPlayer player) { 228 222 if (teleportCommands.config.config.teleporting.isAllowFighting()) { 229 - return; // The config option isn't disabled 223 + return; // The config option is disabled 230 224 } 231 225 232 226 PlayerData data = players.get(player.getUUID()); ··· 238 232 data.fightOnCooldown = true; 239 233 240 234 if (data.pendingTeleport != null) { 241 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.teleport.fighting", player).withStyle(ChatFormatting.WHITE), true); 235 + player.displayClientMessage(getTranslation("commands.teleport_commands.teleport.fighting", player).withStyle(ChatFormatting.WHITE), true); 242 236 data.pendingTeleport = null; 243 237 } 244 238 } 245 - 246 239 } 247 240 }
-194
common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
··· 1 - package dev.mrsnowy.teleport_commands.utils; 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.*; 8 - import java.nio.charset.StandardCharsets; 9 - import java.util.*; 10 - import java.util.regex.Matcher; 11 - import java.util.regex.Pattern; 12 - import java.util.stream.StreamSupport; 13 - 14 - import net.minecraft.core.BlockPos; 15 - import net.minecraft.network.chat.Component; 16 - import net.minecraft.network.chat.MutableComponent; 17 - import net.minecraft.server.MinecraftServer; 18 - import net.minecraft.server.level.ServerLevel; 19 - import net.minecraft.server.level.ServerPlayer; 20 - 21 - import static dev.mrsnowy.teleport_commands.Constants.MOD_ID; 22 - 23 - 24 - public class tools { 25 - private static final Set<String> unsafeCollisionFreeBlocks = Set.of("block.minecraft.lava", "block.minecraft.flowing_lava", "block.minecraft.end_portal", "block.minecraft.end_gateway","block.minecraft.fire", "block.minecraft.soul_fire", "block.minecraft.powder_snow", "block.minecraft.nether_portal"); 26 - 27 - // checks a 7x7x7 location around the player in order to find a safe place to teleport them to. 28 - public static Optional<BlockPos> getSafeBlockPos(BlockPos blockPos, ServerLevel world) { 29 - int row = 1; 30 - int rows = 3; 31 - 32 - int blockPosX = blockPos.getX(); 33 - int blockPosY = blockPos.getY(); 34 - int blockPosZ = blockPos.getZ(); 35 - 36 - if (isBlockPosSafe(blockPos, world)) { 37 - return Optional.of(blockPos); // safe location found! 38 - 39 - } else { 40 - // find a safe location in an x row radius 41 - while (row <= rows) { 42 - // TeleportCommands.LOGGER.info("currently doing row " + row + " of " + rows); //debug 43 - for (int z = -row; z <= row; z++) { 44 - for (int x = -row; x <= row; x++) { 45 - for (int y = -row; y <= row; y++) { 46 - 47 - // checks if we are on the outer layer of the row, not on the inside 48 - if ((x == -row || x == row) || (z == -row || z == row) || (y == -row || y == row)) { 49 - 50 - // calculate a new blockPos based on the offset we generated 51 - BlockPos newPos = new BlockPos(blockPosX + x, blockPosY + y, blockPosZ + z); 52 - 53 - if (isBlockPosSafe(newPos, world)) { 54 - // return Optional.of(new Vec3(newPos.getX() + 0.5, newPos.getY(), newPos.getZ() + 0.5)); // safe location found! 55 - return Optional.of(newPos); 56 - } 57 - } 58 - } 59 - } 60 - } 61 - 62 - row++; 63 - } 64 - 65 - // no safe location 66 - return Optional.empty(); // no safe location found! 67 - } 68 - } 69 - 70 - 71 - // Gets the translated text for each player based on their language, this is fully server side and actually works (UNLIKE MOJANG'S TRANSLATED KEY'S WHICH ARE CLIENT SIDE) (I'm not mad, I swear!) 72 - public static MutableComponent getTranslatedText(String key, ServerPlayer player, MutableComponent... args) { 73 - //todo! maybe make this also loaded in memory? 74 - String language = player.clientInformation().language().toLowerCase(); 75 - String regex = "%(\\d+)%"; 76 - Pattern pattern = Pattern.compile(regex); 77 - 78 - // MinecraftServer server = player.getServer(); 79 - 80 - // MinecraftServer.ServerResourcePackInfo silly2 = server.getResourceManager().listResources() 81 - 82 - // java.util.stream.Stream<net.minecraft.server.packs.PackResources> SILLY = server.getResourceManager().listPacks(); 83 - // 84 - // SILLY.forEach(pack -> { 85 - // Constants.LOGGER.info("{} : {} : {}", pack.packId(), pack.location(), pack.getClass()); 86 - // }); 87 - 88 - // player.displayClientMessage(Component.literal(.toString()), false); 89 - 90 - // the try catch stuff is so wacky, but it works fine and I don't need to check everything 91 - try { 92 - String filePath = String.format("/assets/%s/lang/%s.json", MOD_ID, language); 93 - InputStream stream = TeleportCommands.class.getResourceAsStream(filePath); 94 - 95 - Reader reader = new InputStreamReader(Objects.requireNonNull(stream, String.format("Couldn't find the required language file for \"%s\"", language)), StandardCharsets.UTF_8); 96 - JsonElement json = JsonParser.parseReader(reader); 97 - String translation = json.getAsJsonObject().get(key).getAsString(); 98 - 99 - 100 - // Adds the optional MutableComponents in the correct places 101 - Matcher matcher = pattern.matcher(Objects.requireNonNull(translation)); 102 - 103 - MutableComponent component = Component.literal(""); 104 - int lastIndex = 0; 105 - 106 - while (matcher.find()) { 107 - component.append(Component.literal(translation.substring(lastIndex, matcher.start()))); 108 - 109 - int index = Integer.parseInt(matcher.group(1)); 110 - component.append(args[index]); 111 - 112 - lastIndex = matcher.end(); 113 - } 114 - component.append(translation.substring(lastIndex)); 115 - 116 - return component; 117 - 118 - } catch (Exception e) { 119 - 120 - try { 121 - if (!Objects.equals(language, "en_us")) { 122 - // TeleportCommands.LOGGER.warn("Key \"{}\" not found in the language: {}, falling back to default (en_us)", key, language); 123 - 124 - String filePath = String.format("/assets/%s/lang/en_us.json", MOD_ID); 125 - InputStream stream = TeleportCommands.class.getResourceAsStream(filePath); 126 - 127 - Reader reader = new InputStreamReader(Objects.requireNonNull(stream, String.format("Couldn't find the required language file for \"%s\"", language)), StandardCharsets.UTF_8); 128 - JsonElement json = JsonParser.parseReader(reader); 129 - String translation = json.getAsJsonObject().get(key).getAsString(); 130 - 131 - // Adds the optional MutableComponents in the correct places 132 - Matcher matcher = pattern.matcher(Objects.requireNonNull(translation, "translation cannot be null")); 133 - 134 - MutableComponent component = Component.literal(""); 135 - int lastIndex = 0; 136 - 137 - while (matcher.find()) { 138 - component.append(Component.literal(translation.substring(lastIndex, matcher.start()))); 139 - 140 - int index = Integer.parseInt(matcher.group(1)); 141 - component.append(args[index]); 142 - 143 - lastIndex = matcher.end(); 144 - } 145 - component.append(translation.substring(lastIndex)); 146 - 147 - return component; 148 - } 149 - } catch (Exception ignored1) {} 150 - Constants.LOGGER.error("Key \"{}\" not found in the default language (en_us), sending raw key as fallback.", key); 151 - return Component.literal(key); 152 - } 153 - } 154 - 155 - 156 - // Gets the ids of all the worlds 157 - public static List<String> getWorldIds(MinecraftServer server) { 158 - return StreamSupport.stream(server.getAllLevels().spliterator(), false) 159 - .map(level -> level.dimension().location().toString()) 160 - .toList(); 161 - } 162 - 163 - 164 - // checks if a BlockPos is safe, used by the teleportSafetyChecker. 165 - private static boolean isBlockPosSafe(BlockPos bottomPlayer, ServerLevel world) { 166 - 167 - // get the block below the player 168 - BlockPos belowPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() -1, bottomPlayer.getZ()); // below the player 169 - String belowPlayerId = world.getBlockState(belowPlayer).getBlock().getDescriptionId(); // below the player 170 - 171 - // get the bottom of the player 172 - String BottomPlayerId = world.getBlockState(bottomPlayer).getBlock().getDescriptionId(); // bottom of player 173 - 174 - // get the top of the player 175 - BlockPos TopPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() + 1, bottomPlayer.getZ()); // top of player 176 - String TopPlayerId = world.getBlockState(TopPlayer).getBlock().getDescriptionId(); // top of player 177 - 178 - 179 - // check if the block position isn't safe 180 - if ((belowPlayerId.equals("block.minecraft.water") || !world.getBlockState(belowPlayer).getCollisionShape(world, belowPlayer).isEmpty()) // check if the player is going to fall on teleport 181 - && (world.getBlockState(bottomPlayer).getCollisionShape(world, bottomPlayer).isEmpty() && !unsafeCollisionFreeBlocks.contains(BottomPlayerId)) // check if it is a collision free block that isn't dangerous 182 - && (!unsafeCollisionFreeBlocks.contains(TopPlayerId))) // check if it is a dangerous collision free block, if it is solid then the player crawls 183 - { 184 - return true; // it's safe 185 - } 186 - return false; // it's not safe! 187 - } 188 - 189 - /// This function reloads "reloadable resources" which includes commands 190 - public static void reloadResources(MinecraftServer server) { 191 - Collection<String> collection = server.getPackRepository().getSelectedIds(); 192 - server.reloadResources(collection); 193 - } 194 - }
+2 -2
common/src/main/resources/teleport_commands.mixins.json
··· 5 5 "refmap": "${mod_id}.refmap.json", 6 6 "compatibilityLevel": "JAVA_${java_version}", 7 7 "mixins": [ 8 - "ServerStartMixin", 9 - "PlayerDeathMixin", 8 + "MinecraftServerMixin", 9 + "ServerPlayerMixin", 10 10 "CommandsMixin" 11 11 ], 12 12 "client": [],
+1 -1
gradle.properties
··· 2 2 # Every field you add must be added to the root build.gradle expandProps map. 3 3 4 4 # Project 5 - version=1.3.4 5 + version=1.4.0 6 6 group=dev.mrsnowy.teleport_commands 7 7 java_version=21 8 8