SteamWar/BauSystem2.0
Archiviert
12
0

Merge branch 'master' into QOL
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2023-10-14 13:38:03 +02:00
Commit bbe7edc55a
31 geänderte Dateien mit 1031 neuen und 1060 gelöschten Zeilen

Datei anzeigen

@ -63,38 +63,6 @@ public class NMSWrapper15 implements NMSWrapper {
player.updateInventory();
}
@Override
public void init(LongSupplier longSupplier) {
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
}
private static final List<Packet<?>> packets = new ArrayList<>();
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
@Override
public void createTickCache(World world) {
packets.clear();
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
if (entity instanceof TNTPrimed) {
net.minecraft.server.v1_15_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
packets.add(new PacketPlayOutEntityMetadata(serverEntity.getId(), serverEntity.getDataWatcher(), true));
}
});
}
@Override
public void sendTickPackets() {
Bukkit.getOnlinePlayers().forEach(player -> {
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
for (Packet<?> p : packets) {
connection.sendPacket(p);
}
});
}
private static final Reflection.FieldAccessor<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
@Override

Datei anzeigen

@ -31,7 +31,7 @@ public class PlaceItemWrapper15 implements PlaceItemWrapper {
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
try {
Material nonWallMaterial = Material.valueOf(nonWall);
if (nonWallMaterial != material) {
if (nonWallMaterial != material && nonWallMaterial.isItem() && !nonWallMaterial.isBlock()) {
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
}
} catch (Exception e) {

Datei anzeigen

@ -19,9 +19,12 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntity;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
@ -37,4 +40,20 @@ public class PlayerMovementWrapper15 implements PlayerMovementWrapper {
entityPlayer.setLocation(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0), packetPlayInFlying.a(0F), packetPlayInFlying.b(0F));
}
}
@Override
public Object convertToOut(Player player, Object object) {
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
Object packet = Reflection.newInstance(teleportPacket);
teleportEntity.set(packet, player.getEntityId());
teleportPosition.set(packet, packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0));
if (Float.isNaN(packetPlayInFlying.a(Float.NaN))) {
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
} else {
teleportYaw.set(packet, rotToByte(packetPlayInFlying.a(0.0F)));
teleportPitch.set(packet, rotToByte(packetPlayInFlying.b(0.0F)));
}
return packet;
}
}

Datei anzeigen

@ -73,37 +73,6 @@ public class NMSWrapper18 implements NMSWrapper {
player.updateInventory();
}
@Override
public void init(LongSupplier longSupplier) {
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
}
private static final List<Packet<?>> packets = new ArrayList<>();
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
@Override
public void createTickCache(World world) {
packets.clear();
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
if (entity instanceof TNTPrimed) {
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ae(), serverEntity.ai(), true));
}
});
}
@Override
public void sendTickPackets() {
Bukkit.getOnlinePlayers().forEach(player -> {
for (Packet<?> p : packets) {
TinyProtocol.instance.sendPacket(player, p);
}
});
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.server.level.EntityPlayer;
@ -37,4 +38,20 @@ public class PlayerMovementWrapper18 implements PlayerMovementWrapper {
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
}
}
@Override
public Object convertToOut(Player player, Object object) {
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
Object packet = Reflection.newInstance(teleportPacket);
teleportEntity.set(packet, player.getEntityId());
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
if (packetPlayInFlying.h) {
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
} else {
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
}
return packet;
}
}

Datei anzeigen

@ -73,39 +73,6 @@ public class NMSWrapper19 implements NMSWrapper {
player.updateInventory();
}
@Override
public void init(LongSupplier longSupplier) {
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
}
private static final List<Packet<?>> packets = new ArrayList<>();
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
@Override
public void createTickCache(World world) {
packets.clear();
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
if (entity instanceof TNTPrimed) {
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
List<DataWatcher.b<?>> list = serverEntity.al().c();
if(list != null)
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), list));
}
});
}
@Override
public void sendTickPackets() {
Bukkit.getOnlinePlayers().forEach(player -> {
for (Packet<?> p : packets) {
TinyProtocol.instance.sendPacket(player, p);
}
});
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.Location;
@ -31,50 +32,30 @@ import java.util.UUID;
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
private static class Position {
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
}
private Map<UUID, Position> playerLocationMap = new HashMap<>();
@Override
public void setPosition(Player player, Object object) {
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
Position pos = new Position();
Location location = player.getLocation();
pos.x = location.getX();
pos.y = location.getY();
pos.z = location.getZ();
pos.yaw = location.getYaw();
pos.pitch = location.getPitch();
return pos;
});
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (packetPlayInFlying.h) {
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
position.yaw = packetPlayInFlying.d;
position.pitch = packetPlayInFlying.e;
} else {
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
}
}
@Override
public void disable(Player player) {
Position position = playerLocationMap.remove(player.getUniqueId());
if (position != null) {
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
public Object convertToOut(Player player, Object object) {
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
Object packet = Reflection.newInstance(teleportPacket);
teleportEntity.set(packet, player.getEntityId());
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
if (packetPlayInFlying.h) {
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
} else {
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
}
return packet;
}
}

Datei anzeigen

@ -20,32 +20,23 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.SystemUtils;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot;
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
import net.minecraft.server.level.PlayerInteractManager;
import net.minecraft.world.level.EnumGamemode;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;
public class NMSWrapper20 implements NMSWrapper {
@ -73,39 +64,6 @@ public class NMSWrapper20 implements NMSWrapper {
player.updateInventory();
}
@Override
public void init(LongSupplier longSupplier) {
SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
}
private static final List<Packet<?>> packets = new ArrayList<>();
private static final Vec3D noMotion = new Vec3D(0, 0, 0);
@Override
public void createTickCache(World world) {
packets.clear();
world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> {
packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle()));
if (entity instanceof TNTPrimed) {
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
List<DataWatcher.b<?>> list = serverEntity.aj().c();
if(list != null)
packets.add(new PacketPlayOutEntityMetadata(serverEntity.af(), list));
}
});
}
@Override
public void sendTickPackets() {
Bukkit.getOnlinePlayers().forEach(player -> {
for (Packet<?> p : packets) {
TinyProtocol.instance.sendPacket(player, p);
}
});
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override

Datei anzeigen

@ -19,7 +19,9 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.network.protocol.game.PacketPlayOutEntityTeleport;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
@ -31,50 +33,30 @@ import java.util.UUID;
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
private static class Position {
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
}
private Map<UUID, Position> playerLocationMap = new HashMap<>();
@Override
public void setPosition(Player player, Object object) {
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
Position pos = new Position();
Location location = player.getLocation();
pos.x = location.getX();
pos.y = location.getY();
pos.z = location.getZ();
pos.yaw = location.getYaw();
pos.pitch = location.getPitch();
return pos;
});
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (packetPlayInFlying.h) {
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
position.yaw = packetPlayInFlying.d;
position.pitch = packetPlayInFlying.e;
} else {
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
}
}
@Override
public void disable(Player player) {
Position position = playerLocationMap.remove(player.getUniqueId());
if (position != null) {
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
public Object convertToOut(Player player, Object object) {
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
Object packet = Reflection.newInstance(teleportPacket);
teleportEntity.set(packet, player.getEntityId());
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
if (packetPlayInFlying.h) {
teleportYaw.set(packet, rotToByte(player.getLocation().getYaw()));
teleportPitch.set(packet, rotToByte(player.getLocation().getPitch()));
} else {
teleportYaw.set(packet, rotToByte(packetPlayInFlying.d));
teleportPitch.set(packet, rotToByte(packetPlayInFlying.e));
}
return packet;
}
}

Datei anzeigen

@ -33,7 +33,7 @@ SCOREBOARD_REGION = Region
SCOREBOARD_TRACE = Trace
SCOREBOARD_LOADER = Loader
SCOREBOARD_TPS = TPS
SCOREBOARD_TPS_FROZEN = §e Frozen
SCOREBOARD_TPS_FROZEN = §eFrozen
SCOREBOARD_TRACE_TICKS = Ticks
@ -459,27 +459,31 @@ DEPTH_COUNTER_HOVER = §7X§8ק7Y§8ק7Z
DEPTH_COUNTER_TNT = §7 TNT§8: §e{0}
# TPSLimit
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Step n ticks
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Step one tick
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warp n ticks
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancels tick step/warp
TICK_ERROR = §cYou can not activate another §8'§e/tick step§8'§c or §8'§e/tick warp§8'§c
TICK_CANCEL_ERROR = §cYou have no §8'§e/tick step§8'§c or §8'§e/tick warp§8'§c active
TICK_STEP = §eSkipping {0} ticks
TICK_STEP_LEFT = §eSkipping {0} more ticks
TICK_WARP = §eWarping {0} ticks
TICK_WARP_LEFT = §eWarping {0} more ticks
TICK_CANCEL = §eWarps and Steps canceled
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Freeze TPS
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Slow TPS down
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Speed TPS up
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Set TPS to 20
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Show current TPS
TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Freeze TPS
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Freeze TPS
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Set TPS to 20
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Slow TPS down
TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Speed TPS up
TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Set TPS to 20
TICK_HELP = §8/§etick rate §8-§7 Show current TPS
TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Step n ticks or 1 forward
TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warp n ticks or 1 forward
TICK_BOSSBAR = §7Skipped §e{0}§8/§7{1}
TPSLIMIT_GUI_ITEM_NAME = §eTPS limiter
TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0}
TPSLIMIT_ANVIL_GUI = New TPS limit
TPSLIMIT_HELP = §8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Sets TPS on Build
TPSLIMIT_CURRENT = §7Current TPS limit§8: §e{0}
TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here
TPSLIMIT_SET = §eSet TPS limit to {0}
TPSLIMIT_FROZEN = §eTPS frozen
TPSLIMIT_INVALID = §cOnly numbers between 0,5 and {0}, and 'default'{1} allowed.
TPSLIMIT_INVALID_FROZEN = §c and '0'
# Trace
TRACE_RECORD=§aon

Datei anzeigen

@ -33,7 +33,7 @@ SCOREBOARD_REGION = Region
SCOREBOARD_TRACE = Trace
SCOREBOARD_LOADER = Loader
SCOREBOARD_TPS = TPS
SCOREBOARD_TPS_FROZEN = §e Eingefroren
SCOREBOARD_TPS_FROZEN = §eEingefroren
SCOREBOARD_TRACE_TICKS = Ticks
@ -428,27 +428,31 @@ BLOCK_COUNTER_DISABLE = §7BlockCounter ausgemacht
DEPTH_COUNTER_MESSAGE = §7Tiefe §8> §7
# TPSLimit
TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Spule n Ticks vor
TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Spule einen Ticks vor
TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warpe n Ticks vor
TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancelt den Tick Warp oder Step
TICK_ERROR = §cDu kannst keinen weiteren §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c anmachen
TICK_CANCEL_ERROR = §cDu hast keinen §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c aktiv
TICK_STEP = §eSpult {0} Ticks vor
TICK_STEP_LEFT = §eSpult noch {0} Ticks vor
TICK_WARP = §eWarpe {0} Ticks vor
TICK_WARP_LEFT = §eWarpe noch {0} Ticks vor
TICK_CANCEL = §eWarps und Steps abgebrochen
TPSLIMIT_FREEZE_HELP = §8/§etpslimit 0 §8-§7 Friere TPS ein
TPSLIMIT_LIMIT_HELP = §8/§etpslimit §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
TPSLIMIT_WARP_HELP = §8/§etpslimit §8[§7x>20§8] §8-§7 Beschleunige die TPS
TPSLIMIT_DEFAULT_HELP = §8/§etpslimit default §8-§7 Setze die TPS auf 20
TPSLIMIT_HELP = §8/§etpslimit §8-§7 Zeige die jetzige TPS
TICK_FREEZE_HELP = §8/§etick rate 0 §8-§7 Friere TPS ein
TICK_FREEZE_HELP_2 = §8/§etick freeze §8-§7 Friere TPS ein
TICK_UNFREEZE_HELP = §8/§etick unfreeze §8-§7 Setze die TPS auf 20
TICK_LIMIT_HELP = §8/§etick rate §8[§720>x>0.5§8] §8-§7 Verlangsame die TPS
TICK_WARP_HELP = §8/§etick rate §8[§7x>20§8] §8-§7 Beschleunige die TPS
TICK_DEFAULT_HELP = §8/§etick rate default §8-§7 Setze die TPS auf 20
TICK_HELP = §8/§etick rate §8-§7 Zeige die jetzige TPS
TICK_STEPPING_HELP = §8/§etick step §8<§7Ticks§8> §8-§7 Spule n ticks oder 1 vor
TICK_WARPING_HELP = §8/§etick warp §8<§7Ticks§8> §8<§7TPS§8> §8-§7 Warpe n ticks oder 1 vor
TICK_BOSSBAR = §e{0}§8/§7{1} gesprungen
TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter
TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0}
TPSLIMIT_ANVIL_GUI = Neues TPS Limit
TPSLIMIT_HELP = §8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Setzte die TPS auf dem Bau
TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0}
TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen
TPSLIMIT_SET = §eTPS limit auf {0} gesetzt.
TPSLIMIT_FROZEN = §eTPS eingefroren.
TPSLIMIT_INVALID = §cNur Zahlen zwischen 0,5 und {0}, und 'default'{1} erlaubt.
TPSLIMIT_INVALID_FROZEN = §c und '0'
# Trace
TRACE_RECORD=§aan

Datei anzeigen

@ -21,16 +21,12 @@ package de.steamwar.bausystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.tpslimit.FreezeUtils;
import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
import de.steamwar.bausystem.features.world.RamUsage;
import de.steamwar.bausystem.linkage.LinkageUtils;
import de.steamwar.bausystem.region.loader.PrototypeLoader;
import de.steamwar.bausystem.region.loader.RegionLoader;
import de.steamwar.bausystem.region.loader.Updater;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.bausystem.linkage.LinkageUtils;
import de.steamwar.message.Message;
import lombok.Getter;
import org.bukkit.Bukkit;
@ -139,7 +135,7 @@ public class BauSystem extends JavaPlugin implements Listener {
@Override
public void run() {
if (FreezeUtils.isFrozen()) return;
// if (FreezeUtils.isFrozen()) return;
if (counter >= delay) {
runnable.run();
cancel();
@ -157,7 +153,7 @@ public class BauSystem extends JavaPlugin implements Listener {
@Override
public void run() {
if (FreezeUtils.isFrozen()) return;
// if (FreezeUtils.isFrozen()) return;
if (counter >= (first ? delay : period)) {
first = false;
runnable.run();

Datei anzeigen

@ -2,7 +2,6 @@ package de.steamwar.bausystem.features.bau;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.config.BauServer;
import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.command.SWCommand;
@ -15,8 +14,6 @@ import org.bukkit.entity.Player;
import java.util.List;
import static de.steamwar.bausystem.features.tpslimit.TPSWarpUtils.getTps;
@Linked
public class InfoCommand extends SWCommand {
@ -65,13 +62,11 @@ public class InfoCommand extends SWCommand {
StringBuilder tpsMessage = new StringBuilder();
tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p));
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.ONE_SECOND));
tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.TEN_SECONDS));
if (!TPSWarpUtils.isWarping()) {
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE));
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.ONE_SECOND));
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS));
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE));
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES));
tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES));
p.sendMessage(tpsMessage.toString());
}
}

Datei anzeigen

@ -20,7 +20,6 @@
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.core.TPSWatcher;
import de.steamwar.inventory.SWItem;
@ -76,7 +75,7 @@ public class ServerLib implements LuaLib {
tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
tpsLib.set("current", getter(TPSWatcher::getTPS));
tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
// tpsLib.set("limit", getter(TPSLimitUtils::getCurrentTPSLimit));
serverLib.set("tps", tpsLib);
return serverLib;

Datei anzeigen

@ -1,103 +1,202 @@
/*
* 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
* 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 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.
* 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/>.
* 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.smartplace;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.utils.PlaceItemUtils;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.SoundGroup;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Repeater;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.Switch;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.block.data.*;
import org.bukkit.block.data.type.*;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Linked
public class SmartPlaceListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerInteract(PlayerInteractEvent event) {
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
// TODO: Sneaking not reset sometimes
boolean shouldRotate = event.getPlayer().isSneaking();
Material blockType = event.getClickedBlock().getType();
switch (blockType) {
case REPEATER:
if (shouldRotate && (event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
int i = repeater.getDelay() - 1;
if (i <= 0) i += 4;
repeater.setDelay(i);
event.getClickedBlock().setBlockData(repeater);
event.setCancelled(true);
}
return;
}
BlockData blockData = event.getClickedBlock().getBlockData();
if (blockData instanceof Switch) {
if (!shouldRotate && (event.getItem() == null || event.getItem().getType() == event.getClickedBlock().getType())) {
return;
}
shouldRotate = false;
}
private static final Set<Material> CONTAINERS = new HashSet<>();
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);
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);
}
}
// Fix Double sound for original player
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 onBlockBreak(BlockBreakEvent event) {
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
if (!event.getPlayer().isSneaking()) return;
event.setCancelled(true);
event.getBlock().setType(Material.AIR, false);
if (event.getClickedBlock().getType() != Material.REPEATER) return;
if ((event.getItem() == null || event.getItem().getType() == Material.REPEATER)) {
Repeater repeater = (Repeater) event.getClickedBlock().getBlockData();
int i = repeater.getDelay() - 1;
if (i <= 0) i += 4;
repeater.setDelay(i);
event.getClickedBlock().setBlockData(repeater);
event.setCancelled(true);
}
}
SoundGroup soundGroup = event.getBlock().getBlockData().getSoundGroup();
Bukkit.getOnlinePlayers().forEach(player -> {
if (player == event.getPlayer()) return;
player.playSound(event.getBlock().getLocation(), soundGroup.getBreakSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F);
});
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (!SMART_PLACING.contains(event.getPlayer())) return;
BlockData blockData = event.getBlock().getBlockData();
if (blockData instanceof Bed) {
Bed bed = (Bed) blockData;
Block bedHead = event.getBlock().getRelative(bed.getFacing());
bed.setPart(Bed.Part.HEAD);
bed.setFacing(bed.getFacing().getOppositeFace());
bed = (Bed) bedHead.getBlockData();
bed.setPart(Bed.Part.FOOT);
bed.setFacing(bed.getFacing().getOppositeFace());
bedHead.setBlockData(bed, false);
} else if (blockData instanceof FaceAttachable && ((FaceAttachable) blockData).getAttachedFace() != FaceAttachable.AttachedFace.WALL) {
FaceAttachable faceAttachable = (FaceAttachable) blockData;
faceAttachable.setAttachedFace(faceAttachable.getAttachedFace() == FaceAttachable.AttachedFace.CEILING ? FaceAttachable.AttachedFace.FLOOR : FaceAttachable.AttachedFace.CEILING);
} else if (blockData instanceof Rotatable) {
Rotatable rotatable = (Rotatable) blockData;
rotatable.setRotation(rotatable.getRotation().getOppositeFace());
} else if (blockData instanceof Directional) {
Directional directional = (Directional) blockData;
BlockFace face = directional.getFacing().getOppositeFace();
if (directional.getFaces().contains(face)) {
directional.setFacing(face);
}
} else if (blockData instanceof MultipleFacing && !(blockData instanceof Fence)) {
MultipleFacing multipleFacing = (MultipleFacing) blockData;
List<BlockFace> blockFaceList = multipleFacing.getFaces()
.stream()
.map(BlockFace::getOppositeFace)
.collect(Collectors.toList());
if (multipleFacing.getAllowedFaces().containsAll(blockFaceList)) {
multipleFacing.getFaces().forEach(blockFace -> {
multipleFacing.setFace(blockFace, false);
});
blockFaceList.forEach(blockFace -> {
multipleFacing.setFace(blockFace, true);
});
}
}
if (blockData instanceof Stairs) {
Stairs stairs = (Stairs) blockData;
switch (stairs.getShape()) {
case OUTER_LEFT:
stairs.setShape(Stairs.Shape.INNER_RIGHT);
break;
case INNER_LEFT:
stairs.setShape(Stairs.Shape.OUTER_RIGHT);
break;
case OUTER_RIGHT:
stairs.setShape(Stairs.Shape.INNER_LEFT);
break;
case INNER_RIGHT:
stairs.setShape(Stairs.Shape.OUTER_LEFT);
break;
case STRAIGHT:
break;
}
}
if (blockData instanceof Piston) {
Piston piston = (Piston) blockData;
Block block = event.getBlock().getRelative(piston.getFacing().getOppositeFace());
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
event.getPlayer().sendBlockChange(block.getLocation(), block.getBlockData());
}, 2);
} else if (blockData.getMaterial() == Material.REPEATER || blockData.getMaterial() == Material.COMPARATOR) {
Block block = event.getBlock().getRelative(BlockFace.DOWN);
BlockState old = block.getState();
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
block.setType(Material.GLASS);
old.update(true, false);
}, 1);
}
event.getBlock().setBlockData(blockData, true);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
SMART_PLACING.remove(event.getPlayer());
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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));
}
}
}

Datei anzeigen

@ -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));
}
}

Datei anzeigen

@ -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;
}
}
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -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) : "");
}
}

Datei anzeigen

@ -1,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@ -21,51 +21,52 @@ package de.steamwar.bausystem.features.tpslimit;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import de.steamwar.core.Core;
import de.steamwar.core.TPSWatcher;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.BiFunction;
import static de.steamwar.bausystem.features.tpslimit.TPSLimitCommand.MAX_TPS;
@UtilityClass
public class TPSLimitUtils {
private static final World WORLD = Bukkit.getWorlds().get(0);
static double currentTPSLimit = 20;
private static long currentTime = System.nanoTime();
private static BukkitTask tpsLimiter = null;
private static Queue<Runnable> packetQueue = new ConcurrentLinkedQueue<>();
private long currentTime = System.nanoTime();
private BukkitTask tpsLimiter = null;
void tpsLimiter() {
public void unlimit() {
if (tpsLimiter != null) tpsLimiter.cancel();
double delay = 20 / currentTPSLimit;
tpsLimiter = null;
}
public void limit(double tps) {
if (tpsLimiter != null) tpsLimiter.cancel();
double delay = 20 / tps;
int loops = (int) Math.ceil(delay);
long sleepDelay = (long) (50 * delay) / loops;
TPSWarpUtils.setTPS(currentTPSLimit);
if (currentTPSLimit >= 20) {
if (tpsLimiter == null) return;
tpsLimiter.cancel();
tpsLimiter = null;
} else {
tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
NMSWrapper.impl.createTickCache(WORLD);
for (int i = 0; i < loops; i++) {
sleepUntilNextTick(sleepDelay);
NMSWrapper.impl.sendTickPackets();
tpsLimiter = Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
PacketCache.sendCache();
for (int i = 0; i < loops; i++) {
sleepUntilNextTick(sleepDelay);
PacketCache.sendCache();
while (true) {
Runnable runnable = packetQueue.poll();
if (runnable == null) break;
runnable.run();
}
}, 0, 1);
}
}
PacketCache.clearCache();
}, 0, 1);
}
private void sleepUntilNextTick(long neededDelta) {
@ -83,26 +84,39 @@ public class TPSLimitUtils {
}
}
public static double getCurrentTPSLimit() {
return (double) Math.round(currentTPSLimit * 10.0D) / 10.0D;
}
/*
static {
long timeInterval = 50;
final long[] lastTime = {System.currentTimeMillis()};
final double[] tps = {20.0};
Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
long currentTime = System.currentTimeMillis();
if (currentTime > lastTime[0]) {
tps[0] = (double)timeInterval / (double)(currentTime - lastTime[0]) * 20.0;
}
@SuppressWarnings("unused")
public static void setTPS(double d) {
if (d < 0.5) d = 0.5;
if (d > (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20)) d = (TPSWarpUtils.isWarpAllowed() ? MAX_TPS : 20);
currentTPSLimit = d;
tpsLimiter();
lastTime[0] = currentTime;
Bukkit.getOnlinePlayers().forEach(player -> {
SWUtils.sendToActionbar(player, String.valueOf((int) (tps[0] * 10.0) / 10.0));
});
}, timeInterval / 50L, timeInterval / 50L);
}
*/
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
static {
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
if (currentTPSLimit < 20) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
if (tpsLimiter != null) {
Object object = PlayerMovementWrapper.impl.convertToOut(player, o);
packetQueue.add(() -> {
PlayerMovementWrapper.impl.setPosition(player, o);
}, 1L);
Bukkit.getOnlinePlayers().forEach(p -> {
if (p == player) return;
TinyProtocol.instance.sendPacket(p, object);
});
});
return null;
}
return o;
@ -110,4 +124,4 @@ public class TPSLimitUtils {
TinyProtocol.instance.addFilter(position, positionSetter);
TinyProtocol.instance.addFilter(positionLook, positionSetter);
}
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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;
}
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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));
});
}
}

Datei anzeigen

@ -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));
}
}

Datei anzeigen

@ -98,7 +98,6 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
techHiderCommand.disable(region, player);
if (hidden.get(region).contains(player)) {
hidden.get(region).remove(player);
PlayerMovementWrapper.impl.disable(player);
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
} else {
hidden.get(region).add(player);

Datei anzeigen

@ -23,22 +23,15 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.core.VersionDependent;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.function.LongSupplier;
public interface NMSWrapper {
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
void setInternalGameMode(Player player, GameMode gameMode);
void setSlotToItemStack(Player player, Object o);
void init(LongSupplier longSupplier);
void createTickCache(World world);
void sendTickPackets();
void setGameStateChangeReason(Object packet);
void setPlayerBuildAbilities(Player player);

Datei anzeigen

@ -162,19 +162,29 @@ public class PlaceItemUtils {
if (blockData == null) return PlaceItemResult.NO_BLOCK_ITEM_HELD;
// Placing a Block inside of Water should set it to Waterlogged
if (blockData instanceof Waterlogged) {
((Waterlogged) blockData).setWaterlogged(block.getType() == Material.WATER);
if (blockData instanceof Waterlogged && block.getType() == Material.WATER) {
Levelled levelled = (Levelled) block.getBlockData();
((Waterlogged) blockData).setWaterlogged(levelled.getLevel() == levelled.getMaximumLevel());
}
if (blockData instanceof Slab) {
// Slabs can be set at Top or Bottom
((Slab) blockData).setType(isHitHalfTop(player) ? Slab.Type.TOP : Slab.Type.BOTTOM);
if (againstSide == BlockFace.DOWN) {
((Slab) blockData).setType(Slab.Type.TOP);
}
} else if (blockData instanceof Stairs) {
// Stairs can be set at Top or Bottom
((Stairs) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
if (againstSide == BlockFace.DOWN) {
((Stairs) blockData).setHalf(Bisected.Half.TOP);
}
} else if (blockData instanceof TrapDoor) {
// TrapDoors can be set at Top or Bottom
((TrapDoor) blockData).setHalf(isHitHalfTop(player) ? Bisected.Half.TOP : Bisected.Half.BOTTOM);
if (againstSide == BlockFace.DOWN) {
((TrapDoor) blockData).setHalf(Bisected.Half.TOP);
}
} else if (blockData instanceof Chain) {
// Chains are always rotated against the block you place against
Orientable orientable = (Orientable) blockData;

Datei anzeigen

@ -19,14 +19,26 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
import org.bukkit.entity.Player;
public interface PlayerMovementWrapper {
Class<?> teleportPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, Integer.TYPE, 0);
BountifulWrapper.PositionSetter teleportPosition = BountifulWrapper.impl.getPositionSetter(teleportPacket, Core.getVersion() == 8 ? 1 : 0);
Reflection.FieldAccessor<Byte> teleportYaw = Reflection.getField(teleportPacket, Byte.TYPE, 0);
Reflection.FieldAccessor<Byte> teleportPitch = Reflection.getField(teleportPacket, Byte.TYPE, 1);
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
void setPosition(Player player, Object object);
default void disable(Player player) {
Object convertToOut(Player player, Object object);
default byte rotToByte(float rot) {
return (byte)((int)(rot * 256.0F / 360.0F));
}
}