Dieser Commit ist enthalten in:
Commit
bbe7edc55a
@ -63,38 +63,6 @@ public class NMSWrapper15 implements NMSWrapper {
|
|||||||
player.updateInventory();
|
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);
|
private static final Reflection.FieldAccessor<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,7 +31,7 @@ public class PlaceItemWrapper15 implements PlaceItemWrapper {
|
|||||||
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
|
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
|
||||||
try {
|
try {
|
||||||
Material nonWallMaterial = Material.valueOf(nonWall);
|
Material nonWallMaterial = Material.valueOf(nonWall);
|
||||||
if (nonWallMaterial != material) {
|
if (nonWallMaterial != material && nonWallMaterial.isItem() && !nonWallMaterial.isBlock()) {
|
||||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
|
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -19,9 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||||
import net.minecraft.server.v1_15_R1.EntityPlayer;
|
import net.minecraft.server.v1_15_R1.EntityPlayer;
|
||||||
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
|
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.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
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));
|
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();
|
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);
|
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
@ -37,4 +38,20 @@ public class PlayerMovementWrapper18 implements PlayerMovementWrapper {
|
|||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
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();
|
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);
|
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -31,50 +32,30 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
|
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
|
@Override
|
||||||
public void setPosition(Player player, Object object) {
|
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);
|
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||||
if (packetPlayInFlying.h) {
|
if (packetPlayInFlying.h) {
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
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 {
|
} else {
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||||
position.x = packetPlayInFlying.a;
|
|
||||||
position.y = packetPlayInFlying.b;
|
|
||||||
position.z = packetPlayInFlying.c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable(Player player) {
|
public Object convertToOut(Player player, Object object) {
|
||||||
Position position = playerLocationMap.remove(player.getUniqueId());
|
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||||
if (position != null) {
|
Object packet = Reflection.newInstance(teleportPacket);
|
||||||
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
|
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;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
import de.steamwar.bausystem.features.util.NoClipCommand;
|
||||||
import net.minecraft.SystemUtils;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
import net.minecraft.nbt.NBTBase;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
|
||||||
import net.minecraft.network.syncher.DataWatcher;
|
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
import net.minecraft.server.level.PlayerInteractManager;
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
import net.minecraft.world.level.EnumGamemode;
|
||||||
import net.minecraft.world.phys.Vec3D;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
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.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.LongSupplier;
|
|
||||||
|
|
||||||
public class NMSWrapper20 implements NMSWrapper {
|
public class NMSWrapper20 implements NMSWrapper {
|
||||||
|
|
||||||
@ -73,39 +64,6 @@ public class NMSWrapper20 implements NMSWrapper {
|
|||||||
player.updateInventory();
|
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);
|
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityTeleport;
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||||
@ -31,50 +33,30 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
|
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
|
@Override
|
||||||
public void setPosition(Player player, Object object) {
|
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);
|
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||||
if (packetPlayInFlying.h) {
|
if (packetPlayInFlying.h) {
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
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 {
|
} else {
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||||
position.x = packetPlayInFlying.a;
|
|
||||||
position.y = packetPlayInFlying.b;
|
|
||||||
position.z = packetPlayInFlying.c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable(Player player) {
|
public Object convertToOut(Player player, Object object) {
|
||||||
Position position = playerLocationMap.remove(player.getUniqueId());
|
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||||
if (position != null) {
|
Object packet = Reflection.newInstance(teleportPacket);
|
||||||
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
|
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_TRACE = Trace
|
||||||
SCOREBOARD_LOADER = Loader
|
SCOREBOARD_LOADER = Loader
|
||||||
SCOREBOARD_TPS = TPS
|
SCOREBOARD_TPS = TPS
|
||||||
SCOREBOARD_TPS_FROZEN = §e Frozen
|
SCOREBOARD_TPS_FROZEN = §eFrozen
|
||||||
|
|
||||||
SCOREBOARD_TRACE_TICKS = Ticks
|
SCOREBOARD_TRACE_TICKS = Ticks
|
||||||
|
|
||||||
@ -459,27 +459,31 @@ DEPTH_COUNTER_HOVER = §7X§8ק7Y§8ק7Z
|
|||||||
DEPTH_COUNTER_TNT = §7 TNT§8: §e{0}
|
DEPTH_COUNTER_TNT = §7 TNT§8: §e{0}
|
||||||
|
|
||||||
# TPSLimit
|
# TPSLimit
|
||||||
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Step n ticks
|
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Freeze TPS
|
||||||
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Step one tick
|
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Slow TPS down
|
||||||
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warp n ticks
|
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Speed TPS up
|
||||||
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancels tick step/warp
|
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Set TPS to 20
|
||||||
TICK_ERROR = §cYou can not activate another §8'§e/tick step§8'§c or §8'§e/tick warp§8'§c
|
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Show current TPS
|
||||||
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_FREEZE_HELP = §8/§etick rate 0 §8-§7 Freeze TPS
|
||||||
TICK_STEP_LEFT = §eSkipping {0} more ticks
|
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Freeze TPS
|
||||||
TICK_WARP = §eWarping {0} ticks
|
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Set TPS to 20
|
||||||
TICK_WARP_LEFT = §eWarping {0} more ticks
|
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Slow TPS down
|
||||||
TICK_CANCEL = §eWarps and Steps canceled
|
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_NAME = §eTPS limiter
|
||||||
TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0}
|
TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0}
|
||||||
TPSLIMIT_ANVIL_GUI = New TPS limit
|
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_CURRENT = §7Current TPS limit§8: §e{0}
|
||||||
TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here
|
TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here
|
||||||
TPSLIMIT_SET = §eSet TPS limit to {0}
|
TPSLIMIT_SET = §eSet TPS limit to {0}
|
||||||
TPSLIMIT_FROZEN = §eTPS frozen
|
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
|
||||||
TRACE_RECORD=§aon
|
TRACE_RECORD=§aon
|
||||||
|
@ -33,7 +33,7 @@ SCOREBOARD_REGION = Region
|
|||||||
SCOREBOARD_TRACE = Trace
|
SCOREBOARD_TRACE = Trace
|
||||||
SCOREBOARD_LOADER = Loader
|
SCOREBOARD_LOADER = Loader
|
||||||
SCOREBOARD_TPS = TPS
|
SCOREBOARD_TPS = TPS
|
||||||
SCOREBOARD_TPS_FROZEN = §e Eingefroren
|
SCOREBOARD_TPS_FROZEN = §eEingefroren
|
||||||
|
|
||||||
SCOREBOARD_TRACE_TICKS = Ticks
|
SCOREBOARD_TRACE_TICKS = Ticks
|
||||||
|
|
||||||
@ -428,27 +428,31 @@ BLOCK_COUNTER_DISABLE = §7BlockCounter ausgemacht
|
|||||||
DEPTH_COUNTER_MESSAGE = §7Tiefe §8> §7
|
DEPTH_COUNTER_MESSAGE = §7Tiefe §8> §7
|
||||||
|
|
||||||
# TPSLimit
|
# TPSLimit
|
||||||
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Spule n Ticks vor
|
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Friere TPS ein
|
||||||
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Spule einen Ticks vor
|
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
|
||||||
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warpe n Ticks vor
|
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Beschleunige die TPS
|
||||||
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancelt den Tick Warp oder Step
|
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Setze die TPS auf 20
|
||||||
TICK_ERROR = §cDu kannst keinen weiteren §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c anmachen
|
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Zeige die jetzige TPS
|
||||||
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_FREEZE_HELP = §8/§etick rate 0 §8-§7 Friere TPS ein
|
||||||
TICK_STEP_LEFT = §eSpult noch {0} Ticks vor
|
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Friere TPS ein
|
||||||
TICK_WARP = §eWarpe {0} Ticks vor
|
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Setze die TPS auf 20
|
||||||
TICK_WARP_LEFT = §eWarpe noch {0} Ticks vor
|
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
|
||||||
TICK_CANCEL = §eWarps und Steps abgebrochen
|
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_NAME = §eTPS Limiter
|
||||||
TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0}
|
TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0}
|
||||||
TPSLIMIT_ANVIL_GUI = Neues TPS Limit
|
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_CURRENT = §7Jetziges TPS limit§8: §e{0}
|
||||||
TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen
|
TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen
|
||||||
TPSLIMIT_SET = §eTPS limit auf {0} gesetzt.
|
TPSLIMIT_SET = §eTPS limit auf {0} gesetzt.
|
||||||
TPSLIMIT_FROZEN = §eTPS eingefroren.
|
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
|
||||||
TRACE_RECORD=§aan
|
TRACE_RECORD=§aan
|
||||||
|
@ -21,16 +21,12 @@ package de.steamwar.bausystem;
|
|||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
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.features.world.RamUsage;
|
||||||
|
import de.steamwar.bausystem.linkage.LinkageUtils;
|
||||||
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
||||||
import de.steamwar.bausystem.region.loader.RegionLoader;
|
import de.steamwar.bausystem.region.loader.RegionLoader;
|
||||||
import de.steamwar.bausystem.region.loader.Updater;
|
import de.steamwar.bausystem.region.loader.Updater;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
import de.steamwar.bausystem.worlddata.WorldData;
|
||||||
import de.steamwar.bausystem.linkage.LinkageUtils;
|
|
||||||
import de.steamwar.message.Message;
|
import de.steamwar.message.Message;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -139,7 +135,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (FreezeUtils.isFrozen()) return;
|
// if (FreezeUtils.isFrozen()) return;
|
||||||
if (counter >= delay) {
|
if (counter >= delay) {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
cancel();
|
cancel();
|
||||||
@ -157,7 +153,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (FreezeUtils.isFrozen()) return;
|
// if (FreezeUtils.isFrozen()) return;
|
||||||
if (counter >= (first ? delay : period)) {
|
if (counter >= (first ? delay : period)) {
|
||||||
first = false;
|
first = false;
|
||||||
runnable.run();
|
runnable.run();
|
||||||
|
@ -2,7 +2,6 @@ package de.steamwar.bausystem.features.bau;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.config.BauServer;
|
import de.steamwar.bausystem.config.BauServer;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
|
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.flags.Flag;
|
import de.steamwar.bausystem.region.flags.Flag;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
@ -15,8 +14,6 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static de.steamwar.bausystem.features.tpslimit.TPSWarpUtils.getTps;
|
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class InfoCommand extends SWCommand {
|
public class InfoCommand extends SWCommand {
|
||||||
|
|
||||||
@ -65,13 +62,11 @@ public class InfoCommand extends SWCommand {
|
|||||||
|
|
||||||
StringBuilder tpsMessage = new StringBuilder();
|
StringBuilder tpsMessage = new StringBuilder();
|
||||||
tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p));
|
tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p));
|
||||||
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.ONE_SECOND));
|
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND));
|
||||||
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.TEN_SECONDS));
|
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS));
|
||||||
if (!TPSWarpUtils.isWarping()) {
|
|
||||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE));
|
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.FIVE_MINUTES));
|
||||||
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES));
|
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES));
|
||||||
}
|
|
||||||
p.sendMessage(tpsMessage.toString());
|
p.sendMessage(tpsMessage.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bausystem.features.script.lua.libs;
|
package de.steamwar.bausystem.features.script.lua.libs;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils;
|
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||||
import de.steamwar.core.TPSWatcher;
|
import de.steamwar.core.TPSWatcher;
|
||||||
import de.steamwar.inventory.SWItem;
|
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("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
|
||||||
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
|
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
|
||||||
tpsLib.set("current", getter(TPSWatcher::getTPS));
|
tpsLib.set("current", getter(TPSWatcher::getTPS));
|
||||||
tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
|
// tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
|
||||||
|
|
||||||
serverLib.set("tps", tpsLib);
|
serverLib.set("tps", tpsLib);
|
||||||
return serverLib;
|
return serverLib;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of the SteamWar software.
|
* 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
|
* 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
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -19,39 +19,96 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.smartplace;
|
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.configplayer.Config;
|
||||||
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.SoundGroup;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.type.Repeater;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.type.Sign;
|
import org.bukkit.block.TileState;
|
||||||
import org.bukkit.block.data.type.Switch;
|
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.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
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.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
|
@Linked
|
||||||
public class SmartPlaceListener implements Listener {
|
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) {
|
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.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||||
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
|
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
|
||||||
|
if (!event.getPlayer().isSneaking()) return;
|
||||||
boolean shouldRotate = event.getPlayer().isSneaking();
|
if (event.getClickedBlock().getType() != Material.REPEATER) return;
|
||||||
Material blockType = event.getClickedBlock().getType();
|
if ((event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
|
||||||
switch (blockType) {
|
|
||||||
case REPEATER:
|
|
||||||
if (shouldRotate && (event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
|
|
||||||
Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
|
Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
|
||||||
int i = repeater.getDelay() - 1;
|
int i = repeater.getDelay() - 1;
|
||||||
if (i <= 0) i += 4;
|
if (i <= 0) i += 4;
|
||||||
@ -59,45 +116,87 @@ public class SmartPlaceListener implements Listener {
|
|||||||
event.getClickedBlock().setBlockData(repeater);
|
event.getClickedBlock().setBlockData(repeater);
|
||||||
event.setCancelled(true);
|
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
|
@EventHandler
|
||||||
public void onBlockBreak(BlockBreakEvent event) {
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
|
if (!SMART_PLACING.contains(event.getPlayer())) return;
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
BlockData blockData = event.getBlock().getBlockData();
|
||||||
event.setCancelled(true);
|
if (blockData instanceof Bed) {
|
||||||
event.getBlock().setType(Material.AIR, false);
|
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();
|
bed = (Bed) bedHead.getBlockData();
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
bed.setPart(Bed.Part.FOOT);
|
||||||
if (player == event.getPlayer()) return;
|
bed.setFacing(bed.getFacing().getOppositeFace());
|
||||||
player.playSound(event.getBlock().getLocation(), soundGroup.getBreakSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
|
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.
|
* 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
|
* 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
|
* 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.Reflection;
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.SWUtils;
|
||||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
|
||||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
|
import de.steamwar.core.TPSWatcher;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import static de.steamwar.bausystem.features.tpslimit.TPSLimitCommand.MAX_TPS;
|
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TPSLimitUtils {
|
public class TPSLimitUtils {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static long currentTime = System.nanoTime();
|
||||||
static double currentTPSLimit = 20;
|
private static BukkitTask tpsLimiter = null;
|
||||||
|
private static Queue<Runnable> packetQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
private long currentTime = System.nanoTime();
|
public void unlimit() {
|
||||||
|
|
||||||
|
|
||||||
private BukkitTask tpsLimiter = null;
|
|
||||||
|
|
||||||
void tpsLimiter() {
|
|
||||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
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);
|
int loops = (int) Math.ceil(delay);
|
||||||
long sleepDelay = (long) (50 * delay) / loops;
|
long sleepDelay = (long) (50 * delay) / loops;
|
||||||
|
|
||||||
TPSWarpUtils.setTPS(currentTPSLimit);
|
tpsLimiter = Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
||||||
if (currentTPSLimit >= 20) {
|
PacketCache.sendCache();
|
||||||
if (tpsLimiter == null) return;
|
|
||||||
tpsLimiter.cancel();
|
|
||||||
tpsLimiter = null;
|
|
||||||
} else {
|
|
||||||
tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
|
||||||
NMSWrapper.impl.createTickCache(WORLD);
|
|
||||||
|
|
||||||
for (int i = 0; i < loops; i++) {
|
for (int i = 0; i < loops; i++) {
|
||||||
sleepUntilNextTick(sleepDelay);
|
sleepUntilNextTick(sleepDelay);
|
||||||
NMSWrapper.impl.sendTickPackets();
|
PacketCache.sendCache();
|
||||||
|
while (true) {
|
||||||
|
Runnable runnable = packetQueue.poll();
|
||||||
|
if (runnable == null) break;
|
||||||
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
PacketCache.clearCache();
|
||||||
}, 0, 1);
|
}, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void sleepUntilNextTick(long neededDelta) {
|
private void sleepUntilNextTick(long neededDelta) {
|
||||||
long lastTime = currentTime;
|
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")
|
lastTime[0] = currentTime;
|
||||||
public static void setTPS(double d) {
|
|
||||||
if (d < 0.5) d = 0.5;
|
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||||
if (d > (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20)) d = (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20);
|
SWUtils.sendToActionbar(player, String.valueOf((int) (tps[0] * 10.0) / 10.0));
|
||||||
currentTPSLimit = d;
|
});
|
||||||
tpsLimiter();
|
}, timeInterval / 50L, timeInterval / 50L);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
|
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");
|
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
|
||||||
static {
|
static {
|
||||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
||||||
if (currentTPSLimit < 20) {
|
if (tpsLimiter != null) {
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Object object = PlayerMovementWrapper.impl.convertToOut(player, o);
|
||||||
|
packetQueue.add(() -> {
|
||||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
PlayerMovementWrapper.impl.setPosition(player, o);
|
||||||
}, 1L);
|
Bukkit.getOnlinePlayers().forEach(p -> {
|
||||||
|
if (p == player) return;
|
||||||
|
TinyProtocol.instance.sendPacket(p, object);
|
||||||
|
});
|
||||||
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return o;
|
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);
|
techHiderCommand.disable(region, player);
|
||||||
if (hidden.get(region).contains(player)) {
|
if (hidden.get(region).contains(player)) {
|
||||||
hidden.get(region).remove(player);
|
hidden.get(region).remove(player);
|
||||||
PlayerMovementWrapper.impl.disable(player);
|
|
||||||
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
|
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
|
||||||
} else {
|
} else {
|
||||||
hidden.get(region).add(player);
|
hidden.get(region).add(player);
|
||||||
|
@ -23,22 +23,15 @@ import de.steamwar.bausystem.BauSystem;
|
|||||||
import de.steamwar.core.VersionDependent;
|
import de.steamwar.core.VersionDependent;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.function.LongSupplier;
|
|
||||||
|
|
||||||
public interface NMSWrapper {
|
public interface NMSWrapper {
|
||||||
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||||
|
|
||||||
void setInternalGameMode(Player player, GameMode gameMode);
|
void setInternalGameMode(Player player, GameMode gameMode);
|
||||||
void setSlotToItemStack(Player player, Object o);
|
void setSlotToItemStack(Player player, Object o);
|
||||||
|
|
||||||
void init(LongSupplier longSupplier);
|
|
||||||
void createTickCache(World world);
|
|
||||||
void sendTickPackets();
|
|
||||||
|
|
||||||
void setGameStateChangeReason(Object packet);
|
void setGameStateChangeReason(Object packet);
|
||||||
void setPlayerBuildAbilities(Player player);
|
void setPlayerBuildAbilities(Player player);
|
||||||
|
|
||||||
|
@ -162,19 +162,29 @@ public class PlaceItemUtils {
|
|||||||
if (blockData == null) return PlaceItemResult.NO_BLOCK_ITEM_HELD;
|
if (blockData == null) return PlaceItemResult.NO_BLOCK_ITEM_HELD;
|
||||||
|
|
||||||
// Placing a Block inside of Water should set it to Waterlogged
|
// Placing a Block inside of Water should set it to Waterlogged
|
||||||
if (blockData instanceof Waterlogged) {
|
if (blockData instanceof Waterlogged && block.getType() == Material.WATER) {
|
||||||
((Waterlogged) blockData).setWaterlogged(block.getType() == Material.WATER);
|
Levelled levelled = (Levelled) block.getBlockData();
|
||||||
|
((Waterlogged) blockData).setWaterlogged(levelled.getLevel() == levelled.getMaximumLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockData instanceof Slab) {
|
if (blockData instanceof Slab) {
|
||||||
// Slabs can be set at Top or Bottom
|
// Slabs can be set at Top or Bottom
|
||||||
((Slab) blockData).setType(isHitHalfTop(player) ? Slab.Type.TOP : Slab.Type.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) {
|
} else if (blockData instanceof Stairs) {
|
||||||
// Stairs can be set at Top or Bottom
|
// Stairs can be set at Top or Bottom
|
||||||
((Stairs) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.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) {
|
} else if (blockData instanceof TrapDoor) {
|
||||||
// TrapDoors can be set at Top or Bottom
|
// TrapDoors can be set at Top or Bottom
|
||||||
((TrapDoor) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.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) {
|
} else if (blockData instanceof Chain) {
|
||||||
// Chains are always rotated against the block you place against
|
// Chains are always rotated against the block you place against
|
||||||
Orientable orientable = (Orientable) blockData;
|
Orientable orientable = (Orientable) blockData;
|
||||||
|
@ -19,14 +19,26 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.core.BountifulWrapper;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.core.VersionDependent;
|
import de.steamwar.core.VersionDependent;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface PlayerMovementWrapper {
|
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());
|
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||||
|
|
||||||
void setPosition(Player player, Object object);
|
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