CoddityTeam / movaicode

Concours mensuel du Pire Développeur de France
122 stars 10 forks source link

[movai-code/4] Qui a dit que Minecraft n'était qu'un jeu ? #109

Open sostheneleroy opened 3 years ago

sostheneleroy commented 3 years ago

Y paraît que Minecraft c'est Turing-complet, mais j'avais la flemme d'implémenter ça dans le jeu, alors j'ai fait un programme Java (pratique pour être sûr que t'as Java pour faire tourner Minecraft), qui télécharge un serveur Minecraft, le lance, construit un filtre basique avec les commandes, et vérifie si le filtre est plein à la fin. Y a plein de bazar autour pour que ça marche, et, Java oblige, c'est verbeux.

Testé avec Java Seize sur Fenêtre et Archilinux (écrire une fois, courir n'importe où), en encodage Format de Transformation Unicode Tiret Huit, bien sûr, sinon je peux pas mettre d'accents dans les noms de variables (ce qui serait moche et pas français).

Ah oui au fait, ça prend environ une minute par appel si t'as une bonne connexion, et si y a moins de quatre giga-octets de mémoire vive sur ton ordinateur personnel c'est mort.

Enjaille !

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

public class TrouveurDeBFFParMinecraft {
    public static final String adresseDeMinecraft = "https://launcher.mojang.com/v1/objects/a16d67e5807f57fc4e550299cf20226194497dc2/server.jar";
    public static final String nomBFF = "Jean-BFF <3";

    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println(TrouveurDeBFFParMinecraft.estCeQueMonBFFEstDansMaClasse(Arrays.asList("Christopher", "Matthieu", nomBFF, "Louis")));
        System.out.println(TrouveurDeBFFParMinecraft.estCeQueMonBFFEstDansMaClasse(Arrays.asList("Maurice", "Pascal", "Gertrude")));
    }

    public static boolean estCeQueMonBFFEstDansMaClasse(List<String> listeDesÉlèves) throws IOException, InterruptedException {
        Path dossierServeur = Files.createTempDirectory(null);
        téléchargerMinecraft(dossierServeur);
        écrirePropriétés(dossierServeur);
        Object[] interfacesStandard = initialiserServeur(dossierServeur);
        BufferedReader sortieStandard = (BufferedReader) interfacesStandard[0];
        BufferedWriter entréeStandard = (BufferedWriter) interfacesStandard[1];
        construireMachineQuiFiltre(entréeStandard, sortieStandard);
        insérerListeDansMachine(entréeStandard, sortieStandard, listeDesÉlèves);
        boolean trouvé = vérifierSiLampeAllumée(entréeStandard, sortieStandard);
        couperServeur(entréeStandard, sortieStandard);
        return trouvé;
    }

    private static void téléchargerMinecraft(Path dossier) throws IOException {
        try (InputStream fluxEntrant = new URL(adresseDeMinecraft).openStream()) {
            Files.copy(fluxEntrant, dossier.resolve("server.jar"));
        }
    }

    private static void écrirePropriétés(Path dossier) throws IOException {
        Files.writeString(dossier.resolve("eula.txt").toAbsolutePath(), "eula=true");
        BufferedWriter écriveurDePropriétés = new BufferedWriter(new FileWriter(dossier.resolve("server.properties").toFile()));
        écriveurDePropriétés.write("level-type=flat\n");
        écriveurDePropriétés.write("spawn-monsters=false\n");
        écriveurDePropriétés.write("spawn-npcs=false\n");
        écriveurDePropriétés.write("spawn-animals=false\n");
        écriveurDePropriétés.write("online-mode=false\n");
        écriveurDePropriétés.write("generate-structures=false\n");
        écriveurDePropriétés.write("white-list=true\n");
        écriveurDePropriétés.write("level-seed=775025110009778477\n");
        écriveurDePropriétés.write("server-port=" + ThreadLocalRandom.current().nextInt(30000, 40000) + "\n");
        écriveurDePropriétés.flush();
        écriveurDePropriétés.close();
    }

    private static Object[] initialiserServeur(Path dossier) throws IOException {
        String[] commande = new String[]{"java", "-jar", "server.jar", "nogui"};
        ProcessBuilder constructeurDeProcessus = new ProcessBuilder(commande);
        constructeurDeProcessus.directory(dossier.toFile());
        constructeurDeProcessus.redirectErrorStream(true);
        Process processus = constructeurDeProcessus.start();
        BufferedReader sortieStandard = new BufferedReader(new InputStreamReader(processus.getInputStream()));
        BufferedWriter entréeStandard = new BufferedWriter(new OutputStreamWriter(processus.getOutputStream()));
        while (true) {
            String s = sortieStandard.readLine();
            if (s == null || s.contains(")! For help, type ")) break;
        }
        return new Object[]{sortieStandard, entréeStandard};
    }

    private static void exécuterCommande(BufferedWriter entréeStandard, String commande) throws IOException {
        entréeStandard.write(commande + "\n");
        entréeStandard.flush();
    }

    private static String formatterDonnéesPapier(int nombre, String nom) {
        return "id:'paper',Count:" + nombre + "b,tag:{display:{Name:'{\"text\":\"" + nom + "\"}'}}";
    }

    private static void construireMachineQuiFiltre(BufferedWriter entréeStandard, BufferedReader sortieStandard) throws IOException {
        exécuterCommande(entréeStandard, "setblock 0 64 1 stone");
        exécuterCommande(entréeStandard, "setblock 1 65 1 redstone_block");
        exécuterCommande(entréeStandard, "setblock 0 65 1 comparator[facing=north]");
        exécuterCommande(entréeStandard, "setblock 0 65 2 redstone_lamp");
        String bff64 = formatterDonnéesPapier(64, nomBFF);
        String bff63 = formatterDonnéesPapier(63, nomBFF);
        exécuterCommande(
                entréeStandard,
                "setblock 0 65 0 hopper{Items:[{Slot:0b," + bff64 + "},{Slot:1b," + bff64 + "},{Slot:2b," + bff64 + "},{Slot:3b," + bff64 + "},{Slot:4b," + bff63 + "},]}"
        );
        for (int i = 0; i < 5; i++) {
            sortieStandard.readLine();
        }
    }

    private static void insérerListeDansMachine(BufferedWriter entréeStandard, BufferedReader sortieStandard, List<String> listeDesÉlèves) throws IOException {
        for (String élève : listeDesÉlèves) {
            exécuterCommande(entréeStandard, "summon item 0 66 0 {Item:{" + formatterDonnéesPapier(1, élève) + "}}");
            sortieStandard.readLine();
        }
    }

    private static boolean vérifierSiLampeAllumée(BufferedWriter entréeStandard, BufferedReader sortieStandard) throws IOException, InterruptedException {
        Thread.sleep(1000);
        exécuterCommande(entréeStandard, "execute if block 0 65 2 redstone_lamp[lit=false] run say false");
        exécuterCommande(entréeStandard, "execute if block 0 65 2 redstone_lamp[lit=true] run say true");
        return new Scanner(sortieStandard.readLine().split("\\[Server] ")[1]).nextBoolean();
    }

    private static void couperServeur(BufferedWriter entréeStandard, BufferedReader sortieStandard) throws IOException {
        exécuterCommande(entréeStandard, "stop");
        entréeStandard.close();
        sortieStandard.close();
    }
}
Matthieu-Coddity commented 3 years ago

je mes suis dit "qui le malade qui..." et puis j'ai vu sostheneleroy :)