diff --git a/gradle.properties b/gradle.properties index 440d6f1..9abca17 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -libzontreck=1.10.011524.0045 +libzontreck=1.10.021324.2257 ## Environment Properties @@ -49,7 +49,7 @@ mod_name=Aria's Essentials # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPLv3 # The mod version. See https://semver.org/ -mod_version=1.2.011524.2039 +mod_version=1.2.021424.0009 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/dev/zontreck/essentials/commands/gui/HeartsCommand.java b/src/main/java/dev/zontreck/essentials/commands/gui/HeartsCommand.java index 9850a6e..6e869e0 100644 --- a/src/main/java/dev/zontreck/essentials/commands/gui/HeartsCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/gui/HeartsCommand.java @@ -20,6 +20,7 @@ public class HeartsCommand private static int hearts(CommandSourceStack stack, boolean compressHearts) { + var exec = new CommandExecutionEvent(stack.getPlayer(), "hearts"); if(MinecraftForge.EVENT_BUS.post(exec)) { diff --git a/src/main/java/dev/zontreck/essentials/commands/homes/SetHomeCommand.java b/src/main/java/dev/zontreck/essentials/commands/homes/SetHomeCommand.java index 47f6ca5..04fe69d 100644 --- a/src/main/java/dev/zontreck/essentials/commands/homes/SetHomeCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/homes/SetHomeCommand.java @@ -24,6 +24,7 @@ import net.minecraft.commands.Commands; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.MinecraftForge; @@ -69,6 +70,7 @@ public class SetHomeCommand { Vec2 rot = p.getRotationVector(); TeleportDestination dest = new TeleportDestination(new Vector3(position), new Vector2(rot), p.serverLevel()); + BlockState bs = p.serverLevel().getBlockState(dest.Position.moveDown().asBlockPos()); Home newhome = new Home(p, homeName, dest, new ItemStack(p.getBlockStateOn().getBlock().asItem())); AriasEssentials.player_homes.get(p.getUUID()).add(newhome); diff --git a/src/main/java/dev/zontreck/essentials/commands/teleport/TPEffectsCommand.java b/src/main/java/dev/zontreck/essentials/commands/teleport/TPEffectsCommand.java index a5b9651..21d46ed 100644 --- a/src/main/java/dev/zontreck/essentials/commands/teleport/TPEffectsCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/teleport/TPEffectsCommand.java @@ -2,11 +2,13 @@ package dev.zontreck.essentials.commands.teleport; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.BoolArgumentType; +import dev.zontreck.essentials.Messages; import dev.zontreck.libzontreck.chestgui.ChestGUI; import dev.zontreck.libzontreck.chestgui.ChestGUIButton; import dev.zontreck.libzontreck.chestgui.ChestGUIIdentifier; import dev.zontreck.libzontreck.profiles.Profile; import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException; +import dev.zontreck.libzontreck.util.ChatHelpers; import dev.zontreck.libzontreck.util.ServerUtilities; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; @@ -20,17 +22,18 @@ public class TPEffectsCommand { public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("tpeffects").then(Commands.argument("enable", BoolArgumentType.bool()).executes(x->tpeffects(x.getSource(), BoolArgumentType.getBool(x, "enable"))))); + dispatcher.register(Commands.literal("tpeffects_disable").then(Commands.argument("disabled", BoolArgumentType.bool()).executes(x->tpeffects(x.getSource(), BoolArgumentType.getBool(x, "disabled"))))); } - public static int tpeffects(CommandSourceStack source, boolean enabled) + public static int tpeffects(CommandSourceStack source, boolean disabled) { ServerPlayer player = source.getPlayer(); try { Profile prof = Profile.get_profile_of(player.getStringUUID()); - prof.NBT.putBoolean("tpeffects", enabled); + prof.NBT.putBoolean("tpeffects", disabled); + ChatHelpers.broadcastTo(player.getUUID(), ChatHelpers.macro(Messages.TP_EFFECTS_TOGGLED, disabled ? "disabled" : "enabled"), player.server); return 0; } catch (UserProfileNotYetExistsException e) { throw new RuntimeException(e); diff --git a/src/main/java/dev/zontreck/essentials/commands/warps/RTPWarpCommand.java b/src/main/java/dev/zontreck/essentials/commands/warps/RTPWarpCommand.java index 56ca832..b9d3ed1 100644 --- a/src/main/java/dev/zontreck/essentials/commands/warps/RTPWarpCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/warps/RTPWarpCommand.java @@ -51,7 +51,7 @@ public class RTPWarpCommand { Vec2 rot = p.getRotationVector(); TeleportDestination dest = new TeleportDestination(new Vector3(position), new Vector2(rot), p.serverLevel()); - Warp warp = new Warp(p.getUUID(), string, true, true, dest, new ItemStack(p.getBlockStateOn().getBlock().asItem())); + Warp warp = new Warp(p.getUUID(), string, true, true, dest, new ItemStack(p.getFeetBlockState().getBlock().asItem())); WarpCreatedEvent event = new WarpCreatedEvent(warp); if(MinecraftForge.EVENT_BUS.post(event)) { diff --git a/src/main/java/dev/zontreck/essentials/commands/warps/SetWarpCommand.java b/src/main/java/dev/zontreck/essentials/commands/warps/SetWarpCommand.java index c6efdac..7aa7d9e 100644 --- a/src/main/java/dev/zontreck/essentials/commands/warps/SetWarpCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/warps/SetWarpCommand.java @@ -22,6 +22,7 @@ import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.MinecraftForge; @@ -52,7 +53,9 @@ public class SetWarpCommand { Vec2 rot = p.getRotationVector(); TeleportDestination dest = new TeleportDestination(new Vector3(position), new Vector2(rot), p.serverLevel()); - Warp w = new Warp(p.getUUID(), string, false, true, dest, new ItemStack(p.getBlockStateOn().getBlock().asItem())); + BlockState bs = p.serverLevel().getBlockState(dest.Position.moveDown().asBlockPos()); + + Warp w = new Warp(p.getUUID(), string, false, true, dest, new ItemStack(bs.getBlock().asItem())); WarpCreatedEvent event = new WarpCreatedEvent(w); if(MinecraftForge.EVENT_BUS.post(event)){ ChatHelpers.broadcastTo(p.getUUID(), ChatHelpers.macro(Messages.WARP_CREATE_ERROR, event.denyReason), p.server); diff --git a/src/main/java/dev/zontreck/essentials/commands/warps/WarpsCommand.java b/src/main/java/dev/zontreck/essentials/commands/warps/WarpsCommand.java index 425253f..0952284 100644 --- a/src/main/java/dev/zontreck/essentials/commands/warps/WarpsCommand.java +++ b/src/main/java/dev/zontreck/essentials/commands/warps/WarpsCommand.java @@ -140,6 +140,7 @@ public class WarpsCommand { ) .withInfo(new LoreEntry.Builder().text(ChatHelpers.macro(appendType, warp.destination.Dimension).getString()).build()); + ChatHelpers.broadcastTo(p, warpMsg, p.server); if(warps.size() > (2*9)) { // Say to person diff --git a/src/main/java/dev/zontreck/essentials/configs/client/AEClientConfig.java b/src/main/java/dev/zontreck/essentials/configs/client/AEClientConfig.java index f8a5ef6..5777aa7 100644 --- a/src/main/java/dev/zontreck/essentials/configs/client/AEClientConfig.java +++ b/src/main/java/dev/zontreck/essentials/configs/client/AEClientConfig.java @@ -1,10 +1,8 @@ package dev.zontreck.essentials.configs.client; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import dev.zontreck.essentials.util.EssentialsDatastore; -import dev.zontreck.essentials.util.FileHandler; +import dev.zontreck.libzontreck.util.SNbtIo; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; import java.nio.file.Path; @@ -31,15 +29,7 @@ public class AEClientConfig if(serverConfig.toFile().exists()) { - try { - String snbt = FileHandler.readFile(serverConfig.toFile().getAbsolutePath()); - - inst = deserialize(NbtUtils.snbtToStructure(snbt)); - - - } catch (CommandSyntaxException e) { - throw new RuntimeException(e); - } + inst = deserialize(SNbtIo.loadSnbt(serverConfig)); }else { initNewConfig(); } @@ -67,10 +57,7 @@ public class AEClientConfig Path serverConfig = EssentialsDatastore.of("client.snbt", false); CompoundTag tag = inst.serialize(); - - var snbt = NbtUtils.structureToSnbt(tag); - - FileHandler.writeFile(serverConfig.toFile().getAbsolutePath(), snbt); + SNbtIo.writeSnbt(serverConfig, tag); } public CompoundTag serialize() diff --git a/src/main/java/dev/zontreck/essentials/configs/server/AEServerConfig.java b/src/main/java/dev/zontreck/essentials/configs/server/AEServerConfig.java index eccbca5..35d0879 100644 --- a/src/main/java/dev/zontreck/essentials/configs/server/AEServerConfig.java +++ b/src/main/java/dev/zontreck/essentials/configs/server/AEServerConfig.java @@ -1,17 +1,14 @@ package dev.zontreck.essentials.configs.server; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import dev.zontreck.ariaslib.util.Lists; import dev.zontreck.essentials.configs.server.sections.*; import dev.zontreck.essentials.util.EssentialsDatastore; -import dev.zontreck.essentials.util.FileHandler; import dev.zontreck.essentials.util.Maps; +import dev.zontreck.libzontreck.util.SNbtIo; import net.minecraft.nbt.*; -import java.io.*; import java.nio.file.Path; import java.util.HashMap; -import java.util.List; import java.util.Map; public class AEServerConfig @@ -51,16 +48,7 @@ public class AEServerConfig Path serverConfig = EssentialsDatastore.of("server.snbt"); if(serverConfig.toFile().exists()) { - - try { - String snbt = FileHandler.readFile(serverConfig.toFile().getAbsolutePath()); - - inst = deserialize(NbtUtils.snbtToStructure(snbt)); - - - } catch (CommandSyntaxException e) { - throw new RuntimeException(e); - } + inst = deserialize(SNbtIo.loadSnbt(serverConfig)); }else { initNewConfig(); } @@ -111,10 +99,7 @@ public class AEServerConfig Path serverConfig = EssentialsDatastore.of("server.snbt", false); CompoundTag tag = inst.serialize(); - - var snbt = NbtUtils.structureToSnbt(tag); - - FileHandler.writeFile(serverConfig.toFile().getAbsolutePath(), snbt); + SNbtIo.writeSnbt(serverConfig, tag); } public CompoundTag serialize() diff --git a/src/main/java/dev/zontreck/essentials/rtp/RTP.java b/src/main/java/dev/zontreck/essentials/rtp/RTP.java index 186a81b..8311708 100644 --- a/src/main/java/dev/zontreck/essentials/rtp/RTP.java +++ b/src/main/java/dev/zontreck/essentials/rtp/RTP.java @@ -8,6 +8,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -20,124 +21,87 @@ import java.util.Iterator; import java.util.List; import java.util.Random; -/** - * As of v1.1.121823.x, this is now used for RTP - *

- * This ensures that RTP is only scanned once every so often. This is because RTP lags the server when it is having to check block positions. - *

- * If the RTP system scans each dimension (Not blacklisted), then it can build a list of safe locations that will be rotated out every 2 hours. - *

- * Every 10 minutes, a new RTP location is scanned. This ensures sufficiently semi-random locations. Eventually old locations will be removed from the list. - *

- * At server start, it will scan 10 RTP locations per dimension while there are no players. - */ -public class RTP -{ - public RTP(ServerLevel level) - { - position = new WorldPosition(new Vector3(0,500,0), WorldPosition.getDim(level)); - - if(position.getActualDimension().dimensionType().hasCeiling()) - { - heightMapType = Heightmap.Types.MOTION_BLOCKING_NO_LEAVES; - SearchDirection=-1; - }else { - heightMapType = Heightmap.Types.MOTION_BLOCKING_NO_LEAVES; - SearchDirection=1; - } - } - private final int SearchDirection; - private Thread containingThread; +public class RTP { + private static final List BLACKLIST = Lists.of(Blocks.LAVA, Blocks.WATER, Blocks.BEDROCK); + private final int SEARCH_DIRECTION; private final Heightmap.Types heightMapType; public WorldPosition position; - private final List BLACKLIST = Lists.of(Blocks.LAVA, Blocks.WATER, Blocks.BEDROCK); - protected int tries; - protected int lastThreadDelay = 15; + private final ServerLevel dimension; + private int tries; - protected RTP withThreadDelay(int delay) - { - lastThreadDelay=delay; - if(lastThreadDelay >= 60) lastThreadDelay = 60; - return this; + public RTP(ServerLevel level) { + position = new WorldPosition(new Vector3(0, -60, 0), WorldPosition.getDim(level)); + dimension = position.getActualDimension(); + + if (position.getActualDimension().dimensionType().hasCeiling()) { + heightMapType = Heightmap.Types.MOTION_BLOCKING_NO_LEAVES; + SEARCH_DIRECTION = -1; + } else { + heightMapType = Heightmap.Types.MOTION_BLOCKING_NO_LEAVES; + SEARCH_DIRECTION = 1; + } } - public boolean isDimension(ServerLevel level) - { + public boolean isDimension(ServerLevel level) { String dim = WorldPosition.getDim(level); return dim.equals(position.Dimension); } - /** - * Searches for, and finds, a valid RTP location - * @param level The level to scan - * @return RTP data - */ - public static void find(ServerLevel level) - { - RandomPositionFactory.beginRTPSearch(level); - } + public BlockPos findSafeLandingLocation() { + BlockPos targetPos = position.Position.asBlockPos(); - public static List slicedByDimension(ServerLevel lvl) - { - List slice = new ArrayList<>(); - - Iterator it = RTPCaches.Locations.iterator(); - while(it.hasNext()) - { - RTP nxt = it.next(); - if(nxt.isDimension(lvl)) - { - slice.add(nxt); - } + // Search upward for a safe landing location + while (!isSafe(targetPos) || !isSafe(targetPos.above())) { + targetPos = targetPos.above(); } - return slice; + return targetPos; } - public static RTP getRTP(ServerLevel level) - { + private boolean isSafe(BlockPos blockPos) { + BlockState blockState = dimension.getBlockState(blockPos); + BlockState blockStateAbove = dimension.getBlockState(blockPos.above()); + BlockState blockStateBelow = dimension.getBlockState(blockPos.below()); + + if (blockState.isAir() && blockStateAbove.isAir()) { + if (!blockStateBelow.isAir()) { + return !BLACKLIST.contains(blockStateBelow.getBlock()); + } else { + return false; + } + } else { + return false; + } + } + + public static RTP getRTP(ServerLevel level) { List slice = slicedByDimension(level); - if(slice.size()>0) - { - RTP ret = slice.get(AriasEssentials.random.nextInt(0, slice.size())); + if (!slice.isEmpty()) { + RTP ret = slice.get(AriasEssentials.random.nextInt(slice.size())); RTPCaches.Locations.remove(ret); RandomPositionFactory.beginRTPSearch(ret.position.getActualDimension()); return ret; - } else return null; - } - - - public void moveDown() { - position.Position = position.Position.moveDown(); - } - - public void moveUp() { - position.Position = position.Position.moveUp(); - } - - public void move() - { - if(SearchDirection==1){ - moveUp(); - }else if(SearchDirection==0) - { - moveDown(); + } else { + return null; } } - public void moveOpposite() - { - if(SearchDirection==1){ - moveDown(); - }else if(SearchDirection==0) - { - moveUp(); + + public void move() { + if (SEARCH_DIRECTION == 1) { + position.Position = position.Position.moveUp(); + } else if (SEARCH_DIRECTION == -1) { + position.Position = position.Position.moveDown(); } } + + public void moveOpposite() { + move(); + } + public void newPosition() { - if (!AriasEssentials.ALIVE || tries >= 25) return; + if (!AriasEssentials.ALIVE || tries >= 5) return; - containingThread = Thread.currentThread(); - AriasEssentials.LOGGER.info("RTP starts looking for new position"); + AriasEssentials.LOGGER.info("RTP starts looking for a new position"); Random rng = new Random(Instant.now().getEpochSecond()); @@ -145,37 +109,27 @@ public class RTP BlockPos bpos; do { - pos = new Vector3(rng.nextDouble(0xFFFF), 150, rng.nextDouble(0xFFFF)); + pos = new Vector3(rng.nextDouble(0xFFFF), -60, rng.nextDouble(0xFFFF)); pos = spiralPositions(pos); position.Position = pos; bpos = pos.asBlockPos(); } while (!isValidPosition(bpos)); - - if (pos.y < -30 || pos.y >= position.getActualDimension().getLogicalHeight()) { - newPosition(); - return; - } - tries++; - AriasEssentials.LOGGER.info("RTP returns new position"); + AriasEssentials.LOGGER.info("RTP returns a new position"); } private boolean isValidPosition(BlockPos bpos) { - ServerLevel dimension = position.getActualDimension(); ChunkStatus status = ChunkStatus.SPAWN; - dimension.getChunk(bpos.getX() >> 4, bpos.getZ() >> 4, status); Vector3 pos = new Vector3(dimension.getHeightmapPos(heightMapType, bpos)); return dimension.getWorldBorder().isWithinBounds(pos.asBlockPos()); } - private Vector3 spiralPositions(Vector3 position) { Vec3i posi = position.asMinecraftVec3i(); - ServerLevel dimension = this.position.getActualDimension(); BlockPos startBlockPos = new BlockPos(posi.getX(), dimension.getSeaLevel(), posi.getZ()); for (BlockPos pos : BlockPos.spiralAround(startBlockPos, 16, Direction.WEST, Direction.NORTH)) { @@ -188,32 +142,17 @@ public class RTP return position; } + public static List slicedByDimension(ServerLevel lvl) { + List slice = new ArrayList<>(); - private boolean safe(BlockPos blockPos) - { - containingThread=Thread.currentThread(); - BlockState b = position.getActualDimension().getBlockState(blockPos); - BlockState b2 = position.getActualDimension().getBlockState(blockPos.above()); - BlockState b3 = position.getActualDimension().getBlockState(blockPos.below()); + Iterator it = RTPCaches.Locations.iterator(); + while (it.hasNext()) { + RTP nxt = it.next(); + if (nxt.isDimension(lvl)) { + slice.add(nxt); + } + } - if (b.isAir() && b2.isAir()) { - if (!b3.isAir()) { - return !BLACKLIST.contains(b3.getBlock()); - } else - return false; - } else - return false; - - } - public boolean isSafe(BlockPos blockPos) { - return safe(blockPos); - /* - boolean s = safe(blockPos); - if(s) - { - AriasEssentials.LOGGER.info("/!\\ SAFE /!\\"); - }else AriasEssentials.LOGGER.info("/!\\ NOT SAFE /!\\"); - - return s;*/ + return slice; } } diff --git a/src/main/java/dev/zontreck/essentials/rtp/RTPCaches.java b/src/main/java/dev/zontreck/essentials/rtp/RTPCaches.java index 0751638..ebcbc97 100644 --- a/src/main/java/dev/zontreck/essentials/rtp/RTPCaches.java +++ b/src/main/java/dev/zontreck/essentials/rtp/RTPCaches.java @@ -1,11 +1,31 @@ package dev.zontreck.essentials.rtp; +import dev.zontreck.essentials.events.RTPFoundEvent; +import dev.zontreck.essentials.util.EssentialsDatastore; import dev.zontreck.libzontreck.vectors.WorldPosition; +import net.minecraft.nbt.CompoundTag; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; public class RTPCaches { public static List Locations = new ArrayList<>(); + + + public static final Path BASE = EssentialsDatastore.of("rtp.nbt", false); + + + @SubscribeEvent + public static void onRTPFound(RTPFoundEvent found) + { + + } + + public static void deserialize(CompoundTag tag) + { + + } } diff --git a/src/main/java/dev/zontreck/essentials/rtp/RTPCachesEventHandlers.java b/src/main/java/dev/zontreck/essentials/rtp/RTPCachesEventHandlers.java index 68a5260..aeafc4b 100644 --- a/src/main/java/dev/zontreck/essentials/rtp/RTPCachesEventHandlers.java +++ b/src/main/java/dev/zontreck/essentials/rtp/RTPCachesEventHandlers.java @@ -4,11 +4,14 @@ import dev.zontreck.essentials.AriasEssentials; import dev.zontreck.essentials.Messages; import dev.zontreck.essentials.commands.teleport.TeleportActioner; import dev.zontreck.essentials.events.RTPFoundEvent; +import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.util.ChatHelpers; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.server.ServerLifecycleHooks; public class RTPCachesEventHandlers { @@ -19,6 +22,7 @@ public class RTPCachesEventHandlers { if(!AriasEssentials.ALIVE) return; lastTick++; + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); if(lastTick>=400) { lastTick=0; @@ -31,7 +35,7 @@ public class RTPCachesEventHandlers firstRun=false; AriasEssentials.LOGGER.info("Aria's Essentials startup is running. Scanning for initial RTP locations"); - for(ServerLevel level : event.getServer().getAllLevels()) + for(ServerLevel level : server.getAllLevels()) { if(AriasEssentials.DEBUG) { diff --git a/src/main/java/dev/zontreck/essentials/util/FileHandler.java b/src/main/java/dev/zontreck/essentials/util/FileHandler.java deleted file mode 100644 index abc95b2..0000000 --- a/src/main/java/dev/zontreck/essentials/util/FileHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package dev.zontreck.essentials.util; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -public class FileHandler -{ - - public static String readFile(String filePath) { - try { - byte[] fileBytes = Files.readAllBytes(Paths.get(filePath)); - return new String(fileBytes); - } catch (IOException e) { - return "An error occurred: " + e.getMessage(); - } - } - public static void writeFile(String filePath, String newContent) { - try { - Files.write(Paths.get(filePath), newContent.getBytes()); - } catch (IOException e) { - } - } -}