diff --git a/app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java b/app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java index 9d8e7d8..a8ecc6c 100644 --- a/app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java +++ b/app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java @@ -115,8 +115,11 @@ public final class YoshiBot { commandLineThread = new CommandLine(); commandLineThread.start(); - - StatusProvider.provide(Resources.getStatus_update(), guild); + + new StatusProvider("Vanilla", Resources.getStatus_message_vanilla(), guild, Resources.getStatus_update(), + 25565); + new StatusProvider("Valhelsia 3", Resources.getStatus_message_modded(), guild, Resources.getStatus_update(), + 25566); SauceProvider.init(300); //RedditProvider.init(); diff --git a/app/src/main/java/de/yannicpunktdee/yoshibot/utils/Resources.java b/app/src/main/java/de/yannicpunktdee/yoshibot/utils/Resources.java index 8cd3164..dfeed12 100644 --- a/app/src/main/java/de/yannicpunktdee/yoshibot/utils/Resources.java +++ b/app/src/main/java/de/yannicpunktdee/yoshibot/utils/Resources.java @@ -64,15 +64,19 @@ public final class Resources { private static String[] filteredTags; @Getter private static final Map> feedDetails = new HashMap<>(); - + @Getter private static String mc_server; @Getter private static String status_channel; @Getter - private static String status_message; + private static String status_message_vanilla; + @Getter + private static String status_message_modded; @Getter private static int status_update; + @Getter + private static String path_to_mcstatus; private static Properties propertiesFile; private static Properties redditCreds; @@ -158,7 +162,7 @@ public final class Resources { } public static String getTempPath() { - if (tempPath == null){ + if (tempPath == null) { initTemp(); } File tempDir = new File(tempPath); @@ -318,16 +322,19 @@ public final class Resources { return null; } } - - private static boolean initStatusMessage(){ - if(propertiesFile.containsKey("mc_server") && propertiesFile.containsKey("status_channel") - && propertiesFile.containsKey("status_message") && propertiesFile.containsKey("status_update")) { - mc_server = propertiesFile.getProperty("mc_server"); - status_channel = propertiesFile.getProperty("status_channel"); - status_message = propertiesFile.getProperty("status_message"); - try{ + + private static boolean initStatusMessage() { + if (propertiesFile.containsKey("mc_server") && propertiesFile.containsKey("status_channel") + && propertiesFile.containsKey("status_message_vanilla") && propertiesFile.containsKey("status_update") && + propertiesFile.containsKey("status_message_modded")) { + mc_server = propertiesFile.getProperty("mc_server"); + status_channel = propertiesFile.getProperty("status_channel"); + status_message_vanilla = propertiesFile.getProperty("status_message_vanilla"); + status_message_modded = propertiesFile.getProperty("status_message_modded"); + path_to_mcstatus = propertiesFile.getProperty("path_to_mcstatus"); + try { status_update = Integer.parseInt(propertiesFile.getProperty("status_update")); - }catch(NumberFormatException e){ + } catch (NumberFormatException e) { return false; } return true; diff --git a/app/src/main/java/de/yannicpunktdee/yoshibot/utils/StatusProvider.java b/app/src/main/java/de/yannicpunktdee/yoshibot/utils/StatusProvider.java index 7fc7a97..898837e 100644 --- a/app/src/main/java/de/yannicpunktdee/yoshibot/utils/StatusProvider.java +++ b/app/src/main/java/de/yannicpunktdee/yoshibot/utils/StatusProvider.java @@ -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 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) serverInfo.get("playerNames")), false); + } + statusChannel.editMessageById(this.message_id, "Serverinformation").queue(); + statusChannel.editMessageById(this.message_id, eb.build()).queue(); + } + + private Map getPlayersOnline() throws IOException { + + Process process = mcstatus.start(); + + String output = new BufferedReader(new InputStreamReader(process.getInputStream())).lines().collect( + Collectors.joining()); + + Map 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; + } + } diff --git a/rsc/Config.properties b/rsc/Config.properties index 5564e29..302fc3d 100644 --- a/rsc/Config.properties +++ b/rsc/Config.properties @@ -4,5 +4,7 @@ restrict_commands_to_channel=bot-muell schrein-auf-den-bot greetings_and_byebyes_on=true mc_server=85.214.148.23 status_channel=889880296168755231 -status_message=889887149850251304 -status_update=30 \ No newline at end of file +status_message_vanilla=890007862456238120 +status_message_modded=901742870552281148 +status_update=30 +path_to_mcstatus=/home/paul/.local/bin/mcstatus