diff --git a/BauSystem_12/src/de/steamwar/bausystem/commands/TPSLimit_12.java b/BauSystem_12/src/de/steamwar/bausystem/commands/TPSLimit_12.java
new file mode 100644
index 0000000..d32d4cb
--- /dev/null
+++ b/BauSystem_12/src/de/steamwar/bausystem/commands/TPSLimit_12.java
@@ -0,0 +1,79 @@
+/*
+ This file is a part of the SteamWar software.
+
+ 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
+ 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 .
+*/
+
+package de.steamwar.bausystem.commands;
+
+import net.minecraft.server.v1_12_R1.*;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
+import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
+import org.bukkit.entity.TNTPrimed;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class TPSLimit_12 {
+
+ private static Set velocityPackets = new HashSet<>();
+
+ static void createVelocityPacketCache(World world) {
+ velocityPackets.clear();
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ velocityPackets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), 0, 0, 0));
+ });
+ }
+
+ static void sendVelocityPackets() {
+ sendPacketsToPlayer(velocityPackets);
+ }
+
+ static void sendTntMetaData(World world) {
+ Set> packets = new HashSet<>();
+
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ net.minecraft.server.v1_12_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
+
+ packets.add(new PacketPlayOutEntityMetadata(serverEntity.getId(), serverEntity.getDataWatcher(), true));
+ });
+
+ sendPacketsToPlayer(packets);
+ }
+
+ static void sendTntData(World world) {
+ Set> packets = new HashSet<>();
+
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ net.minecraft.server.v1_12_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
+ packets.add(new PacketPlayOutEntityTeleport(serverEntity));
+ });
+
+ sendPacketsToPlayer(packets);
+ }
+
+ static void sendPacketsToPlayer(Set extends Packet>> packets) {
+ Bukkit.getOnlinePlayers().forEach(player -> {
+ PlayerConnection connection = ((CraftPlayer)player).getHandle().playerConnection;
+ for (Packet> p : packets) {
+ connection.sendPacket(p);
+ }
+ });
+ }
+
+}
diff --git a/BauSystem_15/src/de/steamwar/bausystem/commands/TPSLimit_15.java b/BauSystem_15/src/de/steamwar/bausystem/commands/TPSLimit_15.java
new file mode 100644
index 0000000..cb32794
--- /dev/null
+++ b/BauSystem_15/src/de/steamwar/bausystem/commands/TPSLimit_15.java
@@ -0,0 +1,80 @@
+/*
+ This file is a part of the SteamWar software.
+
+ 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
+ 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 .
+*/
+
+package de.steamwar.bausystem.commands;
+
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
+import org.bukkit.entity.TNTPrimed;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class TPSLimit_15 {
+
+ private static Set velocityPackets = new HashSet<>();
+ private static final Vec3D noMotion = new Vec3D(0, 0, 0);
+
+ static void createVelocityPacketCache(World world) {
+ velocityPackets.clear();
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ velocityPackets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), noMotion));
+ });
+ }
+
+ static void sendVelocityPackets() {
+ sendPacketsToPlayer(velocityPackets);
+ }
+
+ static void sendTntMetaData(World world) {
+ Set> packets = new HashSet<>();
+
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ net.minecraft.server.v1_15_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
+
+ packets.add(new PacketPlayOutEntityMetadata(serverEntity.getId(), serverEntity.getDataWatcher(), true));
+ });
+
+ sendPacketsToPlayer(packets);
+ }
+
+ static void sendTntData(World world) {
+ Set> packets = new HashSet<>();
+
+ world.getEntitiesByClasses(TNTPrimed.class).forEach(entity -> {
+ net.minecraft.server.v1_15_R1.Entity serverEntity = ((CraftEntity) entity).getHandle();
+ packets.add(new PacketPlayOutEntityTeleport(serverEntity));
+ });
+
+ sendPacketsToPlayer(packets);
+ }
+
+ static void sendPacketsToPlayer(Set extends Packet>> packets) {
+ Bukkit.getOnlinePlayers().forEach(player -> {
+ PlayerConnection connection = ((CraftPlayer)player).getHandle().playerConnection;
+ for (Packet> p : packets) {
+ connection.sendPacket(p);
+ }
+ });
+ }
+
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
index 18d1f2a..b3ce821 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
@@ -98,6 +98,8 @@ public class BauSystem extends JavaPlugin implements Listener {
getCommand("trace").setExecutor(new CommandTrace());
getCommand("trace").setTabCompleter(new CommandTraceTabCompleter());
+ getCommand("tpslimit").setExecutor(new CommandTPSLimiter());
+ getCommand("tpslimit").setTabCompleter(new CommandTPSLimiterTabComplete());
getCommand("nightvision").setExecutor(new CommandNV());
getCommand("reset").setExecutor(new CommandReset());
getCommand("speed").setExecutor(new CommandSpeed());
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java
new file mode 100644
index 0000000..94df329
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java
@@ -0,0 +1,180 @@
+/*
+ This file is a part of the SteamWar software.
+
+ 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
+ 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 .
+*/
+
+package de.steamwar.bausystem.commands;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.world.Welt;
+import de.steamwar.core.Core;
+import net.md_5.bungee.api.ChatMessageType;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitTask;
+
+public class CommandTPSLimiter implements CommandExecutor {
+
+ private static int currentTPSLimit = 20;
+ private static World world = Bukkit.getWorlds().get(0);
+ private long lastTime = System.nanoTime();
+ private long currentTime = System.nanoTime();
+
+ private BukkitTask tpsLimiter = null;
+
+ private boolean permissionCheck(Player player) {
+ if (Welt.noPermission(player, Permission.world)) {
+ player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den TPS-Limiter nutzen");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player)) {
+ return false;
+ } else if (args.length == 0) {
+ sender.sendMessage(BauSystem.PREFIX + "Jetziges TPS limit: " + currentTPSLimit);
+ sender.sendMessage(BauSystem.PREFIX + "Ändere das TPS limit mit: §8/§etpslimit §8[§7TPS§8|§edefault§8]");
+ return false;
+ }
+ Player player = (Player) sender;
+ if (!permissionCheck(player)) return false;
+
+ String tpsLimit = args[0];
+ if (tpsLimit.equals("default")) {
+ currentTPSLimit = 20;
+ sendNewTPSLimitMessage();
+ tpsLimiter();
+ return false;
+ }
+
+ try {
+ int tpsLimitInt = Integer.parseInt(tpsLimit);
+ if (tpsLimitInt < 1 || tpsLimitInt > 20) {
+ sendInvalidArgumentMessage(player);
+ return false;
+ }
+ currentTPSLimit = tpsLimitInt;
+ sendNewTPSLimitMessage();
+ tpsLimiter();
+ } catch (NumberFormatException e) {
+ sendInvalidArgumentMessage(player);
+ }
+
+ return false;
+ }
+
+ private void sendNewTPSLimitMessage() {
+ Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§eTPS limit auf " + currentTPSLimit + " gesetzt.")));
+ }
+
+ private void sendInvalidArgumentMessage(Player player) {
+ player.sendMessage(BauSystem.PREFIX + "§cNur Zahlen zwischen 1 und 20, und 'default' erlaubt.");
+ }
+
+ private void tpsLimiter() {
+ if (currentTPSLimit == 20) {
+ if (tpsLimiter == null) return;
+ tpsLimiter.cancel();
+ tpsLimiter = null;
+ } else {
+ if (tpsLimiter != null) return;
+ tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> {
+ sendTntMetaData();
+
+ createVelocityData();
+ for (int i = 0; i < (20 / currentTPSLimit); i++) {
+ sleepUntilNextTick();
+ sendTntData();
+ sendVelocityData();
+ }
+ }, 0, 1);
+ }
+ }
+
+ private void sleepUntilNextTick() {
+ lastTime = currentTime;
+ currentTime = System.nanoTime();
+
+ long timeDelta = (currentTime - lastTime) / 1000000;
+ long neededDelta = 50;
+
+ if (neededDelta - timeDelta < 0) {
+ return;
+ }
+
+ try {
+ Thread.sleep(neededDelta - timeDelta);
+ currentTime = System.nanoTime();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private void createVelocityData() {
+ switch (Core.getVersion()) {
+ case 15:
+ TPSLimit_15.createVelocityPacketCache(world);
+ break;
+ default:
+ TPSLimit_12.createVelocityPacketCache(world);
+ }
+ }
+
+ private void sendVelocityData() {
+ switch (Core.getVersion()) {
+ case 15:
+ TPSLimit_15.sendVelocityPackets();
+ break;
+ default:
+ TPSLimit_12.sendVelocityPackets();
+ }
+ }
+
+ private void sendTntMetaData() {
+ switch (Core.getVersion()) {
+ case 15:
+ TPSLimit_15.sendTntMetaData(world);
+ break;
+ default:
+ TPSLimit_12.sendTntMetaData(world);
+ }
+ }
+
+ private void sendTntData() {
+ switch (Core.getVersion()) {
+ case 15:
+ TPSLimit_15.sendTntData(world);
+ break;
+ default:
+ TPSLimit_12.sendTntData(world);
+ }
+ }
+
+ public static int getCurrentTPSLimit() {
+ return currentTPSLimit;
+ }
+
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiterTabComplete.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiterTabComplete.java
new file mode 100644
index 0000000..9b401ee
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTPSLimiterTabComplete.java
@@ -0,0 +1,48 @@
+/*
+ This file is a part of the SteamWar software.
+
+ 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
+ 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 .
+*/
+
+package de.steamwar.bausystem.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CommandTPSLimiterTabComplete implements TabCompleter {
+
+ private List arguments = Arrays.asList("default", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20");
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String label, String[] args) {
+ if (args.length != 1) {
+ return new ArrayList<>();
+ }
+ List validArguments = new ArrayList<>(arguments.size());
+ for (String s : arguments) {
+ if (s.startsWith(args[0])) {
+ validArguments.add(s);
+ }
+ }
+ return validArguments;
+ }
+
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTraceTabCompleter.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTraceTabCompleter.java
index d21551d..b97fa39 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTraceTabCompleter.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandTraceTabCompleter.java
@@ -20,7 +20,6 @@
package de.steamwar.bausystem.commands;
import de.steamwar.bausystem.tracer.recorder.RecordManager;
-import de.steamwar.core.Core;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/BauScoreboard.java b/BauSystem_Main/src/de/steamwar/bausystem/world/BauScoreboard.java
index bbe4330..117a4ee 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/world/BauScoreboard.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/world/BauScoreboard.java
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.world;
import de.steamwar.bausystem.commands.CommandFreeze;
import de.steamwar.bausystem.commands.CommandTNT;
+import de.steamwar.bausystem.commands.CommandTPSLimiter;
import de.steamwar.bausystem.tracer.TraceManager;
import de.steamwar.bausystem.tracer.recorder.RecordManager;
import de.steamwar.bausystem.tracer.recorder.TNTRecorder;
@@ -72,7 +73,7 @@ public class BauScoreboard implements Listener {
}
strings.add("§4");
- strings.add("§eTPS§8: §7" + TPSWatcher.getTPS());
+ strings.add("§eTPS§8: " + tpsColor() + TPSWatcher.getTPS() + tpsLimit());
int i = strings.size();
HashMap result = new HashMap<>();
@@ -84,4 +85,22 @@ public class BauScoreboard implements Listener {
private long traceTicks() {
return (System.currentTimeMillis() - TNTRecorder.recordStart) / 50;
}
+
+ private String tpsColor() {
+ double tps = TPSWatcher.getTPS();
+ if (tps > CommandTPSLimiter.getCurrentTPSLimit() * 0.9) {
+ return "§a";
+ }
+ if (tps > CommandTPSLimiter.getCurrentTPSLimit() * 0.5) {
+ return "§e";
+ }
+ return "§c";
+ }
+
+ private String tpsLimit() {
+ if (CommandTPSLimiter.getCurrentTPSLimit() == 20) {
+ return "";
+ }
+ return "§8/§7" + CommandTPSLimiter.getCurrentTPSLimit();
+ }
}
diff --git a/BauSystem_Main/src/plugin.yml b/BauSystem_Main/src/plugin.yml
index 4a21d05..bfd4616 100644
--- a/BauSystem_Main/src/plugin.yml
+++ b/BauSystem_Main/src/plugin.yml
@@ -11,6 +11,7 @@ commands:
tnt:
fire:
trace:
+ tpslimit:
testblock:
aliases: tb
reset: