Move RTP functionality into its own thing to reduce overall lag when using RTP

This commit is contained in:
zontreck 2023-12-18 16:57:59 -07:00
parent eb1189e67f
commit 408e5d91d6
14 changed files with 422 additions and 264 deletions

View file

@ -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. # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=GPLv3 mod_license=GPLv3
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=1.1.121823.1531 mod_version=1.1.121823.1657
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # 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. # This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html # See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View file

@ -2,7 +2,7 @@ package dev.zontreck.essentials.commands.teleport;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.essentials.util.RandomPositionFactory; import dev.zontreck.essentials.rtp.RandomPositionFactory;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@ -51,7 +51,7 @@ public class RTPCommand {
Vec3 pos = pla.position(); Vec3 pos = pla.position();
//boolean found_place= false; //boolean found_place= false;
RandomPositionFactory.beginRTPSearch(pla, pos, pla.getRotationVector(), pla.serverLevel()); RandomPositionFactory.beginRTP(pla, pla.serverLevel());
return; return;

View file

@ -1,40 +1,12 @@
package dev.zontreck.essentials.commands.teleport; package dev.zontreck.essentials.commands.teleport;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Iterator;
import java.util.List;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.Messages; import dev.zontreck.essentials.Messages;
import dev.zontreck.essentials.commands.teleport.TeleportActioner;
import dev.zontreck.essentials.commands.teleport.TeleportContainer;
import dev.zontreck.essentials.commands.teleport.TeleportDestination;
import dev.zontreck.essentials.configs.AEServerConfig;
import dev.zontreck.essentials.util.RTPContainer;
import dev.zontreck.essentials.util.RandomPositionFactory;
import dev.zontreck.essentials.warps.NoSuchWarpException;
import dev.zontreck.essentials.warps.Warp;
import dev.zontreck.essentials.warps.WarpsProvider;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.Clickable;
import dev.zontreck.libzontreck.exceptions.InvalidSideException;
import dev.zontreck.libzontreck.util.ChatHelpers; import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;

View file

@ -1,37 +1,22 @@
package dev.zontreck.essentials.commands.warps; package dev.zontreck.essentials.commands.warps;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Iterator;
import java.util.List;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.Messages; import dev.zontreck.essentials.Messages;
import dev.zontreck.essentials.commands.teleport.TeleportActioner; import dev.zontreck.essentials.commands.teleport.TeleportActioner;
import dev.zontreck.essentials.commands.teleport.TeleportContainer; import dev.zontreck.essentials.commands.teleport.TeleportContainer;
import dev.zontreck.essentials.commands.teleport.TeleportDestination; import dev.zontreck.essentials.commands.teleport.TeleportDestination;
import dev.zontreck.essentials.util.RTPContainer; import dev.zontreck.essentials.rtp.RandomPositionFactory;
import dev.zontreck.essentials.util.RandomPositionFactory;
import dev.zontreck.essentials.warps.NoSuchWarpException; import dev.zontreck.essentials.warps.NoSuchWarpException;
import dev.zontreck.essentials.warps.Warp; import dev.zontreck.essentials.warps.Warp;
import dev.zontreck.essentials.warps.WarpsProvider; import dev.zontreck.essentials.warps.WarpsProvider;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.Clickable; import dev.zontreck.libzontreck.chat.Clickable;
import dev.zontreck.libzontreck.exceptions.InvalidSideException;
import dev.zontreck.libzontreck.util.ChatHelpers; import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3; import dev.zontreck.libzontreck.vectors.Vector3;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
@ -78,7 +63,7 @@ public class WarpCommand {
if(type==1){ if(type==1){
try { try {
dest.Position = Vector3.ZERO; dest.Position = Vector3.ZERO;
RandomPositionFactory.beginRTPSearch(p, Vec3.ZERO, Vec2.ZERO, f_dim); RandomPositionFactory.beginRTP(p, f_dim);
return; return;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -0,0 +1,14 @@
package dev.zontreck.essentials.events;
import dev.zontreck.essentials.rtp.RTP;
import net.minecraftforge.eventbus.api.Event;
public class RTPFoundEvent extends Event
{
public RTP rtp;
public RTPFoundEvent(RTP rtp)
{
this.rtp=rtp;
}
}

View file

@ -1,6 +1,6 @@
package dev.zontreck.essentials.events; package dev.zontreck.essentials.events;
import dev.zontreck.essentials.util.RTPContainer; import dev.zontreck.essentials.rtp.RTPContainer;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.Event;

View file

@ -0,0 +1,278 @@
package dev.zontreck.essentials.rtp;
import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.ariaslib.util.Lists;
import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.Messages;
import dev.zontreck.essentials.events.RTPEvent;
import dev.zontreck.essentials.events.RTPNotCancelledEvent;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.libzontreck.vectors.WorldPosition;
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.level.ChunkPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraftforge.common.MinecraftForge;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
/**
* As of v1.1.121823.x, this is now used for RTP
* <p>
* 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.
* <p>
* 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.
* <p>
* Every 10 minutes, a new RTP location is scanned. This ensures sufficiently semi-random locations. Eventually old locations will be removed from the list.
* <p>
* At server start, it will scan 10 RTP locations per dimension while there are no players.
*/
public class RTP
{
public RTP(ServerLevel level)
{
Age = Instant.now().getEpochSecond();
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 int SearchDirection;
private Thread containingThread;
private Heightmap.Types heightMapType;
public WorldPosition position;
private List<Block> BLACKLIST = Lists.of(Blocks.LAVA, Blocks.WATER);
protected int tries;
/**
* This is a unix timestamp, that is checked for being Stale
*/
public long Age;
public boolean isDimension(ServerLevel level)
{
String dim = WorldPosition.getDim(level);
if(dim.equals(position.Dimension))
{
return true;
}else return false;
}
/**
* Checks if the RTP Cached position is stale. This means over 2 hours old
* @return True if stale
*/
public boolean isStale()
{
if((Age+(2*60*60)) < Instant.now().getEpochSecond())
{
return true;
} else return false;
}
public boolean readyForNewer()
{
return ((Age + (10*60)) < Instant.now().getEpochSecond());
}
/**
* 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 static List<RTP> slicedByDimension(ServerLevel lvl)
{
List<RTP> slice = new ArrayList<>();
Iterator<RTP> it = RTPCaches.Locations.iterator();
while(it.hasNext())
{
RTP nxt = it.next();
if(nxt.isDimension(lvl))
{
slice.add(nxt);
}
}
return slice;
}
public static RTP getRTP(ServerLevel level)
{
List<RTP> slice = slicedByDimension(level);
if(slice.size()>0)
{
return slice.get(AriasEssentials.random.nextInt(0, slice.size()));
} 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();
}
}
public void moveOpposite()
{
if(SearchDirection==1){
moveDown();
}else if(SearchDirection==0)
{
moveUp();
}
}
public void newPosition() {
if(!AriasEssentials.ALIVE)return;
containingThread=Thread.currentThread();
if(tries>=30)return;
AriasEssentials.LOGGER.info("RTPContainer starts looking for new position");
Random rng = new Random(Instant.now().getEpochSecond());
Vector3 pos = new Vector3(rng.nextDouble(0xFFFF), 0, rng.nextDouble(0xFFFF));
BlockPos bpos = pos.asBlockPos();
position.getActualDimension().getChunk(bpos.getX() >> 4, bpos.getZ() >> 4, ChunkStatus.SPAWN);
pos = new Vector3(
position.getActualDimension().getHeightmapPos(heightMapType, pos.asBlockPos()));
while (!position.getActualDimension().getWorldBorder().isWithinBounds(pos.asBlockPos())) {
pos = new Vector3(rng.nextDouble(0xffff), 0, rng.nextDouble(0xffff));
bpos = pos.asBlockPos();
position.getActualDimension().getChunk(bpos.getX() >> 4, bpos.getZ() >> 4, ChunkStatus.SPAWN);
pos = new Vector3(
position.getActualDimension().getHeightmapPos(heightMapType, pos.asBlockPos()));
}
position.Position = pos;
if (pos.y < -60) {
newPosition();
return;
}
if (pos.y >= position.getActualDimension().getLogicalHeight()) {
spiralPositions(pos);
}
tries++;
AriasEssentials.LOGGER.info("RTPContainer returns new position");
}
private void spiralPositions(Vector3 position)
{
Vec3i posi = position.asMinecraftVec3i();
for(BlockPos pos : BlockPos.spiralAround(new BlockPos(posi.getX(), this.position.getActualDimension().getSeaLevel(), posi.getZ()), 16, Direction.WEST, Direction.NORTH)){
if(isSafe(pos)){
// Set the new position
this.position.Position = new Vector3(pos);
return;
}
}
}
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());
if (b.isAir() && b2.isAir()) {
if (!b3.isAir()) {
if (BLACKLIST.contains(b3.getBlock())) {
return false;
} else
return true;
} else
return false;
} else
return false;
}
public boolean isSafe(BlockPos blockPos) {
boolean s = safe(blockPos);
if(s)
{
AriasEssentials.LOGGER.info("/!\\ SAFE /!\\");
}else AriasEssentials.LOGGER.info("/!\\ NOT SAFE /!\\");
return s;
}
public void putAge()
{
Age = Instant.now().getEpochSecond();
}
public static void checkStale()
{
Iterator<RTP> it = RTPCaches.Locations.iterator();
List<ServerLevel> uniqueDims = new ArrayList<>();
while(it.hasNext())
{
RTP loc = it.next();
if(loc.isStale()){
it.remove();
}
if(!uniqueDims.contains(loc.position.getActualDimension()))
{
uniqueDims.add(loc.position.getActualDimension());
}
}
checkNeedsNewer(uniqueDims);
}
public static void checkNeedsNewer(List<ServerLevel> dims)
{
Iterator<ServerLevel> it = dims.iterator();
while(it.hasNext())
{
ServerLevel lvl = it.next();
List<RTP> slice = slicedByDimension(lvl);
boolean needsNewer = true;
for(var X : slice)
{
if(!X.readyForNewer()) needsNewer=false;
}
if(needsNewer)
{
RandomPositionFactory.beginRTPSearch(lvl);
}
}
}
}

View file

@ -0,0 +1,11 @@
package dev.zontreck.essentials.rtp;
import dev.zontreck.libzontreck.vectors.WorldPosition;
import java.util.ArrayList;
import java.util.List;
public class RTPCaches
{
public static List<RTP> Locations = new ArrayList<>();
}

View file

@ -0,0 +1,20 @@
package dev.zontreck.essentials.rtp;
import dev.zontreck.essentials.events.RTPFoundEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
public class RTPCachesEventHandlers
{
@SubscribeEvent
public void onTick(TickEvent.ServerTickEvent event)
{
RTP.checkStale();
}
@SubscribeEvent
public void onRTPFound(RTPFoundEvent event)
{
RTPCaches.Locations.add(event.rtp);
}
}

View file

@ -0,0 +1,37 @@
package dev.zontreck.essentials.rtp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Stream;
import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.commands.teleport.TeleportContainer;
import dev.zontreck.libzontreck.vectors.Vector3;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
@Deprecated
/**
* @see RTP instead
*/
public class RTPContainer {
}

View file

@ -0,0 +1,44 @@
package dev.zontreck.essentials.rtp;
import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.essentials.commands.teleport.TeleportActioner;
import dev.zontreck.essentials.commands.teleport.TeleportContainer;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.libzontreck.vectors.WorldPosition;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import java.time.Instant;
/**
* The factory system used to start searching for a random teleport position
*/
public class RandomPositionFactory {
public static RTP beginRTPSearch(ServerLevel level)
{
RTP tmp = new RTP(level);
tmp.position = new WorldPosition(new Vector3(0,0,0), WorldPosition.getDim(level));
Thread tx = new Thread(new RandomPositionLocator(tmp));
tx.setName("RTPTask-"+String.valueOf(DelayedExecutorService.getNext()));
tx.start();
return tmp;
}
public static void beginRTP(ServerPlayer player, ServerLevel level)
{
RTP tmp = RTP.getRTP(level);
if(tmp == null)
{
throw new RuntimeException("No valid destinations were found");
}
TeleportActioner.ApplyTeleportEffect(player);
TeleportContainer cont = new TeleportContainer(player, tmp.position.Position.asMinecraftVector(), player.getRotationVector(), level);
TeleportActioner.PerformTeleport(cont);
}
}

View file

@ -1,12 +1,12 @@
package dev.zontreck.essentials.util; package dev.zontreck.essentials.rtp;
import dev.zontreck.ariaslib.terminal.Task; import dev.zontreck.ariaslib.terminal.Task;
import dev.zontreck.ariaslib.util.DelayedExecutorService; import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.essentials.AriasEssentials; import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.Messages; import dev.zontreck.essentials.Messages;
import dev.zontreck.essentials.events.RTPEvent; import dev.zontreck.essentials.events.RTPEvent;
import dev.zontreck.essentials.events.RTPFoundEvent;
import dev.zontreck.essentials.events.RTPNotCancelledEvent; import dev.zontreck.essentials.events.RTPNotCancelledEvent;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.util.ChatHelpers; import dev.zontreck.libzontreck.util.ChatHelpers;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
@ -21,9 +21,9 @@ import net.minecraftforge.common.MinecraftForge;
*/ */
public class RandomPositionLocator extends Task public class RandomPositionLocator extends Task
{ {
private final RTPContainer contain; private final RTP contain;
public RandomPositionLocator(RTPContainer rtp) public RandomPositionLocator(RTP rtp)
{ {
super("RPL",true); super("RPL",true);
contain=rtp; contain=rtp;
@ -33,10 +33,10 @@ public class RandomPositionLocator extends Task
public void run() { public void run() {
if(!AriasEssentials.ALIVE)return; if(!AriasEssentials.ALIVE)return;
ChatHelpers.broadcastTo(contain.container.PlayerInst.getUUID(), ChatHelpers.macro(Messages.RTP_SEARCHING, String.valueOf(contain.tries), "30"), contain.container.PlayerInst.server); //ChatHelpers.broadcastTo(contain.container.PlayerInst.getUUID(), ChatHelpers.macro(Messages.RTP_SEARCHING, String.valueOf(contain.tries), "30"), contain.container.PlayerInst.server);
ServerLevel levl = contain.container.Dimension; ServerLevel levl = contain.position.getActualDimension();
ChunkAccess chunk = levl.getChunk(contain.container.world_pos.Position.asBlockPos()); ChunkAccess chunk = levl.getChunk(contain.position.Position.asBlockPos());
ChunkPos cpos = chunk.getPos(); ChunkPos cpos = chunk.getPos();
boolean needsLoading = false; boolean needsLoading = false;
needsLoading = !(levl.getForcedChunks().contains(cpos.toLong())); needsLoading = !(levl.getForcedChunks().contains(cpos.toLong()));
@ -48,25 +48,16 @@ public class RandomPositionLocator extends Task
int curChecks=0; int curChecks=0;
while(curChecks<10) while(curChecks<10)
{ {
if(contain.isSafe(contain.container.world_pos.Position.asBlockPos())) if(contain.isSafe(contain.position.Position.asBlockPos()))
{ {
contain.complete=true; contain.putAge();
if(needsLoading) if(needsLoading)
levl.setChunkForced(cpos.x, cpos.z, false); levl.setChunkForced(cpos.x, cpos.z, false);
if(MinecraftForge.EVENT_BUS.post(new RTPEvent(contain.container.PlayerInst, contain.container.world_pos)))
{
contain.complete=false;
contain.container.Position = contain.container.world_pos.Position.asMinecraftVector();
ChatHelpers.broadcastTo(contain.container.PlayerInst.getUUID(), ChatHelpers.macro(Messages.RTP_CANCELLED), contain.container.PlayerInst.server);
break; MinecraftForge.EVENT_BUS.post(new RTPFoundEvent(contain));
}else {
AriasEssentials.LOGGER.info("RTP Not cancelled. Actioning");
new RTPNotCancelledEvent(contain).send();
}
return; return;
}else { } else {
curChecks++; curChecks++;
contain.move(); contain.move();
//AriasEssentials.LOGGER.info("[DEBUG] "+ChatColor.doColors("!Dark_Red!Checking position: "+contain.container.world_pos.Position.toString()+"; "+contain.container.Dimension.getBlockState(contain.container.world_pos.Position.asBlockPos()).getBlock().toString()+"; "+contain.container.Dimension.getBlockState(contain.container.world_pos.Position.asBlockPos().below()).getBlock().toString())); //AriasEssentials.LOGGER.info("[DEBUG] "+ChatColor.doColors("!Dark_Red!Checking position: "+contain.container.world_pos.Position.toString()+"; "+contain.container.Dimension.getBlockState(contain.container.world_pos.Position.asBlockPos()).getBlock().toString()+"; "+contain.container.Dimension.getBlockState(contain.container.world_pos.Position.asBlockPos().below()).getBlock().toString()));
@ -80,8 +71,6 @@ public class RandomPositionLocator extends Task
if(contain.tries > 30) if(contain.tries > 30)
{ {
// Abort // Abort
ChatHelpers.broadcastTo(contain.container.PlayerInst.getUUID(), ChatHelpers.macro(Messages.RTP_ABORTED,"30"), contain.container.PlayerInst.server);
contain.aborted=true;
return; return;
}else { }else {
// Schedule the task to execute // Schedule the task to execute

View file

@ -1,169 +0,0 @@
package dev.zontreck.essentials.util;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Stream;
import dev.zontreck.essentials.AriasEssentials;
import dev.zontreck.essentials.commands.teleport.TeleportContainer;
import dev.zontreck.libzontreck.vectors.Vector3;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
public class RTPContainer {
public TeleportContainer container;
public int tries = -1;
public boolean complete = false;
public boolean aborted=false;
public Thread containingThread;
private Types heightMapType;
private int SearchDirection;
public static final List<Block> BLACKLIST;
static {
List<Block> tmp = new ArrayList<>();
tmp.add(Blocks.LAVA);
tmp.add(Blocks.BEDROCK);
tmp.add(Blocks.WATER);
BLACKLIST = tmp;
}
public void moveDown() {
container.world_pos.Position = container.world_pos.Position.moveDown();
container.Position = container.world_pos.Position.asMinecraftVector();
}
public void moveUp() {
container.world_pos.Position = container.world_pos.Position.moveUp();
container.Position = container.world_pos.Position.asMinecraftVector();
}
public void move()
{
if(SearchDirection==1){
moveUp();
}else if(SearchDirection==0)
{
moveDown();
}
}
public void moveOpposite()
{
if(SearchDirection==1){
moveDown();
}else if(SearchDirection==0)
{
moveUp();
}
}
public void newPosition() {
if(!AriasEssentials.ALIVE)return;
containingThread=Thread.currentThread();
if(tries>=30)return;
AriasEssentials.LOGGER.info("RTPContainer starts looking for new position");
Random rng = new Random(Instant.now().getEpochSecond());
Vector3 pos = new Vector3(rng.nextDouble(0xFFFF), 0, rng.nextDouble(0xFFFF));
BlockPos bpos = pos.asBlockPos();
container.Dimension.getChunk(bpos.getX() >> 4, bpos.getZ() >> 4, ChunkStatus.SPAWN);
pos = new Vector3(
container.Dimension.getHeightmapPos(heightMapType, pos.asBlockPos()));
while (!container.Dimension.getWorldBorder().isWithinBounds(pos.asBlockPos())) {
pos = new Vector3(rng.nextDouble(0xffff), 0, rng.nextDouble(0xffff));
bpos = pos.asBlockPos();
container.Dimension.getChunk(bpos.getX() >> 4, bpos.getZ() >> 4, ChunkStatus.SPAWN);
pos = new Vector3(
container.Dimension.getHeightmapPos(heightMapType, pos.asBlockPos()));
}
container.world_pos.Position = pos;
container.Position = container.world_pos.Position.asMinecraftVector();
if (pos.y < -60) {
newPosition();
return;
}
if (pos.y >= container.Dimension.getLogicalHeight()) {
spiralPositions(pos);
}
tries++;
AriasEssentials.LOGGER.info("RTPContainer returns new position");
}
private void spiralPositions(Vector3 position)
{
Vec3i posi = position.asMinecraftVec3i();
for(BlockPos pos : BlockPos.spiralAround(new BlockPos(posi.getX(), container.Dimension.getSeaLevel(), posi.getZ()), 16, Direction.WEST, Direction.NORTH)){
if(isSafe(pos)){
// Set the new position
container.world_pos.Position = new Vector3(pos);
container.Position = container.world_pos.Position.asMinecraftVector();
return;
}
}
}
protected RTPContainer(ServerPlayer player, Vec3 pos, Vec2 rot, ServerLevel level) {
container = new TeleportContainer(player, pos, rot, level);
if(container.Dimension.dimensionType().hasCeiling())
{
heightMapType = Heightmap.Types.MOTION_BLOCKING_NO_LEAVES;
SearchDirection=-1;
}else {
heightMapType = Types.MOTION_BLOCKING_NO_LEAVES;
SearchDirection=1;
}
newPosition();
}
private boolean safe(BlockPos blockPos)
{
containingThread=Thread.currentThread();
BlockState b = container.Dimension.getBlockState(blockPos);
BlockState b2 = container.Dimension.getBlockState(blockPos.above());
BlockState b3 = container.Dimension.getBlockState(blockPos.below());
if (b.isAir() && b2.isAir()) {
if (!b3.isAir()) {
if (BLACKLIST.contains(b3.getBlock())) {
return false;
} else
return true;
} else
return false;
} else
return false;
}
public boolean isSafe(BlockPos blockPos) {
boolean s = safe(blockPos);
if(s)
{
AriasEssentials.LOGGER.info("/!\\ SAFE /!\\");
}else AriasEssentials.LOGGER.info("/!\\ NOT SAFE /!\\");
return s;
}
}

View file

@ -1,23 +0,0 @@
package dev.zontreck.essentials.util;
import dev.zontreck.ariaslib.util.DelayedExecutorService;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
/**
* The factory system used to start searching for a random teleport position
*/
public class RandomPositionFactory {
public static RTPContainer beginRTPSearch(ServerPlayer player, Vec3 pos, Vec2 rot, ServerLevel level)
{
RTPContainer contain= new RTPContainer(player, pos, rot, level);
Thread tx = new Thread(new RandomPositionLocator(contain));
tx.setName("RTPTask-"+String.valueOf(DelayedExecutorService.getNext()));
tx.start();
return contain;
}
}