Dieser Commit ist enthalten in:
Commit
bbe7edc55a
@ -63,38 +63,6 @@ public class NMSWrapper15 implements NMSWrapper {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LongSupplier longSupplier) {
|
||||
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
|
||||
}
|
||||
|
||||
private static final List<Packet<?>> packets = new ArrayList<>();
|
||||
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public void createTickCache(World world) {
|
||||
packets.clear();
|
||||
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
|
||||
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
|
||||
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
|
||||
|
||||
if (entity instanceof TNTPrimed) {
|
||||
net.minecraft.server.v1_15_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.getId(), serverEntity.getDataWatcher(), true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTickPackets() {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
for (Packet<?> p : packets) {
|
||||
connection.sendPacket(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
|
||||
|
||||
@Override
|
||||
|
@ -31,7 +31,7 @@ public class PlaceItemWrapper15 implements PlaceItemWrapper {
|
||||
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
|
||||
try {
|
||||
Material nonWallMaterial = Material.valueOf(nonWall);
|
||||
if (nonWallMaterial != material) {
|
||||
if (nonWallMaterial != material && nonWallMaterial.isItem() && !nonWallMaterial.isBlock()) {
|
||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -19,9 +19,12 @@
|
||||
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||
import net.minecraft.server.v1_15_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntity;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -37,4 +40,20 @@ public class PlayerMovementWrapper15 implements PlayerMovementWrapper {
|
||||
entityPlayer.setLocation(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0), packetPlayInFlying.a(0F), packetPlayInFlying.b(0F));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertToOut(Player player, Object object) {
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
Object packet = Reflection.newInstance(teleportPacket);
|
||||
teleportEntity.set(packet, player.getEntityId());
|
||||
teleportPosition.set(packet, packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0));
|
||||
if (Float.isNaN(packetPlayInFlying.a(Float.NaN))) {
|
||||
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
|
||||
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
|
||||
} else {
|
||||
teleportYaw.set(packet, rotToByte(packetPlayInFlying.a(0.0F)));
|
||||
teleportPitch.set(packet, rotToByte(packetPlayInFlying.b(0.0F)));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
@ -73,37 +73,6 @@ public class NMSWrapper18 implements NMSWrapper {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LongSupplier longSupplier) {
|
||||
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
|
||||
}
|
||||
|
||||
private static final List<Packet<?>> packets = new ArrayList<>();
|
||||
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public void createTickCache(World world) {
|
||||
packets.clear();
|
||||
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
|
||||
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
|
||||
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
|
||||
|
||||
if (entity instanceof TNTPrimed) {
|
||||
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ae(), serverEntity.ai(), true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTickPackets() {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
for (Packet<?> p : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||
|
||||
@Override
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
@ -37,4 +38,20 @@ public class PlayerMovementWrapper18 implements PlayerMovementWrapper {
|
||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertToOut(Player player, Object object) {
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
Object packet = Reflection.newInstance(teleportPacket);
|
||||
teleportEntity.set(packet, player.getEntityId());
|
||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
if (packetPlayInFlying.h) {
|
||||
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
|
||||
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
|
||||
} else {
|
||||
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
|
||||
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
@ -73,39 +73,6 @@ public class NMSWrapper19 implements NMSWrapper {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LongSupplier longSupplier) {
|
||||
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
|
||||
}
|
||||
|
||||
private static final List<Packet<?>> packets = new ArrayList<>();
|
||||
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public void createTickCache(World world) {
|
||||
packets.clear();
|
||||
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
|
||||
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
|
||||
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
|
||||
|
||||
if (entity instanceof TNTPrimed) {
|
||||
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
|
||||
List<DataWatcher.b<?>> list = serverEntity.al().c();
|
||||
if(list != null)
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), list));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTickPackets() {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
for (Packet<?> p : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||
|
||||
@Override
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import org.bukkit.Location;
|
||||
@ -31,50 +32,30 @@ import java.util.UUID;
|
||||
|
||||
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
|
||||
|
||||
private static class Position {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
}
|
||||
|
||||
private Map<UUID, Position> playerLocationMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setPosition(Player player, Object object) {
|
||||
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
|
||||
Position pos = new Position();
|
||||
Location location = player.getLocation();
|
||||
pos.x = location.getX();
|
||||
pos.y = location.getY();
|
||||
pos.z = location.getZ();
|
||||
pos.yaw = location.getYaw();
|
||||
pos.pitch = location.getPitch();
|
||||
return pos;
|
||||
});
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
if (packetPlayInFlying.h) {
|
||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
position.yaw = packetPlayInFlying.d;
|
||||
position.pitch = packetPlayInFlying.e;
|
||||
} else {
|
||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(Player player) {
|
||||
Position position = playerLocationMap.remove(player.getUniqueId());
|
||||
if (position != null) {
|
||||
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
|
||||
public Object convertToOut(Player player, Object object) {
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
Object packet = Reflection.newInstance(teleportPacket);
|
||||
teleportEntity.set(packet, player.getEntityId());
|
||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
if (packetPlayInFlying.h) {
|
||||
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
|
||||
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
|
||||
} else {
|
||||
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
|
||||
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
@ -20,32 +20,23 @@
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
||||
import net.minecraft.SystemUtils;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.syncher.DataWatcher;
|
||||
import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
|
||||
import net.minecraft.server.level.PlayerInteractManager;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
import net.minecraft.world.phys.Vec3D;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public class NMSWrapper20 implements NMSWrapper {
|
||||
|
||||
@ -73,39 +64,6 @@ public class NMSWrapper20 implements NMSWrapper {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LongSupplier longSupplier) {
|
||||
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
|
||||
}
|
||||
|
||||
private static final List<Packet<?>> packets = new ArrayList<>();
|
||||
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public void createTickCache(World world) {
|
||||
packets.clear();
|
||||
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
|
||||
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
|
||||
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
|
||||
|
||||
if (entity instanceof TNTPrimed) {
|
||||
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
|
||||
List<DataWatcher.b<?>> list = serverEntity.aj().c();
|
||||
if(list != null)
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.af(), list));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTickPackets() {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
for (Packet<?> p : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutEntityTeleport;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
@ -31,50 +33,30 @@ import java.util.UUID;
|
||||
|
||||
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
|
||||
|
||||
private static class Position {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
}
|
||||
|
||||
private Map<UUID, Position> playerLocationMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setPosition(Player player, Object object) {
|
||||
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
|
||||
Position pos = new Position();
|
||||
Location location = player.getLocation();
|
||||
pos.x = location.getX();
|
||||
pos.y = location.getY();
|
||||
pos.z = location.getZ();
|
||||
pos.yaw = location.getYaw();
|
||||
pos.pitch = location.getPitch();
|
||||
return pos;
|
||||
});
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
if (packetPlayInFlying.h) {
|
||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
position.yaw = packetPlayInFlying.d;
|
||||
position.pitch = packetPlayInFlying.e;
|
||||
} else {
|
||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(Player player) {
|
||||
Position position = playerLocationMap.remove(player.getUniqueId());
|
||||
if (position != null) {
|
||||
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
|
||||
public Object convertToOut(Player player, Object object) {
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
Object packet = Reflection.newInstance(teleportPacket);
|
||||
teleportEntity.set(packet, player.getEntityId());
|
||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
if (packetPlayInFlying.h) {
|
||||
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
|
||||
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
|
||||
} else {
|
||||
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
|
||||
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ SCOREBOARD_REGION = Region
|
||||
SCOREBOARD_TRACE = Trace
|
||||
SCOREBOARD_LOADER = Loader
|
||||
SCOREBOARD_TPS = TPS
|
||||
SCOREBOARD_TPS_FROZEN = §e Frozen
|
||||
SCOREBOARD_TPS_FROZEN = §eFrozen
|
||||
|
||||
SCOREBOARD_TRACE_TICKS = Ticks
|
||||
|
||||
@ -459,27 +459,31 @@ DEPTH_COUNTER_HOVER = §7X§8ק7Y§8ק7Z
|
||||
DEPTH_COUNTER_TNT = §7 TNT§8: §e{0}
|
||||
|
||||
# TPSLimit
|
||||
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Step n ticks
|
||||
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Step one tick
|
||||
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warp n ticks
|
||||
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancels tick step/warp
|
||||
TICK_ERROR = §cYou can not activate another §8'§e/tick step§8'§c or §8'§e/tick warp§8'§c
|
||||
TICK_CANCEL_ERROR = §cYou have no §8'§e/tick step§8'§c or §8'§e/tick warp§8'§c active
|
||||
TICK_STEP = §eSkipping {0} ticks
|
||||
TICK_STEP_LEFT = §eSkipping {0} more ticks
|
||||
TICK_WARP = §eWarping {0} ticks
|
||||
TICK_WARP_LEFT = §eWarping {0} more ticks
|
||||
TICK_CANCEL = §eWarps and Steps canceled
|
||||
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Freeze TPS
|
||||
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Slow TPS down
|
||||
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Speed TPS up
|
||||
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Set TPS to 20
|
||||
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Show current TPS
|
||||
|
||||
TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Freeze TPS
|
||||
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Freeze TPS
|
||||
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Set TPS to 20
|
||||
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Slow TPS down
|
||||
TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Speed TPS up
|
||||
TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Set TPS to 20
|
||||
TICK_HELP = §8/§etick rate §8-§7 Show current TPS
|
||||
|
||||
TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Step n ticks or 1 forward
|
||||
TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warp n ticks or 1 forward
|
||||
|
||||
TICK_BOSSBAR = §7Skipped §e{0}§8/§7{1}
|
||||
TPSLIMIT_GUI_ITEM_NAME = §eTPS limiter
|
||||
TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0}
|
||||
TPSLIMIT_ANVIL_GUI = New TPS limit
|
||||
TPSLIMIT_HELP = §8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Sets TPS on Build
|
||||
TPSLIMIT_CURRENT = §7Current TPS limit§8: §e{0}
|
||||
TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here
|
||||
TPSLIMIT_SET = §eSet TPS limit to {0}
|
||||
TPSLIMIT_FROZEN = §eTPS frozen
|
||||
TPSLIMIT_INVALID = §cOnly numbers between 0,5 and {0}, and 'default'{1} allowed.
|
||||
TPSLIMIT_INVALID_FROZEN = §c and '0'
|
||||
|
||||
# Trace
|
||||
TRACE_RECORD=§aon
|
||||
|
@ -33,7 +33,7 @@ SCOREBOARD_REGION = Region
|
||||
SCOREBOARD_TRACE = Trace
|
||||
SCOREBOARD_LOADER = Loader
|
||||
SCOREBOARD_TPS = TPS
|
||||
SCOREBOARD_TPS_FROZEN = §e Eingefroren
|
||||
SCOREBOARD_TPS_FROZEN = §eEingefroren
|
||||
|
||||
SCOREBOARD_TRACE_TICKS = Ticks
|
||||
|
||||
@ -428,27 +428,31 @@ BLOCK_COUNTER_DISABLE = §7BlockCounter ausgemacht
|
||||
DEPTH_COUNTER_MESSAGE = §7Tiefe §8> §7
|
||||
|
||||
# TPSLimit
|
||||
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Spule n Ticks vor
|
||||
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Spule einen Ticks vor
|
||||
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warpe n Ticks vor
|
||||
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancelt den Tick Warp oder Step
|
||||
TICK_ERROR = §cDu kannst keinen weiteren §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c anmachen
|
||||
TICK_CANCEL_ERROR = §cDu hast keinen §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c aktiv
|
||||
TICK_STEP = §eSpult {0} Ticks vor
|
||||
TICK_STEP_LEFT = §eSpult noch {0} Ticks vor
|
||||
TICK_WARP = §eWarpe {0} Ticks vor
|
||||
TICK_WARP_LEFT = §eWarpe noch {0} Ticks vor
|
||||
TICK_CANCEL = §eWarps und Steps abgebrochen
|
||||
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Friere TPS ein
|
||||
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
|
||||
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Beschleunige die TPS
|
||||
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Setze die TPS auf 20
|
||||
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Zeige die jetzige TPS
|
||||
|
||||
TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Friere TPS ein
|
||||
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Friere TPS ein
|
||||
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Setze die TPS auf 20
|
||||
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
|
||||
TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Beschleunige die TPS
|
||||
TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Setze die TPS auf 20
|
||||
TICK_HELP = §8/§etick rate §8-§7 Zeige die jetzige TPS
|
||||
|
||||
TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Spule n ticks oder 1 vor
|
||||
TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warpe n ticks oder 1 vor
|
||||
|
||||
TICK_BOSSBAR = §e{0}§8/§7{1} gesprungen
|
||||
TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter
|
||||
TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0}
|
||||
TPSLIMIT_ANVIL_GUI = Neues TPS Limit
|
||||
TPSLIMIT_HELP = §8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Setzte die TPS auf dem Bau
|
||||
TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0}
|
||||
TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen
|
||||
TPSLIMIT_SET = §eTPS limit auf {0} gesetzt.
|
||||
TPSLIMIT_FROZEN = §eTPS eingefroren.
|
||||
TPSLIMIT_INVALID = §cNur Zahlen zwischen 0,5 und {0}, und 'default'{1} erlaubt.
|
||||
TPSLIMIT_INVALID_FROZEN = §c und '0'
|
||||
|
||||
# Trace
|
||||
TRACE_RECORD=§aan
|
||||
|
@ -21,16 +21,12 @@ package de.steamwar.bausystem;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.features.tpslimit.FreezeUtils;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
|
||||
import de.steamwar.bausystem.features.world.RamUsage;
|
||||
import de.steamwar.bausystem.linkage.LinkageUtils;
|
||||
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
||||
import de.steamwar.bausystem.region.loader.RegionLoader;
|
||||
import de.steamwar.bausystem.region.loader.Updater;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import de.steamwar.bausystem.linkage.LinkageUtils;
|
||||
import de.steamwar.message.Message;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -139,7 +135,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (FreezeUtils.isFrozen()) return;
|
||||
// if (FreezeUtils.isFrozen()) return;
|
||||
if (counter >= delay) {
|
||||
runnable.run();
|
||||
cancel();
|
||||
@ -157,7 +153,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (FreezeUtils.isFrozen()) return;
|
||||
// if (FreezeUtils.isFrozen()) return;
|
||||
if (counter >= (first ? delay : period)) {
|
||||
first = false;
|
||||
runnable.run();
|
||||
|
@ -2,7 +2,6 @@ package de.steamwar.bausystem.features.bau;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.config.BauServer;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.command.SWCommand;
|
||||
@ -15,8 +14,6 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.tpslimit.TPSWarpUtils.getTps;
|
||||
|
||||
@Linked
|
||||
public class InfoCommand extends SWCommand {
|
||||
|
||||
@ -65,13 +62,11 @@ public class InfoCommand extends SWCommand {
|
||||
|
||||
StringBuilder tpsMessage = new StringBuilder();
|
||||
tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p));
|
||||
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.ONE_SECOND));
|
||||
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.TEN_SECONDS));
|
||||
if (!TPSWarpUtils.isWarping()) {
|
||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND));
|
||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS));
|
||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE));
|
||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES));
|
||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES));
|
||||
}
|
||||
p.sendMessage(tpsMessage.toString());
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
package de.steamwar.bausystem.features.script.lua.libs;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
@ -76,7 +75,7 @@ public class ServerLib implements LuaLib {
|
||||
tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
|
||||
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
|
||||
tpsLib.set("current", getter(TPSWatcher::getTPS));
|
||||
tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
|
||||
// tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
|
||||
|
||||
serverLib.set("tps", tpsLib);
|
||||
return serverLib;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
@ -19,39 +19,96 @@
|
||||
|
||||
package de.steamwar.bausystem.features.smartplace;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.SoundGroup;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Repeater;
|
||||
import org.bukkit.block.data.type.Sign;
|
||||
import org.bukkit.block.data.type.Switch;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.TileState;
|
||||
import org.bukkit.block.data.*;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Linked
|
||||
public class SmartPlaceListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
// TODO: Sneaking not reset sometimes
|
||||
|
||||
private static final Set<Material> CONTAINERS = new HashSet<>();
|
||||
|
||||
static {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
Block block = world.getBlockAt(0, 0, 0);
|
||||
BlockState state = block.getState();
|
||||
for (Material material : Material.values()) {
|
||||
if (material.isLegacy()) continue;
|
||||
if (!material.isInteractable() && !material.isBlock()) continue;
|
||||
BlockData blockData = material.createBlockData();
|
||||
block.setBlockData(blockData);
|
||||
if (block.getState() instanceof TileState) {
|
||||
CONTAINERS.add(material);
|
||||
} else if (blockData instanceof Stairs) {
|
||||
CONTAINERS.add(material);
|
||||
}
|
||||
}
|
||||
CONTAINERS.add(Material.GRINDSTONE);
|
||||
state.update(true, false);
|
||||
}
|
||||
|
||||
private static final Class<?> useItem = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem");
|
||||
private static final Set<Player> SMART_PLACING = new HashSet<>();
|
||||
|
||||
public SmartPlaceListener() {
|
||||
TinyProtocol.instance.addFilter(useItem, (player, object) -> {
|
||||
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) {
|
||||
return object;
|
||||
}
|
||||
|
||||
Block block = player.getTargetBlockExact(6);
|
||||
if (block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType())) {
|
||||
return object;
|
||||
}
|
||||
|
||||
boolean isSneaking = player.isSneaking();
|
||||
if (isSneaking) {
|
||||
SMART_PLACING.add(player);
|
||||
}
|
||||
if (!isSneaking) {
|
||||
player.setSneaking(true);
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
player.setSneaking(isSneaking);
|
||||
SMART_PLACING.remove(player);
|
||||
}, 0);
|
||||
return object;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
|
||||
|
||||
boolean shouldRotate = event.getPlayer().isSneaking();
|
||||
Material blockType = event.getClickedBlock().getType();
|
||||
switch (blockType) {
|
||||
case REPEATER:
|
||||
if (shouldRotate && (event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
|
||||
if (!event.getPlayer().isSneaking()) return;
|
||||
if (event.getClickedBlock().getType() != Material.REPEATER) return;
|
||||
if ((event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
|
||||
Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
|
||||
int i = repeater.getDelay() - 1;
|
||||
if (i <= 0) i += 4;
|
||||
@ -59,45 +116,87 @@ public class SmartPlaceListener implements Listener {
|
||||
event.getClickedBlock().setBlockData(repeater);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
BlockData blockData = event.getClickedBlock().getBlockData();
|
||||
if (blockData instanceof Switch) {
|
||||
if (!shouldRotate && (event.getItem() == null || event.getItem().getType() == event.getClickedBlock().getType())) {
|
||||
return;
|
||||
}
|
||||
shouldRotate = false;
|
||||
}
|
||||
|
||||
PlaceItemUtils.PlaceItemResult result = PlaceItemUtils.placeItem(event.getPlayer(), event.getItem(), event.getClickedBlock(), event.getBlockFace(), event.getHand(), true, true, shouldRotate, false);
|
||||
if (result.isSuccess()) {
|
||||
event.setCancelled(true);
|
||||
Block block = event.getClickedBlock().getRelative(event.getBlockFace());
|
||||
SoundGroup soundGroup = block.getBlockData().getSoundGroup();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
if (!(event.getClickedBlock().getBlockData() instanceof Sign) && player == event.getPlayer()) {
|
||||
return;
|
||||
}
|
||||
player.playSound(block.getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
|
||||
});
|
||||
if (result.wasForced()) {
|
||||
event.getPlayer().playSound(block.getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
|
||||
}
|
||||
}
|
||||
// Fix Double sound for original player
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
|
||||
if (!event.getPlayer().isSneaking()) return;
|
||||
event.setCancelled(true);
|
||||
event.getBlock().setType(Material.AIR, false);
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (!SMART_PLACING.contains(event.getPlayer())) return;
|
||||
BlockData blockData = event.getBlock().getBlockData();
|
||||
if (blockData instanceof Bed) {
|
||||
Bed bed = (Bed) blockData;
|
||||
Block bedHead = event.getBlock().getRelative(bed.getFacing());
|
||||
bed.setPart(Bed.Part.HEAD);
|
||||
bed.setFacing(bed.getFacing().getOppositeFace());
|
||||
|
||||
SoundGroup soundGroup = event.getBlock().getBlockData().getSoundGroup();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
if (player == event.getPlayer()) return;
|
||||
player.playSound(event.getBlock().getLocation(), soundGroup.getBreakSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
|
||||
bed = (Bed) bedHead.getBlockData();
|
||||
bed.setPart(Bed.Part.FOOT);
|
||||
bed.setFacing(bed.getFacing().getOppositeFace());
|
||||
bedHead.setBlockData(bed, false);
|
||||
} else if (blockData instanceof FaceAttachable && ((FaceAttachable) blockData).getAttachedFace() != FaceAttachable.AttachedFace.WALL) {
|
||||
FaceAttachable faceAttachable = (FaceAttachable) blockData;
|
||||
faceAttachable.setAttachedFace(faceAttachable.getAttachedFace() == FaceAttachable.AttachedFace.CEILING ? FaceAttachable.AttachedFace.FLOOR : FaceAttachable.AttachedFace.CEILING);
|
||||
} else if (blockData instanceof Rotatable) {
|
||||
Rotatable rotatable = (Rotatable) blockData;
|
||||
rotatable.setRotation(rotatable.getRotation().getOppositeFace());
|
||||
} else if (blockData instanceof Directional) {
|
||||
Directional directional = (Directional) blockData;
|
||||
BlockFace face = directional.getFacing().getOppositeFace();
|
||||
if (directional.getFaces().contains(face)) {
|
||||
directional.setFacing(face);
|
||||
}
|
||||
} else if (blockData instanceof MultipleFacing && !(blockData instanceof Fence)) {
|
||||
MultipleFacing multipleFacing = (MultipleFacing) blockData;
|
||||
List<BlockFace> blockFaceList = multipleFacing.getFaces()
|
||||
.stream()
|
||||
.map(BlockFace::getOppositeFace)
|
||||
.collect(Collectors.toList());
|
||||
if (multipleFacing.getAllowedFaces().containsAll(blockFaceList)) {
|
||||
multipleFacing.getFaces().forEach(blockFace -> {
|
||||
multipleFacing.setFace(blockFace, false);
|
||||
});
|
||||
blockFaceList.forEach(blockFace -> {
|
||||
multipleFacing.setFace(blockFace, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (blockData instanceof Stairs) {
|
||||
Stairs stairs = (Stairs) blockData;
|
||||
switch (stairs.getShape()) {
|
||||
case OUTER_LEFT:
|
||||
stairs.setShape(Stairs.Shape.INNER_RIGHT);
|
||||
break;
|
||||
case INNER_LEFT:
|
||||
stairs.setShape(Stairs.Shape.OUTER_RIGHT);
|
||||
break;
|
||||
case OUTER_RIGHT:
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
break;
|
||||
case INNER_RIGHT:
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
break;
|
||||
case STRAIGHT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blockData instanceof Piston) {
|
||||
Piston piston = (Piston) blockData;
|
||||
Block block = event.getBlock().getRelative(piston.getFacing().getOppositeFace());
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
event.getPlayer().sendBlockChange(block.getLocation(), block.getBlockData());
|
||||
}, 2);
|
||||
} else if (blockData.getMaterial() == Material.REPEATER || blockData.getMaterial() == Material.COMPARATOR) {
|
||||
Block block = event.getBlock().getRelative(BlockFace.DOWN);
|
||||
BlockState old = block.getState();
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
block.setType(Material.GLASS);
|
||||
old.update(true, false);
|
||||
}, 1);
|
||||
}
|
||||
event.getBlock().setBlockData(blockData, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
SMART_PLACING.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.BountifulWrapper;
|
||||
import de.steamwar.core.ChatWrapper;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import yapion.utils.ReflectionsUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
public class FreezeUtils {
|
||||
|
||||
private static final Field field;
|
||||
public static final boolean freezeEnabled;
|
||||
|
||||
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", null);
|
||||
|
||||
@Getter
|
||||
private static boolean frozen = false;
|
||||
|
||||
private static final World world;
|
||||
|
||||
static {
|
||||
field = ReflectionsUtils.getField(Reflection.getClass("{nms.server.level}.WorldServer"), "freezed");
|
||||
if (field != null) field.setAccessible(true);
|
||||
freezeEnabled = field != null;
|
||||
world = Bukkit.getWorlds().get(0);
|
||||
}
|
||||
|
||||
public static void freeze() {
|
||||
setFreeze(world, true);
|
||||
}
|
||||
|
||||
public static void unfreeze() {
|
||||
setFreeze(world, false);
|
||||
}
|
||||
|
||||
public static boolean frozen() {
|
||||
return freezeEnabled && frozen;
|
||||
}
|
||||
|
||||
private void setFreeze(World world, boolean state) {
|
||||
if (freezeEnabled) {
|
||||
try {
|
||||
field.set(getWorldHandle.invoke(world), state);
|
||||
cacheEntityPackets(state);
|
||||
frozen = state;
|
||||
} catch (IllegalAccessException e) {
|
||||
// Ignored;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> packets = new ArrayList<>();
|
||||
private Set<Entity> entities = new HashSet<>();
|
||||
private BukkitTask task = null;
|
||||
|
||||
private Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
|
||||
private Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
||||
private Object ZERO_VEC3D = zeroVec3d.get(null);
|
||||
private Class<?> velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
||||
private Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
||||
|
||||
private Class<?> teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
||||
private Class<?> entityClass = Reflection.getClass("{nms.world.entity}.Entity");
|
||||
private Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
||||
|
||||
private Class<?> craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity");
|
||||
private Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
||||
|
||||
private Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
||||
private Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
||||
|
||||
private void cacheEntityPackets(boolean state) {
|
||||
if (state) {
|
||||
createPackets();
|
||||
|
||||
if (task == null) {
|
||||
task = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createPackets();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
for (Object packet : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(BauSystem.getInstance(), 1, 1);
|
||||
}
|
||||
} else {
|
||||
packets.clear();
|
||||
entities.clear();
|
||||
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createPackets() {
|
||||
if (FreezeUtils.entities.stream().anyMatch(Entity::isDead)) {
|
||||
entities.clear();
|
||||
packets.clear();
|
||||
}
|
||||
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> !FreezeUtils.entities.contains(e))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Entity entity : entities) {
|
||||
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof TNTPrimed)) continue;
|
||||
TNTPrimed tnt = (TNTPrimed) entity;
|
||||
int fuse = tnt.getFuseTicks();
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
||||
}
|
||||
|
||||
FreezeUtils.entities.addAll(entities);
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.core.BountifulWrapper;
|
||||
import de.steamwar.core.ChatWrapper;
|
||||
import de.steamwar.core.Core;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
class PacketCache {
|
||||
|
||||
private static List<Object> packets = new ArrayList<>();
|
||||
private static Set<Entity> entities = new HashSet<>();
|
||||
private static BukkitTask task = null;
|
||||
|
||||
private static Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
|
||||
private static Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
||||
private static Object ZERO_VEC3D = zeroVec3d.get(null);
|
||||
private static Class<?> velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
||||
private static Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
||||
|
||||
private static Class<?> teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
||||
private static Class<?> entityClass = Reflection.getClass("{nms.world.entity}.Entity");
|
||||
private static Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
||||
|
||||
private static Class<?> craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity");
|
||||
private static Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
||||
|
||||
private static Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
||||
private static Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
||||
|
||||
public void continuousSendCache() {
|
||||
if (task != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
createPackets();
|
||||
task = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
_sendCache();
|
||||
}
|
||||
}.runTaskTimer(Core.getInstance(), 1, 1);
|
||||
}
|
||||
|
||||
public void sendCache() {
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
_sendCache();
|
||||
}
|
||||
|
||||
private void _sendCache() {
|
||||
createPackets();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
for (Object packet : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
packets.clear();
|
||||
entities.clear();
|
||||
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void createPackets() {
|
||||
if (entities.stream().anyMatch(Entity::isDead)) {
|
||||
entities.clear();
|
||||
packets.clear();
|
||||
}
|
||||
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> PacketCache.entities.add(e))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Entity entity : entities) {
|
||||
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof TNTPrimed)) continue;
|
||||
TNTPrimed tnt = (TNTPrimed) entity;
|
||||
int fuse = tnt.getFuseTicks();
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@Linked
|
||||
public class TPSCommand extends SWCommand {
|
||||
|
||||
public TPSCommand() {
|
||||
super("tps");
|
||||
unregister();
|
||||
register();
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Player p, String... args) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_HEAD", p);
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_MESSAGE", p,
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)
|
||||
);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Player p, TPSWatcher.TPSType type) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, TPSSystem.getInstance().getTPS(type));
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
@UtilityClass
|
||||
public class TPSFreezeUtils {
|
||||
|
||||
private static Reflection.FieldAccessor<Boolean> fieldAccessor;
|
||||
@Getter
|
||||
private static final boolean canFreeze;
|
||||
|
||||
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", null);
|
||||
|
||||
@Getter
|
||||
private static boolean frozen = false;
|
||||
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
static {
|
||||
Reflection.FieldAccessor<Boolean> fieldAccessor;
|
||||
try {
|
||||
fieldAccessor = Reflection.getField(Reflection.getClass("{nms.server.level}.WorldServer"), "freezed", boolean.class);
|
||||
} catch (IllegalArgumentException e) {
|
||||
fieldAccessor = null;
|
||||
}
|
||||
canFreeze = fieldAccessor != null;
|
||||
TPSFreezeUtils.fieldAccessor = fieldAccessor;
|
||||
}
|
||||
|
||||
public void freeze() {
|
||||
setFreeze(world, true);
|
||||
}
|
||||
|
||||
public void unfreeze() {
|
||||
setFreeze(world, false);
|
||||
}
|
||||
|
||||
public boolean frozen() {
|
||||
return canFreeze && frozen;
|
||||
}
|
||||
|
||||
private void setFreeze(World world, boolean state) {
|
||||
if (canFreeze) {
|
||||
fieldAccessor.set(getWorldHandle.invoke(world), state);
|
||||
if (state) {
|
||||
PacketCache.continuousSendCache();
|
||||
} else {
|
||||
PacketCache.clearCache();
|
||||
}
|
||||
frozen = state;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.linkage.specific.BauGuiItem;
|
||||
import de.steamwar.inventory.SWAnvilInv;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Linked
|
||||
public class TPSLimitBauGuiItem extends BauGuiItem {
|
||||
|
||||
public TPSLimitBauGuiItem() {
|
||||
super(19);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(Player player) {
|
||||
return new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_LORE", player, TPSLimitUtils.getCurrentTPSLimit())), false, clickType -> {
|
||||
}).getItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean click(ClickType click, Player p) {
|
||||
p.closeInventory();
|
||||
SWAnvilInv inv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("TPSLIMIT_ANVIL_GUI", p));
|
||||
inv.setItem(Material.CLOCK);
|
||||
inv.setCallback(s -> p.performCommand("tpslimit " + s));
|
||||
inv.open();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission permission() {
|
||||
return Permission.WORLD;
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.SWCommandUtils;
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.api.Enable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Linked
|
||||
public class TPSLimitCommand extends SWCommand implements Enable {
|
||||
|
||||
private final List<String> tabCompletions = new ArrayList<>();
|
||||
|
||||
static final int MAX_TPS = Integer.MAX_VALUE;
|
||||
|
||||
public TPSLimitCommand() {
|
||||
super("tpslimit");
|
||||
tabCompletions.add("0,5");
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
tabCompletions.add(i + "");
|
||||
}
|
||||
if (TPSWarpUtils.isWarpAllowed()) {
|
||||
for (int i = 20; i <= 60; i += 5) {
|
||||
tabCompletions.add(i + "");
|
||||
}
|
||||
for (int i = 60; i <= 240; i += 10) {
|
||||
tabCompletions.add(i + "");
|
||||
}
|
||||
}
|
||||
if (FreezeUtils.freezeEnabled) {
|
||||
tabCompletions.add("0");
|
||||
}
|
||||
addDefaultHelpMessage("TPSLIMIT_HELP");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
TPSWarpUtils.init();
|
||||
}
|
||||
|
||||
@Register
|
||||
public void checkCommand(Player p) {
|
||||
if (!permissionCheck(p)) return;
|
||||
BauSystem.MESSAGE.send("TPSLIMIT_CURRENT", p, TPSLimitUtils.currentTPSLimit);
|
||||
}
|
||||
|
||||
@Register({"default"})
|
||||
public void defaultCommand(Player p) {
|
||||
if (!permissionCheck(p)) return;
|
||||
valueCommand(p, 20D);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void valueCommand(Player p, /*@DoubleRange(min = 0.5, max = 60)*/ double tpsLimitDouble) {
|
||||
if (!permissionCheck(p)) return;
|
||||
if (FreezeUtils.freezeEnabled && tpsLimitDouble == 0) {
|
||||
FreezeUtils.freeze();
|
||||
TPSLimitUtils.currentTPSLimit = 20;
|
||||
TPSLimitUtils.tpsLimiter();
|
||||
sendNewTPSLimitMessage(true);
|
||||
return;
|
||||
}
|
||||
if (tpsLimitDouble < 0.5 || tpsLimitDouble > (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20)) {
|
||||
sendInvalidArgumentMessage(p);
|
||||
return;
|
||||
}
|
||||
FreezeUtils.unfreeze();
|
||||
TPSLimitUtils.currentTPSLimit = tpsLimitDouble;
|
||||
TPSLimitUtils.tpsLimiter();
|
||||
sendNewTPSLimitMessage(false);
|
||||
}
|
||||
|
||||
@ClassMapper(value = double.class, local = true)
|
||||
public TypeMapper<Double> doubleTypeMapper() {
|
||||
return SWCommandUtils.createMapper(s -> {
|
||||
if (s.equalsIgnoreCase("nan")) return -1D;
|
||||
try {
|
||||
return Double.parseDouble(s.replace(',', '.'));
|
||||
} catch (NumberFormatException e) {
|
||||
return -1D;
|
||||
}
|
||||
}, s -> tabCompletions);
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
protected static boolean permissionCheck(Player player) {
|
||||
if (!Permission.hasPermission(player, Permission.WORLD)) {
|
||||
BauSystem.MESSAGE.send("TPSLIMIT_NO_PERMS", player);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendNewTPSLimitMessage(boolean frozen) {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
if (frozen) {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_FROZEN", player));
|
||||
} else {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_SET", player, TPSLimitUtils.currentTPSLimit));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendInvalidArgumentMessage(Player player) {
|
||||
BauSystem.MESSAGE.send("TPSLIMIT_INVALID", player, TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20, FreezeUtils.freezeEnabled ? BauSystem.MESSAGE.parse("TPSLIMIT_INVALID_FROZEN", player) : "");
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
@ -21,52 +21,53 @@ package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static de.steamwar.bausystem.features.tpslimit.TPSLimitCommand.MAX_TPS;
|
||||
|
||||
@UtilityClass
|
||||
public class TPSLimitUtils {
|
||||
|
||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||
static double currentTPSLimit = 20;
|
||||
private static long currentTime = System.nanoTime();
|
||||
private static BukkitTask tpsLimiter = null;
|
||||
private static Queue<Runnable> packetQueue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private long currentTime = System.nanoTime();
|
||||
|
||||
|
||||
private BukkitTask tpsLimiter = null;
|
||||
|
||||
void tpsLimiter() {
|
||||
public void unlimit() {
|
||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
||||
double delay = 20 / currentTPSLimit;
|
||||
tpsLimiter = null;
|
||||
}
|
||||
|
||||
public void limit(double tps) {
|
||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
||||
|
||||
double delay = 20 / tps;
|
||||
int loops = (int) Math.ceil(delay);
|
||||
long sleepDelay = (long) (50 * delay) / loops;
|
||||
|
||||
TPSWarpUtils.setTPS(currentTPSLimit);
|
||||
if (currentTPSLimit >= 20) {
|
||||
if (tpsLimiter == null) return;
|
||||
tpsLimiter.cancel();
|
||||
tpsLimiter = null;
|
||||
} else {
|
||||
tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
NMSWrapper.impl.createTickCache(WORLD);
|
||||
|
||||
tpsLimiter = Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
||||
PacketCache.sendCache();
|
||||
for (int i = 0; i < loops; i++) {
|
||||
sleepUntilNextTick(sleepDelay);
|
||||
NMSWrapper.impl.sendTickPackets();
|
||||
PacketCache.sendCache();
|
||||
while (true) {
|
||||
Runnable runnable = packetQueue.poll();
|
||||
if (runnable == null) break;
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
PacketCache.clearCache();
|
||||
}, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void sleepUntilNextTick(long neededDelta) {
|
||||
long lastTime = currentTime;
|
||||
@ -83,26 +84,39 @@ public class TPSLimitUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static double getCurrentTPSLimit() {
|
||||
return (double) Math.round(currentTPSLimit * 10.0D) / 10.0D;
|
||||
/*
|
||||
static {
|
||||
long timeInterval = 50;
|
||||
final long[] lastTime = {System.currentTimeMillis()};
|
||||
final double[] tps = {20.0};
|
||||
Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime > lastTime[0]) {
|
||||
tps[0] = (double)timeInterval / (double)(currentTime - lastTime[0]) * 20.0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void setTPS(double d) {
|
||||
if (d < 0.5) d = 0.5;
|
||||
if (d > (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20)) d = (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20);
|
||||
currentTPSLimit = d;
|
||||
tpsLimiter();
|
||||
lastTime[0] = currentTime;
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, String.valueOf((int) (tps[0] * 10.0) / 10.0));
|
||||
});
|
||||
}, timeInterval / 50L, timeInterval / 50L);
|
||||
}
|
||||
*/
|
||||
|
||||
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
|
||||
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
|
||||
static {
|
||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
||||
if (currentTPSLimit < 20) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
if (tpsLimiter != null) {
|
||||
Object object = PlayerMovementWrapper.impl.convertToOut(player, o);
|
||||
packetQueue.add(() -> {
|
||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
||||
}, 1L);
|
||||
Bukkit.getOnlinePlayers().forEach(p -> {
|
||||
if (p == player) return;
|
||||
TinyProtocol.instance.sendPacket(p, object);
|
||||
});
|
||||
});
|
||||
return null;
|
||||
}
|
||||
return o;
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@Linked
|
||||
public class TPSScoreboardElement implements ScoreboardElement {
|
||||
|
||||
@Override
|
||||
public ScoreboardGroup getGroup() {
|
||||
return ScoreboardGroup.FOOTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(Region region, Player p) {
|
||||
if (FreezeUtils.frozen()) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p);
|
||||
} else {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
|
||||
}
|
||||
}
|
||||
|
||||
private String tpsColor() {
|
||||
double tps = TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_SECOND);
|
||||
if (tps > TPSLimitUtils.getCurrentTPSLimit() * 0.9) {
|
||||
return "§a";
|
||||
}
|
||||
if (tps > TPSLimitUtils.getCurrentTPSLimit() * 0.5) {
|
||||
return "§e";
|
||||
}
|
||||
return "§c";
|
||||
}
|
||||
|
||||
private String tpsLimit() {
|
||||
if (TPSLimitUtils.getCurrentTPSLimit() == 20) {
|
||||
return "";
|
||||
}
|
||||
return "§8/§7" + TPSLimitUtils.getCurrentTPSLimit();
|
||||
}
|
||||
}
|
@ -0,0 +1,409 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.bausystem.linkage.specific.BauGuiItem;
|
||||
import de.steamwar.bausystem.region.GlobalRegion;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeValidator;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.TPSWarpUtils;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import de.steamwar.inventory.SWAnvilInv;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.api.Plain;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Linked
|
||||
public class TPSSystem implements Plain {
|
||||
|
||||
@Getter
|
||||
private double currentTPSLimit = 20;
|
||||
|
||||
@Getter
|
||||
private static TPSSystem instance;
|
||||
|
||||
public double getTPS(TPSWatcher.TPSType tpsType) {
|
||||
return TPSWatcher.getTPSUnlimited(tpsType);
|
||||
}
|
||||
|
||||
public TPSSystem() {
|
||||
if (TPSFreezeUtils.isCanFreeze()) {
|
||||
new TPSFreezeCommand();
|
||||
new TickFreezeCommand();
|
||||
new TickStepCommand();
|
||||
}
|
||||
new TPSLimitCommand();
|
||||
new TickLimitCommand();
|
||||
if (Core.getVersion() >= 15 && Core.getVersion() <= 20) { // If 1.21 support is not directly present
|
||||
new TPSWarpCommand();
|
||||
new TickWarpCommand();
|
||||
if (TPSFreezeUtils.isCanFreeze()) {
|
||||
new TickWarpingCommand();
|
||||
}
|
||||
}
|
||||
new TPSDefaultCommand();
|
||||
new TickDefaultCommand();
|
||||
new TPSBaseCommand();
|
||||
new TickBaseCommand();
|
||||
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private BukkitTask stepper = null;
|
||||
|
||||
private void setTPS(double tps) {
|
||||
if (stepper != null) {
|
||||
stepper.cancel();
|
||||
stepper = null;
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
BossBarService.instance.remove(player, GlobalRegion.getInstance(), "TickStep");
|
||||
});
|
||||
}
|
||||
TPSWarpUtils.warp(tps);
|
||||
if (currentTPSLimit == 0 && tps != 0) {
|
||||
TPSFreezeUtils.unfreeze();
|
||||
}
|
||||
currentTPSLimit = tps;
|
||||
if (tps == 0) {
|
||||
TPSLimitUtils.unlimit();
|
||||
TPSFreezeUtils.freeze();
|
||||
} else if (tps < 20.0) {
|
||||
TPSLimitUtils.limit(tps);
|
||||
} else if (tps >= 20) {
|
||||
TPSLimitUtils.unlimit();
|
||||
}
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
if (currentTPSLimit == 0) {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_FROZEN", player));
|
||||
} else {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_SET", player, currentTPSLimit));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSkip(int steps, double tpsLimitToUse) {
|
||||
double currentLimit = tpsLimitToUse == 20 ? 0 : currentTPSLimit;
|
||||
setTPS(tpsLimitToUse);
|
||||
stepper = new BukkitRunnable() {
|
||||
AtomicInteger stepsLeft = new AtomicInteger(steps);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (steps > 1) {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "TickStep");
|
||||
bossbar.setColor(BarColor.YELLOW);
|
||||
bossbar.setTitle(BauSystem.MESSAGE.parse("TICK_BOSSBAR", player, (steps - stepsLeft.get()), steps));
|
||||
bossbar.setProgress((steps - stepsLeft.get()) / (double) steps);
|
||||
});
|
||||
}
|
||||
if (stepsLeft.decrementAndGet() < 0) {
|
||||
setTPS(currentLimit);
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(BauSystem.getInstance(), 1, 1);
|
||||
}
|
||||
|
||||
public TypeValidator<Player> player() {
|
||||
return (commandSender, player, messageSender) -> {
|
||||
if (!Permission.hasPermission(player, Permission.WORLD)) {
|
||||
messageSender.send("TPSLIMIT_NO_PERMS");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private class TPSBaseCommand extends SWCommand {
|
||||
|
||||
private TPSBaseCommand() {
|
||||
super("tpslimit");
|
||||
setMessage(BauSystem.MESSAGE);
|
||||
addDefaultHelpMessage("TPSLIMIT_HELP");
|
||||
}
|
||||
|
||||
@ClassValidator(value = Player.class, local = true)
|
||||
public TypeValidator<Player> player() {
|
||||
return TPSSystem.this.player();
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TPSBaseCommand.class)
|
||||
private class TPSFreezeCommand extends SWCommand {
|
||||
|
||||
private TPSFreezeCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "0", description = "TPSLIMIT_FREEZE_HELP")
|
||||
public void freeze(@Validator Player player) {
|
||||
setTPS(0);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TPSBaseCommand.class)
|
||||
private class TPSLimitCommand extends SWCommand {
|
||||
|
||||
private TPSLimitCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(description = "TPSLIMIT_LIMIT_HELP")
|
||||
public void limit(@Validator Player player, @Min(doubleValue = 0.5) @Max(doubleValue = 20.0) double tpsLimit) {
|
||||
setTPS(tpsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TPSBaseCommand.class)
|
||||
private class TPSWarpCommand extends SWCommand {
|
||||
|
||||
private TPSWarpCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(description = "TPSLIMIT_WARP_HELP")
|
||||
public void warp(@Validator Player player, @Min(doubleValue = 20.0, inclusive = false) double tpsLimit) {
|
||||
setTPS(tpsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TPSBaseCommand.class)
|
||||
private class TPSDefaultCommand extends SWCommand {
|
||||
|
||||
private TPSDefaultCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(description = "TPSLIMIT_HELP")
|
||||
public void currentLimit(Player player) {
|
||||
BauSystem.MESSAGE.send("TPSLIMIT_CURRENT", player, currentTPSLimit);
|
||||
}
|
||||
|
||||
@Register(value = "default", description = "TPSLIMIT_DEFAULT_HELP")
|
||||
public void reset(@Validator Player player) {
|
||||
setTPS(20);
|
||||
}
|
||||
}
|
||||
|
||||
private class TickBaseCommand extends SWCommand {
|
||||
|
||||
public TickBaseCommand() {
|
||||
super("tick");
|
||||
setMessage(BauSystem.MESSAGE);
|
||||
}
|
||||
|
||||
@ClassValidator(value = Player.class, local = true)
|
||||
public TypeValidator<Player> player() {
|
||||
return TPSSystem.this.player();
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickFreezeCommand extends SWCommand {
|
||||
|
||||
private TickFreezeCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = {"rate", "0"}, description = "TICK_FREEZE_HELP")
|
||||
@Register(value = "freeze", description = "TICK_FREEZE_HELP_2")
|
||||
public void freeze(@Validator Player player) {
|
||||
setTPS(0);
|
||||
}
|
||||
|
||||
@Register(value = "unfreeze", description = "TICK_UNFREEZE_HELP")
|
||||
public void unfreeze(@Validator Player player) {
|
||||
setTPS(20);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickStepCommand extends SWCommand {
|
||||
|
||||
public TickStepCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "step", description = "TICK_STEPPING_HELP")
|
||||
public void step(@Validator Player player, @Min(intValue = 1) @OptionalValue("1") int steps) {
|
||||
setSkip(steps, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickWarpingCommand extends SWCommand {
|
||||
|
||||
public TickWarpingCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "warp", description = "TICK_WARPING_HELP")
|
||||
public void warp(@Validator Player player, @Min(intValue = 1) @OptionalValue("1") int steps, @Min(doubleValue = 20) @OptionalValue("4000") double tps) {
|
||||
setSkip(steps, tps);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickLimitCommand extends SWCommand {
|
||||
|
||||
private TickLimitCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "rate", description = "TICK_LIMIT_HELP")
|
||||
public void limit(@Validator Player player, @Min(doubleValue = 0.5, inclusive = false) @Max(doubleValue = 20.0) double tpsLimit) {
|
||||
setTPS(tpsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickWarpCommand extends SWCommand {
|
||||
|
||||
private TickWarpCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "rate", description = "TICK_WARP_HELP")
|
||||
public void warp(@Validator Player player, @Min(doubleValue = 20.0, inclusive = false) double tpsLimit) {
|
||||
setTPS(tpsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@AbstractSWCommand.PartOf(TickBaseCommand.class)
|
||||
private class TickDefaultCommand extends SWCommand {
|
||||
|
||||
private TickDefaultCommand() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Register(value = "rate", description = "TICK_HELP")
|
||||
public void currentLimit(Player player) {
|
||||
BauSystem.MESSAGE.send("TPSLIMIT_CURRENT", player, currentTPSLimit);
|
||||
}
|
||||
|
||||
@Register(value = {"rate", "default"}, description = "TICK_DEFAULT_HELP")
|
||||
public void reset(@Validator Player player) {
|
||||
setTPS(20);
|
||||
}
|
||||
}
|
||||
|
||||
@Linked
|
||||
public static class TPSScoreboardElement implements ScoreboardElement {
|
||||
|
||||
@Override
|
||||
public ScoreboardGroup getGroup() {
|
||||
return ScoreboardGroup.FOOTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(Region region, Player p) {
|
||||
if (TPSSystem.getInstance().stepper != null) {
|
||||
long time = System.currentTimeMillis() % 1000;
|
||||
if (time < 250) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §7•••";
|
||||
} else if (time < 500) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §e•§7••";
|
||||
} else if (time < 750) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §7•§e•§7•";
|
||||
} else {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §7••§e•";
|
||||
}
|
||||
} else if (TPSFreezeUtils.frozen()) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p);
|
||||
} else {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + TPSSystem.getInstance().getTPS(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
|
||||
}
|
||||
}
|
||||
|
||||
private String tpsColor() {
|
||||
double tps = TPSSystem.getInstance().getTPS(TPSWatcher.TPSType.ONE_SECOND);
|
||||
if (tps > TPSSystem.getInstance().getCurrentTPSLimit() * 0.9) {
|
||||
return "§a";
|
||||
}
|
||||
if (tps > TPSSystem.getInstance().getCurrentTPSLimit() * 0.5) {
|
||||
return "§e";
|
||||
}
|
||||
return "§c";
|
||||
}
|
||||
|
||||
private String tpsLimit() {
|
||||
if (TPSSystem.getInstance().getCurrentTPSLimit() == 20) {
|
||||
return "";
|
||||
}
|
||||
return "§8/§7" + TPSSystem.getInstance().getCurrentTPSLimit();
|
||||
}
|
||||
}
|
||||
|
||||
@Linked
|
||||
public static class TPSSystemBauGuiItem extends BauGuiItem {
|
||||
|
||||
public TPSSystemBauGuiItem() {
|
||||
super(19);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(Player player) {
|
||||
return new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_LORE", player, TPSSystem.getInstance().currentTPSLimit)), false, clickType -> {
|
||||
}).getItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean click(ClickType click, Player p) {
|
||||
p.closeInventory();
|
||||
SWAnvilInv inv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("TPSLIMIT_ANVIL_GUI", p));
|
||||
inv.setItem(Material.CLOCK);
|
||||
inv.setCallback(s -> p.performCommand("tpslimit " + s));
|
||||
inv.open();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission permission() {
|
||||
return Permission.WORLD;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
@UtilityClass
|
||||
public class TPSWarpUtils {
|
||||
|
||||
private static boolean warp = true;
|
||||
private static long nanoOffset = 0;
|
||||
private static long nanoDOffset = 0;
|
||||
private static BukkitTask bukkitTask = null;
|
||||
|
||||
static void init() {
|
||||
NMSWrapper.impl.init(() -> nanoOffset);
|
||||
}
|
||||
|
||||
public static void setTPS(double tps) {
|
||||
double d = 50 - (50 / (tps / 20.0));
|
||||
// nanoDOffset = Math.max(0, Math.min((long) (d * 1000000), 375000000));
|
||||
nanoDOffset = Math.max(0, (long) (d * 1000000));
|
||||
if (nanoDOffset == 0) {
|
||||
if (bukkitTask == null) return;
|
||||
bukkitTask.cancel();
|
||||
bukkitTask = null;
|
||||
} else if (bukkitTask == null) {
|
||||
bukkitTask = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> nanoOffset += nanoDOffset, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWarpAllowed() {
|
||||
return warp;
|
||||
}
|
||||
|
||||
public static boolean isWarping() {
|
||||
return nanoDOffset > 0;
|
||||
}
|
||||
|
||||
public static double getTps(TPSWatcher.TPSType tpsType) {
|
||||
if (TPSWarpUtils.isWarping())
|
||||
return TPSWatcher.getTPS(tpsType, Math.max(TPSLimitUtils.getCurrentTPSLimit(), 20));
|
||||
return TPSWatcher.getTPS(tpsType);
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Linked
|
||||
public class TickCommand extends SWCommand {
|
||||
|
||||
private AtomicInteger ticksLeft = null;
|
||||
private Runnable disableTask = null;
|
||||
private Consumer<Integer> ticksLeftActionBar = null;
|
||||
|
||||
public TickCommand() {
|
||||
super("tick");
|
||||
if (!FreezeUtils.freezeEnabled) {
|
||||
unregister();
|
||||
return;
|
||||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ticksLeft == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ticksLeft.getAndDecrement() <= 0) {
|
||||
disableTask.run();
|
||||
disableTask = null;
|
||||
ticksLeft = null;
|
||||
}
|
||||
if (ticksLeftActionBar != null && ticksLeft != null) {
|
||||
ticksLeftActionBar.accept(ticksLeft.get());
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(BauSystem.getInstance(), 0L, 1L);
|
||||
}
|
||||
|
||||
@Register(value = {"step"}, description = {"TICK_STEP_SINGLE_HELP", "TICK_STEP_HELP"})
|
||||
public void stepCommand(Player p, @OptionalValue("1") int ticks) {
|
||||
if (!TPSLimitCommand.permissionCheck(p)) return;
|
||||
if (ticksLeft != null) {
|
||||
BauSystem.MESSAGE.send("TICK_ERROR", p);
|
||||
return;
|
||||
}
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_STEP", player, ticks));
|
||||
});
|
||||
FreezeUtils.unfreeze();
|
||||
ticksLeft = new AtomicInteger(ticks);
|
||||
disableTask = FreezeUtils::freeze;
|
||||
ticksLeftActionBar = currentTicksLeft -> {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_STEP_LEFT", player, currentTicksLeft));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@Register(value = {"warp"}, description = "TICK_WARP_HELP")
|
||||
public void warpCommand(Player p, int ticks) {
|
||||
if (!TPSLimitCommand.permissionCheck(p)) return;
|
||||
if (ticksLeft != null) {
|
||||
BauSystem.MESSAGE.send("TICK_ERROR", p);
|
||||
return;
|
||||
}
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_WARP", player, ticks));
|
||||
});
|
||||
boolean frozen = FreezeUtils.frozen();
|
||||
double currentTPSLimit = TPSLimitUtils.currentTPSLimit;
|
||||
if (ticks > 1000) {
|
||||
TPSLimitUtils.currentTPSLimit = 60;
|
||||
} else {
|
||||
TPSLimitUtils.currentTPSLimit = 240;
|
||||
}
|
||||
TPSLimitUtils.tpsLimiter();
|
||||
|
||||
FreezeUtils.unfreeze();
|
||||
ticksLeft = new AtomicInteger(ticks);
|
||||
disableTask = () -> {
|
||||
if (frozen) {
|
||||
FreezeUtils.freeze();
|
||||
}
|
||||
TPSLimitUtils.currentTPSLimit = currentTPSLimit;
|
||||
TPSLimitUtils.tpsLimiter();
|
||||
};
|
||||
ticksLeftActionBar = currentTicksLeft -> {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_WARP_LEFT", player, currentTicksLeft));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@Register(value = {"cancel"}, description = "TICK_CANCEL_HELP")
|
||||
public void cancelCommand(Player p) {
|
||||
if (!TPSLimitCommand.permissionCheck(p)) return;
|
||||
if (ticksLeft == null) {
|
||||
BauSystem.MESSAGE.send("TICK_CANCEL_ERROR", p);
|
||||
return;
|
||||
}
|
||||
ticksLeft.set(0);
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_CANCEL", player));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.util;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.TPSWatcher;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@Linked
|
||||
public class TpsCommand extends SWCommand {
|
||||
|
||||
public TpsCommand() {
|
||||
super("tps");
|
||||
unregister();
|
||||
register();
|
||||
}
|
||||
|
||||
@Register(help = true)
|
||||
public void genericCommand(Player p, String... args) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_HEAD", p);
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_MESSAGE", p,
|
||||
TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_SECOND),
|
||||
TPSWarpUtils.getTps(TPSWatcher.TPSType.TEN_SECONDS),
|
||||
TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_MINUTE),
|
||||
TPSWarpUtils.getTps(TPSWatcher.TPSType.FIVE_MINUTES),
|
||||
TPSWarpUtils.getTps(TPSWatcher.TPSType.TEN_MINUTES)
|
||||
);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Player p, TPSWatcher.TPSType type) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, TPSWarpUtils.getTps(type));
|
||||
}
|
||||
}
|
@ -98,7 +98,6 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
||||
techHiderCommand.disable(region, player);
|
||||
if (hidden.get(region).contains(player)) {
|
||||
hidden.get(region).remove(player);
|
||||
PlayerMovementWrapper.impl.disable(player);
|
||||
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
|
||||
} else {
|
||||
hidden.get(region).add(player);
|
||||
|
@ -23,22 +23,15 @@ import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public interface NMSWrapper {
|
||||
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||
|
||||
void setInternalGameMode(Player player, GameMode gameMode);
|
||||
void setSlotToItemStack(Player player, Object o);
|
||||
|
||||
void init(LongSupplier longSupplier);
|
||||
void createTickCache(World world);
|
||||
void sendTickPackets();
|
||||
|
||||
void setGameStateChangeReason(Object packet);
|
||||
void setPlayerBuildAbilities(Player player);
|
||||
|
||||
|
@ -162,19 +162,29 @@ public class PlaceItemUtils {
|
||||
if (blockData == null) return PlaceItemResult.NO_BLOCK_ITEM_HELD;
|
||||
|
||||
// Placing a Block inside of Water should set it to Waterlogged
|
||||
if (blockData instanceof Waterlogged) {
|
||||
((Waterlogged) blockData).setWaterlogged(block.getType() == Material.WATER);
|
||||
if (blockData instanceof Waterlogged && block.getType() == Material.WATER) {
|
||||
Levelled levelled = (Levelled) block.getBlockData();
|
||||
((Waterlogged) blockData).setWaterlogged(levelled.getLevel() == levelled.getMaximumLevel());
|
||||
}
|
||||
|
||||
if (blockData instanceof Slab) {
|
||||
// Slabs can be set at Top or Bottom
|
||||
((Slab) blockData).setType(isHitHalfTop(player) ? Slab.Type.TOP : Slab.Type.BOTTOM);
|
||||
if (againstSide == BlockFace.DOWN) {
|
||||
((Slab) blockData).setType(Slab.Type.TOP);
|
||||
}
|
||||
} else if (blockData instanceof Stairs) {
|
||||
// Stairs can be set at Top or Bottom
|
||||
((Stairs) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
|
||||
if (againstSide == BlockFace.DOWN) {
|
||||
((Stairs) blockData).setHalf(Bisected.Half.TOP);
|
||||
}
|
||||
} else if (blockData instanceof TrapDoor) {
|
||||
// TrapDoors can be set at Top or Bottom
|
||||
((TrapDoor) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
|
||||
if (againstSide == BlockFace.DOWN) {
|
||||
((TrapDoor) blockData).setHalf(Bisected.Half.TOP);
|
||||
}
|
||||
} else if (blockData instanceof Chain) {
|
||||
// Chains are always rotated against the block you place against
|
||||
Orientable orientable = (Orientable) blockData;
|
||||
|
@ -19,14 +19,26 @@
|
||||
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.BountifulWrapper;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface PlayerMovementWrapper {
|
||||
Class<?> teleportPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
||||
Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, Integer.TYPE, 0);
|
||||
BountifulWrapper.PositionSetter teleportPosition = BountifulWrapper.impl.getPositionSetter(teleportPacket, Core.getVersion() == 8 ? 1 : 0);
|
||||
Reflection.FieldAccessor<Byte> teleportYaw = Reflection.getField(teleportPacket, Byte.TYPE, 0);
|
||||
Reflection.FieldAccessor<Byte> teleportPitch = Reflection.getField(teleportPacket, Byte.TYPE, 1);
|
||||
|
||||
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||
|
||||
void setPosition(Player player, Object object);
|
||||
default void disable(Player player) {
|
||||
Object convertToOut(Player player, Object object);
|
||||
|
||||
default byte rotToByte(float rot) {
|
||||
return (byte)((int)(rot * 256.0F / 360.0F));
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren