|
|
@ -1,80 +1,103 @@ |
|
|
|
package de.yannicpunktdee.yoshibot.utils; |
|
|
|
|
|
|
|
import lombok.SneakyThrows; |
|
|
|
import net.dv8tion.jda.api.EmbedBuilder; |
|
|
|
import net.dv8tion.jda.api.entities.Guild; |
|
|
|
import net.dv8tion.jda.api.entities.TextChannel; |
|
|
|
import org.json.JSONArray; |
|
|
|
import org.json.JSONObject; |
|
|
|
|
|
|
|
import java.io.DataInputStream; |
|
|
|
import java.io.DataOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.*; |
|
|
|
import java.net.Socket; |
|
|
|
import java.net.UnknownHostException; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.Executors; |
|
|
|
import java.util.concurrent.ScheduledExecutorService; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.StreamSupport; |
|
|
|
|
|
|
|
public class StatusProvider { |
|
|
|
|
|
|
|
private static final ScheduledExecutorService statusScheduler = Executors.newScheduledThreadPool(1); |
|
|
|
|
|
|
|
private static int lastPlayersOnline = -1; |
|
|
|
|
|
|
|
|
|
|
|
public static void provide(int secondsPerTime, Guild guild){ |
|
|
|
TextChannel statusChannel = guild.getTextChannelById(Resources.getStatus_channel()); |
|
|
|
statusScheduler.scheduleAtFixedRate(() -> { |
|
|
|
try { |
|
|
|
updateStatusMessage(statusChannel); |
|
|
|
} catch (IOException e) { |
|
|
|
Logger.logError("Konnte Status nicht richtig abfragen."); |
|
|
|
} |
|
|
|
}, 0, secondsPerTime, TimeUnit.SECONDS); |
|
|
|
} |
|
|
|
|
|
|
|
public static void updateStatusMessage(TextChannel statusChannel) throws IOException { |
|
|
|
int newPlayersOnline = getPlayersOnline(); |
|
|
|
if(newPlayersOnline == lastPlayersOnline) return; |
|
|
|
else lastPlayersOnline = newPlayersOnline; |
|
|
|
|
|
|
|
EmbedBuilder eb = new EmbedBuilder(); |
|
|
|
eb.setTitle("Status"); |
|
|
|
eb.addField("Minecraft-Server, Spieler online: ", Integer.toString(lastPlayersOnline), false); |
|
|
|
statusChannel.editMessageById(Resources.getStatus_message(), eb.build()).queue(); |
|
|
|
} |
|
|
|
|
|
|
|
private static int getPlayersOnline() throws IOException { |
|
|
|
Socket socket = null; |
|
|
|
DataOutputStream out = null; |
|
|
|
DataInputStream in = null; |
|
|
|
|
|
|
|
try { |
|
|
|
socket = new Socket(Resources.getMc_server(), 25565); |
|
|
|
out = new DataOutputStream(socket.getOutputStream()); |
|
|
|
in = new DataInputStream(socket.getInputStream()); |
|
|
|
} catch (UnknownHostException e) { |
|
|
|
System.err.println("Don't know about host: " + Resources.getMc_server()); |
|
|
|
} catch (IOException e) { |
|
|
|
System.err.println("Couldn't get I/O for " + "the connection to:" + Resources.getMc_server()); |
|
|
|
} |
|
|
|
|
|
|
|
out.write(0xFE); |
|
|
|
|
|
|
|
byte[] b = new byte[241]; |
|
|
|
in.read(b, 0, 241); |
|
|
|
StringBuffer buffer = new StringBuffer(); |
|
|
|
for (int i = 4; i < b.length; i++) { |
|
|
|
if (b[i] != 0) { |
|
|
|
buffer.append((char) b[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
String[] split = buffer.toString().split(String.valueOf((char) -89)); |
|
|
|
|
|
|
|
out.close(); |
|
|
|
in.close(); |
|
|
|
socket.close(); |
|
|
|
|
|
|
|
return Integer.parseInt(split[1]); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static final ScheduledExecutorService statusScheduler = Executors.newScheduledThreadPool(1); |
|
|
|
|
|
|
|
private int lastPlayersOnline = -1; |
|
|
|
|
|
|
|
private final String message_id; |
|
|
|
|
|
|
|
private final int serverPort; |
|
|
|
|
|
|
|
private final String desc; |
|
|
|
|
|
|
|
private LocalDateTime timestampLastPlayerOnline = null; |
|
|
|
|
|
|
|
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss E, dd.MM.yyyy", |
|
|
|
Locale.GERMANY); |
|
|
|
|
|
|
|
private final ProcessBuilder mcstatus = new ProcessBuilder(); |
|
|
|
|
|
|
|
|
|
|
|
public StatusProvider(String desc, String messageId, Guild guild, int secondsPerTime, int serverPort) { |
|
|
|
this.desc = desc; |
|
|
|
this.message_id = messageId; |
|
|
|
this.serverPort = serverPort; |
|
|
|
this.mcstatus.command(Resources.getPath_to_mcstatus(), Resources.getMc_server() + ":" + serverPort, "json"); |
|
|
|
|
|
|
|
TextChannel statusChannel = guild.getTextChannelById(Resources.getStatus_channel()); |
|
|
|
statusScheduler.scheduleAtFixedRate(() -> updateStatusMessage(statusChannel), 0, secondsPerTime, |
|
|
|
TimeUnit.SECONDS); |
|
|
|
} |
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SneakyThrows |
|
|
|
public void updateStatusMessage(TextChannel statusChannel) { |
|
|
|
Map<String, Object> serverInfo = getPlayersOnline(); |
|
|
|
int newPlayersOnline = (int) serverInfo.get("playerCount"); |
|
|
|
if (newPlayersOnline == lastPlayersOnline) return; |
|
|
|
else { |
|
|
|
if (timestampLastPlayerOnline == null && newPlayersOnline == 0 && lastPlayersOnline != -1) { |
|
|
|
timestampLastPlayerOnline = LocalDateTime.now(); |
|
|
|
} else if (timestampLastPlayerOnline != null && newPlayersOnline > 0) { |
|
|
|
timestampLastPlayerOnline = null; |
|
|
|
} |
|
|
|
lastPlayersOnline = newPlayersOnline; |
|
|
|
} |
|
|
|
|
|
|
|
EmbedBuilder eb = new EmbedBuilder(); |
|
|
|
eb.setTitle(desc); |
|
|
|
eb.addField("IP", Resources.getMc_server() + ":" + serverPort, false); |
|
|
|
eb.addField("Spieler online", lastPlayersOnline + " / " + serverInfo.get("playerMax"), false); |
|
|
|
if (timestampLastPlayerOnline != null) { |
|
|
|
eb.addField("Zuletzt gesehen", TIME_FORMATTER.format(timestampLastPlayerOnline), false); |
|
|
|
} |
|
|
|
if (lastPlayersOnline > 0) { |
|
|
|
eb.addField("Spieler:", String.join(", ", (List<String>) serverInfo.get("playerNames")), false); |
|
|
|
} |
|
|
|
statusChannel.editMessageById(this.message_id, "Serverinformation").queue(); |
|
|
|
statusChannel.editMessageById(this.message_id, eb.build()).queue(); |
|
|
|
} |
|
|
|
|
|
|
|
private Map<String, Object> getPlayersOnline() throws IOException { |
|
|
|
|
|
|
|
Process process = mcstatus.start(); |
|
|
|
|
|
|
|
String output = new BufferedReader(new InputStreamReader(process.getInputStream())).lines().collect( |
|
|
|
Collectors.joining()); |
|
|
|
|
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
|
|
|
|
JSONObject obj = new JSONObject(output); |
|
|
|
|
|
|
|
result.put("playerCount", obj.get("player_count")); |
|
|
|
result.put("playerMax", obj.get("player_max")); |
|
|
|
result.put("playerNames", |
|
|
|
StreamSupport.stream(obj.getJSONArray("players").spliterator(), false) |
|
|
|
.map(jsonobj -> ((JSONObject) jsonobj).getString("name")).sorted().collect( |
|
|
|
Collectors.toList())); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
} |