Files
ForkWar/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java
T

177 lines
5.8 KiB
Java

/*
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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.commands;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.CraftbukkitWrapper;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.world.TPSUtils;
import de.steamwar.bausystem.world.Welt;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
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.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CommandTPSLimiter extends SWCommand {
private static CommandTPSLimiter instance = null;
{
instance = this;
}
private static final World WORLD = Bukkit.getWorlds().get(0);
private static double currentTPSLimit = 20;
private long lastTime = System.nanoTime();
private long currentTime = System.nanoTime();
private double delay = 0;
private int loops = 0;
private long sleepDelay = 0;
private BukkitTask tpsLimiter = null;
private List<String> tabCompletions = new ArrayList<>(Arrays.asList("0,5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"));
public CommandTPSLimiter() {
super("tpslimit");
if (TPSUtils.isWarpAllowed()) {
for (int i = 20; i <= 60; i += 5) {
tabCompletions.add(i + "");
}
}
}
@Register(help = true)
public void genericHelp(Player p, String... args) {
p.sendMessage(BauSystem.PREFIX + "Jetziges TPS limit: " + currentTPSLimit);
p.sendMessage("§8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Setzte die TPS auf dem Bau");
}
@Register({"default"})
public void defaultCommand(Player p) {
if (!permissionCheck(p)) return;
currentTPSLimit = 20;
sendNewTPSLimitMessage();
tpsLimiter();
}
@Register
public void valueCommand(Player p, double tpsLimitDouble) {
if (!permissionCheck(p)) return;
if (tpsLimitDouble < 0.5 || tpsLimitDouble > (TPSUtils.isWarpAllowed() ? 60 : 20)) {
sendInvalidArgumentMessage(p);
return;
}
currentTPSLimit = tpsLimitDouble;
sendNewTPSLimitMessage();
tpsLimiter();
}
@ClassMapper(value = double.class, local = true)
public TypeMapper<Double> doubleTypeMapper() {
return SWCommandUtils.createMapper(s -> {
try {
return Double.parseDouble(s.replace(',', '.'));
} catch (NumberFormatException e) {
return 0D;
}
}, s -> tabCompletions);
}
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;
}
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 0,5 und " + (TPSUtils.isWarpAllowed() ? 60 : 20) + ", und 'default' erlaubt.");
}
private void tpsLimiter() {
delay = 20 / currentTPSLimit;
loops = (int) Math.ceil(delay);
sleepDelay = (long) (50 * delay) / loops;
TPSUtils.setTPS(currentTPSLimit);
if (currentTPSLimit >= 20) {
if (tpsLimiter == null) return;
tpsLimiter.cancel();
tpsLimiter = null;
} else {
if (tpsLimiter != null) return;
tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> {
CraftbukkitWrapper.impl.createTickCache(WORLD);
for (int i = 0; i < loops; i++) {
sleepUntilNextTick(sleepDelay);
CraftbukkitWrapper.impl.sendTickPackets();
}
}, 0, 1);
}
}
private void sleepUntilNextTick(long neededDelta) {
lastTime = currentTime;
currentTime = System.nanoTime();
long timeDelta = (currentTime - lastTime) / 1000000;
if (neededDelta - timeDelta < 0) return;
try {
Thread.sleep(neededDelta - timeDelta);
currentTime = System.nanoTime();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static double getCurrentTPSLimit() {
return (double) Math.round(currentTPSLimit * 10.0D) / 10.0D;
}
public static void setTPS(double d) {
if (d < 0.5) d = 0.5;
if (d > (TPSUtils.isWarpAllowed() ? 60 : 20)) d = (TPSUtils.isWarpAllowed() ? 60 : 20);
if (instance != null) {
currentTPSLimit = d;
instance.tpsLimiter();
}
}
}