diff --git a/.gitignore b/.gitignore index 7eefc56..2be294e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ target/ forwarding.secret progress.properties progress.properties.tmp +admins.txt diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/Admins.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/Admins.java new file mode 100644 index 0000000..0cf3983 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/Admins.java @@ -0,0 +1,32 @@ +package eu.mhsl.minecraft.endlessjumper; + +import net.minestom.server.entity.Player; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * Admins aus admins.txt im Arbeitsverzeichnis: eine UUID pro Zeile, „#“ leitet einen Kommentar ein. + * Der Limbo kennt kein LuckPerms, die Datei wird aus dessen Admin-Gruppen erzeugt. + */ +public class Admins { + private static final Path FILE = Path.of("admins.txt"); + private static Set admins = Set.of(); + + public static void load() throws IOException { + if(!Files.exists(FILE)) return; + admins = Files.readAllLines(FILE).stream() + .map(line -> line.replaceFirst("#.*", "").trim()) + .filter(line -> !line.isEmpty()) + .map(UUID::fromString) + .collect(Collectors.toUnmodifiableSet()); + } + + public static boolean is(Player player) { + return admins.contains(player.getUuid()); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java index 02787d2..380fd43 100644 --- a/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java @@ -4,6 +4,8 @@ import eu.mhsl.minecraft.endlessjumper.generator.JumpGenerator; import net.minestom.server.Auth; import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.arguments.ArgumentType; +import net.minestom.server.command.builder.arguments.ArgumentWord; import net.minestom.server.coordinate.Vec; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; @@ -37,6 +39,7 @@ public class EndlessJumper { public static void main(String[] args) throws IOException { MinecraftServer server = MinecraftServer.init(new Auth.Velocity(readForwardingSecret())); Progress.load(); + Admins.load(); GlobalEventHandler eventHandler = MinecraftServer.getGlobalEventHandler(); PlayerSkin skin = PlayerSkin.fromUsername("Notch"); @@ -96,6 +99,13 @@ public class EndlessJumper { }); MinecraftServer.getCommandManager().register(reset); + // nur für Admins (admins.txt): Joker zum Testen direkt geben + Command joker = new Command("joker"); + joker.setCondition((sender, commandString) -> sender instanceof Player player && Admins.is(player)); + ArgumentWord type = ArgumentType.Word("typ").from(Jokers.keys()); + joker.addSyntax((sender, context) -> Jokers.byKey(context.get(type)).add((Player) sender), type); + MinecraftServer.getCommandManager().register(joker); + server.start("0.0.0.0", 25501); } diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/Jokers.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/Jokers.java index ad02e3d..f2362f1 100644 --- a/src/main/java/eu/mhsl/minecraft/endlessjumper/Jokers.java +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/Jokers.java @@ -15,16 +15,19 @@ import java.util.Random; * Strecke; wer bei 0 beginnt, bekommt ein Totem. Das Totem wirkt automatisch, die anderen per Rechtsklick (siehe JumpGenerator#useJoker). */ public enum Jokers { - BRIDGE(0, Material.BRICK, "Brücke", NamedTextColor.AQUA, "Rechtsklick: Weg über die nächsten 10 Blöcke"), - FEATHER_FALL(1, Material.FEATHER, "Federfall", NamedTextColor.WHITE, "Rechtsklick: 15 Sekunden langsames Fallen"), - SPRING(2, Material.RABBIT_FOOT, "Sprungfeder", NamedTextColor.GREEN, "Rechtsklick: die nächsten 10 Sprünge mit Sprungkraft"), - TOTEM(8, Material.TOTEM_OF_UNDYING, "Rettungstotem", NamedTextColor.GOLD, "Rettet dich automatisch beim Runterfallen"); + BRIDGE("bruecke", 0, Material.BRICK, "Brücke", NamedTextColor.AQUA, "Rechtsklick: Weg über die nächsten 10 Blöcke"), + FEATHER_FALL("federfall", 1, Material.FEATHER, "Federfall", NamedTextColor.WHITE, "Rechtsklick: 15 Sekunden langsames Fallen"), + SPRING("sprungfeder", 2, Material.RABBIT_FOOT, "Sprungfeder", NamedTextColor.GREEN, "Rechtsklick: die nächsten 10 Sprünge mit Sprungkraft"), + TOTEM("totem", 8, Material.TOTEM_OF_UNDYING, "Rettungstotem", NamedTextColor.GOLD, "Rettet dich automatisch beim Runterfallen"); + // Name im Befehl /joker (Brigadier erlaubt keine Umlaute) + private final String key; private final int slot; private final String name; private final ItemStack item; - Jokers(int slot, Material material, String name, TextColor color, String lore) { + Jokers(String key, int slot, Material material, String name, TextColor color, String lore) { + this.key = key; this.slot = slot; this.name = name; this.item = ItemStack.builder(material) @@ -62,6 +65,19 @@ public enum Jokers { return values()[random.nextInt(values().length)]; } + public static String[] keys() { + String[] keys = new String[values().length]; + for(Jokers joker : values()) keys[joker.ordinal()] = joker.key; + return keys; + } + + public static Jokers byKey(String key) { + for(Jokers joker : values()) { + if(joker.key.equals(key)) return joker; + } + return null; + } + public static Jokers of(ItemStack stack) { for(Jokers joker : values()) { if(joker.matches(stack)) return joker;