diff --git a/CHANGELOG.md b/CHANGELOG.md index 582f8d1..0984c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +### [W.I.P] +- Storage is loaded in memory instead of reading it again and again, Improves speed and IO usage +- Made it so the DeathLocation is only kept in memory (WIP) +- Improved the Storage classes and functions (I'm doing proper java, yipie) + ### [v1.2.2] - Handled a case where the client (geyser) will return the language as uppercase instead of lowercase. - Fixed null-pointer exceptions being logged when a language file couldn't be found. diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java b/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java index d62e88f..bf1efc5 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java @@ -1,10 +1,10 @@ package dev.mrsnowy.teleport_commands; import com.google.gson.*; +import com.mojang.datafixers.util.Pair; import dev.mrsnowy.teleport_commands.storage.StorageManager; import dev.mrsnowy.teleport_commands.commands.*; import net.minecraft.commands.Commands; -import net.minecraft.core.BlockPos; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.storage.LevelResource; @@ -17,8 +17,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import net.minecraft.core.BlockPos; -import static dev.mrsnowy.teleport_commands.utils.tools.DeathLocationUpdater; +import static dev.mrsnowy.teleport_commands.storage.StorageManager.*; public class TeleportCommands { public static final String MOD_ID = "teleport_commands"; @@ -42,7 +43,7 @@ public class TeleportCommands { SERVER = server; - cleanStorage(); + StorageManager.STORAGE = storageValidator(); // initialize commands, also allows me to easily disable any when there is a config Commands commandManager = server.getCommands(); @@ -53,27 +54,51 @@ public class TeleportCommands { worldspawn.register(commandManager); } + + // Runs when the playerDeath mixin calls it, updates the /back command position public static void onPlayerDeath(ServerPlayer player) { try { - // update /back command position - DeathLocationUpdater(new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()), player.serverLevel(), player.getStringUUID()); + BlockPos pos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); + + Pair storages = GetPlayerStorage(player.getStringUUID()); + + StorageManager.StorageClass.Player playerStorage = storages.getSecond(); + + playerStorage.deathLocation.x = pos.getX(); + playerStorage.deathLocation.y = pos.getY(); + playerStorage.deathLocation.z = pos.getZ(); + playerStorage.deathLocation.world = player.serverLevel().dimension().location().toString(); + + StorageSaver(); } catch (Exception e) { - LOGGER.error(e.toString()); + LOGGER.error("Error while saving the player death location! => ", e); } } - // cleans and updates Storage to the newest "version" - private static void cleanStorage() { +// private static StorageManager.StorageClass loadStorage() throws Exception { +// // double check that the storage file is intact +// StorageInit(); +// +// String jsonContent = Files.readString(STORAGE_FILE); +// Gson gson = new GsonBuilder().create(); +// +//} + + // cleans and updates Storage to the newest "version". This is painful + private static StorageClass storageValidator() { LOGGER.info("Cleaning and updating Storage!"); + try { - StorageManager.StorageInit(); + StorageInit(); + long startFileSize = Files.size(StorageManager.STORAGE_FILE); FileReader reader = new FileReader(StorageManager.STORAGE_FILE.toString()); JsonElement jsonElement = JsonParser.parseReader(reader); if (jsonElement.isJsonObject()) { + JsonObject mainJsonObject = jsonElement.getAsJsonObject(); JsonArray newWarpsArray = new JsonArray(); JsonArray newPlayersArray = new JsonArray(); @@ -88,7 +113,6 @@ public class TeleportCommands { if (warpElement.isJsonObject()) { JsonObject warp = warpElement.getAsJsonObject(); - String warpName = warp.has("name") ? warp.get("name").getAsString() : ""; Integer warpX = warp.has("x") ? warp.get("x").getAsInt() : null; Integer warpY = warp.has("y") ? warp.get("y").getAsInt() : null; @@ -109,8 +133,6 @@ public class TeleportCommands { } } } - - } @@ -204,7 +226,7 @@ public class TeleportCommands { newPlayer.addProperty("UUID", UUID); newPlayer.addProperty("DefaultHome", DefaultHome); - newPlayer.add("deathLocation", deathLocation); + newPlayer.add("deathLocationClass", deathLocation); newPlayer.add("Homes", homes); newPlayersArray.add(newPlayer); @@ -225,12 +247,14 @@ public class TeleportCommands { byte[] json = gson.toJson(mainJsonObject).getBytes(); Files.write(StorageManager.STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - long endFileSize = Files.size(StorageManager.STORAGE_FILE); - - LOGGER.info("Success! Cleaned: {}B", Math.round((startFileSize - endFileSize))); + LOGGER.info("Success! Cleaned: {}B", Math.round(( startFileSize - Files.size(StorageManager.STORAGE_FILE) ))); + return gson.fromJson(mainJsonObject, StorageManager.StorageClass.class); } + } catch (IOException e) { LOGGER.error("Error while cleaning the database!", e); } - } + + return null; + } } \ No newline at end of file diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java index 8d5674d..20f0742 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java @@ -3,10 +3,10 @@ package dev.mrsnowy.teleport_commands.commands; import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.datafixers.util.Pair; import dev.mrsnowy.teleport_commands.TeleportCommands; -import dev.mrsnowy.teleport_commands.storage.StorageManager; import java.util.*; +import dev.mrsnowy.teleport_commands.utils.tools; import net.minecraft.ChatFormatting; import net.minecraft.commands.Commands; import net.minecraft.core.BlockPos; @@ -15,11 +15,24 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.phys.Vec3; -import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage; import static dev.mrsnowy.teleport_commands.utils.tools.*; import static net.minecraft.commands.Commands.argument; public class back { + public static final ArrayList backList = new ArrayList<>(); + + public static class deathLocationClass { + final public String UUID; + final public BlockPos pos; + final public String world; + + public deathLocationClass(String uuid, BlockPos pos, String world) { + this.UUID = uuid; + this.pos = pos; + this.world = world; + backList.add(this); + } + } public static void register(Commands commandManager) { @@ -58,69 +71,66 @@ public class back { } - private static void ToDeathLocation(ServerPlayer player, boolean safetyDisabled) throws Exception { - StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).getSecond(); - - // todo : fix... what do i need to fix LMAO - - if (playerStorage.deathLocation == null) { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.noLocation", player).withStyle(ChatFormatting.RED), true); - } else { - final BlockPos pos = new BlockPos(playerStorage.deathLocation.x, playerStorage.deathLocation.y, playerStorage.deathLocation.z); + private static void ToDeathLocation(ServerPlayer player, boolean safetyDisabled) { - boolean found = false; - for (ServerLevel currentWorld : TeleportCommands.SERVER.getAllLevels()) { + Optional OptionalDeathLocation = backList.stream() + .filter( deathLocation -> Objects.equals( deathLocation.UUID, player.getStringUUID() )) + .findFirst(); - if (Objects.equals(currentWorld.dimension().location().toString(), playerStorage.deathLocation.world)) { + if (OptionalDeathLocation.isEmpty()) { + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player).withStyle(ChatFormatting.RED), true); + return; + } - // check if the death location isn't safe and that safety isn't enabled - if (!safetyDisabled) { + deathLocationClass deathLocation = OptionalDeathLocation.get(); - Pair> teleportData = teleportSafetyChecker(pos.getX(), pos.getY(), pos.getZ(), currentWorld, player); + Optional OptionalWorld = tools.getWorld( deathLocation.world ); + if (OptionalWorld.isEmpty()) { + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player).withStyle(ChatFormatting.RED), true); + return; + } - switch (teleportData.getFirst()) { - case 0: // safe location found! - if (teleportData.getSecond().isPresent()) { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); - Teleporter(player, currentWorld, teleportData.getSecond().get()); - } else { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); - } + ServerLevel world = OptionalWorld.get(); - break; - case 1: // same - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); - break; - case 2: // no safe location + // check if the death location isn't safe and that safety isn't enabled + if (!safetyDisabled) { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) - .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/back true"))),false); - break; - } + Pair> teleportData = teleportSafetyChecker(deathLocation.pos, world, player); + switch (teleportData.getFirst()) { + case 0: // safe location found! + if (teleportData.getSecond().isPresent()) { + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); + Teleporter(player, world, teleportData.getSecond().get()); } else { - BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); - if (!playerBlockPos.equals(pos) || player.level() != currentWorld) { - - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); - Teleporter(player, currentWorld, new Vec3(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5)); - - } else { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); - } + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); } + break; + case 1: // same + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); + break; + case 2: // no safe location - found = true; + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noSafeLocation", player).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), false); + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.safetyIsForLosers", player).withStyle(ChatFormatting.AQUA), false); + player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.forceTeleport", player).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD) + .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/back true"))),false); break; - } } - if (!found) { - player.displayClientMessage(getTranslatedText("commands.teleport_commands.common.noLocation", player).withStyle(ChatFormatting.RED), true); + } else { + BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); + + if (!playerBlockPos.equals(deathLocation.pos) || player.level() != world) { + + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.go", player), true); + Teleporter(player, world, new Vec3(deathLocation.pos.getX() + 0.5, deathLocation.pos.getY(), deathLocation.pos.getZ() + 0.5)); + + } else { + player.displayClientMessage(getTranslatedText("commands.teleport_commands.back.same", player).withStyle(ChatFormatting.AQUA), true); } } + } } diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java index 5f61d47..2f395d4 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java @@ -172,13 +172,7 @@ public class home { if (homeNotFound) { // Create a new NamedLocation - StorageManager.StorageClass.NamedLocation homeLocation = new StorageManager.StorageClass.NamedLocation(); - - homeLocation.name = homeName; - homeLocation.x = blockPos.getX(); - homeLocation.y = blockPos.getY(); - homeLocation.z = blockPos.getZ(); - homeLocation.world = world.dimension().location().toString(); + StorageManager.StorageClass.NamedLocation homeLocation = new StorageManager.StorageClass.NamedLocation(homeName, blockPos, world.dimension().location().toString()); playerStorage.Homes.add(homeLocation); @@ -186,7 +180,7 @@ public class home { playerStorage.DefaultHome = homeName; } - StorageSaver(storage); + StorageSaver(); player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.set", player), true); } else { player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.exists", player).withStyle(ChatFormatting.RED), true); @@ -251,7 +245,7 @@ public class home { if (Objects.equals(currentHome.name, homeName)) { // delete the home playerStorage.Homes.remove(currentHome); - StorageSaver(storage); + StorageSaver(); deletedHome = true; player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.delete", player), true); @@ -294,7 +288,7 @@ public class home { } currentHome.name = newHomeName; - StorageSaver(storage); + StorageSaver(); WarpRenamed = true; player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.rename", player), true); @@ -332,7 +326,7 @@ public class home { if (!Objects.equals(playerStorage.DefaultHome, homeName)) { playerStorage.DefaultHome = homeName; - StorageSaver(storage); + StorageSaver(); player.displayClientMessage(getTranslatedText("commands.teleport_commands.home.default", player), true); } else { diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java index d9f6bf3..91fc814 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java @@ -21,9 +21,16 @@ public class tpa { public static final ArrayList tpaList = new ArrayList<>(); public static class tpaArrayClass { - public String InitPlayer; - public String RecPlayer; - boolean here; + public final String InitPlayer; + public final String RecPlayer; + final boolean here; + + public tpaArrayClass(String initPlayer, String recPlayer, boolean here) { + InitPlayer = initPlayer; + RecPlayer = recPlayer; + this.here = here; + tpaList.add(this); + } } public static void register(Commands commandManager) { @@ -122,11 +129,7 @@ public class tpa { String hereText = here ? "Here" : ""; // Store da request - tpaArrayClass tpaRequest = new tpaArrayClass(); - tpaRequest.InitPlayer = FromPlayer.getStringUUID(); - tpaRequest.RecPlayer = ToPlayer.getStringUUID(); - tpaRequest.here = here; - tpaList.add(tpaRequest); + tpaArrayClass tpaRequest = new tpaArrayClass( FromPlayer.getStringUUID(), ToPlayer.getStringUUID(), here ); String ReceivedFromPlayer = Objects.requireNonNull(FromPlayer.getName().getString(), "FromPlayer name cannot be null"); String SentToPlayer = Objects.requireNonNull(ToPlayer.getName().getString(), "ToPlayer name cannot be null"); @@ -163,46 +166,46 @@ public class tpa { private static void tpaAccept(ServerPlayer FromPlayer, ServerPlayer ToPlayer) { if (FromPlayer == ToPlayer) { FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.self", FromPlayer).withStyle(ChatFormatting.AQUA),true); + return; + } - } else { - Optional tpaStorage = tpaList.stream() - .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.InitPlayer)) - .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.RecPlayer)) - .findFirst(); + Optional tpaStorage = tpaList.stream() + .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.InitPlayer)) + .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.RecPlayer)) + .findFirst(); - // Check if there is a request - if (tpaStorage.isPresent()) { + // Check if there is a request + if (tpaStorage.isPresent()) { - ServerPlayer destinationPlayer = tpaStorage.get().here ? ToPlayer : FromPlayer; - ServerPlayer toSentPlayer = tpaStorage.get().here ? FromPlayer : ToPlayer; + ServerPlayer destinationPlayer = tpaStorage.get().here ? ToPlayer : FromPlayer; + ServerPlayer toSentPlayer = tpaStorage.get().here ? FromPlayer : ToPlayer; - Pair> teleportData = teleportSafetyChecker(destinationPlayer.getBlockX(), destinationPlayer.getBlockY(), destinationPlayer.getBlockZ(), destinationPlayer.serverLevel(), toSentPlayer); + Pair> teleportData = teleportSafetyChecker(destinationPlayer.blockPosition(), destinationPlayer.serverLevel(), toSentPlayer); // todo! make sure .blockPosition is correct - switch (teleportData.getFirst()) { - case 1: // same (let it fall through) - case 0: // safe! - if (teleportData.getSecond().isPresent() ) { + switch (teleportData.getFirst()) { + case 1: // same (let it fall through) + case 0: // safe! + if (teleportData.getSecond().isPresent() ) { - Teleporter(toSentPlayer, destinationPlayer.serverLevel(), teleportData.getSecond().get()); - break; - } else { - toSentPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", toSentPlayer).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); - return; // exit - } - case 2: // if no safe location then just teleport to the player - Teleporter(toSentPlayer, destinationPlayer.serverLevel(), destinationPlayer.position()); + Teleporter(toSentPlayer, destinationPlayer.serverLevel(), teleportData.getSecond().get()); break; - } + } else { + toSentPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.common.error", toSentPlayer).withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true); + return; // exit + } + case 2: // if no safe location then just teleport to the player + Teleporter(toSentPlayer, destinationPlayer.serverLevel(), destinationPlayer.position()); + break; + } - // if the player teleported then these messages get sent && the request gets removed - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", FromPlayer).withStyle(ChatFormatting.WHITE),true); - ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", ToPlayer).withStyle(ChatFormatting.GREEN),true); - tpaList.remove(tpaStorage.get()); + // if the player teleported then these messages get sent && the request gets removed + FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", FromPlayer).withStyle(ChatFormatting.WHITE),true); + ToPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.accepted", ToPlayer).withStyle(ChatFormatting.GREEN),true); + tpaList.remove(tpaStorage.get()); - // No request found - } else { - FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); - } + // No request found + } else { + FromPlayer.displayClientMessage(getTranslatedText("commands.teleport_commands.tpa.notFound", FromPlayer).withStyle(ChatFormatting.RED),true); } } diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java index f053ba3..3e99a58 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/warp.java @@ -4,7 +4,6 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.datafixers.util.Pair; import dev.mrsnowy.teleport_commands.TeleportCommands; import dev.mrsnowy.teleport_commands.storage.StorageManager; -import dev.mrsnowy.teleport_commands.suggestions.HomeSuggestionProvider; import dev.mrsnowy.teleport_commands.suggestions.WarpSuggestionProvider; import net.minecraft.ChatFormatting; import net.minecraft.commands.Commands; @@ -149,17 +148,10 @@ public class warp { if (warpNotFound) { // Create a new NamedLocation - StorageClass.NamedLocation warpData = new StorageClass.NamedLocation(); - - warpData.name = warpName; - warpData.x = blockPos.getX(); - warpData.y = blockPos.getY(); - warpData.z = blockPos.getZ(); - warpData.world = world.dimension().location().toString(); - + StorageClass.NamedLocation warpData = new StorageClass.NamedLocation(warpName, blockPos, world.dimension().location().toString()); storage.Warps.add(warpData); - StorageSaver(storage); + StorageSaver(); player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.set", player), true); } else { player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.exists", player).withStyle(ChatFormatting.RED), true); @@ -215,7 +207,7 @@ public class warp { if (Objects.equals(currentWarp.name, warpName)){ // delete the warp WarpStorage.remove(currentWarp); - StorageSaver(storage); + StorageSaver(); deletedWarp = true; player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.delete", player), true); @@ -255,7 +247,7 @@ public class warp { if (Objects.equals(currentWarp.name, warpName)){ currentWarp.name = newWarpName; - StorageSaver(storage); + StorageSaver(); WarpRenamed = true; player.displayClientMessage(getTranslatedText("commands.teleport_commands.warp.rename", player), true); diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java index 7088105..b75cada 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/worldspawn.java @@ -11,7 +11,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.phys.Vec3; -import java.util.Iterator; import java.util.Objects; import java.util.Optional; @@ -63,7 +62,7 @@ public class worldspawn { BlockPos worldSpawn = Objects.requireNonNull(world,"Overworld cannot be null").getSharedSpawnPos(); if (!safetyDisabled) { - Pair> teleportData = teleportSafetyChecker(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), world, player); + Pair> teleportData = teleportSafetyChecker(worldSpawn, world, player); switch (teleportData.getFirst()) { case 0: // safe location found! diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java index 08cceac..1931a15 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java @@ -4,6 +4,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mojang.datafixers.util.Pair; import dev.mrsnowy.teleport_commands.TeleportCommands; +import net.minecraft.core.BlockPos; import java.io.File; import java.nio.file.Files; @@ -17,136 +18,122 @@ import java.util.Optional; public class StorageManager { public static Path STORAGE_FOLDER; public static Path STORAGE_FILE; + public static StorageClass STORAGE; public static void StorageInit() { STORAGE_FOLDER = TeleportCommands.SAVE_DIR.resolve("TeleportCommands/"); STORAGE_FILE = STORAGE_FOLDER.resolve("storage.json"); try { + // check if the folder exists and create it if (!Files.exists(STORAGE_FOLDER)) { Files.createDirectories(STORAGE_FOLDER); } + // check if the file exists and create it if (!Files.exists(STORAGE_FILE)) { Files.createFile(STORAGE_FILE); } - // create the storage + // create the basic storage if it is empty if (new File(String.valueOf(STORAGE_FILE)).length() == 0) { - StorageClass root = new StorageClass(); - root.Players = new ArrayList<>(); - root.Warps = new ArrayList<>(); - StorageSaver(root); + STORAGE = new StorageClass(); + StorageSaver(); // todo! verify that it creates em correctly } } catch (Exception e) { - TeleportCommands.LOGGER.error("Error while creating the storage file! Exiting! {}", e.getMessage()); + TeleportCommands.LOGGER.error("Error while creating the storage file! Exiting! => ", e); // crashing is probably better here, otherwise the whole mod will be broken System.exit(1); } } - public static void StorageAdd(String UUID) throws Exception { - StorageClass storage = StorageRetriever(); + public static StorageClass.Player PlayerAdd(String UUID) { - Optional playerStorage = storage.Players.stream() + // try to find an exising storage for this player + Optional playerStorage = STORAGE.Players.stream() .filter(player -> Objects.equals(UUID, player.UUID)) .findFirst(); if (playerStorage.isEmpty()) { - StorageClass.Player newPlayer = new StorageClass.Player(); + StorageClass.Player newPlayer = new StorageClass.Player(UUID); // TODO! verify that it creates the player proper - newPlayer.UUID = UUID; - newPlayer.DefaultHome = ""; - newPlayer.deathLocation = new StorageClass.Location(); - newPlayer.deathLocation.x = new StorageClass.Location().x; - newPlayer.deathLocation.y = new StorageClass.Location().y; - newPlayer.deathLocation.z = new StorageClass.Location().z; - newPlayer.deathLocation.world = ""; - - newPlayer.Homes = new ArrayList<>(); - - List playerList = storage.Players; + List playerList = STORAGE.Players; playerList.add(newPlayer); - StorageSaver(storage); +// StorageSaver(); // no need to save since no data is actually set yet! TeleportCommands.LOGGER.info("Player '{}' added successfully in storage!", UUID); + return newPlayer; } else { TeleportCommands.LOGGER.info("Player '{}' already exists!", UUID); + return playerStorage.get(); } } - public static void StorageSaver(StorageClass storage) throws Exception { + public static void StorageSaver() throws Exception { Gson gson = new GsonBuilder().create(); - byte[] json = gson.toJson(storage).getBytes(); - Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - } + byte[] json = gson.toJson( STORAGE ).getBytes(); - private static StorageClass StorageRetriever() throws Exception { - // double check that the storage file is intact - if (new File(String.valueOf(STORAGE_FILE)).length() == 0) { - StorageInit(); - } - String jsonContent = Files.readString(STORAGE_FILE); - Gson gson = new GsonBuilder().create(); - return gson.fromJson(jsonContent, StorageClass.class); + Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); } - public static Pair> getWarpStorage() throws Exception { - StorageClass storage = StorageRetriever(); - return new Pair<>(storage, storage.Warps); + public static Pair> getWarpStorage() { + return new Pair<>(STORAGE, STORAGE.Warps); } + public static Pair GetPlayerStorage(String UUID) { - public static Pair GetPlayerStorage(String UUID) throws Exception { - StorageClass storage = StorageRetriever(); - - Optional playerStorage = storage.Players.stream() + // try to find an exising storage for this player + Optional playerStorage = STORAGE.Players.stream() .filter(player -> Objects.equals(UUID, player.UUID)) .findFirst(); if (playerStorage.isEmpty()) { - StorageAdd(UUID); - - storage = StorageRetriever(); + StorageClass.Player player = PlayerAdd(UUID); // create a new player - playerStorage = storage.Players.stream() - .filter(player -> Objects.equals(UUID, player.UUID)) - .findFirst(); - - if (playerStorage.isEmpty()) { - throw new Exception("No Player found?!"); - } + return new Pair<>(STORAGE, player); } - return new Pair<>(storage, playerStorage.get()); + return new Pair<>(STORAGE, playerStorage.get()); } public static class StorageClass { - public List Warps; - public List Players; + public static List Warps = new ArrayList<>(); + public static List Players = new ArrayList<>(); public static class NamedLocation { public String name; - public int x; - public int y; - public int z; - public String world; + public final int x; + public final int y; + public final int z; + public final String world; + + public NamedLocation(String name, BlockPos pos, String world) { + this.name = name; + this.x = pos.getX(); + this.y = pos.getY(); + this.z = pos.getZ(); + this.world = world; + } } public static class Location { - public int x; - public int y; - public int z; - public String world; + public int x = 0; + public int y = 0; + public int z = 0; + public String world = ""; } public static class Player { - public String UUID; - public String DefaultHome; - public Location deathLocation; - public List Homes; + public final String UUID; + public String DefaultHome = ""; + public Location deathLocation; // todo! deprecate + public List Homes = new ArrayList<>(); + + public Player(String uuid) { + this.UUID = uuid; + } } } } diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java b/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java index f1a6665..2b69a35 100644 --- a/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java +++ b/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java @@ -3,13 +3,14 @@ package dev.mrsnowy.teleport_commands.utils; import com.google.gson.*; import com.mojang.datafixers.util.Pair; import dev.mrsnowy.teleport_commands.TeleportCommands; -import dev.mrsnowy.teleport_commands.storage.StorageManager; + import java.io.*; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.StreamSupport; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -22,8 +23,6 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.world.phys.Vec3; import static dev.mrsnowy.teleport_commands.TeleportCommands.MOD_ID; -import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage; -import static dev.mrsnowy.teleport_commands.storage.StorageManager.StorageSaver; import static net.minecraft.sounds.SoundEvents.ENDERMAN_TELEPORT; public class tools { @@ -64,27 +63,14 @@ public class tools { } - public static void DeathLocationUpdater(BlockPos pos, ServerLevel world, String UUID) throws Exception { - Pair storages = GetPlayerStorage(UUID); - - StorageManager.StorageClass storage = storages.getFirst(); - StorageManager.StorageClass.Player playerStorage = storages.getSecond(); - - playerStorage.deathLocation.x = pos.getX(); - playerStorage.deathLocation.y = pos.getY(); - playerStorage.deathLocation.z = pos.getZ(); - playerStorage.deathLocation.world = world.dimension().location().toString(); - - StorageSaver(storage); - } - - - public static Pair> teleportSafetyChecker(int playerX, int playerY, int playerZ, ServerLevel world, ServerPlayer player) { + public static Pair> teleportSafetyChecker(BlockPos blockPos, ServerLevel world, ServerPlayer player) { int row = 1; int rows = 3; BlockPos playerBlockPos = new BlockPos(player.getBlockX(), player.getBlockY(), player.getBlockZ()); - BlockPos blockPos = new BlockPos(playerX, playerY, playerZ); + int playerX = blockPos.getX(); + int playerY = blockPos.getY(); + int playerZ= blockPos.getZ(); // find a safe location in an x row radius if (isBlockPosUnsafe(blockPos, world)) { @@ -130,6 +116,15 @@ public class tools { } + // function to quickly filter the worlds and compare them to a string + public static Optional getWorld(String worldString) { + + return StreamSupport.stream( TeleportCommands.SERVER.getAllLevels().spliterator(), false ) // woa, this looks silly + .filter(level -> Objects.equals( level.dimension().location().toString(), worldString )) + .findFirst(); + + } + // 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) public static MutableComponent getTranslatedText(String key, ServerPlayer player, MutableComponent... args) { @@ -204,7 +199,6 @@ public class tools { private static boolean isBlockPosUnsafe(BlockPos bottomPlayer, ServerLevel world) { - // bottomPlayer is presumed to be the bottom of the player character BlockPos belowPlayer = new BlockPos(bottomPlayer.getX(), bottomPlayer.getY() -1, bottomPlayer.getZ()); // below the player String belowPlayerId = world.getBlockState(belowPlayer).getBlock().getDescriptionId(); // below the player @@ -216,11 +210,10 @@ public class tools { // check if the death location isn't safe - if ( - (belowPlayerId.equals("block.minecraft.water") || !world.getBlockState(belowPlayer).getCollisionShape(world, belowPlayer).isEmpty()) // check if the player is going to fall on teleport - && (world.getBlockState(bottomPlayer).getCollisionShape(world, bottomPlayer).isEmpty() && !unsafeCollisionFreeBlocks.contains(BottomPlayerId)) // check if it is a collision free block, that isn't dangerous - && (!unsafeCollisionFreeBlocks.contains(TopPlayerId)) // check if it is a dangerous collision free block, if it is solid then the player crawls - ) { + if ((belowPlayerId.equals("block.minecraft.water") || !world.getBlockState(belowPlayer).getCollisionShape(world, belowPlayer).isEmpty()) // check if the player is going to fall on teleport + && (world.getBlockState(bottomPlayer).getCollisionShape(world, bottomPlayer).isEmpty() && !unsafeCollisionFreeBlocks.contains(BottomPlayerId)) // check if it is a collision free block, that isn't dangerous + && (!unsafeCollisionFreeBlocks.contains(TopPlayerId))) // check if it is a dangerous collision free block, if it is solid then the player crawls + { return false; // it's safe } return true; // it's not safe!