Merge pull request 'Checkpoint idle server' (#221) from checkpoint into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #221 Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Commit
016a2a3469
@ -902,7 +902,7 @@ REGION_TNT_NO_PERMS=§cYou are not allowed to toggle tnt damage here
|
|||||||
REGION_TNT_BUILD_DESTROY=§cAn explosion would have destroyed blocks in the building area
|
REGION_TNT_BUILD_DESTROY=§cAn explosion would have destroyed blocks in the building area
|
||||||
REGION_TNT_TB_DESTROY=§cAn explosion would have destroyed blocks in the testblock area
|
REGION_TNT_TB_DESTROY=§cAn explosion would have destroyed blocks in the testblock area
|
||||||
|
|
||||||
AFK_KICK_MESSAGE=§cNothing happened on this server for 5 minutes.
|
AFK_KICK_MESSAGE=§cNothing happened on this server for 15 minutes.
|
||||||
AFK_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive
|
AFK_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive
|
||||||
|
|
||||||
SKIN_HELP = §8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking
|
SKIN_HELP = §8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking
|
||||||
|
@ -863,7 +863,7 @@ REGION_TNT_TB=§aTNT-Schaden außerhalb Baurahmen aktiviert
|
|||||||
REGION_TNT_NO_PERMS=§cDu darfst hier nicht TNT-Schaden (de-)aktivieren
|
REGION_TNT_NO_PERMS=§cDu darfst hier nicht TNT-Schaden (de-)aktivieren
|
||||||
REGION_TNT_BUILD_DESTROY=§cEine Explosion hätte Blöcke im Baubereich zerstört
|
REGION_TNT_BUILD_DESTROY=§cEine Explosion hätte Blöcke im Baubereich zerstört
|
||||||
REGION_TNT_TB_DESTROY=§cEine Explosion hätte Blöcke im Testblockbereich zerstört
|
REGION_TNT_TB_DESTROY=§cEine Explosion hätte Blöcke im Testblockbereich zerstört
|
||||||
AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert.
|
AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 15 Minuten nichts passiert.
|
||||||
AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
|
AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
|
||||||
|
|
||||||
SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren)
|
SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren)
|
||||||
|
@ -22,7 +22,6 @@ package de.steamwar.bausystem;
|
|||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
import de.steamwar.bausystem.configplayer.Config;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
|
||||||
import de.steamwar.bausystem.features.world.RamUsage;
|
|
||||||
import de.steamwar.bausystem.linkage.LinkageUtils;
|
import de.steamwar.bausystem.linkage.LinkageUtils;
|
||||||
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
||||||
import de.steamwar.bausystem.region.loader.RegionLoader;
|
import de.steamwar.bausystem.region.loader.RegionLoader;
|
||||||
@ -76,25 +75,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
new Updater(RegionLoader.file, RegionLoader::load);
|
new Updater(RegionLoader.file, RegionLoader::load);
|
||||||
|
|
||||||
LinkageUtils.link();
|
LinkageUtils.link();
|
||||||
RamUsage.init();
|
|
||||||
TickListener.impl.init();
|
TickListener.impl.init();
|
||||||
|
|
||||||
// This could disable any watchdog stuff. We need to investigate if this is a problem.
|
|
||||||
/*
|
|
||||||
Thread thread = new Thread(() -> {
|
|
||||||
while (true) {
|
|
||||||
WatchdogThread.tick();
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.setName("WatchdogThread ticker");
|
|
||||||
thread.setDaemon(true);
|
|
||||||
thread.start();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,63 +20,56 @@
|
|||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.core.CheckpointUtils;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class AFKStopperListener implements Listener {
|
public class AFKStopperListener implements Listener {
|
||||||
|
|
||||||
// CPU > 50%
|
|
||||||
// RAM > 60%
|
|
||||||
|
|
||||||
private int afkTicks = 0;
|
private int afkTicks = 0;
|
||||||
|
|
||||||
public AFKStopperListener() {
|
public AFKStopperListener() {
|
||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
// System.out.println("CPU: " + load + " RAM: " + usage);
|
|
||||||
if (Bukkit.getOnlinePlayers().isEmpty()) {
|
|
||||||
if (RamUsage.getLoad() >= 50.0 || RamUsage.getUsage() >= 0.6) {
|
|
||||||
Bukkit.shutdown();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (RamUsage.getLoad() < 50.0 && RamUsage.getUsage() < 0.6) {
|
|
||||||
afkTicks = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (afkTicks) {
|
switch (afkTicks) {
|
||||||
case 90:
|
|
||||||
Bukkit.shutdown();
|
|
||||||
break;
|
|
||||||
case 15:
|
case 15:
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
p.kickPlayer(BauSystem.MESSAGE.parse("AFK_KICK_MESSAGE", p));
|
p.kickPlayer(BauSystem.MESSAGE.parse("AFK_KICK_MESSAGE", p));
|
||||||
}
|
}
|
||||||
case 12:
|
case 14:
|
||||||
BauSystem.MESSAGE.broadcast("AFK_WARNING_MESSAGE");
|
BauSystem.MESSAGE.broadcast("AFK_WARNING_MESSAGE");
|
||||||
default:
|
default:
|
||||||
afkTicks++;
|
afkTicks++;
|
||||||
}
|
}
|
||||||
}, 20*60, 20*60); //every minute
|
}, 1200, 1200); //every minute
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
if (event.getTo() == null) return;
|
Location to = event.getTo();
|
||||||
if (event.getFrom().getPitch() != event.getTo().getPitch()) {
|
if (to == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Location from = event.getFrom();
|
||||||
|
if (from.getPitch() != to.getPitch() || from.getYaw() != to.getYaw())
|
||||||
afkTicks = 0;
|
afkTicks = 0;
|
||||||
}
|
}
|
||||||
if (event.getFrom().getYaw() != event.getTo().getYaw()) {
|
|
||||||
afkTicks = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
event.getPlayer().setOp(true);
|
event.getPlayer().setOp(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
if(Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().size() == 1 && Bukkit.getOnlinePlayers().contains(event.getPlayer())))
|
||||||
|
CheckpointUtils.freeze();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,120 +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.world;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.concurrent.locks.LockSupport;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class RamUsage {
|
|
||||||
|
|
||||||
private File meminfo = new File("/proc/meminfo");
|
|
||||||
private File stat = new File("/proc/stat");
|
|
||||||
|
|
||||||
private double usageSelf = 0D;
|
|
||||||
private double usage = 0D;
|
|
||||||
private double load = 0D;
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
Thread thread = new Thread(() -> {
|
|
||||||
while (true) {
|
|
||||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
|
||||||
long totalMemory = Runtime.getRuntime().totalMemory();
|
|
||||||
long freeMemory = Runtime.getRuntime().freeMemory();
|
|
||||||
long usedMemory = totalMemory - freeMemory;
|
|
||||||
usageSelf = usedMemory / (double) totalMemory;
|
|
||||||
double usageSelfByMax = usedMemory / (double) maxMemory;
|
|
||||||
// System.out.println("Self: " + usageSelf + "/" + usageSelfByMax + /* " " + maxMemory + " " + totalMemory + " " + freeMemory + " " + usedMemory + */ " Ram: " + usage + " CPU: " + load);
|
|
||||||
|
|
||||||
usage = _getUsage();
|
|
||||||
load = _getLoad();
|
|
||||||
Thread.yield();
|
|
||||||
LockSupport.parkNanos(1000000000L);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.setDaemon(true);
|
|
||||||
thread.setName("RamUsage");
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double getUsage() {
|
|
||||||
return usage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double _getUsage() {
|
|
||||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) {
|
|
||||||
String memTotal = bufferedReader.readLine().replaceAll(" +", " ");
|
|
||||||
bufferedReader.readLine();
|
|
||||||
String memAvailable = bufferedReader.readLine().replaceAll(" +", " ");
|
|
||||||
|
|
||||||
long memTotalLong = getNumber(memTotal);
|
|
||||||
long memAvailableLong = getNumber(memAvailable);
|
|
||||||
return (memTotalLong - memAvailableLong) / (double) memTotalLong;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return 1D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double getLoad() {
|
|
||||||
return load;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long lastCpuSecond = -1;
|
|
||||||
private long lastCpuForth = -1;
|
|
||||||
private long lastCpuFifth = -1;
|
|
||||||
|
|
||||||
private static double _getLoad() {
|
|
||||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(stat)))) {
|
|
||||||
String[] strings = bufferedReader.readLine().split(" ");
|
|
||||||
|
|
||||||
long cpuSecond = Long.parseLong(strings[2]);
|
|
||||||
long cpuForth = Long.parseLong(strings[4]);
|
|
||||||
long cpuFifth = Long.parseLong(strings[5]);
|
|
||||||
|
|
||||||
if (lastCpuSecond == -1) {
|
|
||||||
lastCpuSecond = cpuSecond;
|
|
||||||
lastCpuForth = cpuForth;
|
|
||||||
lastCpuFifth = cpuFifth;
|
|
||||||
return 0D;
|
|
||||||
}
|
|
||||||
|
|
||||||
long cpuSecondDiff = cpuSecond - lastCpuSecond;
|
|
||||||
long cpuForthDiff = cpuForth - lastCpuForth;
|
|
||||||
long cpuSixthDiff = cpuFifth - lastCpuFifth;
|
|
||||||
|
|
||||||
lastCpuSecond = cpuSecond;
|
|
||||||
lastCpuForth = cpuForth;
|
|
||||||
lastCpuFifth = cpuFifth;
|
|
||||||
|
|
||||||
return (cpuSecondDiff + cpuForthDiff) / (double) (cpuSecondDiff + cpuForthDiff + cpuSixthDiff);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return 1D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long getNumber(String s) {
|
|
||||||
return Long.parseLong(s.split(" ")[1]);
|
|
||||||
}
|
|
||||||
}
|
|
In neuem Issue referenzieren
Einen Benutzer sperren