package com.slprojects.slcraftplugin.parallelTasks; import com.slprojects.slcraftplugin.Main; import com.slprojects.slcraftplugin.utils.ConsoleLog; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.net.URLEncoder; public class InternalWebServer { @SuppressWarnings({"unchecked", "InfiniteLoopStatement"}) public static void startServer(Main plugin) { int serverPort = plugin.getConfig().getInt("internal-webserver-port"); ConsoleLog.info("Lancement du serveur web intégré sur le port " + ChatColor.GOLD + serverPort); ConsoleLog.warning("Attention! Le serveur ne fonctionne pas avec les requêtes https!"); // On fait un thread pour écouter le port Runnable serverThread = () -> { try { ServerSocket serverSocket = new ServerSocket(serverPort); while (true) { Socket client = serverSocket.accept(); //ConsoleLog.info("Nouvelle connexion sur le port " + ChatColor.GOLD + serverPort); // Get input and output streams to talk to the client BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(client.getOutputStream()); // Start sending our reply, using the HTTP 1.1 protocol out.print("HTTP/1.1 200 \r\n"); // Version & status code out.print("Content-Type: application/json\r\n"); // The type of data out.print("Connection: close\r\n"); // Will close stream out.print("\r\n"); // End of headers // Now, read the HTTP request from the client, and send it // right back to the client as part of the body of our // response. The client doesn't disconnect, so we never get // an EOF. It does sends an empty line at the end of the // headers, though. So when we see the empty line, we stop // reading. This means we don't mirror the contents of POST // requests, for example. Note that the readLine() method // works with Unix, Windows, and Mac line terminators. String line, commandName = ""; String[] aliases = new String[0]; while ((line = in.readLine()) != null) { if (line.equals("")) { break; } // On va regarder si la ligne commence par GET if (line.startsWith("GET")) { // On split par les espaces String[] split = line.split(" "); // Et on récupère le nom de la commande String command = split[1]; // On split par des / aliases = command.split("/"); // On récupère le nom de la commande commandName = aliases[1]; // On ne process pas la commande ici car ça cause des problèmes vu qu'on va renvoyer le résultat avant que le client n'écoute } } JSONObject answer = new JSONObject(); switch (commandName) { case "discordMsg": JSONObject json = (JSONObject) new JSONParser().parse(URLDecoder.decode(aliases[2], "UTF-8")); String message = json.get("message").toString(); String playerName = json.get("playerName").toString(); // On envoie le message aux joueurs for (Player p : plugin.getServer().getOnlinePlayers()) { p.sendMessage(ChatColor.DARK_PURPLE + playerName + ChatColor.WHITE + ": " + message); } plugin.getServer().getConsoleSender().sendMessage(ChatColor.DARK_PURPLE + playerName + ": " + message); answer.put("status", "ok"); out.print(answer.toJSONString()); break; case "getPlayers": // On renvoie la liste des joueurs JSONObject listToReturn = new JSONObject(); JSONObject players = new JSONObject(); for (Player p : plugin.getServer().getOnlinePlayers()) { JSONObject playerInfos = new JSONObject(); playerInfos.put("username", p.getName()); playerInfos.put("uuid", p.getUniqueId().toString()); players.put(p.getName(), playerInfos); } listToReturn.put("players", players); out.print(listToReturn.toJSONString()); break; default: answer.put("status", "error"); answer.put("message", "Commande " + commandName + " inconnue"); out.print(answer.toJSONString()); break; } // Close socket, breaking the connection to the client, and // closing the input and output streams out.close(); // Flush and close the output stream in.close(); // Close the input stream client.close(); // Close the socket itself } } catch (IOException e) { ConsoleLog.danger("Erreur lors de l'écoute du port " + ChatColor.GOLD + serverPort); e.printStackTrace(); // On va logger le message sur discord JSONObject json = new JSONObject(); json.put("desc", "Erreur lors de l'écoute du port " + serverPort); json.put("message", e.getMessage()); String urlString = null; try { urlString = plugin.getConfig().getString("discordBot-api-url") + "mc/error/" + URLEncoder.encode(json.toJSONString(), "UTF-8").replace("+", "%20"); relaunchListener(plugin); } catch (UnsupportedEncodingException ex) { ConsoleLog.danger("Erreur lors de l'encodage du message. Func waitForDiscordMsg::startServer(Main plugin)"); ex.printStackTrace(); } plugin.getHttp(urlString); } catch (ParseException e) { e.printStackTrace(); } }; new Thread(serverThread).start(); } // TODO: Vérifier l'utilité de cette fonction public static void relaunchListener(Main plugin) { // On relance la fonction avec une latence startServer(plugin); } }