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.

Still rewriting, I'm getting there!

+399 -211
+1
CHANGELOG.md
··· 12 12 - Improved the Storage classes and functions (I'm doing proper java, yipie) 13 13 - Better error handling for command suggestions 14 14 - Added hover effects for warp and homes text (W.I.P) 15 + - Throw an exception when the world isn't found (when doing back or home), instead of giving an incorrect notFound error. 15 16 16 17 ### [v1.2.2] 17 18 - Handled a case where the client (geyser) will return the language as uppercase instead of lowercase.
+40 -44
common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java
··· 1 1 package dev.mrsnowy.teleport_commands.commands; 2 2 3 3 import com.mojang.brigadier.arguments.BoolArgumentType; 4 - import com.mojang.datafixers.util.Pair; 5 4 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 5 7 6 import java.util.*; 8 7 9 8 import dev.mrsnowy.teleport_commands.storage.DeathLocationStorage; 10 - import dev.mrsnowy.teleport_commands.utils.tools; 9 + import dev.mrsnowy.teleport_commands.common.DeathLocation; 11 10 import net.minecraft.ChatFormatting; 12 11 import net.minecraft.commands.Commands; 13 12 import net.minecraft.core.BlockPos; ··· 58 57 } 59 58 60 59 61 - private static void ToDeathLocation(ServerPlayer player, boolean safetyDisabled) { 60 + // ----- 62 61 63 - DeathLocationStorage.backList backList = DeathLocationStorage.backList; 64 62 65 - // get the deathLocation 66 - Optional<DeathLocationStorage.deathLocationClass> optionalDeathLocation = backList.getDeathLocation( player.getStringUUID() ); 63 + // Gets the DeathLocation of the player and teleports the player to it 64 + private static void ToDeathLocation(ServerPlayer player, boolean safetyDisabled) throws Exception { 65 + 66 + Optional<DeathLocation> optionalDeathLocation = DeathLocationStorage.getDeathLocation(player.getStringUUID()); 67 + 67 68 if (optionalDeathLocation.isEmpty()) { 68 69 player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player) 69 70 .withStyle(ChatFormatting.RED), true); 70 71 return; 71 72 } 72 73 73 - DeathLocationStorage.deathLocationClass deathLocation = optionalDeathLocation.get(); 74 + DeathLocation deathLocation = optionalDeathLocation.get(); 74 75 75 - // get the world 76 - Optional<ServerLevel> OptionalWorld = tools.getWorld( deathLocation.world ); 77 - if (OptionalWorld.isEmpty()) { 78 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player) 79 - .withStyle(ChatFormatting.RED), true); 80 - return; 76 + // get the world, otherwise throw an exception 77 + Optional<ServerLevel> optionalWorld = deathLocation.getWorld(); 78 + if (optionalWorld.isEmpty()) { 79 + // todo! test this exception 80 + 81 + throw new Exception( String.format("Couldn't find a world with the id: %s \nAvailable worlds: %s", 82 + deathLocation.getWorldString(), TeleportCommands.SERVER.getAllLevels())); 81 83 } 82 84 83 - ServerLevel world = OptionalWorld.get(); 85 + ServerLevel deathLocationWorld = optionalWorld.get(); 86 + BlockPos teleportBlockPos; 84 87 85 - // if safety is enabled, check if the death location is safe. 88 + // Sets the teleportBlockPos based on if it should do safety checking 86 89 if (!safetyDisabled) { 87 - 88 - Pair<Integer, Optional<Vec3>> teleportData = teleportSafetyChecker(deathLocation.pos, world, player); 89 - 90 - switch (teleportData.getFirst()) { 91 - case 0: // safe location found! 92 - if (teleportData.getSecond().isPresent()) { 93 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); 94 - Teleporter(player, world, teleportData.getSecond().get()); 95 - } else { 96 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 97 - } 90 + Optional<BlockPos> safeBlockPos = getSafeBlockPos(deathLocation.getBlockPos(), deathLocationWorld); 98 91 99 - break; 100 - case 1: // same 101 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); 102 - break; 103 - case 2: // no safe location 92 + // Check if there is a safe BlockPos 93 + if (safeBlockPos.isPresent()) { 94 + teleportBlockPos = safeBlockPos.get(); 104 95 105 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); 106 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); 107 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) 108 - .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/back true"))),false); 109 - break; 96 + } else { 97 + // asks the player if they want to teleport anyway 98 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); 99 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); 100 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) 101 + .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/back true"))),false); 102 + return; 110 103 } 111 104 112 105 } else { 113 - BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 106 + // no checking needed, just set it. 107 + teleportBlockPos = deathLocation.getBlockPos(); 108 + } 114 109 115 - if (!playerBlockPos.equals(deathLocation.pos) || player.level() != world) { 110 + // check if the player is already at this location (in the same world) 111 + if (player.blockPosition().equals(teleportBlockPos) && player.level() == deathLocationWorld) { 112 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); 116 113 117 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); 118 - Teleporter(player, world, new Vec3(deathLocation.pos.getX() + 0.5, deathLocation.pos.getY(), deathLocation.pos.getZ() + 0.5)); 114 + } else { 115 + // teleport the player! 116 + Vec3 teleportPos = new Vec3(teleportBlockPos.getX() + 0.5, teleportBlockPos.getY(), teleportBlockPos.getZ() + 0.5); 119 117 120 - } else { 121 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); 122 - } 118 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); 119 + Teleporter(player, deathLocationWorld, teleportPos); 123 120 } 124 - 125 121 } 126 122 }
+86 -68
common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java
··· 4 4 import com.mojang.datafixers.util.Pair; 5 5 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 6 import dev.mrsnowy.teleport_commands.storage.StorageManager; 7 + import dev.mrsnowy.teleport_commands.common.NamedLocation; 8 + import dev.mrsnowy.teleport_commands.common.Player; 7 9 import dev.mrsnowy.teleport_commands.suggestions.HomeSuggestionProvider; 10 + 11 + import java.util.Locale; 8 12 import java.util.Objects; 13 + import java.util.Optional; 14 + 9 15 import net.minecraft.ChatFormatting; 10 16 import net.minecraft.commands.Commands; 11 17 import net.minecraft.core.BlockPos; ··· 15 21 import net.minecraft.server.level.ServerPlayer; 16 22 import net.minecraft.world.phys.Vec3; 17 23 24 + import static dev.mrsnowy.teleport_commands.storage.StorageManager.STORAGE; 18 25 import static dev.mrsnowy.teleport_commands.utils.tools.getTranslatedText; 19 26 import static net.minecraft.commands.Commands.argument; 20 - import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage; 21 27 import static dev.mrsnowy.teleport_commands.storage.StorageManager.StorageSaver; 22 28 import static dev.mrsnowy.teleport_commands.utils.tools.Teleporter; 23 29 ··· 150 156 } 151 157 152 158 159 + // ----- 153 160 161 + // Adds a new home to the homeList of a player 154 162 private static void SetHome(ServerPlayer player, String homeName) throws Exception { 155 163 homeName = homeName.toLowerCase(); 156 - BlockPos blockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 164 + BlockPos blockPos = player.blockPosition(); 157 165 ServerLevel world = player.serverLevel(); 158 166 159 - Pair<StorageManager.StorageClass, StorageManager.StorageClass.Player> storages = GetPlayerStorage(player.getStringUUID()); 160 - StorageManager.StorageClass storage = storages.getFirst(); 161 - StorageManager.StorageClass.Player playerStorage = storages.getSecond(); 162 - 163 - boolean homeNotFound = true; 167 + // Gets player storage and makes it if it doesn't exist 168 + Player playerStorage = StorageManager.STORAGE.addPlayer(player.getStringUUID()); 164 169 165 170 // check for duplicates 166 - for (StorageManager.StorageClass.NamedLocation currentHome : playerStorage.Homes) { 167 - if (Objects.equals(currentHome.name, homeName)) { 168 - homeNotFound = false; 169 - break; 170 - } 171 + if (playerStorage.getHome(homeName).isPresent()) { 172 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.exists", player).withStyle(ChatFormatting.RED), true); 173 + return; 171 174 } 172 175 173 - if (homeNotFound) { 174 - // Create a new NamedLocation 175 - StorageManager.StorageClass.NamedLocation homeLocation = new StorageManager.StorageClass.NamedLocation(homeName, blockPos, world.dimension().location().toString()); 176 + // Create a new NamedLocation 177 + playerStorage.setHome(homeName, blockPos, world.dimension().location().toString()); 176 178 177 - playerStorage.Homes.add(homeLocation); 178 - 179 - if (playerStorage.Homes.size() == 1) { 180 - playerStorage.DefaultHome = homeName; 181 - } 179 + // Set it as the default if there are no other homes 180 + if (playerStorage.getHomes().size() == 1) { 181 + playerStorage.setDefaultHome(homeName); 182 + } 182 183 183 - StorageSaver(); 184 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.set", player), true); 185 - } else { 186 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.exists", player).withStyle(ChatFormatting.RED), true); 187 - } 184 + // Display message that the home as been set 185 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.set", player), true); 188 186 } 189 187 188 + // Teleports the player to the home. It will go to the defaultHome if homeName is empty 190 189 private static void GoHome(ServerPlayer player, String homeName) throws Exception { 191 190 homeName = homeName.toLowerCase(); 192 - StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).getSecond(); 191 + 192 + // Gets player storage 193 + Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 194 + if (optionalPlayerStorage.isEmpty()) { 195 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 196 + return; 197 + } 193 198 194 - // check if there is a default exists 199 + Player playerStorage = optionalPlayerStorage.get(); 200 + 201 + // if homeName is empty, get the default home 195 202 if (homeName.isEmpty()) { 196 - if (playerStorage.DefaultHome.isEmpty()) { 203 + // todo! if there is no default home set, maybe give an message saying: no default home set! 204 + String defaultHome = playerStorage.getDefaultHome(); 205 + 206 + if (defaultHome.isEmpty()) { 197 207 player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 198 208 return; 199 209 } else { 200 - homeName = playerStorage.DefaultHome; 210 + homeName = defaultHome; 201 211 } 202 212 } 203 213 204 - boolean foundWorld = false; 205 - 206 - // find correct home 207 - for (StorageManager.StorageClass.NamedLocation currentHome : playerStorage.Homes) { 208 - if (Objects.equals(currentHome.name, homeName)) { 214 + // get the home (if it exists) 215 + Optional<NamedLocation> optionalHome = playerStorage.getHome(homeName); 216 + if (optionalHome.isEmpty()) { 217 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.AQUA), true); 218 + return; 219 + } 209 220 210 - // find correct world 211 - for (ServerLevel currentWorld : TeleportCommands.SERVER.getAllLevels()) { 212 - if (Objects.equals(currentWorld.dimension().location().toString(), currentHome.world)) { 213 - foundWorld = true; 221 + NamedLocation home = optionalHome.get(); 214 222 215 - BlockPos blockPos = new BlockPos(currentHome.x, currentHome.y, currentHome.z); 216 - BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 223 + // get the world, otherwise throw an exception 224 + Optional<ServerLevel> optionalHomeWorld = home.getWorld(); 225 + if (optionalHomeWorld.isEmpty()) { 226 + // todo! test this exception 217 227 218 - if (!playerBlockPos.equals(blockPos) || player.level() != currentWorld) { 219 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.go", player), true); 220 - Teleporter(player, currentWorld, new Vec3(currentHome.x + 0.5, currentHome.y, currentHome.z + 0.5)); 221 - } else { 222 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.goSame", player).withStyle(ChatFormatting.AQUA), true); 223 - } 224 - break; 225 - } 226 - } 227 - } 228 + throw new Exception( String.format("Couldn't find a world with the id: %s \nAvailable worlds: %s", 229 + home.getWorldString(), TeleportCommands.SERVER.getAllLevels())); 228 230 } 229 231 230 - if (!foundWorld) { 231 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 232 + ServerLevel homeWorld = optionalHomeWorld.get(); 233 + BlockPos teleportBlockPos = home.getBlockPos(); 234 + 235 + // check if the player is already at this location (in the same world) 236 + if (player.blockPosition().equals(teleportBlockPos) && player.level() == homeWorld) { 237 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.goSame", player).withStyle(ChatFormatting.AQUA), true); 238 + 239 + } else { 240 + // teleport the player! 241 + Vec3 teleportPos = new Vec3(teleportBlockPos.getX() + 0.5, teleportBlockPos.getY(), teleportBlockPos.getZ() + 0.5); 242 + 243 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.go", player), true); 244 + Teleporter(player, homeWorld, teleportPos); 232 245 } 233 246 } 234 247 235 248 private static void DeleteHome(ServerPlayer player, String homeName) throws Exception { 236 249 homeName = homeName.toLowerCase(); 237 - Pair<StorageManager.StorageClass, StorageManager.StorageClass.Player> storages = GetPlayerStorage(player.getStringUUID()); 238 - StorageManager.StorageClass storage = storages.getFirst(); 239 - StorageManager.StorageClass.Player playerStorage = storages.getSecond(); 240 250 241 - boolean deletedHome = false; 251 + // Gets player storage 252 + Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 253 + if (optionalPlayerStorage.isEmpty()) { 254 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.homeless", player).withStyle(ChatFormatting.AQUA), true); 255 + return; 256 + } 242 257 243 - // get correct home 244 - for (StorageManager.StorageClass.NamedLocation currentHome : playerStorage.Homes) { 245 - if (Objects.equals(currentHome.name, homeName)) { 246 - // delete the home 247 - playerStorage.Homes.remove(currentHome); 248 - StorageSaver(); 258 + Player playerStorage = optionalPlayerStorage.get(); 249 259 250 - deletedHome = true; 251 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.delete", player), true); 252 - break; 253 - } 260 + // Get the home from the player 261 + Optional<NamedLocation> optionalHome = playerStorage.getHome(homeName); 262 + if (optionalHome.isEmpty()) { 263 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.AQUA), true); 264 + return; 254 265 } 255 266 256 - if (!deletedHome) { 257 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.notFound", player).withStyle(ChatFormatting.RED), true); 267 + NamedLocation home = optionalHome.get(); 268 + 269 + // check if it's the default home, if it is set it to the default value 270 + if (playerStorage.getDefaultHome().equals(homeName)) { 271 + playerStorage.setDefaultHome(""); 258 272 } 273 + 274 + // delete the home 275 + playerStorage.deleteHome(home); 276 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.delete", player), true); 259 277 } 260 278 261 279 private static void RenameHome(ServerPlayer player, String homeName, String newHomeName) throws Exception {
+15 -20
common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java
··· 2 2 3 3 import java.util.*; 4 4 5 - import com.mojang.datafixers.util.Pair; 6 5 import dev.mrsnowy.teleport_commands.TeleportCommands; 7 6 import dev.mrsnowy.teleport_commands.suggestions.tpaSuggestionProvider; 8 7 9 8 import net.minecraft.ChatFormatting; 10 9 import net.minecraft.commands.Commands; 11 10 import net.minecraft.commands.arguments.EntityArgument; 11 + import net.minecraft.core.BlockPos; 12 12 import net.minecraft.network.chat.ClickEvent; 13 13 import net.minecraft.network.chat.Component; 14 14 import net.minecraft.server.level.ServerPlayer; ··· 31 31 this.here = here; 32 32 tpaList.add(this); 33 33 } 34 + 35 + 34 36 } 35 37 36 38 public static void register(Commands commandManager) { ··· 115 117 .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.InitPlayer)) 116 118 .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.RecPlayer)) 117 119 .count(); 118 - 119 120 120 121 if (FromPlayer == ToPlayer) { 121 122 FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); ··· 165 166 166 167 private static void tpaAccept(ServerPlayer FromPlayer, ServerPlayer ToPlayer) { 167 168 if (FromPlayer == ToPlayer) { 168 - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA),true); 169 + FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA), true); 169 170 return; 170 171 } 171 172 173 + // Check if there is a request 172 174 Optional<tpaArrayClass> tpaStorage = tpaList.stream() 173 175 .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.InitPlayer)) 174 176 .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.RecPlayer)) 175 177 .findFirst(); 176 178 177 - // Check if there is a request 178 179 if (tpaStorage.isPresent()) { 179 - 180 + // Request found 180 181 ServerPlayer destinationPlayer = tpaStorage.get().here ? ToPlayer : FromPlayer; 181 182 ServerPlayer toSentPlayer = tpaStorage.get().here ? FromPlayer : ToPlayer; 182 183 183 - Pair<Integer, Optional<Vec3>> teleportData = teleportSafetyChecker(destinationPlayer.blockPosition(), destinationPlayer.serverLevel(), toSentPlayer); // todo! make sure .blockPosition is correct 184 + Optional<BlockPos> teleportData = getSafeBlockPos(destinationPlayer.blockPosition(), destinationPlayer.serverLevel()); 184 185 185 - switch (teleportData.getFirst()) { 186 - case 1: // same (let it fall through) 187 - case 0: // safe! 188 - if (teleportData.getSecond().isPresent() ) { 186 + if (teleportData.isPresent()) { 187 + BlockPos safeBlockPos = teleportData.get(); 188 + Vec3 teleportPos = new Vec3(safeBlockPos.getX() + 0.5, safeBlockPos.getY(), safeBlockPos.getZ() + 0.5); 189 189 190 - Teleporter(toSentPlayer, destinationPlayer.serverLevel(), teleportData.getSecond().get()); 191 - break; 192 - } else { 193 - toSentPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", toSentPlayer).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 194 - return; // exit 195 - } 196 - case 2: // if no safe location then just teleport to the player 197 - Teleporter(toSentPlayer, destinationPlayer.serverLevel(), destinationPlayer.position()); 198 - break; 190 + Teleporter(toSentPlayer, destinationPlayer.serverLevel(), teleportPos); 191 + } else { 192 + // if no safe location then just teleport to the player 193 + Teleporter(toSentPlayer, destinationPlayer.serverLevel(), destinationPlayer.position()); 199 194 } 200 195 201 196 // if the player teleported then these messages get sent && the request gets removed ··· 203 198 ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", ToPlayer).withStyle(ChatFormatting.GREEN),true); 204 199 tpaList.remove(tpaStorage.get()); 205 200 206 - // No request found 207 201 } else { 202 + // No request found 208 203 FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); 209 204 } 210 205 }
+2 -5
common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java
··· 3 3 import com.mojang.brigadier.arguments.StringArgumentType; 4 4 import com.mojang.datafixers.util.Pair; 5 5 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 - import dev.mrsnowy.teleport_commands.storage.StorageManager; 7 - import dev.mrsnowy.teleport_commands.storage.classes.NamedLocation; 6 + import dev.mrsnowy.teleport_commands.common.NamedLocation; 8 7 import dev.mrsnowy.teleport_commands.suggestions.WarpSuggestionProvider; 9 8 import net.minecraft.ChatFormatting; 10 9 import net.minecraft.commands.Commands; ··· 15 14 import net.minecraft.server.level.ServerLevel; 16 15 import net.minecraft.server.level.ServerPlayer; 17 16 import net.minecraft.world.phys.Vec3; 18 - import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; 19 17 20 - import javax.swing.text.html.Option; 21 18 import java.util.ArrayList; 22 19 import java.util.List; 23 20 import java.util.Objects; ··· 206 203 Optional<NamedLocation> optionalWarp = STORAGE.getWarp(warpName); 207 204 208 205 if (optionalWarp.isPresent()) { 209 - STORAGE.removeWarp(warpName); //todo! maybe improve double getting of warp? 206 + STORAGE.rmWarp(optionalWarp.get()); 210 207 211 208 } else { 212 209 // the warp is not found
+25 -27
common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java
··· 1 1 package dev.mrsnowy.teleport_commands.commands; 2 2 3 3 import com.mojang.brigadier.arguments.BoolArgumentType; 4 - import com.mojang.datafixers.util.Pair; 5 4 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 5 import net.minecraft.ChatFormatting; 7 6 import net.minecraft.commands.Commands; ··· 31 30 toWorldSpawn(player, false); 32 31 33 32 } catch (Exception error) { 34 - TeleportCommands.LOGGER.error("Error while going back! => ", error); 33 + TeleportCommands.LOGGER.error("Error while going to the worldspawn! => ", error); 35 34 player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 36 35 return 1; 37 36 } ··· 47 46 toWorldSpawn(player, safety); 48 47 49 48 } catch (Exception error) { 50 - TeleportCommands.LOGGER.error("Error while going back! => ", error); 49 + TeleportCommands.LOGGER.error("Error while going to the worldspawn! => ", error); 51 50 player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 52 51 return 1; 53 52 } ··· 60 59 private static void toWorldSpawn(ServerPlayer player, boolean safetyDisabled) throws NullPointerException { 61 60 // todo! maybe make this more fool proof? 62 61 ServerLevel world = TeleportCommands.SERVER.getLevel(OVERWORLD); 63 - BlockPos worldSpawn = Objects.requireNonNull(world,"Overworld cannot be null").getSharedSpawnPos(); 62 + BlockPos worldSpawn = Objects.requireNonNull(world,"Overworld cannot be null!").getSharedSpawnPos(); 64 63 65 64 if (!safetyDisabled) { 66 - Pair<Integer, Optional<Vec3>> teleportData = teleportSafetyChecker(worldSpawn, world, player); 65 + Optional<BlockPos> teleportData = getSafeBlockPos(worldSpawn, world); 67 66 68 - switch (teleportData.getFirst()) { 69 - case 0: // safe location found! 70 - if (teleportData.getSecond().isPresent()) { 71 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.go", player), true); 72 - Teleporter(player, world, teleportData.getSecond().get()); 73 - } else { 74 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); 75 - } 67 + if (teleportData.isPresent()) { 68 + BlockPos safeBlockPos = teleportData.get(); 69 + 70 + // check if the player is already at this location 71 + if (player.blockPosition().equals(safeBlockPos) && player.level() == world) { 76 72 77 - break; 78 - case 1: // the location is already safe! 79 73 player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 80 - break; 81 - case 2: // no safe location found! 74 + } else { 75 + Vec3 teleportPos = new Vec3(safeBlockPos.getX() + 0.5, safeBlockPos.getY(), safeBlockPos.getZ() + 0.5); 82 76 83 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); 84 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); 85 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) 86 - .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/worldspawn true"))),false); 87 - break; 77 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.go", player), true); 78 + Teleporter(player, world, teleportPos); 79 + } 80 + 81 + } else { 82 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); 83 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); 84 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) 85 + .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/worldspawn true"))),false); 88 86 } 87 + 89 88 } else { 90 - BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 89 + 90 + if (player.blockPosition().equals(worldSpawn) && player.level() == world) { 91 91 92 - if (!playerBlockPos.equals(worldSpawn) || player.level() != world) { 92 + player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 93 + } else { 93 94 94 95 player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.go", player), true); 95 96 Teleporter(player, world, new Vec3(worldSpawn.getX() + 0.5, worldSpawn.getY(), worldSpawn.getZ() + 0.5)); 96 - 97 - } else { 98 - player.displayClientMessage(getTranslatedText("commands.teleport_commands.worldspawn.same", player).withStyle(ChatFormatting.AQUA), true); 99 97 } 100 98 } 101 99 }
+54
common/src/main/java/dev/mrsnowy/teleport_commands/common/DeathLocation.java
··· 1 + package dev.mrsnowy.teleport_commands.common; 2 + 3 + import dev.mrsnowy.teleport_commands.TeleportCommands; 4 + import net.minecraft.core.BlockPos; 5 + import net.minecraft.server.level.ServerLevel; 6 + 7 + import java.util.Objects; 8 + import java.util.Optional; 9 + import java.util.stream.StreamSupport; 10 + 11 + public class DeathLocation { 12 + private final String UUID; 13 + private BlockPos pos; 14 + private String world; 15 + 16 + public DeathLocation(String uuid, BlockPos pos, String world) { 17 + this.UUID = uuid; 18 + this.pos = pos; 19 + this.world = world; 20 + } 21 + 22 + // ----- 23 + 24 + public String getUUID() { 25 + return UUID; 26 + } 27 + 28 + public BlockPos getBlockPos() { 29 + return pos; 30 + } 31 + 32 + // maybe add getX getY and getZ? todo! 33 + 34 + public String getWorldString() { 35 + return world; 36 + } 37 + 38 + // function to quickly filter the worlds and get the ServerLevel for the string 39 + public Optional<ServerLevel> getWorld() { 40 + return StreamSupport.stream( TeleportCommands.SERVER.getAllLevels().spliterator(), false ) // woa, this looks silly 41 + .filter(level -> Objects.equals( level.dimension().location().toString(), this.world )) 42 + .findFirst(); 43 + } 44 + 45 + // ----- note to self: these don't need to be saved since this class isn't a part of the storage :3 46 + 47 + public void setBlockPos(BlockPos pos) { 48 + this.pos = pos; 49 + } 50 + 51 + public void setWorld(String world) { 52 + this.world = world; 53 + } 54 + }
+67
common/src/main/java/dev/mrsnowy/teleport_commands/common/NamedLocation.java
··· 1 + package dev.mrsnowy.teleport_commands.common; 2 + 3 + import dev.mrsnowy.teleport_commands.TeleportCommands; 4 + import dev.mrsnowy.teleport_commands.storage.StorageManager; 5 + import net.minecraft.core.BlockPos; 6 + import net.minecraft.server.level.ServerLevel; 7 + 8 + import java.util.Objects; 9 + import java.util.Optional; 10 + import java.util.stream.StreamSupport; 11 + 12 + public class NamedLocation { 13 + private String name; 14 + private final int x; 15 + private final int y; 16 + private final int z; 17 + private final String world; 18 + 19 + public NamedLocation(String name, BlockPos pos, String world) { 20 + this.name = name; 21 + this.x = pos.getX(); 22 + this.y = pos.getY(); 23 + this.z = pos.getZ(); 24 + this.world = world; 25 + } 26 + 27 + // ----- 28 + 29 + public String getName() { 30 + return this.name; 31 + } 32 + 33 + public BlockPos getBlockPos() { 34 + return new BlockPos(this.x, this.y, this.z); 35 + } 36 + 37 + public int getX() { 38 + return this.x; 39 + } 40 + 41 + public int getY() { 42 + return this.y; 43 + } 44 + 45 + public int getZ() { 46 + return this.z; 47 + } 48 + 49 + public String getWorldString() { 50 + return this.world; 51 + } 52 + 53 + // function to quickly filter the worlds and get the ServerLevel for the string 54 + public Optional<ServerLevel> getWorld() { 55 + return StreamSupport.stream( TeleportCommands.SERVER.getAllLevels().spliterator(), false ) // woa, this looks silly 56 + .filter(level -> Objects.equals( level.dimension().location().toString(), this.world )) 57 + .findFirst(); 58 + 59 + } 60 + 61 + // ----- 62 + 63 + public void setName(String name) throws Exception { 64 + this.name = name; 65 + StorageManager.StorageSaver(); 66 + } 67 + }
+76
common/src/main/java/dev/mrsnowy/teleport_commands/common/Player.java
··· 1 + package dev.mrsnowy.teleport_commands.common; 2 + 3 + import dev.mrsnowy.teleport_commands.storage.StorageManager; 4 + import net.minecraft.core.BlockPos; 5 + 6 + import java.util.ArrayList; 7 + import java.util.Objects; 8 + import java.util.Optional; 9 + 10 + import static java.util.Collections.unmodifiableList; 11 + 12 + public class Player { 13 + private final String UUID; 14 + private String DefaultHome = ""; 15 + private final ArrayList<NamedLocation> Homes = new ArrayList<>(); 16 + 17 + public Player(String uuid) { 18 + this.UUID = uuid; 19 + } 20 + 21 + // ----- 22 + 23 + public String getUUID() { 24 + return UUID; 25 + } 26 + 27 + public String getDefaultHome() { 28 + return DefaultHome; 29 + } 30 + 31 + // returns all homes 32 + public ArrayList<NamedLocation> getHomes() { 33 + return (ArrayList<NamedLocation>) unmodifiableList(Homes); 34 + } 35 + 36 + // returns a specific home based on the name (if there is one) 37 + public Optional<NamedLocation> getHome(String name) { 38 + return Homes.stream() 39 + .filter( home -> Objects.equals( home.getName(), name )) 40 + .findFirst(); 41 + } 42 + 43 + // ----- 44 + 45 + public void setDefaultHome(String defaultHome) throws Exception { 46 + this.DefaultHome = defaultHome; 47 + StorageManager.StorageSaver(); 48 + } 49 + 50 + // todo! modify this so it uses a NamedLocation as an input 51 + // creates a new home, if there already is a home it will update the existing one 52 + public void setHome(String name, BlockPos pos, String world) throws Exception { 53 + Optional<NamedLocation> optionalHome = getHome(name); 54 + NamedLocation home; 55 + 56 + if (optionalHome.isEmpty()) { 57 + home = new NamedLocation(name, pos, world); 58 + 59 + Homes.add(home); 60 + } else { 61 + home = optionalHome.get(); 62 + 63 + home.setName(name); 64 + } 65 + 66 + StorageManager.StorageSaver(); 67 + } 68 + 69 + // ----- 70 + 71 + public void deleteHome(NamedLocation home) throws Exception { 72 + Homes.remove(home); 73 + 74 + StorageManager.StorageSaver(); 75 + } 76 + }
+1 -1
common/src/main/java/dev/mrsnowy/teleport_commands/storage/DeathLocationStorage.java
··· 1 1 package dev.mrsnowy.teleport_commands.storage; 2 2 3 - import dev.mrsnowy.teleport_commands.storage.classes.DeathLocation; 3 + import dev.mrsnowy.teleport_commands.common.DeathLocation; 4 4 import net.minecraft.core.BlockPos; 5 5 6 6 import java.util.ArrayList;
+6 -11
common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
··· 3 3 import com.google.gson.Gson; 4 4 import com.google.gson.GsonBuilder; 5 5 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 - import dev.mrsnowy.teleport_commands.storage.classes.NamedLocation; 7 - import dev.mrsnowy.teleport_commands.storage.classes.Player; 6 + import dev.mrsnowy.teleport_commands.common.NamedLocation; 7 + import dev.mrsnowy.teleport_commands.common.Player; 8 8 import net.minecraft.core.BlockPos; 9 9 10 10 import java.io.File; ··· 101 101 } 102 102 103 103 // creates a new player, if there already is a player it will return the existing one. The player won't be saved unless they actually do something lol 104 + // todo! check if this works fully 104 105 public Player addPlayer(String uuid) { 105 106 final Optional<Player> OptionalPlayer = getPlayer(uuid); 106 107 ··· 120 121 121 122 // ----- 122 123 123 - public void removeWarp(String name) throws Exception { 124 - Optional<NamedLocation> OptionalWarp = getWarp(name); 125 - 126 - if (OptionalWarp.isPresent()) { 127 - Warps.remove(OptionalWarp.get()); 128 - StorageSaver(); 129 - } else { 130 - //todo! ??? 131 - } 124 + public void rmWarp(NamedLocation warp) throws Exception { 125 + Warps.remove(warp); 126 + StorageSaver(); 132 127 } 133 128 } 134 129 }
+4 -4
common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomeSuggestionProvider.java
··· 9 9 import java.util.Optional; 10 10 import java.util.concurrent.CompletableFuture; 11 11 12 - import dev.mrsnowy.teleport_commands.storage.classes.NamedLocation; 13 - import dev.mrsnowy.teleport_commands.storage.classes.Player; 12 + import dev.mrsnowy.teleport_commands.common.NamedLocation; 13 + import dev.mrsnowy.teleport_commands.common.Player; 14 14 import net.minecraft.commands.CommandSourceStack; 15 15 import net.minecraft.server.level.ServerPlayer; 16 16 ··· 24 24 Optional<Player> optionalPlayerStorage = STORAGE.getPlayer(player.getStringUUID()); 25 25 26 26 if (optionalPlayerStorage.isPresent()) { 27 - Player PlayerStorage = optionalPlayerStorage.get(); 27 + Player playerStorage = optionalPlayerStorage.get(); 28 28 29 - for (NamedLocation currentHome : PlayerStorage.getHomes()) { 29 + for (NamedLocation currentHome : playerStorage.getHomes()) { 30 30 builder.suggest(currentHome.getName()); 31 31 } 32 32 }
+1 -1
common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/WarpSuggestionProvider.java
··· 7 7 8 8 import dev.mrsnowy.teleport_commands.TeleportCommands; 9 9 import dev.mrsnowy.teleport_commands.storage.StorageManager; 10 - import dev.mrsnowy.teleport_commands.storage.classes.NamedLocation; 10 + import dev.mrsnowy.teleport_commands.common.NamedLocation; 11 11 12 12 import net.minecraft.commands.CommandSourceStack; 13 13
+21 -30
common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
··· 1 1 package dev.mrsnowy.teleport_commands.utils; 2 2 3 3 import com.google.gson.*; 4 - import com.mojang.datafixers.util.Pair; 5 4 import dev.mrsnowy.teleport_commands.TeleportCommands; 6 5 7 6 import java.io.*; ··· 39 38 // teleport! 40 39 player.teleportTo(world, coords.x, coords.y, coords.z, Set.of(), player.getYRot(), player.getXRot(), false); 41 40 42 - // Restore flying when teleporting dimensions 41 + // Restore flying when teleporting trough dimensions 43 42 if (flying) { 44 43 player.getAbilities().flying = true; 45 44 player.onUpdateAbilities(); ··· 61 60 ); 62 61 } 63 62 63 + 64 64 // checks a 7x7x7 location around the player in order to find a safe place to teleport them to. 65 - public static Pair<Integer, Optional<Vec3>> teleportSafetyChecker(BlockPos blockPos, ServerLevel world, ServerPlayer player) { 65 + public static Optional<BlockPos> getSafeBlockPos(BlockPos blockPos, ServerLevel world) { 66 66 int row = 1; 67 67 int rows = 3; 68 68 69 - BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 70 - int playerX = blockPos.getX(); 71 - int playerY = blockPos.getY(); 72 - int playerZ = blockPos.getZ(); 69 + int blockPosX = blockPos.getX(); 70 + int blockPosY = blockPos.getY(); 71 + int blockPosZ = blockPos.getZ(); 73 72 74 - // find a safe location in an x row radius 75 - if (isBlockPosUnsafe(blockPos, world)) { 73 + if (isBlockPosSafe(blockPos, world)) { 74 + return Optional.of(blockPos); // safe location found! 76 75 76 + } else { 77 + // find a safe location in an x row radius 77 78 while (row <= rows) { 78 79 // TeleportCommands.LOGGER.info("currently doing row " + row + " of " + rows); //debug 79 - 80 80 for (int z = -row; z <= row; z++) { 81 81 for (int x = -row; x <= row; x++) { 82 82 for (int y = -row; y <= row; y++) { ··· 84 84 // checks if we are on the outer layer of the row, not on the inside 85 85 if ((x == -row || x == row) || (z == -row || z == row) || (y == -row || y == row)) { 86 86 87 - BlockPos newSafePos = new BlockPos(playerX + x, playerY + y, playerZ + z); 87 + // calculate a new blockPos based on the offset we generated 88 + BlockPos newPos = new BlockPos(blockPosX + x, blockPosY + y, blockPosZ + z); 88 89 89 - if (!isBlockPosUnsafe(newSafePos, world)) { 90 - 91 - if (!playerBlockPos.equals(newSafePos) || player.level() != world) { 92 - return new Pair<>(0, Optional.of(new Vec3(newSafePos.getX() + 0.5, newSafePos.getY(), newSafePos.getZ() + 0.5))); // safe location found! 93 - 94 - } else { 95 - return new Pair<>(1, Optional.of(new Vec3(newSafePos.getX() + 0.5, newSafePos.getY(), newSafePos.getZ() + 0.5))); // the location is already safe! 96 - } 90 + if (isBlockPosSafe(newPos, world)) { 91 + // return Optional.of(new Vec3(newPos.getX() + 0.5, newPos.getY(), newPos.getZ() + 0.5)); // safe location found! 92 + return Optional.of(newPos); 97 93 } 98 94 } 99 95 } ··· 102 98 103 99 row++; 104 100 } 105 - // no safe location 106 - return new Pair<>(2, Optional.empty()); // no safe location found! 107 101 108 - // check if the location is the same 109 - } else if (!playerBlockPos.equals(blockPos) || player.level() != world) { 110 - return new Pair<>(0, Optional.of(new Vec3(playerX + 0.5, playerY, playerZ + 0.5))); // safe location found! 111 - 112 - } else { 113 - return new Pair<>(1, Optional.of(new Vec3(playerX + 0.5, playerY, playerZ + 0.5))); // the location is already safe! 102 + // no safe location 103 + return Optional.empty(); // no safe location found! 114 104 } 115 105 } 116 106 ··· 186 176 } 187 177 } 188 178 179 + // todo! test 189 180 // checks if a bock position is unsafe, used by the teleportSafetyChecker. 190 - private static boolean isBlockPosUnsafe(BlockPos bottomPlayer, ServerLevel world) { 181 + private static boolean isBlockPosSafe(BlockPos bottomPlayer, ServerLevel world) { 191 182 192 183 // get the block below the player 193 184 BlockPos belowPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() -1, bottomPlayer.getZ()); // below the player ··· 206 197 && (world.getBlockState(bottomPlayer).getCollisionShape(world, bottomPlayer).isEmpty() && !unsafeCollisionFreeBlocks.contains(BottomPlayerId)) // check if it is a collision free block that isn't dangerous 207 198 && (!unsafeCollisionFreeBlocks.contains(TopPlayerId))) // check if it is a dangerous collision free block, if it is solid then the player crawls 208 199 { 209 - return false; // it's safe 200 + return true; // it's safe 210 201 } 211 - return true; // it's not safe! 202 + return false; // it's not safe! 212 203 } 213 204 }