diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ec5d165..76f1305f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,15 +28,6 @@ jobs: with: fetch-depth: 0 - - name: Check version in gradle.properties - run: | - MOD_VERSION=$(grep "^mod_version=" gradle.properties | cut -d'=' -f2) - echo "Found mod version: $MOD_VERSION" - if [ "$MOD_VERSION" != "${{ inputs.version }}" ]; then - echo "Version mismatch! gradle.properties=$MOD_VERSION input=${{ inputs.version }}" - exit 1 - fi - - name: Set up JDK uses: actions/setup-java@v5 with: @@ -48,7 +39,7 @@ jobs: run: chmod +x ./gradlew - name: Build with Gradle - run: ./gradlew build --full-stacktrace + run: ./gradlew build --full-stacktrace -Pmod_version=${{ inputs.version }} - name: Upload artifacts uses: actions/upload-artifact@v7 @@ -65,4 +56,5 @@ jobs: --target main \ --repo="$GITHUB_REPOSITORY" \ --title="$tag" \ - --generate-notes + --generate-notes \ + build/libs/*.jar diff --git a/README.md b/README.md index 449b701e..b6d26a35 100644 --- a/README.md +++ b/README.md @@ -10,43 +10,39 @@ reibungsloser und angenehmer gestalten. - Sollte ein Command mit einem Großbuchstaben eingegeben werden (z. B. `/Afk` statt `/afk`) wird dieser Command automatisch zu einem gültigen Command umgewandelt +- Statt `/navi Haus:` kann `/navi ` genutzt werden - Als Business-Besitzer wird in der Business-Info ein Button angezeigt, um die Einnahmen direkt abzubuchen - Wirft man eine Glasflasche in der Nähe eines Shops weg, wird diese als Pfand abgegeben -- Es wird angezeigt wie lang der Cooldown für Bandagen, Schmerzpillen und Absorption ist +- Es wird angezeigt, wie lang der Cooldown für Bandagen und Schmerzpillen ist - Es werden Sounds abgespielt für Notrufe, Bomben, Feuer, Staatsbankraub und weitere Situationen - Über der Hungerleiste wird der Durst angezeigt -- Mit einem Rechtsklick, während man schleicht, kann man bewusstlosen Personen Erste-Hilfe geben -- Über dem Spielernamen wird eine Information angezeigt, wenn ein Spieler AFK oder im A-Duty ist +- Über den Spielernamen wird AFK angezeigt, wenn der Spieler AFK ist - Für Teammitglieder wird eine Warnung angezeigt, wenn sie sich im Admindienst befinden und eine Waffe in der Hand haben -- Hinter der Nachricht, dass sich das Karma geändert hat, wird angezeigt, wie viel Karma man insgesamt besitzt und wann ein Spieler despawnen sollte (falls das Karma durch einen Kill geändert wurde) - Bei der Mieterübersicht wird angezeigt wie lang ein Mieter offline ist und ein Button um diesen zu kündigen - Beim Beten wird nach 15 Sekunden automatisch der zweite Befehl ausgeführt -- Es gibt Benachrichtigungen, wenn ein Spieler den Server betritt oder verlässt, einen Report betritt oder verlässt, den Baumodus betritt oder verlässt und den Admindienst betritt oder verlässt +- Es gibt Benachrichtigungen, wenn ein Spieler den Server betritt oder verlässt, einen Report betritt oder verlässt, den Baumodus + betritt oder verlässt und den Admindienst betritt oder verlässt ### Auto +- Das zuletzt gefahrene Fahrzeug wird besonders hervorgehoben - Beim Suchen seines Fahrzeugs (`/car find`) wird automatisch das erste Fahrzeug ausgewählt - Werden die Koordinaten eines Autos angezeigt, wird automatisch eine Navigation zu diesen gestartet +- Wenn man schleicht und ein Auto rechtsklickt, wird `/checkkfz` ausgeführt + +Folgende Funktionen sind nur für Spieler ohne Premium-Rang verfügbar, da Spieler mit Premium diese Funktion vom Server aus können: - Das Auf-/Abschließen eines Fahrzeuges wurde teilweise automatisiert (automatisches Klicken des Items im Inventar) - Beim Rechtsklick auf das eigene Fahrzeug wird automatisch `/car lock` ausgeführt - Steigt man in ein Fahrzeug ein, wird dieses automatisch gestartet und abgeschlossen -- Das zuletzt gefahrene Fahrzeug wird mit einem Symbol markiert ### Fraktionen -- Für bewusstlose Spieler wird hinter dem Spielernamen ein Symbol angezeigt, um die dazugehörige Fraktion zu erkennen -- Sollte ein Spieler Contract, auf der Blacklist stehen, Hausverbot oder Wanted-Punkte haben, wird der Name dementsprechend eingefärbt - und in der Spielerliste angezeigt - Das Design der Reinforcements ist so überarbeitet, dass diese besser auffallen -- Für das FBI, die Polizei und den Rettungsdienst gibt es einen Timer, der die Dauer der Bombe anzeigt -- Mit einem Rechtsklick auf ein Fraktionstor (nicht Fraktionstür) wird dieses automatisch geöffnet oder geschlossen - Für den Rettungsdienst wird der Cooldown von Bandagen und Schmerzpillen unter dem Spielernamen angezeigt -- Wenn man den Navi-Punkt eines Notrufs erreicht, wird der Notruf automatisch als erledigt markiert - Der Fraktionschat kann individuell eingefärbt werden -- Eine Plantage kann direkt durch gleichzeitiges Schleichen und Klicken mit einem Samen in der Hand gelegt werden -- Eine Plantage kann durch einen Rechtsklick mit einem Wassereimer oder Dünger direkt gewässert beziehungsweise gedüngt werden -- Der Rettungsdienst kann durch einen Rechtsklick auf eine bewusstlose Person diese wiederbeleben -- Mit `/fbank einzahlen ` kann das Eingabe GUI des Servers übersprungen werden +- Für den Rettungsdienst gibt es im Herstellungs-Inventar für Medikamente einen Button, um die benötigte Anzahl an Stoffen in den + Fraktionschat zu senden +- Für den Dealer und Schwarzmarkt wird (in der Übersicht) angezeigt, an welchem Ort der Händler gefunden wurde ### Jobs @@ -56,8 +52,9 @@ reibungsloser und angenehmer gestalten. - Der Müllmann-Job gibt am Ende den gesammelten Müll automatisch ab, ohne dass der `/dropwaste` Command ausgeführt werden muss - Für den Pizzalieferanten-Job wird `/getpizza` automatisch ausgeführt, bis 10 Pizzen gesammelt wurden - Es werden Countdowns angezeigt, bis ein Job wieder ausgeführt werden kann -- Bei der Abgabe von Uran am Atomkraftwerk muss man nicht mehr aus dem Auto aussteigen - Aktive Mining XP-Booster werden angezeigt +- Das Angel-Captcha wird zusätzlich in der Mitte des Bildschirms angezeigt, damit es nicht vom Chat verdeckt wird +- Nach der erfolgreichen Eingabe des Angel-Captchas wird die Angel automatisch wieder ausgeworfen ### Widgets @@ -73,11 +70,8 @@ reibungsloser und angenehmer gestalten. | Befehl | Beschreibung | |-----------------------------------|-----------------------------------------------------------------------------------------------------------------| | `/ucutils ()` | Zeigt nützliche Status-Informationen über das Projekt an oder startet eine Synchronisierung | -| `/mi` | Alias für `/memberinfo` | -| `/mia` | Alias für `/memberinfoall` | | `/screenshot` | Erstellt einen Screenshot in einer bestimmten Kategorie | | `/shutdown ` | Aktiviert das automatische Herunterfahren des PCs nachdem man nicht mehr auf dem Friedhof oder im Gefängnis ist | -| `/selldrugall` `/sda` | Verkauft alle illegalen Drogen für 0$ an den angegebenen Spieler (Pulver, Kräuter, Kristalle und Wundertüten) | **Chat** @@ -86,27 +80,3 @@ reibungsloser und angenehmer gestalten. | `/ff` | Aktiviert und deaktiviert das dauerhafte Schreiben im F-Chat ohne den `/f` Befehl jedes Mal eingeben zu müssen | | `/dd` | Aktiviert und deaktiviert das dauerhafte Schreiben im D-Chat ohne den `/d` Befehl jedes Mal eingeben zu müssen | | `/ww` | Aktiviert und deaktiviert das dauerhafte Flüstern ohne den `/w` Befehl jedes Mal eingeben zu müssen | - -**Fraktionen** - -| Befehl | Beschreibung | -|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------| -| `/eigenbedarf` | Nimmt eine eingestellte Menge an Drogen aus der Drogenbank einer Fraktion oder gibt diese an einen Spieler | -| `/schwarzmarkt` | Zeigt alle Schwarzmärkte an einschließlich des Zeitpunkts des letzten Besuchs des Ortes und einer Markierung ob sich der Schwarzmarkt dort befand | -| `/dealer` | Zeigt alle Dealer an einschließlich des Zeitpunkts des letzten Besuchs des Ortes und einer Markierung ob sich der Dealer dort befand | -| `/dbankdropall` `/dda` | Legt alle Drogen in die Drogenbank der Fraktion (Pulver, Kräuter, Kristalle und Wundertüten) | - -**Geld** - -| Befehl | Beschreibung | -|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `/einzahlen ()` | Zahlt das gesamte Bargeld in den ATM in der Nähe ein | -| `/adropmoney` | Bucht für den Geldtransport-Job so viel Geld vom Konto ab, sodass das Geld vom Geldtransport-Job in den ATM eingezahlt werden kann und bucht das Geld anschließend zurück auf das Konto | - -**Handy** - -| Befehl | Beschreibung | -|-----------------------------------|--------------------------------------------------------------------------| -| `/acall ` | Ermöglicht das Anrufen mittels Spielername statt der Nummer | -| `/asms ` | Ermöglicht das Schreiben einer SMS mittels Spielername statt der Nummer | -| `/reply ` | Antwortet direkt auf eine SMS | diff --git a/gradle.properties b/gradle.properties index a4a78fc0..77e4da71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,10 +10,10 @@ org.gradle.configuration-cache=false minecraft_version=1.21.10 yarn_mappings=1.21.10+build.3 loader_version=0.19.2 -loom_version=1.16.2 +loom_version=1.17.3 # Mod Properties -mod_version=2.7.1 +mod_version=0.0.0 maven_group=de.rettichlp # Dependencies diff --git a/src/main/java/de/rettichlp/ucutils/UCUtils.java b/src/main/java/de/rettichlp/ucutils/UCUtils.java index 064fbe6f..6f9b0832 100644 --- a/src/main/java/de/rettichlp/ucutils/UCUtils.java +++ b/src/main/java/de/rettichlp/ucutils/UCUtils.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import static java.lang.Boolean.getBoolean; +import static java.lang.System.currentTimeMillis; import static java.util.Objects.isNull; public class UCUtils implements ModInitializer { @@ -68,6 +69,7 @@ public void onInitialize() { boolean isUnicaCity = isUnicaCity(handler); storage.setUnicaCity(isUnicaCity); + storage.setJoinTimestamp(currentTimeMillis()); if (isUnicaCity) { client.execute(() -> { this.registry.registerListeners(); diff --git a/src/main/java/de/rettichlp/ucutils/command/MiCommand.java b/src/main/java/de/rettichlp/ucutils/command/MiCommand.java deleted file mode 100644 index 9b93ce2c..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/MiCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.rettichlp.ucutils.command; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Faction.fromDisplayName; -import static java.util.Arrays.stream; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "mi") -public class MiCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("faction", greedyString()) - .suggests((context, builder) -> suggestMatching(stream(Faction.values()) - .map(Faction::getDisplayName), builder)) - .executes(context -> { - String input = getString(context, "faction"); - fromDisplayName(input).ifPresentOrElse(faction -> commandService.sendCommand("memberinfo " + faction.getDisplayName()), - () -> messageService.sendModMessage("Die Fraktion " + input + " konnte nicht gefunden werden.", false)); - - return 1; - }) - ) - .executes(context -> { - String playerName = player.getGameProfile().name(); - Faction faction = storage.getFaction(playerName); - commandService.sendCommand("memberinfo " + faction.getDisplayName()); - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/MiaCommand.java b/src/main/java/de/rettichlp/ucutils/command/MiaCommand.java deleted file mode 100644 index dc8f4441..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/MiaCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.rettichlp.ucutils.command; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Faction.fromDisplayName; -import static java.util.Arrays.stream; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "mia") -public class MiaCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("faction", greedyString()) - .suggests((context, builder) -> suggestMatching(stream(Faction.values()) - .map(Faction::getDisplayName), builder)) - .executes(context -> { - String input = getString(context, "faction"); - fromDisplayName(input).ifPresentOrElse(faction -> commandService.sendCommand("memberinfoall " + faction.getDisplayName()), - () -> messageService.sendModMessage("Die Fraktion " + input + " konnte nicht gefunden werden.", false)); - - return 1; - }) - ) - .executes(context -> { - String playerName = player.getGameProfile().name(); - Faction faction = storage.getFaction(playerName); - commandService.sendCommand("memberinfoall " + faction.getDisplayName()); - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/NotVisitedHousesCommand.java b/src/main/java/de/rettichlp/ucutils/command/NotVisitedHousesCommand.java deleted file mode 100644 index 20a33b3d..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/NotVisitedHousesCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.rettichlp.ucutils.command; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import de.rettichlp.ucutils.listener.impl.EventListener; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; - -@UCUtilsCommand(label = "notvisitedhouses") -public class NotVisitedHousesCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .executes(context -> { - List doorNumbersVisited = configuration.getHalloweenClickedDoors().stream() - .map(EventListener.HalloweenDoor::getDoorNumber) - .toList(); - - Collection doorNumbersNotVisited = new ArrayList<>(); - for (int i = 1; i <= 828; i++) { - if (!doorNumbersVisited.contains(i)) { - doorNumbersNotVisited.add(i); - } - } - - player.sendMessage(empty(), false); - - messageService.sendModMessage("Noch nicht besuchte Häuser:", false); - doorNumbersNotVisited.forEach(integer -> messageService.sendModMessage(of("Haus " + integer), false)); - - player.sendMessage(empty(), false); - - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/ScreenshotCommand.java b/src/main/java/de/rettichlp/ucutils/command/ScreenshotCommand.java similarity index 98% rename from src/main/java/de/rettichlp/ucutils/command/faction/ScreenshotCommand.java rename to src/main/java/de/rettichlp/ucutils/command/ScreenshotCommand.java index c21598a2..c67eabfa 100644 --- a/src/main/java/de/rettichlp/ucutils/command/faction/ScreenshotCommand.java +++ b/src/main/java/de/rettichlp/ucutils/command/ScreenshotCommand.java @@ -1,4 +1,4 @@ -package de.rettichlp.ucutils.command.faction; +package de.rettichlp.ucutils.command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.rettichlp.ucutils.common.models.ScreenshotType; diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/BlackMarketCommand.java b/src/main/java/de/rettichlp/ucutils/command/faction/BlackMarketCommand.java deleted file mode 100644 index 5e2d19d9..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/faction/BlackMarketCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.rettichlp.ucutils.command.faction; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static java.util.Comparator.comparingDouble; -import static net.minecraft.text.Text.empty; - -@UCUtilsCommand(label = "blackmarket", aliases = "schwarzmarkt") -public class BlackMarketCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .requires(fabricClientCommandSource -> storage.getFaction(player.getStringifiedName()).isBadFaction() || commandService.isSuperUser()) - .executes(context -> { - player.sendMessage(empty(), false); - - messageService.sendModMessage("Schwarzmarkt Orte:", false); - storage.getBlackMarkets().stream() - .sorted(comparingDouble(value -> value.getType().getBlockPos().getSquaredDistance(player.getBlockPos()))) - .forEach(blackMarket -> messageService.sendModMessage(blackMarket.getText(), false)); - - player.sendMessage(empty(), false); - - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/DBankDropAllCommand.java b/src/main/java/de/rettichlp/ucutils/command/faction/DBankDropAllCommand.java deleted file mode 100644 index 90af90cf..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/faction/DBankDropAllCommand.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.rettichlp.ucutils.command.faction; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.models.Ingredient; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import de.rettichlp.ucutils.listener.impl.InventoryListener; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.models.Ingredient.POWDER; - -@UCUtilsCommand(label = "dbankdropall", aliases = "dda") -public class DBankDropAllCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .executes(context -> { - // sync inventory - InventoryListener.inventorySyncStep = POWDER; - commandService.sendCommand("inv"); - - utilService.delayedAction(() -> { - // handle - List commandQueue = new ArrayList<>(); - - storage.getInventory().entrySet().stream() - .filter(ingredientMapEntry -> ingredientMapEntry.getKey().isDrugBankDropable()) - .forEach(ingredientMapEntry -> { - Ingredient ingredient = ingredientMapEntry.getKey(); - - ingredientMapEntry.getValue().entrySet().stream() - .filter(purityIntegerEntry -> purityIntegerEntry.getValue() > 0) - .forEach(purityIntegerEntry -> { - int purityNumber = purityIntegerEntry.getKey().ordinal(); - Integer amount = purityIntegerEntry.getValue(); - commandQueue.add("dbank drop " + ingredient.getDisplayName() + " " + amount + " " + purityNumber); - }); - }); - - commandService.sendCommands(commandQueue, 1000); - }, 2500); - - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/DealerCommand.java b/src/main/java/de/rettichlp/ucutils/command/faction/DealerCommand.java deleted file mode 100644 index bb351d9e..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/faction/DealerCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.rettichlp.ucutils.command.faction; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static java.util.Comparator.comparingDouble; -import static net.minecraft.text.Text.empty; - -@UCUtilsCommand(label = "dealer") -public class DealerCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .requires(fabricClientCommandSource -> storage.getFaction(player.getStringifiedName()).isBadFaction() || commandService.isSuperUser()) - .executes(context -> { - player.sendMessage(empty(), false); - - messageService.sendModMessage("Dealer Orte:", false); - storage.getDealers().stream() - .sorted(comparingDouble(value -> value.getType().getBlockPos().getSquaredDistance(player.getBlockPos()))) - .forEach(dealer -> messageService.sendModMessage(dealer.getText(), false)); - - player.sendMessage(empty(), false); - - return 1; - }); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/PersonalUseCommand.java b/src/main/java/de/rettichlp/ucutils/command/faction/PersonalUseCommand.java deleted file mode 100644 index b9bb0e5b..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/faction/PersonalUseCommand.java +++ /dev/null @@ -1,93 +0,0 @@ -package de.rettichlp.ucutils.command.faction; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.word; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.networkHandler; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static java.lang.String.valueOf; -import static java.util.regex.Pattern.compile; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "eigenbedarf") -public class PersonalUseCommand extends CommandBase implements IMessageReceiveListener { - - private static final Pattern DEAL_ACCEPTED = compile("^\\[Deal] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat den Deal angenommen\\.$"); - private static final Pattern DEAL_DECLINED = compile("^(?:\\[UC])?(?[a-zA-Z0-9_]+) hat das Angebot abgelehnt\\.$"); - - private List commands = new ArrayList<>(); - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(literal("give") - .then(argument("player", word()) - .suggests((context, builder) -> { - List list = networkHandler.getPlayerList().stream() - .map(PlayerListEntry::getProfile) - .map(GameProfile::name) - .toList(); - return suggestMatching(list, builder); - }) - .executes(context -> { - String targetPlayer = getString(context, "player"); - this.commands = new ArrayList<>(createCommands("selldrug " + targetPlayer + " %name% %amount% %purity% 0")); - removeAndExecuteFirst(); - return 1; - }))) - .executes(context -> { - commandService.sendCommands(createCommands("dbank get %name% %amount% %purity%"), 1000); - return 1; - }); - } - - @Override - public boolean onMessageReceive(Text text, String message) { - if (DEAL_ACCEPTED.matcher(message).find() || DEAL_DECLINED.matcher(message).find()) { - utilService.delayedAction(this::removeAndExecuteFirst, 500); - } - - return true; - } - - private @NotNull List createCommands(String commandTemplate) { - List commandStrings = configuration.getOptions().personalUse().stream() - .filter(personalUseEntry -> personalUseEntry.getAmount() > 0) - .map(personalUseEntry -> commandTemplate - .replace("%name%", personalUseEntry.getInventoryItem().getDisplayName()) - .replace("%amount%", valueOf(personalUseEntry.getAmount())) - .replace("%purity%", valueOf(personalUseEntry.getPurity().ordinal()))) - .toList(); - - if (commandStrings.isEmpty()) { - messageService.sendModMessage("Du hast keinen Eigenbedarf gesetzt.", false); - } - - return commandStrings; - } - - private void removeAndExecuteFirst() { - if (!this.commands.isEmpty()) { - String firstCommandString = this.commands.removeFirst(); - commandService.sendCommand(firstCommandString); - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/faction/SellDrugAllCommand.java b/src/main/java/de/rettichlp/ucutils/command/faction/SellDrugAllCommand.java deleted file mode 100644 index 0dbfc588..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/faction/SellDrugAllCommand.java +++ /dev/null @@ -1,71 +0,0 @@ -package de.rettichlp.ucutils.command.faction; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.models.Ingredient; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import de.rettichlp.ucutils.listener.impl.InventoryListener; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.client.network.PlayerListEntry; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.word; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.networkHandler; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.models.Ingredient.POWDER; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "selldrugall", aliases = "sda") -public class SellDrugAllCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("player", word()) - .suggests((context, builder) -> { - List list = networkHandler.getPlayerList().stream() - .map(PlayerListEntry::getProfile) - .map(GameProfile::name) - .toList(); - return suggestMatching(list, builder); - }) - .executes(context -> { - // sync inventory - InventoryListener.inventorySyncStep = POWDER; - commandService.sendCommand("inv"); - - String targetName = getString(context, "player"); - - utilService.delayedAction(() -> { - // handle - List commandQueue = new ArrayList<>(); - - storage.getInventory().entrySet().stream() - .filter(ingredientMapEntry -> ingredientMapEntry.getKey().isDrugBankDropable()) - .forEach(ingredientMapEntry -> { - Ingredient ingredient = ingredientMapEntry.getKey(); - - ingredientMapEntry.getValue().entrySet().stream() - .filter(purityIntegerEntry -> purityIntegerEntry.getValue() > 0) - .forEach(purityIntegerEntry -> { - int purityNumber = purityIntegerEntry.getKey().ordinal(); - Integer amount = purityIntegerEntry.getValue(); - commandQueue.add("selldrug " + targetName + " " + ingredient.getDisplayName() + " " + purityNumber + " " + amount + " " + 0); - }); - }); - - commandService.sendCommandsWithAwaitingResponse(commandQueue); - }, 2500); - - return 1; - })); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/mobile/ACallCommand.java b/src/main/java/de/rettichlp/ucutils/command/mobile/ACallCommand.java deleted file mode 100644 index 71596968..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/mobile/ACallCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.rettichlp.ucutils.command.mobile; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.client.network.PlayerListEntry; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.word; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.networkHandler; -import static de.rettichlp.ucutils.UCUtils.storage; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "acall") -public class ACallCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("player", word()) - .suggests((context, builder) -> { - List list = networkHandler.getPlayerList().stream() - .map(PlayerListEntry::getProfile) - .map(GameProfile::name) - .toList(); - return suggestMatching(list, builder); - }) - .executes(context -> { - String playerName = getString(context, "player"); - - boolean numberAlreadyRetrieved = storage.getRetrievedNumbers().containsKey(playerName); - if (numberAlreadyRetrieved) { - int number = storage.getRetrievedNumbers().get(playerName); - call(number); - } else { - commandService.retrieveNumberAndRun(playerName, this::call); - } - - return 1; - })); - } - - private void call(int number) { - commandService.sendCommand("call " + number); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/mobile/ASMSCommand.java b/src/main/java/de/rettichlp/ucutils/command/mobile/ASMSCommand.java deleted file mode 100644 index 316a629f..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/mobile/ASMSCommand.java +++ /dev/null @@ -1,56 +0,0 @@ -package de.rettichlp.ucutils.command.mobile; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.client.network.PlayerListEntry; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static com.mojang.brigadier.arguments.StringArgumentType.word; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.networkHandler; -import static de.rettichlp.ucutils.UCUtils.storage; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.minecraft.command.CommandSource.suggestMatching; - -@UCUtilsCommand(label = "asms") -public class ASMSCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("player", word()) - .suggests((context, builder) -> { - List list = networkHandler.getPlayerList().stream() - .map(PlayerListEntry::getProfile) - .map(GameProfile::name) - .toList(); - return suggestMatching(list, builder); - }) - .then(argument("message", greedyString()) - .executes(context -> { - String playerName = getString(context, "player"); - String message = getString(context, "message"); - - boolean numberAlreadyRetrieved = storage.getRetrievedNumbers().containsKey(playerName); - if (numberAlreadyRetrieved) { - int number = storage.getRetrievedNumbers().get(playerName); - sms(number, message); - } else { - commandService.retrieveNumberAndRun(playerName, number -> sms(number, message)); - } - - return 1; - }))); - } - - private void sms(int number, String message) { - commandService.sendCommand("sms " + number + " " + message); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/mobile/ReplyCommand.java b/src/main/java/de/rettichlp/ucutils/command/mobile/ReplyCommand.java deleted file mode 100644 index 06383c74..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/mobile/ReplyCommand.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.rettichlp.ucutils.command.mobile; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.jetbrains.annotations.NotNull; - -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.storage; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; - -@UCUtilsCommand(label = "reply", aliases = "r") -public class ReplyCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(argument("message", greedyString()) - .executes(context -> { - String message = getString(context, "message"); - - int lastReceivedSmsNumber = storage.getLastReceivedSmsNumber(); - - if (lastReceivedSmsNumber < 0) { - messageService.sendModMessage("Kein SMS-Empfänger gefunden.", false); - return 1; - } - - commandService.sendCommand("sms " + lastReceivedSmsNumber + " " + message); - - return 1; - })); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/money/ADropMoneyCommand.java b/src/main/java/de/rettichlp/ucutils/command/money/ADropMoneyCommand.java deleted file mode 100644 index 256b0357..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/money/ADropMoneyCommand.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.rettichlp.ucutils.command.money; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.scoreboard.ReadableScoreboardScore; -import net.minecraft.scoreboard.Scoreboard; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static java.lang.Math.min; -import static java.util.Optional.ofNullable; -import static net.minecraft.scoreboard.ScoreHolder.fromName; -import static net.minecraft.scoreboard.ScoreboardDisplaySlot.SIDEBAR; - -@UCUtilsCommand(label = "adropmoney") -public class ADropMoneyCommand extends CommandBase { - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .executes(context -> { - Scoreboard scoreboard = player.getEntityWorld().getScoreboard(); - - Optional optionalReadableScoreboardScore = ofNullable(scoreboard.getObjectiveForSlot(SIDEBAR)) - .map(scoreboardObjective -> scoreboard.getScore(fromName("§9Geld§8:"), scoreboardObjective)); - - if (optionalReadableScoreboardScore.isEmpty()) { - messageService.sendModMessage("Der Geldtransport-Job wird nicht ausgeführt.", false); - return 1; - } - - List scheduledCommands = getScheduledCommands(optionalReadableScoreboardScore); - - commandService.sendCommands(scheduledCommands); - - return 1; - }); - } - - private @NotNull List getScheduledCommands(@NotNull Optional optionalReadableScoreboardScore) { - ReadableScoreboardScore readableScoreboardScore = optionalReadableScoreboardScore.get(); - int moneyToDrop = readableScoreboardScore.getScore(); - - List scheduledCommands = new ArrayList<>(); - - while (moneyToDrop > 0) { - int moneyCanDrop = min(moneyToDrop, configuration.getMoneyBankAmount()); - scheduledCommands.add("bank abbuchen " + moneyCanDrop); - scheduledCommands.add("dropmoney"); - scheduledCommands.add("bank einzahlen " + moneyCanDrop); - moneyToDrop -= moneyCanDrop; - } - return scheduledCommands; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java b/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java deleted file mode 100644 index 88273447..00000000 --- a/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java +++ /dev/null @@ -1,97 +0,0 @@ -package de.rettichlp.ucutils.command.money; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.rettichlp.ucutils.common.registry.CommandBase; -import de.rettichlp.ucutils.common.registry.UCUtilsCommand; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; -import static java.lang.Integer.parseInt; -import static java.util.regex.Pattern.compile; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; - -@UCUtilsCommand(label = "einzahlen") -@UCUtilsListener -public class DepositCommand extends CommandBase implements IMessageReceiveListener { - - private static final Pattern PLAYER_MONEY_AMOUNT_PATTERN = compile("- Geld: (?\\d+)\\$"); - private static final Pattern ATM_MONEY_AMOUNT_PATTERN = compile("^ATM (?\\d+): (?\\d+)\\$/(?\\d+)\\$$"); - - private static int money = 0; - private static int atmMoneyAvailable = -1; - - @Override - public LiteralArgumentBuilder execute(@NotNull LiteralArgumentBuilder node) { - return node - .then(literal("force") - .executes(context -> { - commandService.sendCommand("stats"); - - utilService.delayedAction(() -> { - if (money <= 0) { - messageService.sendModMessage("Du hast kein Geld zum Einzahlen.", false); - return; - } - - commandService.sendCommand("bank einzahlen " + money); - messageService.sendModMessage("Nutze \"force\" bitte nur in Notfällen um zu vermeiden dass AMTs überfüllt werden und Geld dadurch \"verloren\" geht.", false); - }, COMMAND_COOLDOWN_MILLIS); - - return 1; - }) - ) - .executes(context -> { - commandService.sendCommand("stats"); - utilService.delayedAction(() -> commandService.sendCommandWithHiddenOutput("atminfo"), COMMAND_COOLDOWN_MILLIS); - - utilService.delayedAction(() -> { - if (money <= 0) { - messageService.sendModMessage("Du hast kein Geld zum Einzahlen.", false); - return; - } - - if (atmMoneyAvailable == 0) { - messageService.sendModMessage("Der ATM ist voll.", false); - messageService.sendModMessage("Nutze einen anderen ATM oder '/einzahlen force' um dennoch Geld in diesen ATM zu legen.", false); - } else if (atmMoneyAvailable > 0 && money > atmMoneyAvailable) { - commandService.sendCommand("bank einzahlen " + atmMoneyAvailable); - messageService.sendModMessage("Der ATM ist voll. Es wurden nur " + atmMoneyAvailable + "$ eingezahlt.", false); - messageService.sendModMessage("Nutze einen anderen ATM oder '/einzahlen force' um dennoch Geld in diesen ATM zu legen.", false); - } else { - commandService.sendCommand("bank einzahlen " + money); - } - }, COMMAND_COOLDOWN_MILLIS * 2); - - return 1; - }); - } - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher playerMoneyAmountMatcher = PLAYER_MONEY_AMOUNT_PATTERN.matcher(message); - if (playerMoneyAmountMatcher.find()) { - money = parseInt(playerMoneyAmountMatcher.group("moneyAmount")); - return true; - } - - Matcher atmMoneyAmountMatcher = ATM_MONEY_AMOUNT_PATTERN.matcher(message); - if (atmMoneyAmountMatcher.find()) { - int amountCurrent = parseInt(atmMoneyAmountMatcher.group("amountCurrent")); - int amountMax = parseInt(atmMoneyAmountMatcher.group("amountMax")); - atmMoneyAvailable = amountMax - amountCurrent; - return commandService.showCommandOutputMessage("atminfo"); - } - - return true; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/Storage.java b/src/main/java/de/rettichlp/ucutils/common/Storage.java index 246743a4..1851bc70 100644 --- a/src/main/java/de/rettichlp/ucutils/common/Storage.java +++ b/src/main/java/de/rettichlp/ucutils/common/Storage.java @@ -1,28 +1,20 @@ package de.rettichlp.ucutils.common; -import de.rettichlp.ucutils.common.models.BlackMarket; -import de.rettichlp.ucutils.common.models.BlacklistEntry; -import de.rettichlp.ucutils.common.models.BlacklistReason; -import de.rettichlp.ucutils.common.models.ContractEntry; import de.rettichlp.ucutils.common.models.Countdown; -import de.rettichlp.ucutils.common.models.Dealer; import de.rettichlp.ucutils.common.models.Faction; import de.rettichlp.ucutils.common.models.FactionEntry; import de.rettichlp.ucutils.common.models.FactionMember; -import de.rettichlp.ucutils.common.models.HousebanEntry; -import de.rettichlp.ucutils.common.models.Ingredient; import de.rettichlp.ucutils.common.models.Job; -import de.rettichlp.ucutils.common.models.PlantEntry; -import de.rettichlp.ucutils.common.models.Purity; -import de.rettichlp.ucutils.common.models.Reinforcement; import de.rettichlp.ucutils.common.models.ShutdownReason; import de.rettichlp.ucutils.common.models.TeamResponse; import de.rettichlp.ucutils.common.models.WantedEntry; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import net.minecraft.component.type.MapIdComponent; import net.minecraft.entity.vehicle.MinecartEntity; import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; import org.jetbrains.annotations.Nullable; import java.time.LocalDateTime; @@ -35,11 +27,8 @@ import java.util.Set; import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.common.Storage.ToggledChat.NONE; import static de.rettichlp.ucutils.common.models.Faction.NULL; -import static java.util.Arrays.stream; -import static java.util.Optional.ofNullable; import static net.minecraft.text.Text.translatable; public class Storage { @@ -47,57 +36,37 @@ public class Storage { @Getter private final List activeShutdowns = new ArrayList<>(); - @Getter - private final List blacklistEntries = new ArrayList<>(); - - @Getter - private final Map> blacklistReasons = new HashMap<>(); - - @Getter - private final List blackMarkets = new ArrayList<>(); - - @Getter - private final List contractEntries = new ArrayList<>(); - @Getter private final List countdowns = new ArrayList<>(); - @Getter - private final List dealers = new ArrayList<>(); - @Getter private final Set factionEntries = new HashSet<>(); - @Getter - private final List housebanEntries = new ArrayList<>(); - - @Getter - private final Map> inventory = new HashMap<>(); - @Getter private final Map medicBandageCooldowns = new HashMap<>(); @Getter private final Map medicPillCooldowns = new HashMap<>(); - @Getter - private final List plantEntries = new ArrayList<>(); - @Getter private final Map playerFactionCache = new HashMap<>(); @Getter - private final List reinforcements = new ArrayList<>(); + private final List wantedEntries = new ArrayList<>(); @Getter - private final Map retrievedNumbers = new HashMap<>(); + @Setter + private int activeServices = 0; @Getter - private final List wantedEntries = new ArrayList<>(); + @Setter + @Nullable + private Vec3d blackMarketPosition; @Getter @Setter - private int activeServices = 0; + @Nullable + private MapIdComponent captchaMap; @Getter @Setter @@ -114,7 +83,8 @@ public class Storage { @Getter @Setter - private String fBankDepositReason = ""; + @Nullable + private Vec3d dealerPosition; @Getter @Setter @@ -122,7 +92,7 @@ public class Storage { @Getter @Setter - private int lastReceivedSmsNumber = -1; + private long joinTimestamp = 0; @Getter @Setter @@ -130,7 +100,7 @@ public class Storage { @Getter @Setter - private int moneyAtmAmount = 0; + private boolean premium = false; @Getter @Setter @@ -144,47 +114,25 @@ public class Storage { @Setter private boolean unicaCity = false; - { - this.blackMarkets.addAll(stream(BlackMarket.Type.values()) - .map(type -> new BlackMarket(type, null, false)) - .toList()); - - this.dealers.addAll(stream(Dealer.Type.values()) - .map(type -> new Dealer(type, null, false)) - .toList()); - } - public void print() { //activeShutdowns LOGGER.info("activeShutdowns[{}]: {}", this.activeShutdowns.size(), this.activeShutdowns); - // blacklistEntries - LOGGER.info("blacklistEntries[{}]: {}", this.blacklistEntries.size(), this.blacklistEntries); - // blacklistReasons - this.blacklistReasons.forEach((faction, blacklistReasons) -> LOGGER.info("blacklistReasons[{}:{}]: {}", faction, blacklistReasons.size(), blacklistReasons)); - // blackMarkets - LOGGER.info("blackMarkets[{}]: {}", this.blackMarkets.size(), this.blackMarkets); - // contractEntries - LOGGER.info("contractEntries[{}]: {}", this.contractEntries.size(), this.contractEntries); + // blackMarketPosition + LOGGER.info("blackMarketPosition: {}", this.blackMarketPosition); + // captchaMapImage + LOGGER.info("captchaMap: {}", this.captchaMap); // countdowns LOGGER.info("countdowns[{}]: {}", this.countdowns.size(), this.countdowns); - // dealers - LOGGER.info("dealers[{}]: {}", this.dealers.size(), this.dealers); + // dealerPosition + LOGGER.info("dealerPosition: {}", this.dealerPosition); // factionEntries this.factionEntries.forEach(factionEntry -> LOGGER.info("factionEntries[{}:{}]: {}", factionEntry.faction(), factionEntry.members().size(), factionEntry.members())); - // housebanEntries - LOGGER.info("housebanEntries[{}]: {}", this.housebanEntries.size(), this.housebanEntries); - // inventory - this.inventory.forEach((ingredient, ingredientMap) -> LOGGER.info("inventory[{}:{}]: {}", ingredient, ingredientMap.size(), ingredientMap)); // medicBandageCooldowns LOGGER.info("medicBandageCooldowns[{}]: {}", this.medicBandageCooldowns.size(), this.medicBandageCooldowns); // medicPillCooldowns LOGGER.info("medicPillCooldowns[{}]: {}", this.medicPillCooldowns.size(), this.medicPillCooldowns); // playerFactionCache LOGGER.info("playerFactionCache[{}]: {}", this.playerFactionCache.size(), this.playerFactionCache); - // reinforcements - LOGGER.info("reinforcements[{}]: {}", this.reinforcements.size(), this.reinforcements); - // retrievedNumbers - LOGGER.info("retrievedNumbers[{}]: {}", this.retrievedNumbers.size(), this.retrievedNumbers); // wantedEntries LOGGER.info("wantedEntries[{}]: {}", this.wantedEntries.size(), this.wantedEntries); // activeServices @@ -195,16 +143,14 @@ public void print() { LOGGER.info("currentJob: {}", this.currentJob); // dead LOGGER.info("dead: {}", this.dead); - // fBankDepositReason - LOGGER.info("fBankDepositReason: {}", this.fBankDepositReason); // hydration LOGGER.info("hydration: {}", this.hydration); - // lastReceivedSmsNumber - LOGGER.info("lastReceivedSmsNumber: {}", this.lastReceivedSmsNumber); + // joinTimestamp + LOGGER.info("joinTimestamp: {}", this.joinTimestamp); // minecartEntityToHighlight LOGGER.info("minecartEntityToHighlight: {}", this.minecartEntityToHighlight); - // moneyAtmAmount - LOGGER.info("moneyAtmAmount: {}", this.moneyAtmAmount); + // premium + LOGGER.info("premium: {}", this.premium); // team LOGGER.info("team: {}", this.team); // toggledChat @@ -213,10 +159,6 @@ public void print() { LOGGER.info("unicaCity: {}", this.unicaCity); } - public Faction getCachedFaction(String playerName) { - return ofNullable(this.playerFactionCache.get(playerName)).orElseGet(() -> storage.getFaction(playerName)); - } - public Faction getFaction(String playerName) { Faction faction = this.factionEntries.stream() .filter(factionEntry -> factionEntry.members().stream() @@ -236,13 +178,6 @@ public Optional getFactionMember(String playerName) { .findFirst(); } - public void trackReinforcement(Reinforcement reinforcement) { - // remove all previous reinforcements of the same sender - this.reinforcements.removeIf(r -> r.getSenderPlayerName().equals(reinforcement.getSenderPlayerName())); - // add new reinforcement - this.reinforcements.add(reinforcement); - } - @Getter @AllArgsConstructor public enum ToggledChat { diff --git a/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java b/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java index 2cf94054..1cd7db8f 100644 --- a/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java +++ b/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java @@ -1,27 +1,19 @@ package de.rettichlp.ucutils.common.configuration; import de.rettichlp.ucutils.common.configuration.options.Options; -import de.rettichlp.ucutils.listener.impl.EventListener; import lombok.Data; import net.fabricmc.loader.api.FabricLoader; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.nio.file.Path; -import java.time.LocalDateTime; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import static de.rettichlp.ucutils.UCUtils.LOGGER; import static de.rettichlp.ucutils.UCUtils.api; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.notificationService; import static java.nio.file.Files.newBufferedReader; import static java.nio.file.Files.newBufferedWriter; @@ -37,9 +29,6 @@ public class Configuration { private int minutesSinceLastPayDay = 0; private int predictedPayDaySalary = 0; private int predictedPayDayExp = 0; - @Nullable - private LocalDateTime firstAidLicenseExpireDateTime = null; - private Set halloweenClickedDoors = new HashSet<>(); public void addMinutesSinceLastPayDay(int minutes) { this.minutesSinceLastPayDay += minutes; @@ -47,19 +36,6 @@ public void addMinutesSinceLastPayDay(int minutes) { if (this.minutesSinceLastPayDay % 10 == 0) { new Thread(this::saveToFile).start(); // asynchronously save every active 10 minutes } - - if (configuration.getMoneyBankAmount() > 100000) { - switch (this.minutesSinceLastPayDay) { - case 50 -> { - messageService.sendModMessage("Du hast in 10 Minuten PayDay und über 100000$ auf der Bank!", false); - notificationService.notificationSound(1); - } - case 55 -> { - messageService.sendModMessage("Du hast in 5 Minuten PayDay und über 100000$ auf der Bank!", false); - notificationService.notificationSound(2); - } - } - } } public void addPredictedPayDaySalary(int salary) { diff --git a/src/main/java/de/rettichlp/ucutils/common/configuration/options/NameTagOptions.java b/src/main/java/de/rettichlp/ucutils/common/configuration/options/NameTagOptions.java index c99e62bd..08546141 100644 --- a/src/main/java/de/rettichlp/ucutils/common/configuration/options/NameTagOptions.java +++ b/src/main/java/de/rettichlp/ucutils/common/configuration/options/NameTagOptions.java @@ -9,9 +9,6 @@ @Accessors(fluent = true) public class NameTagOptions { - private boolean aDuty = true; private boolean afk = true; - private boolean houseBan = true; - private boolean outlaw = true; private boolean medicalInformation = true; } diff --git a/src/main/java/de/rettichlp/ucutils/common/configuration/options/Options.java b/src/main/java/de/rettichlp/ucutils/common/configuration/options/Options.java index 5a5d34ca..ee6ebefb 100644 --- a/src/main/java/de/rettichlp/ucutils/common/configuration/options/Options.java +++ b/src/main/java/de/rettichlp/ucutils/common/configuration/options/Options.java @@ -2,7 +2,6 @@ import de.rettichlp.ucutils.common.gui.screens.components.CyclingButtonEntry; import de.rettichlp.ucutils.common.models.Color; -import de.rettichlp.ucutils.common.models.PersonalUseEntry; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -12,9 +11,6 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; - import static de.rettichlp.ucutils.common.configuration.options.Options.AtmInformationType.NONE; import static de.rettichlp.ucutils.common.configuration.options.Options.ReinforcementType.UNICACITYADDON; import static net.minecraft.text.Text.empty; @@ -31,7 +27,6 @@ public class Options { private final NameTagOptions nameTag = new NameTagOptions(); - private final List personalUse = new ArrayList<>(); private final CarOptions car = new CarOptions(); private final SoundOptions sound = new SoundOptions(); private final NotificationOptions notification = new NotificationOptions(); @@ -40,7 +35,6 @@ public class Options { private AtmInformationType atmInformationType = NONE; private boolean showHydration = true; private boolean checkUnicacityServer = true; - private boolean showEnrichedKarma = true; private boolean changeFactionChatColor = false; private Color factionChatColorPrimary = Color.BLUE; private Color factionChatColorSecondary = Color.DARK_AQUA; diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/ShutdownScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/ShutdownScreen.java index b797327d..633ad200 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/ShutdownScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/ShutdownScreen.java @@ -1,11 +1,11 @@ package de.rettichlp.ucutils.common.gui.screens; import de.rettichlp.ucutils.common.models.ShutdownReason; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; import net.minecraft.client.gui.widget.TextWidget; import net.minecraft.text.Text; -import static de.rettichlp.ucutils.UCUtils.renderService; import static de.rettichlp.ucutils.UCUtils.storage; import static net.minecraft.client.gui.widget.DirectionalLayoutWidget.vertical; import static net.minecraft.text.Text.empty; @@ -44,7 +44,7 @@ public void initBody() { directionalLayoutWidget.add(new TextWidget(empty() .append(of("wird das automatische Herunterfahren gestoppt.").copy().formatted(GRAY)), this.textRenderer), positioner -> positioner.marginBottom(16)); - renderService.addButton(directionalLayoutWidget, BUTTON_SHUTDOWN_ABORT_NAME, button -> close(), 150); + directionalLayoutWidget.add(ButtonWidget.builder(BUTTON_SHUTDOWN_ABORT_NAME, button -> close()).width(150).build()); directionalLayoutWidget.forEachChild(this::addDrawableChild); } diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/ItemButtonWidget.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/ItemButtonWidget.java deleted file mode 100644 index 4beef24b..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/ItemButtonWidget.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.rettichlp.ucutils.common.gui.screens.components; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; - -import static net.minecraft.text.Text.translatable; - -public class ItemButtonWidget extends ButtonWidget { - - private final Item item; - - public ItemButtonWidget(String key, Item item, PressAction onPress) { - super(0, 0, 20, 20, Text.empty(), onPress, DEFAULT_NARRATION_SUPPLIER); - this.item = item; - setTooltip(Tooltip.of(translatable(key))); - } - - @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - super.renderWidget(context, mouseX, mouseY, delta); - - int x = getX() + (getWidth() / 2) - 8; - int y = getY() + (getHeight() / 2) - 8; - - ItemStack stack = new ItemStack(this.item); - context.drawItem(stack, x, y); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/TableHeaderTextWidget.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/TableHeaderTextWidget.java deleted file mode 100644 index 04d6ff54..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/components/TableHeaderTextWidget.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.rettichlp.ucutils.common.gui.screens.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.Click; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; - -import java.util.Comparator; -import java.util.function.Consumer; - -import static de.rettichlp.ucutils.common.gui.screens.components.TableHeaderTextWidget.SortingDirection.ASCENDING; -import static de.rettichlp.ucutils.common.gui.screens.components.TableHeaderTextWidget.SortingDirection.DESCENDING; -import static de.rettichlp.ucutils.common.gui.screens.components.TableHeaderTextWidget.SortingDirection.NONE; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.AQUA; - -public class TableHeaderTextWidget extends ClickableWidget { - - private static final TextRenderer TEXT_RENDERER = MinecraftClient.getInstance().textRenderer; - - private final Text text; - private final Consumer onChange; - private SortingDirection sortingDirection; - - public TableHeaderTextWidget(Text text, Consumer onChange, SortingDirection initialSortingDirection) { - super(0, 0, TEXT_RENDERER.getWidth(text), TEXT_RENDERER.fontHeight, empty()); - this.text = text; - this.onChange = onChange; - this.sortingDirection = initialSortingDirection; - } - - @Override - protected void renderWidget(@NotNull DrawContext context, int mouseX, int mouseY, float delta) { - Text modifiedText = getModifiedText(); - int textWidth = TEXT_RENDERER.getWidth(modifiedText); - context.drawText(TEXT_RENDERER, modifiedText, getX() + (getWidth() - textWidth) / 2, getY(), 0xFFFFFFFF, false); - } - - @Override - public boolean mouseClicked(Click click, boolean doubled) { - boolean mouseClicked = super.mouseClicked(click, doubled); - - if (click.button() != 0 || !isMouseOver(click.x(), click.y())) { - return mouseClicked; - } - - this.sortingDirection = switch (this.sortingDirection) { - case NONE -> ASCENDING; - case ASCENDING -> DESCENDING; - case DESCENDING -> NONE; - }; - - this.onChange.accept(this.sortingDirection); - - return mouseClicked; - } - - @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - - } - - private Text getModifiedText() { - String arrow = switch (this.sortingDirection) { - case ASCENDING -> " ↓"; - case DESCENDING -> " ↑"; - default -> ""; - }; - - return this.text.copy().append(of(arrow).copy().formatted(AQUA)); - } - - public enum SortingDirection { - - NONE, - ASCENDING, - DESCENDING; - - public Comparator apply(Comparator comparator) { - return this == DESCENDING ? comparator.reversed() : comparator; - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/CarOptionsScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/CarOptionsScreen.java index 39fcc0fa..fe67b22f 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/CarOptionsScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/CarOptionsScreen.java @@ -1,22 +1,23 @@ package de.rettichlp.ucutils.common.gui.screens.options; +import de.rettichlp.ucutils.common.configuration.options.CarOptions; import de.rettichlp.ucutils.common.gui.screens.OptionsScreen; +import de.rettichlp.ucutils.common.gui.screens.components.ToggleButtonWidget; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.DirectionalLayoutWidget; -import net.minecraft.client.gui.widget.Positioner; -import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.client.gui.tooltip.Tooltip; +import net.minecraft.client.gui.widget.GridWidget; +import net.minecraft.client.gui.widget.MultilineTextWidget; import net.minecraft.text.Text; -import static de.rettichlp.ucutils.UCUtils.renderService; -import static net.minecraft.client.gui.widget.DirectionalLayoutWidget.horizontal; -import static net.minecraft.client.gui.widget.DirectionalLayoutWidget.vertical; +import static de.rettichlp.ucutils.UCUtils.configuration; +import static net.minecraft.client.gui.widget.Positioner.create; import static net.minecraft.text.Text.translatable; +import static net.minecraft.util.Formatting.GOLD; public class CarOptionsScreen extends OptionsScreen { private static final Text TEXT_CAR = translatable("ucutils.options.text.car"); - private static final Text TEXT_GENERAL = translatable("ucutils.options.text.general"); - private static final Text TEXT_AUTOMATION = translatable("ucutils.options.text.automation"); + private static final Text CAR_PREMIUM_INFO = translatable("ucutils.options.car.premium_info"); private static final Text CAR_GENERAL_FAST_FIND_NAME = translatable("ucutils.options.car.general.fast_find.name"); private static final Text CAR_GENERAL_FAST_FIND_TOOLTIP = translatable("ucutils.options.car.general.fast_find.tooltip"); private static final Text CAR_GENERAL_FAST_LOCK_NAME = translatable("ucutils.options.car.general.fast_lock.name"); @@ -36,26 +37,47 @@ public CarOptionsScreen(Screen parent) { @Override public void initBody() { - DirectionalLayoutWidget directionalLayoutWidget = this.layout.addBody(vertical().spacing(4)); + GridWidget gridWidget = this.layout.addBody(new GridWidget()); + gridWidget.setColumnSpacing(8).setRowSpacing(4); + GridWidget.Adder gridWidgetAdder = gridWidget.createAdder(2); - directionalLayoutWidget.add(new TextWidget(TEXT_GENERAL, this.textRenderer), Positioner::alignHorizontalCenter); + CarOptions carOptions = configuration.getOptions().car(); - DirectionalLayoutWidget directionalLayoutWidget1 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addToggleButton(directionalLayoutWidget1, CAR_GENERAL_FAST_FIND_NAME, CAR_GENERAL_FAST_FIND_TOOLTIP, (options, value) -> options.car().fastFind(value), options -> options.car().fastFind(), 150); - renderService.addToggleButton(directionalLayoutWidget1, CAR_GENERAL_FAST_LOCK_NAME, CAR_GENERAL_FAST_LOCK_TOOLTIP, (options, value) -> options.car().fastLock(value), options -> options.car().fastLock(), 150); + ToggleButtonWidget toggleButton1 = new ToggleButtonWidget(CAR_GENERAL_HIGHLIGHT_NAME, carOptions::highlight, carOptions.highlight()); + toggleButton1.setWidth(150); + toggleButton1.setTooltip(Tooltip.of(CAR_GENERAL_HIGHLIGHT_TOOLTIP)); + gridWidgetAdder.add(toggleButton1); - DirectionalLayoutWidget directionalLayoutWidget2 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addToggleButton(directionalLayoutWidget2, CAR_GENERAL_HIGHLIGHT_NAME, CAR_GENERAL_HIGHLIGHT_TOOLTIP, (options, value) -> options.car().highlight(value), options -> options.car().highlight(), 150); + ToggleButtonWidget toggleButton2 = new ToggleButtonWidget(CAR_GENERAL_FAST_FIND_NAME, carOptions::fastFind, carOptions.fastFind()); + toggleButton2.setWidth(150); + toggleButton2.setTooltip(Tooltip.of(CAR_GENERAL_FAST_FIND_TOOLTIP)); + gridWidgetAdder.add(toggleButton2); - directionalLayoutWidget.add(new TextWidget(TEXT_AUTOMATION, this.textRenderer), positioner -> positioner.alignHorizontalCenter().marginTop(16)); + ToggleButtonWidget toggleButton3 = new ToggleButtonWidget(CAR_AUTOMATION_CHECK_KFZ_NAME, carOptions::automatedCheckKfz, carOptions.automatedCheckKfz()); + toggleButton3.setWidth(150); + toggleButton3.setTooltip(Tooltip.of(CAR_AUTOMATION_CHECK_KFZ_TOOLTIP)); + gridWidgetAdder.add(toggleButton3); - DirectionalLayoutWidget directionalLayoutWidget3 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addToggleButton(directionalLayoutWidget3, CAR_AUTOMATION_LOCK_NAME, CAR_AUTOMATION_LOCK_TOOLTIP, (options, value) -> options.car().automatedLock(value), options -> options.car().automatedLock(), 150); - renderService.addToggleButton(directionalLayoutWidget3, CAR_AUTOMATION_START_NAME, CAR_AUTOMATION_START_TOOLTIP, (options, value) -> options.car().automatedStart(value), options -> options.car().automatedStart(), 150); + MultilineTextWidget multilineTextWidget = gridWidgetAdder.add(new MultilineTextWidget(CAR_PREMIUM_INFO.copy().formatted(GOLD), this.textRenderer), 2, create().alignHorizontalCenter().marginTop(16)); + multilineTextWidget.setMaxWidth(308); + multilineTextWidget.setCentered(true); - DirectionalLayoutWidget directionalLayoutWidget4 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addToggleButton(directionalLayoutWidget4, CAR_AUTOMATION_CHECK_KFZ_NAME, CAR_AUTOMATION_CHECK_KFZ_TOOLTIP, (options, value) -> options.car().automatedCheckKfz(value), options -> options.car().automatedCheckKfz(), 150); + ToggleButtonWidget toggleButton4 = new ToggleButtonWidget(CAR_GENERAL_FAST_LOCK_NAME, carOptions::fastLock, carOptions.fastLock()); + toggleButton4.setWidth(150); + toggleButton4.setTooltip(Tooltip.of(CAR_GENERAL_FAST_LOCK_TOOLTIP)); + gridWidgetAdder.add(toggleButton4); - directionalLayoutWidget.forEachChild(this::addDrawableChild); + ToggleButtonWidget toggleButton5 = new ToggleButtonWidget(CAR_AUTOMATION_LOCK_NAME, carOptions::automatedLock, carOptions.automatedLock()); + toggleButton5.setWidth(150); + toggleButton5.setTooltip(Tooltip.of(CAR_AUTOMATION_LOCK_TOOLTIP)); + gridWidgetAdder.add(toggleButton5); + + ToggleButtonWidget toggleButton6 = new ToggleButtonWidget(CAR_AUTOMATION_START_NAME, carOptions::automatedStart, carOptions.automatedStart()); + toggleButton6.setWidth(150); + toggleButton6.setTooltip(Tooltip.of(CAR_AUTOMATION_START_TOOLTIP)); + gridWidgetAdder.add(toggleButton6); + + gridWidget.refreshPositions(); + gridWidget.forEachChild(this::addDrawableChild); } } diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/MainOptionsScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/MainOptionsScreen.java index 0aa7596f..7de6605b 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/MainOptionsScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/MainOptionsScreen.java @@ -3,6 +3,7 @@ import de.rettichlp.ucutils.common.configuration.options.Options; import de.rettichlp.ucutils.common.gui.screens.OptionsScreen; import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; import net.minecraft.text.Text; @@ -22,12 +23,9 @@ public class MainOptionsScreen extends OptionsScreen { private static final Text TEXT_SOUNDS = translatable("ucutils.options.text.sounds"); private static final Text TEXT_WIDGETS = translatable("ucutils.options.text.widgets"); private static final Text TEXT_NOTIFICATIONS = translatable("ucutils.options.text.notifications"); - private static final Text TEXT_PERSONAL_USE = translatable("ucutils.options.text.personal_use"); private static final Text HYDRATION_NAME = translatable("ucutils.options.hydration.name"); private static final Text HYDRATION_TOOLTIP = translatable("ucutils.options.hydration.tooltip"); private static final Text BANK_INFORMATION_NAME = translatable("ucutils.options.atm_information.name"); - private static final Text ENRICHED_KARMA_NAME = translatable("ucutils.options.enriched_karma.name"); - private static final Text ENRICHED_KARMA_TOOLTIP = translatable("ucutils.options.enriched_karma.tooltip"); public MainOptionsScreen() { super(new GameMenuScreen(true)); @@ -41,25 +39,21 @@ public void initBody() { renderService.addCyclingButton(directionalLayoutWidget, REINFORCEMENT_STYLE_NAME, Options.ReinforcementType.values(), Options.ReinforcementType::getDisplayName, Options::reinforcementType, Options::reinforcementType, 308); DirectionalLayoutWidget directionalLayoutWidget1 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addButton(directionalLayoutWidget1, TEXT_NAMETAG, button -> this.client.setScreen(new NameTagOptionsScreen(this)), 150); - renderService.addButton(directionalLayoutWidget1, TEXT_CHAT, button -> this.client.setScreen(new ChatOptionsScreen(this)), 150); + directionalLayoutWidget1.add(ButtonWidget.builder(TEXT_NAMETAG, button -> this.client.setScreen(new NameTagOptionsScreen(this))).width(150).build()); + directionalLayoutWidget1.add(ButtonWidget.builder(TEXT_CHAT, button -> this.client.setScreen(new ChatOptionsScreen(this))).width(150).build()); DirectionalLayoutWidget directionalLayoutWidget2 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addButton(directionalLayoutWidget2, TEXT_CAR, button -> this.client.setScreen(new CarOptionsScreen(this)), 150); - renderService.addButton(directionalLayoutWidget2, TEXT_SOUNDS, button -> this.client.setScreen(new SoundOptionsScreen(this)), 150); + directionalLayoutWidget2.add(ButtonWidget.builder(TEXT_CAR, button -> this.client.setScreen(new CarOptionsScreen(this))).width(150).build()); + directionalLayoutWidget2.add(ButtonWidget.builder(TEXT_SOUNDS, button -> this.client.setScreen(new SoundOptionsScreen(this))).width(150).build()); DirectionalLayoutWidget directionalLayoutWidget3 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addButton(directionalLayoutWidget3, TEXT_WIDGETS, button -> this.client.setScreen(new WidgetOptionsScreen(this)), 150); - renderService.addButton(directionalLayoutWidget3, TEXT_NOTIFICATIONS, button -> this.client.setScreen(new NotificationOptionsScreen(this)), 150); + directionalLayoutWidget3.add(ButtonWidget.builder(TEXT_WIDGETS, button -> this.client.setScreen(new WidgetOptionsScreen(this))).width(150).build()); + directionalLayoutWidget3.add(ButtonWidget.builder(TEXT_NOTIFICATIONS, button -> this.client.setScreen(new NotificationOptionsScreen(this))).width(150).build()); DirectionalLayoutWidget directionalLayoutWidget4 = directionalLayoutWidget.add(horizontal().spacing(8)); renderService.addToggleButton(directionalLayoutWidget4, HYDRATION_NAME, HYDRATION_TOOLTIP, Options::showHydration, Options::showHydration, 150); renderService.addCyclingButton(directionalLayoutWidget4, BANK_INFORMATION_NAME, Options.AtmInformationType.values(), Options.AtmInformationType::getDisplayName, Options::atmInformationType, Options::atmInformationType, 150); - DirectionalLayoutWidget directionalLayoutWidget5 = directionalLayoutWidget.add(horizontal().spacing(8)); - renderService.addButton(directionalLayoutWidget5, TEXT_PERSONAL_USE, button -> this.client.setScreen(new PersonalUseOptionsScreen(this)), 150); - renderService.addToggleButton(directionalLayoutWidget5, ENRICHED_KARMA_NAME, ENRICHED_KARMA_TOOLTIP, Options::showEnrichedKarma, Options::showEnrichedKarma, 150); - directionalLayoutWidget.forEachChild(this::addDrawableChild); } } diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/NameTagOptionsScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/NameTagOptionsScreen.java index a504cbc7..bfcd5bff 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/NameTagOptionsScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/NameTagOptionsScreen.java @@ -14,14 +14,8 @@ public class NameTagOptionsScreen extends OptionsScreen { private static final Text TEXT_NAMETAG = translatable("ucutils.options.text.nametag"); - private static final Text NAMETAG_A_DUTY_NAME = translatable("ucutils.options.nametag.a_duty.name"); - private static final Text NAMETAG_A_DUTY_TOOLTIP = translatable("ucutils.options.nametag.a_duty.tooltip"); private static final Text NAMETAG_AFK_NAME = translatable("ucutils.options.nametag.afk.name"); private static final Text NAMETAG_AFK_TOOLTIP = translatable("ucutils.options.nametag.afk.tooltip"); - private static final Text NAMETAG_HOUSE_BAN_NAME = translatable("ucutils.options.nametag.house_ban.name"); - private static final Text NAMETAG_HOUSE_BAN_TOOLTIP = translatable("ucutils.options.nametag.house_ban.tooltip"); - private static final Text NAMETAG_OUTLAW_NAME = translatable("ucutils.options.nametag.outlaw.name"); - private static final Text NAMETAG_OUTLAW_TOOLTIP = translatable("ucutils.options.nametag.outlaw.tooltip"); private static final Text NAMETAG_MEDICAL_INFORMATION_NAME = translatable("ucutils.options.nametag.medical_information.name"); private static final Text NAMETAG_MEDICAL_INFORMATION_TOOLTIP = translatable("ucutils.options.nametag.medical_information.tooltip"); @@ -37,31 +31,16 @@ public void initBody() { NameTagOptions nameTagOptions = configuration.getOptions().nameTag(); - ToggleButtonWidget toggleButton1 = new ToggleButtonWidget(NAMETAG_A_DUTY_NAME, nameTagOptions::aDuty, nameTagOptions.aDuty()); + ToggleButtonWidget toggleButton1 = new ToggleButtonWidget(NAMETAG_AFK_NAME, nameTagOptions::afk, nameTagOptions.afk()); toggleButton1.setWidth(150); - toggleButton1.setTooltip(Tooltip.of(NAMETAG_A_DUTY_TOOLTIP)); + toggleButton1.setTooltip(Tooltip.of(NAMETAG_AFK_TOOLTIP)); gridWidgetAdder.add(toggleButton1); - ToggleButtonWidget toggleButton2 = new ToggleButtonWidget(NAMETAG_AFK_NAME, nameTagOptions::afk, nameTagOptions.afk()); + ToggleButtonWidget toggleButton2 = new ToggleButtonWidget(NAMETAG_MEDICAL_INFORMATION_NAME, nameTagOptions::medicalInformation, nameTagOptions.medicalInformation()); toggleButton2.setWidth(150); - toggleButton2.setTooltip(Tooltip.of(NAMETAG_AFK_TOOLTIP)); + toggleButton2.setTooltip(Tooltip.of(NAMETAG_MEDICAL_INFORMATION_TOOLTIP)); gridWidgetAdder.add(toggleButton2); - ToggleButtonWidget toggleButton3 = new ToggleButtonWidget(NAMETAG_HOUSE_BAN_NAME, nameTagOptions::houseBan, nameTagOptions.houseBan()); - toggleButton3.setWidth(150); - toggleButton3.setTooltip(Tooltip.of(NAMETAG_HOUSE_BAN_TOOLTIP)); - gridWidgetAdder.add(toggleButton3); - - ToggleButtonWidget toggleButton4 = new ToggleButtonWidget(NAMETAG_OUTLAW_NAME, nameTagOptions::outlaw, nameTagOptions.outlaw()); - toggleButton4.setWidth(150); - toggleButton4.setTooltip(Tooltip.of(NAMETAG_OUTLAW_TOOLTIP)); - gridWidgetAdder.add(toggleButton4); - - ToggleButtonWidget toggleButton5 = new ToggleButtonWidget(NAMETAG_MEDICAL_INFORMATION_NAME, nameTagOptions::medicalInformation, nameTagOptions.medicalInformation()); - toggleButton5.setWidth(150); - toggleButton5.setTooltip(Tooltip.of(NAMETAG_MEDICAL_INFORMATION_TOOLTIP)); - gridWidgetAdder.add(toggleButton5); - gridWidget.refreshPositions(); gridWidget.forEachChild(this::addDrawableChild); } diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/PersonalUseOptionsScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/PersonalUseOptionsScreen.java deleted file mode 100644 index e3852ce0..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/PersonalUseOptionsScreen.java +++ /dev/null @@ -1,135 +0,0 @@ -package de.rettichlp.ucutils.common.gui.screens.options; - -import de.rettichlp.ucutils.common.gui.screens.OptionsScreen; -import de.rettichlp.ucutils.common.models.InventoryItem; -import de.rettichlp.ucutils.common.models.PersonalUseEntry; -import de.rettichlp.ucutils.common.models.Purity; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.DirectionalLayoutWidget; -import net.minecraft.client.gui.widget.EmptyWidget; -import net.minecraft.client.gui.widget.Positioner; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.TextWidget; -import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.renderService; -import static java.lang.Integer.parseInt; -import static java.lang.String.valueOf; -import static java.util.Arrays.stream; -import static net.minecraft.client.gui.widget.DirectionalLayoutWidget.horizontal; -import static net.minecraft.client.gui.widget.DirectionalLayoutWidget.vertical; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; -import static net.minecraft.text.Text.translatable; - -public class PersonalUseOptionsScreen extends OptionsScreen { - - private static final Text TEXT_PERSONAL_USE = translatable("ucutils.options.text.personal_use"); - private static final Text TEXT_PURITY = translatable("ucutils.options.text.purity"); - private static final Text TEXT_AMOUNT = translatable("ucutils.options.text.amount"); - - public PersonalUseOptionsScreen(Screen parent) { - super(parent, TEXT_PERSONAL_USE); - } - - @Override - public void initBody() { - DirectionalLayoutWidget directionalLayoutWidget = this.layout.addBody(vertical().spacing(4)); - - DirectionalLayoutWidget directionalLayoutWidget1 = directionalLayoutWidget.add(horizontal().spacing(8)); - - EmptyWidget widget = new EmptyWidget(100, 0); - directionalLayoutWidget1.add(widget); - - TextWidget widget1 = new TextWidget(TEXT_PURITY, this.textRenderer); - widget1.setWidth(96); - directionalLayoutWidget1.add(widget1, positioner -> positioner.alignVerticalCenter().alignHorizontalCenter()); - - TextWidget widget2 = new TextWidget(TEXT_AMOUNT, this.textRenderer); - widget2.setWidth(96); - directionalLayoutWidget1.add(widget2, positioner -> positioner.alignVerticalCenter().alignHorizontalCenter()); - - stream(InventoryItem.values()) - .filter(InventoryItem::isDrugBankItem) - .forEach(inventoryItem -> directionalLayoutWidget.add(personalUseRow(inventoryItem))); - - directionalLayoutWidget.forEachChild(this::addDrawableChild); - } - - private @NotNull DirectionalLayoutWidget personalUseRow(@NotNull InventoryItem inventoryItem) { - PersonalUseEntry personalUseEntry = configuration.getOptions().personalUse().stream() - .filter(oue -> oue.getInventoryItem() == inventoryItem) - .findFirst() - .orElseGet(() -> new PersonalUseEntry(inventoryItem)); - - DirectionalLayoutWidget directionalLayoutWidget = horizontal().spacing(8); - - // text - TextWidget widget = new TextWidget(translatable("ucutils.inventory." + inventoryItem.name().toLowerCase()), this.textRenderer); - widget.setWidth(100); - // FIXME widget.alignLeft(); - directionalLayoutWidget.add(widget, Positioner::alignVerticalCenter); - - // purity input - renderService.addCyclingButton(directionalLayoutWidget, TEXT_PURITY, Purity.values(), Purity::getDisplayName, (options, value) -> updatePersonalUseEntry(personalUseEntry, value), options -> personalUseEntry.getPurity(), 96); - - // amount input - DirectionalLayoutWidget widget2 = personalUseInput(personalUseEntry); - directionalLayoutWidget.add(widget2); - - return directionalLayoutWidget; - } - - private @NotNull DirectionalLayoutWidget personalUseInput(@NotNull PersonalUseEntry personalUseEntry) { - DirectionalLayoutWidget directionalLayoutWidget = horizontal(); - - TextFieldWidget widget = new TextFieldWidget(this.textRenderer, 40, 20, empty()); - widget.setWidth(80); - widget.setChangedListener(value -> updatePersonalUseEntry(personalUseEntry, value)); - widget.setEditable(true); - widget.setPlaceholder(of(valueOf(personalUseEntry.getAmount()))); - - TextWidget widget1 = new TextWidget(of(" g"), this.textRenderer); - widget1.setWidth(16); - // FIXME widget1.alignLeft(); - - directionalLayoutWidget.add(widget); - directionalLayoutWidget.add(widget1, Positioner::alignVerticalCenter); - - return directionalLayoutWidget; - } - - private void updatePersonalUseEntry(@NotNull PersonalUseEntry personalUseEntry, Purity newPurity) { - personalUseEntry.setPurity(newPurity); - List personalUseEntries = configuration.getOptions().personalUse(); - personalUseEntries.removeIf(pue -> pue.getInventoryItem() == personalUseEntry.getInventoryItem()); - personalUseEntries.add(personalUseEntry); - } - - private void updatePersonalUseEntry(@NotNull PersonalUseEntry personalUseEntry, String newAmount) { - int parsedInt; - - try { - parsedInt = parseInt(newAmount); - } catch (NumberFormatException e) { - LOGGER.warn("Could not parse personal use amount: {}", newAmount); - parsedInt = -1; - } - - // skip config edit if the amount did not change or is negative - if (parsedInt == personalUseEntry.getAmount() || parsedInt < 0) { - LOGGER.info("Skipping personal use config edit, amount did not change or is negative (newAmount: {}, currentAmount: {})", parsedInt, personalUseEntry.getAmount()); - return; - } - - personalUseEntry.setAmount(parsedInt); - List personalUseEntries = configuration.getOptions().personalUse(); - personalUseEntries.removeIf(pue -> pue.getInventoryItem() == personalUseEntry.getInventoryItem()); - personalUseEntries.add(personalUseEntry); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsPositionScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsPositionScreen.java index 7ca7a5f3..694478ae 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsPositionScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsPositionScreen.java @@ -6,6 +6,7 @@ import net.minecraft.client.gui.Click; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; import net.minecraft.client.util.Window; import net.minecraft.text.Text; @@ -39,16 +40,16 @@ public WidgetOptionsPositionScreen(Screen parent) { public void initBody() { DirectionalLayoutWidget directionalLayoutWidget = this.layout.addBody(horizontal().spacing(8), positioner -> positioner.marginTop(this.client.getWindow().getScaledHeight() / 4)); - renderService.addButton(directionalLayoutWidget, DONE, button -> { + directionalLayoutWidget.add(ButtonWidget.builder(DONE, button -> { renderService.getWidgets().forEach(AbstractUCUtilsWidget::saveConfiguration); back(); - }, 150); + }).width(150).build()); - renderService.addButton(directionalLayoutWidget, CANCEL, button -> { + directionalLayoutWidget.add(ButtonWidget.builder(CANCEL, button -> { // restore configurations from the configuration file renderService.getWidgets().forEach(AbstractUCUtilsWidget::loadConfiguration); back(); - }, 150); + }).width(150).build()); directionalLayoutWidget.forEachChild(this::addDrawableChild); } diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsScreen.java b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsScreen.java index 4652132b..be8b47ee 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsScreen.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/screens/options/WidgetOptionsScreen.java @@ -7,6 +7,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.tooltip.Tooltip; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; import net.minecraft.client.gui.widget.GridWidget; import net.minecraft.client.gui.widget.Positioner; @@ -40,7 +41,7 @@ public void initBody() { // general directionalLayoutWidget.add(new TextWidget(TEXT_GENERAL, this.textRenderer), Positioner::alignHorizontalCenter); - renderService.addButton(directionalLayoutWidget, TEXT_POSITION, button -> this.client.setScreen(new WidgetOptionsPositionScreen(this)), 308); + directionalLayoutWidget.add(ButtonWidget.builder(TEXT_POSITION, button -> this.client.setScreen(new WidgetOptionsPositionScreen(this))).width(308).build()); // general - enable status GridWidget gridWidget = directionalLayoutWidget.add(new GridWidget()); diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/widgets/CarLockedWidget.java b/src/main/java/de/rettichlp/ucutils/common/gui/widgets/CarLockedWidget.java index 492fe0b0..83f0486b 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/widgets/CarLockedWidget.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/widgets/CarLockedWidget.java @@ -37,9 +37,9 @@ public Text text() { return getWidgetConfiguration().getStyle() == MINIMALISTIC ? (storage.isCarLocked() ? of("🔒").copy().formatted(GREEN) : of("🔓").copy().formatted(GOLD)) : empty() - .append(of("Fahrzeug").copy().formatted(GRAY)) - .append(of(":").copy().formatted(DARK_GRAY)).append(" ") - .append(storage.isCarLocked() ? of("zu").copy().formatted(GREEN) : of("offen").copy().formatted(GOLD)); + .append(of("Fahrzeug").copy().formatted(GRAY)) + .append(of(":").copy().formatted(DARK_GRAY)).append(" ") + .append(storage.isCarLocked() ? of("zu").copy().formatted(GREEN) : of("offen").copy().formatted(GOLD)); } @Override diff --git a/src/main/java/de/rettichlp/ucutils/common/gui/widgets/MoneyWidget.java b/src/main/java/de/rettichlp/ucutils/common/gui/widgets/MoneyWidget.java index e70c4d0a..3411898e 100644 --- a/src/main/java/de/rettichlp/ucutils/common/gui/widgets/MoneyWidget.java +++ b/src/main/java/de/rettichlp/ucutils/common/gui/widgets/MoneyWidget.java @@ -20,11 +20,11 @@ public Text text() { // with over 100.000$ on bank and PayDay within next 5 minutes, animate text return configuration.getMinutesSinceLastPayDay() >= 55 && configuration.getMoneyBankAmount() > 100000 && (currentTimeMillis() / 500 % 2 == 0) ? empty() - .append(keyValue("Geld", configuration.getMoneyCashAmount() + "$")).append(" ") - .append(keyValue("Bank", configuration.getMoneyBankAmount() + "$").withColor(RED.getRGB())) + .append(keyValue("Geld", configuration.getMoneyCashAmount() + "$")).append(" ") + .append(keyValue("Bank", configuration.getMoneyBankAmount() + "$").withColor(RED.getRGB())) : empty() - .append(keyValue("Geld", configuration.getMoneyCashAmount() + "$")).append(" ") - .append(keyValue("Bank", configuration.getMoneyBankAmount() + "$")); + .append(keyValue("Geld", configuration.getMoneyCashAmount() + "$")).append(" ") + .append(keyValue("Bank", configuration.getMoneyBankAmount() + "$")); } @Override diff --git a/src/main/java/de/rettichlp/ucutils/common/models/BlackMarket.java b/src/main/java/de/rettichlp/ucutils/common/models/BlackMarket.java deleted file mode 100644 index 38907fe7..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/BlackMarket.java +++ /dev/null @@ -1,97 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.time.Duration; -import java.time.LocalDateTime; - -import static java.time.LocalDateTime.now; -import static java.util.Objects.isNull; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.DARK_GRAY; -import static net.minecraft.util.Formatting.DARK_GREEN; -import static net.minecraft.util.Formatting.GOLD; -import static net.minecraft.util.Formatting.GRAY; -import static net.minecraft.util.Formatting.GREEN; -import static net.minecraft.util.Formatting.RED; -import static net.minecraft.util.Formatting.YELLOW; - -@Getter -@AllArgsConstructor -public class BlackMarket { - - private final Type type; - @Nullable - private final LocalDateTime visitedAt; - private boolean found; // whether the black market was found or not - - public Text getText() { - return empty() - .styled(style -> style - .withHoverEvent(new HoverEvent.ShowText(of("Klicke, um die Navigation zu starten").copy().formatted(GOLD))) - .withClickEvent(new ClickEvent.RunCommand(this.type.getNavigationCommand()))) - .append(of(this.type.getDisplayName())).append(" ") - .append(of("(").copy().formatted(DARK_GRAY)) - .append(of("Besucht:").copy().formatted(GRAY)).append(" ") - .append(getLastVisitedText()) - .append(of(")").copy().formatted(DARK_GRAY)) - .append(this.found ? of(" ←").copy().formatted(GREEN) : empty()); - } - - private Text getLastVisitedText() { - if (isNull(this.visitedAt)) { - return of("Nie").copy().formatted(GRAY); - } - - Duration duration = Duration.between(this.visitedAt, now()); - long minutes = duration.toMinutes(); - - if (minutes >= 60) { - return of("vor über einer Stunde").copy().formatted(RED); - } - - if (minutes == 0) { - return of("Jetzt").copy().formatted(DARK_GREEN); - } - - return of("vor " + minutes + (minutes == 1 ? " Minute" : " Minuten")).copy().formatted(YELLOW); - } - - @Getter - @AllArgsConstructor - public enum Type { - - JAIL("Gefängnis", -777, 64, 143), - PANEL_BUILDING("Plattenbau", 470, 69, 424), - AIRPORT("Flughafen", -292, 69, 636), - SH_PARK("Park an der Stadthalle", 58, 70, 355), - FARM("Farm", 427, 82, 512), - CINEMA("Kino", 770, 68, 331), - CHURCH("Wohnwagen an der Kirche", -304, 71, -206), - SUBWAY_MEXICAN("U-Bahn (Mexikanisches Kartell)", -94, 51, -34); - - private final String displayName; - private final int x; - private final int y; - private final int z; - - @Contract(pure = true) - public @NotNull String getNavigationCommand() { - return "/navi " + this.x + "/" + this.y + "/" + this.z; - } - - @Contract(value = " -> new", pure = true) - public @NotNull BlockPos getBlockPos() { - return new BlockPos(this.x, this.y, this.z); - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/BlacklistEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/BlacklistEntry.java deleted file mode 100644 index 7de0f763..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/BlacklistEntry.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.Getter; - -@Getter -public class BlacklistEntry extends BlacklistReason { - - private final String playerName; - - public BlacklistEntry(String playerName, String reason, boolean outlaw, int kills, int price) { - super(reason, outlaw, kills, price); - this.playerName = playerName; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/BlacklistReason.java b/src/main/java/de/rettichlp/ucutils/common/models/BlacklistReason.java deleted file mode 100644 index c871d5f2..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/BlacklistReason.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class BlacklistReason { - - private final String reason; - private final boolean outlaw; - private int kills; - private int price; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/ContractEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/ContractEntry.java deleted file mode 100644 index 77dd3cc9..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/ContractEntry.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class ContractEntry { - - private String playerName; - private int price; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/Dealer.java b/src/main/java/de/rettichlp/ucutils/common/models/Dealer.java deleted file mode 100644 index 77ca9000..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/Dealer.java +++ /dev/null @@ -1,95 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.time.Duration; -import java.time.LocalDateTime; - -import static java.time.LocalDateTime.now; -import static java.util.Objects.isNull; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.DARK_GRAY; -import static net.minecraft.util.Formatting.DARK_GREEN; -import static net.minecraft.util.Formatting.GOLD; -import static net.minecraft.util.Formatting.GRAY; -import static net.minecraft.util.Formatting.GREEN; -import static net.minecraft.util.Formatting.RED; -import static net.minecraft.util.Formatting.YELLOW; - -@Getter -@AllArgsConstructor -public class Dealer { - - private final Type type; - @Nullable - private final LocalDateTime visitedAt; - private boolean found; // whether the dealer was found or not - - public Text getText() { - return empty() - .styled(style -> style - .withHoverEvent(new HoverEvent.ShowText(of("Klicke, um die Navigation zu starten").copy().formatted(GOLD))) - .withClickEvent(new ClickEvent.RunCommand(this.type.getNavigationCommand()))) - .append(of(this.type.getDisplayName())).append(" ") - .append(of("(").copy().formatted(DARK_GRAY)) - .append(of("Besucht:").copy().formatted(GRAY)).append(" ") - .append(getLastVisitedText()) - .append(of(")").copy().formatted(DARK_GRAY)) - .append(this.found ? of(" ←").copy().formatted(GREEN) : empty()); - } - - private Text getLastVisitedText() { - if (isNull(this.visitedAt)) { - return of("Nie").copy().formatted(GRAY); - } - - Duration duration = Duration.between(this.visitedAt, now()); - long minutes = duration.toMinutes(); - - if (minutes >= 60) { - return of("vor über einer Stunde").copy().formatted(RED); - } - - if (minutes == 0) { - return of("Jetzt").copy().formatted(DARK_GREEN); - } - - return of("vor " + minutes + (minutes == 1 ? " Minute" : " Minuten")).copy().formatted(YELLOW); - } - - @Getter - @AllArgsConstructor - public enum Type { - - PAPER_COMPANY("Papierfabrik", -37, 70, -279), - HARBOR("Hafen", -417, 69, 185), - MEXICAN("Wohnwagen (Mex)", -381, 69, -198), - WINE_MAKER("Winzer", -2, 88, 598), - ALTSTADT("Altstadt", 0, 0, 0), - AIRPORT("Flughafen", -93, 64, 924); - - private final String displayName; - private final int x; - private final int y; - private final int z; - - @Contract(pure = true) - public @NotNull String getNavigationCommand() { - return "/navi " + this.x + "/" + this.y + "/" + this.z; - } - - @Contract(value = " -> new", pure = true) - public @NotNull BlockPos getBlockPos() { - return new BlockPos(this.x, this.y, this.z); - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/Faction.java b/src/main/java/de/rettichlp/ucutils/common/models/Faction.java index ef8b3d53..9cdd445d 100644 --- a/src/main/java/de/rettichlp/ucutils/common/models/Faction.java +++ b/src/main/java/de/rettichlp/ucutils/common/models/Faction.java @@ -52,9 +52,9 @@ public enum Faction { public Text getNameTagSuffix() { return this != NULL ? empty() - .append(literal("⌜").copy().formatted(DARK_GRAY)) - .append(literal(this.icon).copy().formatted(this.color)) - .append(literal("⌟").copy().formatted(DARK_GRAY)) + .append(literal("⌜").copy().formatted(DARK_GRAY)) + .append(literal(this.icon).copy().formatted(this.color)) + .append(literal("⌟").copy().formatted(DARK_GRAY)) : empty(); } diff --git a/src/main/java/de/rettichlp/ucutils/common/models/HousebanEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/HousebanEntry.java deleted file mode 100644 index 2639b4d5..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/HousebanEntry.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -@Data -@AllArgsConstructor -public class HousebanEntry { - - private String playerName; - private List reasons; - private LocalDateTime unbanDateTime; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/Ingredient.java b/src/main/java/de/rettichlp/ucutils/common/models/Ingredient.java deleted file mode 100644 index a22fe3fd..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/Ingredient.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NonNull; - -import java.util.Optional; - -import static java.util.Arrays.stream; - -@Getter -@AllArgsConstructor -public enum Ingredient { - - POWDER("Pulver", true, true), - HERBS("Kräuter", true, true), - MEDICINAL_HERBS("Medizinische Kräuter"), - CRYSTALS("Kristalle", true, true), - SURPRISE_BAG("Wundertüte", false, true), - COUGH_SYRUP("Hustensaft"), - PAINKILLERS("Schmerzmittel"), - ANTIBIOTICS("Antibiotika"), - MASK("Maske"), - IRON("Eisen"), - GUNPOWDER("Schwarzpulver"), - KEVLAR_FIBERS("Kevlarfasern"); - - private final String displayName; - private final boolean purity; - private final boolean drugBankDropable; - - Ingredient(String displayName) { - this.displayName = displayName; - this.purity = false; - this.drugBankDropable = false; - } - - public static @NonNull Optional fromDisplayName(String displayName) { - return stream(values()) - .filter(ingredient -> ingredient.getDisplayName().equals(displayName)) - .findFirst(); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/InventoryItem.java b/src/main/java/de/rettichlp/ucutils/common/models/InventoryItem.java deleted file mode 100644 index 406fbf2e..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/InventoryItem.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum InventoryItem { - - // drugs - POWDER("Pulver", true), - HERBS("Kräuter", true), - CRYSTALS("Kristalle", true), - GRAB_BAG("Wundertüte", true), - - // medical - COUGH_SYRUP("Hustensaft", false), - PAINKILLERS("Schmerzmittel", false), - ANTIBIOTICS("Antibiotika", false), - - // other - MASK("Maske", false), - GUN_POWDER("Schwarzpulver", false), - IRON("Eisen", false); - - private final String displayName; - private final boolean drugBankItem; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/PersonalUseEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/PersonalUseEntry.java deleted file mode 100644 index 10af3db2..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/PersonalUseEntry.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.Data; - -import static de.rettichlp.ucutils.common.models.Purity.BEST; - -@Data -public class PersonalUseEntry { - - private final InventoryItem inventoryItem; - private Purity purity = BEST; - private int amount = 0; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/PlantEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/PlantEntry.java deleted file mode 100644 index db0a6c80..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/PlantEntry.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.Data; -import lombok.RequiredArgsConstructor; -import net.minecraft.util.math.BlockPos; - -import java.time.LocalDateTime; - -@Data -@RequiredArgsConstructor -public class PlantEntry { - - private final BlockPos blockPos; - private final LocalDateTime plantedAt; - private LocalDateTime lastWateredAt; - private LocalDateTime lastFertilizedAt; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/Purity.java b/src/main/java/de/rettichlp/ucutils/common/models/Purity.java deleted file mode 100644 index c9f611b1..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/Purity.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import de.rettichlp.ucutils.common.gui.screens.components.CyclingButtonEntry; -import lombok.AllArgsConstructor; -import lombok.Getter; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.text.Text; - -import static net.minecraft.text.Text.translatable; -import static net.minecraft.util.Formatting.DARK_GREEN; -import static net.minecraft.util.Formatting.GREEN; -import static net.minecraft.util.Formatting.RED; -import static net.minecraft.util.Formatting.YELLOW; - -@Getter -@AllArgsConstructor -public enum Purity implements CyclingButtonEntry { - - BEST(translatable("ucutils.purity.best").formatted(DARK_GREEN)), - GOOD(translatable("ucutils.purity.good").formatted(GREEN)), - MEDIUM(translatable("ucutils.purity.medium").formatted(YELLOW)), - BAD(translatable("ucutils.purity.bad").formatted(RED)); - - private final Text displayName; - - @Override - public Tooltip getTooltip() { - return Tooltip.of(this.displayName); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/common/models/Reinforcement.java b/src/main/java/de/rettichlp/ucutils/common/models/Reinforcement.java deleted file mode 100644 index 1c36abb8..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/Reinforcement.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.Data; -import net.minecraft.util.math.BlockPos; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import static java.time.LocalDateTime.now; - -@Data -public class Reinforcement { - - private final LocalDateTime createdAt = now(); - private final List acceptedPlayerNames = new ArrayList<>(); - private final String type; - private final String senderPlayerName; - private final String naviPoint; - private final String distance; - private BlockPos blockPos; - private boolean addedAsActivity; -} diff --git a/src/main/java/de/rettichlp/ucutils/common/registry/Registry.java b/src/main/java/de/rettichlp/ucutils/common/registry/Registry.java index ef379c50..0f7ddb74 100644 --- a/src/main/java/de/rettichlp/ucutils/common/registry/Registry.java +++ b/src/main/java/de/rettichlp/ucutils/common/registry/Registry.java @@ -3,53 +3,31 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.rettichlp.ucutils.common.models.Sound; -import de.rettichlp.ucutils.listener.IAbsorptionGetListener; -import de.rettichlp.ucutils.listener.IBlockRightClickListener; import de.rettichlp.ucutils.listener.ICommandSendListener; -import de.rettichlp.ucutils.listener.IEnterVehicleListener; -import de.rettichlp.ucutils.listener.IEntityRenderListener; -import de.rettichlp.ucutils.listener.IEntityRightClickListener; import de.rettichlp.ucutils.listener.IHudRenderListener; -import de.rettichlp.ucutils.listener.IKeyPressListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; import de.rettichlp.ucutils.listener.IMessageSendListener; -import de.rettichlp.ucutils.listener.IMoveListener; import de.rettichlp.ucutils.listener.INaviSpotReachedListener; -import de.rettichlp.ucutils.listener.IScreenOpenListener; import de.rettichlp.ucutils.listener.ITickListener; import de.rettichlp.ucutils.listener.IUCUtilsListener; -import de.rettichlp.ucutils.listener.callback.PlayerEnterVehicleCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; -import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderEvents; -import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; -import net.fabricmc.fabric.api.event.player.UseBlockCallback; -import net.fabricmc.fabric.api.event.player.UseEntityCallback; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.NotNull; import java.util.Objects; import java.util.Set; import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static java.util.Collections.emptySet; -import static java.util.Objects.isNull; -import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.toSet; import static java.util.stream.StreamSupport.stream; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; -import static net.minecraft.entity.effect.StatusEffects.ABSORPTION; import static net.minecraft.registry.Registries.SOUND_EVENT; import static net.minecraft.registry.Registry.register; -import static net.minecraft.util.ActionResult.PASS; -import static net.minecraft.util.Hand.OFF_HAND; import static org.atteo.classindex.ClassIndex.getAnnotated; public class Registry { @@ -59,8 +37,6 @@ public class Registry { private final Set listenerInstances = getListenerInstances(); private boolean initialized = false; - private BlockPos lastPlayerPos = null; - private boolean lastAbsorptionState = false; public void registerSounds() { for (Sound value : Sound.values()) { @@ -138,59 +114,10 @@ public void registerListeners() { return executeCommand; }); - ClientTickEvents.END_CLIENT_TICK.register((server) -> { - // handle tick - getListenersImplementing(ITickListener.class).forEach(ITickListener::onTick); - - // handle on move - BlockPos blockPos = player.getBlockPos(); - if (isNull(this.lastPlayerPos) || !this.lastPlayerPos.equals(blockPos)) { - this.lastPlayerPos = blockPos; - getListenersImplementing(IMoveListener.class).forEach(iMoveListener -> iMoveListener.onMove(blockPos)); - } - - // handle absorption - boolean hasAbsorption = ofNullable(player) - .map(clientPlayerEntity -> clientPlayerEntity.hasStatusEffect(ABSORPTION)) - .orElse(false); - - if (!this.lastAbsorptionState && hasAbsorption) { - getListenersImplementing(IAbsorptionGetListener.class).forEach(IAbsorptionGetListener::onAbsorptionGet); - } - - this.lastAbsorptionState = hasAbsorption; - - // handle key press - KeyBinding swapHandsKey = MinecraftClient.getInstance().options.swapHandsKey; - if (swapHandsKey.isPressed()) { - getListenersImplementing(IKeyPressListener.class).forEach(IKeyPressListener::onSwapHandsKeyPress); - } - }); + ClientTickEvents.END_CLIENT_TICK.register((server) -> getListenersImplementing(ITickListener.class).forEach(ITickListener::onTick)); HudRenderCallback.EVENT.register((drawContext, tickCounter) -> getListenersImplementing(IHudRenderListener.class).forEach(iHudRenderListener -> iHudRenderListener.onHudRender(drawContext, tickCounter))); - PlayerEnterVehicleCallback.EVENT.register(vehicle -> getListenersImplementing(IEnterVehicleListener.class).forEach(iEnterVehicleListener -> iEnterVehicleListener.onEnterVehicle(vehicle))); - - ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> getListenersImplementing(IScreenOpenListener.class).forEach(iScreenOpenListener -> iScreenOpenListener.onScreenOpen(screen, scaledWidth, scaledHeight))); - - UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> { - if (hand != OFF_HAND && world.isClient()) { - getListenersImplementing(IBlockRightClickListener.class).forEach(iBlockRightClickListener -> iBlockRightClickListener.onBlockRightClick(world, hand, hitResult)); - } - - return PASS; - }); - - UseEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> { - if (hand != OFF_HAND && world.isClient()) { - getListenersImplementing(IEntityRightClickListener.class).forEach(iEntityRightClickListener -> iEntityRightClickListener.onEntityRightClick(world, hand, entity, hitResult)); - } - - return PASS; - }); - - WorldRenderEvents.AFTER_ENTITIES.register(context -> getListenersImplementing(IEntityRenderListener.class).forEach(iEntityRenderListener -> iEntityRenderListener.onEntityRender(context))); - // prevent multiple registrations of listeners this.initialized = true; } @@ -212,9 +139,9 @@ public void registerListeners() { private Set getListenersImplementing(Class listenerInterface) { return storage.isUnicaCity() ? this.listenerInstances.stream() - .filter(listenerInterface::isInstance) - .map(listenerInterface::cast) - .collect(toSet()) + .filter(listenerInterface::isInstance) + .map(listenerInterface::cast) + .collect(toSet()) : emptySet(); } } diff --git a/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java b/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java index 7dedc38e..a6a00ca4 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java @@ -9,19 +9,15 @@ import java.util.Map; import java.util.Timer; import java.util.TimerTask; -import java.util.function.Consumer; import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.messageService; import static de.rettichlp.ucutils.UCUtils.nameTagService; import static de.rettichlp.ucutils.UCUtils.networkHandler; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; import static java.lang.Boolean.getBoolean; import static java.lang.System.currentTimeMillis; import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; public class CommandService { @@ -90,11 +86,4 @@ public boolean showCommandOutputMessage(String command) { public boolean isSuperUser() { return nonNull(player) && (UUID_RETTICHLP.equals(player.getUuidAsString()) || getBoolean("fabric.development")); } - - public void retrieveNumberAndRun(String playerName, Consumer runWithNumber) { - sendCommand("nummer " + playerName); - - utilService.delayedAction(() -> ofNullable(storage.getRetrievedNumbers().get(playerName)) - .ifPresentOrElse(runWithNumber, () -> messageService.sendModMessage("Die Nummer von " + playerName + " konnte nicht abgerufen werden.", false)), COMMAND_COOLDOWN_MILLIS); - } } diff --git a/src/main/java/de/rettichlp/ucutils/common/services/NameTagService.java b/src/main/java/de/rettichlp/ucutils/common/services/NameTagService.java index b29936f4..462fe6c7 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/NameTagService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/NameTagService.java @@ -29,14 +29,8 @@ public class NameTagService { - public static final MutableText A_DUTY_TAG = empty() - .append(literal("ᴀ").formatted(BLUE, BOLD)) - .append(literal("ᴅᴜᴛʏ").formatted(RED, BOLD)); - public static final MutableText AFK_TAG = literal("ᴀꜰᴋ").formatted(GOLD, BOLD); - public static final MutableText HOUSE_BAN_TAG = literal("Hᴀᴜѕᴠᴇʀʙᴏᴛ").formatted(RED, BOLD); - private static final MutableText A_DUTY_PREFIX = empty() .append(literal("[").formatted(DARK_GRAY)) .append(literal("UC").formatted(BLUE)) diff --git a/src/main/java/de/rettichlp/ucutils/common/services/RenderService.java b/src/main/java/de/rettichlp/ucutils/common/services/RenderService.java index 06c25dd1..067cc9cd 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/RenderService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/RenderService.java @@ -6,16 +6,9 @@ import de.rettichlp.ucutils.common.gui.widgets.base.AbstractUCUtilsWidget; import de.rettichlp.ucutils.common.gui.widgets.base.UCUtilsWidget; import lombok.Getter; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.CyclingButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; @@ -29,8 +22,6 @@ import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toCollection; import static java.util.stream.StreamSupport.stream; -import static net.minecraft.client.font.TextRenderer.TextLayerType.SEE_THROUGH; -import static net.minecraft.util.math.RotationAxis.POSITIVE_Y; import static org.atteo.classindex.ClassIndex.getAnnotated; public class RenderService { @@ -40,50 +31,6 @@ public class RenderService { @Getter private LinkedHashSet> widgets = new LinkedHashSet<>(); - public void renderTextAboveEntity(@NotNull MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - @NotNull Entity entity, - Text text, - float scale) { - renderTextAt(matrices, vertexConsumers, entity.getX(), entity.getY() + 1.35, entity.getZ(), text, scale); - } - - public void renderTextAt(@NotNull MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - double x, - double y, - double z, - Text text, - float scale) { - // save the current matrix state - matrices.push(); - - Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); - double camX = camera.getPos().x; - double camY = camera.getPos().y; - double camZ = camera.getPos().z; - - matrices.translate(x - camX, y - camY, z - camZ); - - // make the text face the camera - matrices.multiply(camera.getRotation()); - matrices.multiply(POSITIVE_Y.rotationDegrees(180.0F)); - - // scale the text down so it's not too big - matrices.scale(-scale, -scale, scale); - - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - // calculate the width of the text to center it - float textWidth = -textRenderer.getWidth(text) / 2.0F; - - // render the text - textRenderer.draw(text, textWidth, 0.0F, 0xFFFFFFFF, false, matrices.peek().getPositionMatrix(), vertexConsumers, SEE_THROUGH, 0x55000000, 0xF000F0); - - // restore the previous matrix state - matrices.pop(); - } - public Color getSecondaryColor(@NotNull Color color) { return new Color(color.getRed() / 2, color.getGreen() / 2, color.getBlue() / 2, 100); } @@ -103,18 +50,6 @@ public void initializeWidgets() { .collect(toCollection(LinkedHashSet::new)); } - public void addButton(@NotNull DirectionalLayoutWidget widget, - Text name, - ButtonWidget.PressAction onPress, - int width) { - ButtonWidget buttonWidget = ButtonWidget.builder(name, onPress) - .build(); - - buttonWidget.setWidth(width); - - widget.add(buttonWidget); - } - public void addCyclingButton(@NotNull DirectionalLayoutWidget widget, Text name, E[] values, diff --git a/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java b/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java index 8462f7f6..7488bdd0 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java @@ -73,12 +73,7 @@ public void syncFactionSpecificData() { Faction faction = storage.getFaction(player.getStringifiedName()); switch (faction) { case FBI, POLIZEI -> commandService.sendCommandWithHiddenOutput("wanteds"); - case MERCENARY -> commandService.sendCommandWithHiddenOutput("contractlist"); - case RETTUNGSDIENST -> commandService.sendCommandWithHiddenOutput("hausverbot"); default -> { - if (faction.isBadFaction()) { - commandService.sendCommandWithHiddenOutput("blacklist"); - } } } } diff --git a/src/main/java/de/rettichlp/ucutils/listener/IAbsorptionGetListener.java b/src/main/java/de/rettichlp/ucutils/listener/IAbsorptionGetListener.java deleted file mode 100644 index 558cba50..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IAbsorptionGetListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.rettichlp.ucutils.listener; - -public interface IAbsorptionGetListener extends IUCUtilsListener { - - void onAbsorptionGet(); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IBlockRightClickListener.java b/src/main/java/de/rettichlp/ucutils/listener/IBlockRightClickListener.java deleted file mode 100644 index c5487c68..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IBlockRightClickListener.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.world.World; - -public interface IBlockRightClickListener extends IUCUtilsListener { - - void onBlockRightClick(World world, Hand hand, BlockHitResult hitResult); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IEnterVehicleListener.java b/src/main/java/de/rettichlp/ucutils/listener/IEnterVehicleListener.java deleted file mode 100644 index 70e82649..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IEnterVehicleListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.minecraft.entity.Entity; - -public interface IEnterVehicleListener extends IUCUtilsListener { - - void onEnterVehicle(Entity vehicle); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IEntityRenderListener.java b/src/main/java/de/rettichlp/ucutils/listener/IEntityRenderListener.java deleted file mode 100644 index 2538ff86..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IEntityRenderListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderContext; - -public interface IEntityRenderListener extends IUCUtilsListener { - - void onEntityRender(WorldRenderContext context); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IEntityRightClickListener.java b/src/main/java/de/rettichlp/ucutils/listener/IEntityRightClickListener.java deleted file mode 100644 index ccc0ac9d..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IEntityRightClickListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.minecraft.entity.Entity; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.world.World; - -public interface IEntityRightClickListener extends IUCUtilsListener { - - void onEntityRightClick(World world, Hand hand, Entity entity, EntityHitResult hitResult); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IKeyPressListener.java b/src/main/java/de/rettichlp/ucutils/listener/IKeyPressListener.java deleted file mode 100644 index 4badaba5..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IKeyPressListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.rettichlp.ucutils.listener; - -public interface IKeyPressListener extends IUCUtilsListener { - - void onSwapHandsKeyPress(); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IMoveListener.java b/src/main/java/de/rettichlp/ucutils/listener/IMoveListener.java deleted file mode 100644 index 8777bb08..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IMoveListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.minecraft.util.math.BlockPos; - -public interface IMoveListener extends IUCUtilsListener { - - void onMove(BlockPos blockPos); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/IScreenOpenListener.java b/src/main/java/de/rettichlp/ucutils/listener/IScreenOpenListener.java deleted file mode 100644 index 0a501bcf..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/IScreenOpenListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.rettichlp.ucutils.listener; - -import net.minecraft.client.gui.screen.Screen; - -public interface IScreenOpenListener extends IUCUtilsListener { - - void onScreenOpen(Screen screen, int scaledWidth, int scaledHeight); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/callback/PlayerEnterVehicleCallback.java b/src/main/java/de/rettichlp/ucutils/listener/callback/PlayerEnterVehicleCallback.java deleted file mode 100644 index 5978084d..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/callback/PlayerEnterVehicleCallback.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.rettichlp.ucutils.listener.callback; - -import net.fabricmc.fabric.api.event.Event; -import net.minecraft.entity.Entity; - -import static net.fabricmc.fabric.api.event.EventFactory.createArrayBacked; - -public interface PlayerEnterVehicleCallback { - - Event EVENT = createArrayBacked(PlayerEnterVehicleCallback.class, listeners -> vehicle -> { - for (PlayerEnterVehicleCallback listener : listeners) { - listener.onEnter(vehicle); - } - }); - - void onEnter(Entity vehicle); -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/CarListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/CarListener.java index 5f83a8b6..1a724662 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/CarListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/CarListener.java @@ -1,81 +1,26 @@ package de.rettichlp.ucutils.listener.impl; import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IEnterVehicleListener; -import de.rettichlp.ucutils.listener.IEntityRenderListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import de.rettichlp.ucutils.listener.IScreenOpenListener; -import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderContext; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.vehicle.MinecartEntity; import net.minecraft.text.Text; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static de.rettichlp.ucutils.UCUtils.LOGGER; import static de.rettichlp.ucutils.UCUtils.commandService; import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.renderService; import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; import static java.lang.Integer.parseInt; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; import static java.util.regex.Pattern.compile; -import static net.minecraft.screen.slot.SlotActionType.PICKUP; -import static net.minecraft.util.Formatting.AQUA; @UCUtilsListener -public class CarListener - implements IEnterVehicleListener, IEntityRenderListener, IMessageReceiveListener, IScreenOpenListener { +public class CarListener implements IMessageReceiveListener { private static final Pattern CAR_UNLOCK_PATTERN = compile("^\\[Car] Du hast deinen .+ aufgeschlossen\\.$"); private static final Pattern CAR_LOCK_PATTERN = compile("^\\[Car] Du hast deinen .+ abgeschlossen\\.$"); private static final Pattern CAR_LOCKED_OWN_PATTERN = compile("^\\[Car] Dein Fahrzeug ist abgeschlossen\\.$"); private static final Pattern CAR_FIND_PATTERN = compile("^\\[Car] Das Fahrzeug befindet sich bei » X: (?-?\\d+) \\| Y: (?-?\\d+) \\| Z: (?-?\\d+)$"); - @Override - public void onEnterVehicle(Entity vehicle) { - // the entity is a car - if (!(vehicle instanceof MinecartEntity)) { - return; - } - - storage.setMinecartEntityToHighlight(null); - - if (configuration.getOptions().car().automatedStart()) { - // start the car with a small delay to ensure the player is fully in the vehicle - utilService.delayedAction(() -> commandService.sendCommand("car start"), 500); - } - - // lock the car after 1 second and the small delay if not already locked - if (!storage.isCarLocked() && configuration.getOptions().car().automatedLock()) { - utilService.delayedAction(() -> commandService.sendCommand("car lock"), 1500); - } - } - - @Override - public void onEntityRender(WorldRenderContext context) { - MatrixStack matrices = context.matrices(); - VertexConsumerProvider vertexConsumers = context.consumers(); - ClientWorld world = MinecraftClient.getInstance().world; - - if (world != null && configuration.getOptions().car().highlight()) { - ofNullable(storage.getMinecartEntityToHighlight()) - .map(minecartEntity -> world.getEntityById(minecartEntity.getId())) - .ifPresent(minecartEntity -> renderService.renderTextAboveEntity(matrices, vertexConsumers, minecartEntity, Text.of("🚗").copy().formatted(AQUA), 0.05F)); - } - } - @Override public boolean onMessageReceive(Text text, String message) { Matcher carUnlockMatcher = CAR_UNLOCK_PATTERN.matcher(message); @@ -97,7 +42,7 @@ public boolean onMessageReceive(Text text, String message) { } Matcher carFindMatcher = CAR_FIND_PATTERN.matcher(message); - if (carFindMatcher.find()) { + if (carFindMatcher.find() && configuration.getOptions().car().fastFind()) { int x = parseInt(carFindMatcher.group("x")); int y = parseInt(carFindMatcher.group("y")); int z = parseInt(carFindMatcher.group("z")); @@ -107,31 +52,4 @@ public boolean onMessageReceive(Text text, String message) { return true; } - - @Override - public void onScreenOpen(Screen screen, int scaledWidth, int scaledHeight) { - ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager; - - if (nonNull(interactionManager) && screen instanceof GenericContainerScreen genericContainerScreen) { - String titleString = genericContainerScreen.getTitle().getString(); - - switch (titleString) { - case "ᴄᴀʀᴄᴏɴᴛʀᴏʟ" -> { - if (configuration.getOptions().car().fastLock()) { - interactionManager.clickSlot(genericContainerScreen.getScreenHandler().syncId, 0, 0, PICKUP, player); - } - } - case "Fahrzeuge" -> { - if (configuration.getOptions().car().fastFind()) { - interactionManager.clickSlot(genericContainerScreen.getScreenHandler().syncId, 0, 0, PICKUP, player); - } - } - default -> { - if (commandService.isSuperUser()) { - LOGGER.info("Screen opened: {}", titleString); - } - } - } - } - } } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java index 4c7a2700..aaba2e06 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java @@ -9,7 +9,6 @@ import java.util.regex.Pattern; import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.storage; import static java.lang.Character.isUpperCase; import static java.util.regex.Pattern.compile; @@ -17,7 +16,6 @@ public class CommandListener implements ICommandSendListener { private static final Pattern COMMAND_NAVI_HOUSE_NUMBER_PATTERN = compile("^navi (?\\d+)$"); - private static final Pattern FACTION_BANK_DEPOSIT_WITH_REASON_PATTERN = compile("^fbank einzahlen (?\\d+) (?.+)$"); @Override public boolean onCommandSend(@NotNull String command) { @@ -45,15 +43,6 @@ public boolean onCommandSend(@NotNull String command) { return false; } - Matcher factionBankDepositWithReasonMatcher = FACTION_BANK_DEPOSIT_WITH_REASON_PATTERN.matcher(command); - if (factionBankDepositWithReasonMatcher.find()) { - String amount = factionBankDepositWithReasonMatcher.group("amount"); - String reason = factionBankDepositWithReasonMatcher.group("reason"); - storage.setFBankDepositReason(reason); - commandService.sendCommand("fbank einzahlen " + amount); - return false; - } - return true; } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/EconomyListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/EconomyListener.java index 1d984295..24f93fc7 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/EconomyListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/EconomyListener.java @@ -7,6 +7,7 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -17,10 +18,10 @@ import static de.rettichlp.ucutils.UCUtils.notificationService; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; +import static de.rettichlp.ucutils.UCUtils.utilService; import static java.lang.Integer.parseInt; import static java.lang.Math.max; import static java.lang.System.currentTimeMillis; -import static java.util.Collections.emptyList; import static java.util.Optional.ofNullable; import static java.util.regex.Pattern.compile; import static net.minecraft.text.Text.of; @@ -55,10 +56,13 @@ public class EconomyListener implements IMessageReceiveListener { private static final Pattern PAYDAY_TIME_PATTERN = compile("^- Zeit seit PayDay: (?\\d+)/60 Minuten$"); private static final Pattern PAYDAY_SALARY_PATTERN = compile("^\\[PayDay] Du bekommst dein Gehalt von (?\\d+)\\$ am PayDay ausgezahlt\\.$"); private static final Pattern PAYDAY_MINE_SALARY_PATTERN = compile("^\\[PayDay] Du bekommst deine Mine Einnahmen von (?\\d+)\\$ am PayDay ausgezahlt\\.$"); - private static final Pattern PAYDAY_COUNTDOWN_PATTERN = compile("^Info: Du hast in 3 Minuten deinen PayDay$"); + private static final Pattern PAYDAY_COUNTDOWN_PATTERN = compile("^Info: Du hast in (?\\d+) Minuten? deinen PayDay$"); + + // stock market + private static final Pattern STOCK_MARKET_BUY_PATTERN = compile("^\\[Aktien] Du hast (?\\d+)x (?.+) für (?\\d+)\\$ gekauft\\. \\(Gebühr: (?\\d+)\\$\\)$"); + private static final Pattern STOCK_MARKET_SELL_PATTERN = compile("^\\[Aktien] (?\\d+)x (?.+) verkauft für (?\\d+)\\$\\. \\(Gebühr: (?\\d+)\\$\\) (?[+-]\\d+)\\$ Brutto / (?[+-]\\d+)\\$ Netto$"); // other - private static final Pattern ATM_MONEY_AMOUNT_PATTERN = compile("ATM \\d+: (?\\d+)\\$/100000\\$"); private static final Pattern BUSINESS_CASH_PATTERN = compile("^Kasse: (\\d+)\\$$"); private static final Pattern EXP_PATTERN = compile("(?[+-]\\d+) Exp!( \\(x(?\\d)\\))?"); private static final Pattern LOTTO_WIN_PATTERN = compile("^\\[Lotto] Du hast im Lotto gewonnen! \\((?\\d+)\\$\\)$"); @@ -76,12 +80,16 @@ public boolean onMessageReceive(Text text, String message) { int amount = parseInt(bankStatementMatcher.group("amount")); configuration.setMoneyBankAmount(amount); - List commands = switch (configuration.getOptions().atmInformationType()) { - case NONE -> emptyList(); - case F_BANK -> List.of("fbank"); - case G_BANK -> List.of("gruppierungkasse"); - case BOTH -> List.of("fbank", "gruppierungkasse"); - }; + List commands = new ArrayList<>(); + commands.add("atminfo"); + + switch (configuration.getOptions().atmInformationType()) { + case NONE -> { + } + case F_BANK -> commands.add("fbank"); + case G_BANK -> commands.add("gruppierungkasse"); + case BOTH -> commands.addAll(List.of("fbank", "gruppierungkasse")); + } commandService.sendCommands(commands); @@ -239,20 +247,37 @@ public boolean onMessageReceive(Text text, String message) { Matcher paydayCountdownMatcher = PAYDAY_COUNTDOWN_PATTERN.matcher(message); if (paydayCountdownMatcher.find()) { - configuration.setMinutesSinceLastPayDay(57); + int minutes = parseInt(paydayCountdownMatcher.group("minutes")); + int minutesSinceLastPayDay = 60 - minutes; + configuration.setMinutesSinceLastPayDay(minutesSinceLastPayDay); - if (configuration.getMoneyBankAmount() > 100000) { - messageService.sendModMessage("Du hast über 100000$ auf der Bank!", false); - notificationService.notificationSound(3); - } + utilService.delayedAction(() -> { + if (configuration.getMoneyBankAmount() > 100000) { + messageService.sendModMessage("Du hast über 100000$ auf der Bank!", false); + + switch (minutes) { + case 10 -> notificationService.notificationSound(1); + case 5 -> notificationService.notificationSound(2); + case 3, 2, 1 -> notificationService.notificationSound(3); + } + } + }, 50); + + return true; + } + Matcher stockMarketBuyMatcher = STOCK_MARKET_BUY_PATTERN.matcher(message); + if (stockMarketBuyMatcher.find()) { + int price = parseInt(stockMarketBuyMatcher.group("price")); + int fee = parseInt(stockMarketBuyMatcher.group("fee")); + configuration.setMoneyCashAmount(configuration.getMoneyCashAmount() - price - fee); return true; } - Matcher moneyAtmAmountMatcher = ATM_MONEY_AMOUNT_PATTERN.matcher(message); - if (moneyAtmAmountMatcher.find()) { - int moneyAtmAmount = parseInt(moneyAtmAmountMatcher.group("moneyAtmAmount")); - storage.setMoneyAtmAmount(moneyAtmAmount); + Matcher stockMarketSellMatcher = STOCK_MARKET_SELL_PATTERN.matcher(message); + if (stockMarketSellMatcher.find()) { + int price = parseInt(stockMarketSellMatcher.group("price")); + configuration.setMoneyCashAmount(configuration.getMoneyCashAmount() + price); return true; } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/EventListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/EventListener.java deleted file mode 100644 index 986591ba..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/EventListener.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.rettichlp.ucutils.listener.impl; - -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.minecraft.text.Text; - -import java.time.LocalDateTime; -import java.util.Set; -import java.util.function.Predicate; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.configuration; -import static java.lang.Integer.parseInt; -import static java.time.LocalDateTime.now; -import static java.util.regex.Pattern.compile; - -@UCUtilsListener -public class EventListener implements IMessageReceiveListener { - - private static final Pattern HALLOWEEN_DOOR_VISITED_PATTERN = compile("^\\[Halloween] Du hast bei Haus (?\\d+) geklingelt\\.$"); - - private static final Predicate HALLOWEEN_DOOR_REMOVE_PREDICATE = halloweenDoor -> { - LocalDateTime now = now(); - LocalDateTime today4am = now.withHour(4).withMinute(0).withSecond(0).withNano(0); - LocalDateTime timestamp = halloweenDoor.getTimestamp(); - return now.isAfter(today4am) - ? timestamp.isBefore(today4am) - : timestamp.isBefore(today4am.minusDays(1)); - }; - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher halloweenDoorVisitedMatcher = HALLOWEEN_DOOR_VISITED_PATTERN.matcher(message); - if (halloweenDoorVisitedMatcher.find()) { - int doorNumber = parseInt(halloweenDoorVisitedMatcher.group("number")); - HalloweenDoor halloweenDoor = new HalloweenDoor(doorNumber); - - Set halloweenClickedDoors = configuration.getHalloweenClickedDoors(); - halloweenClickedDoors.removeIf(HALLOWEEN_DOOR_REMOVE_PREDICATE); - halloweenClickedDoors.add(halloweenDoor); - return true; - } - - return true; - } - - @Getter - @RequiredArgsConstructor - public static class HalloweenDoor { - - private final LocalDateTime timestamp = now(); - private final int doorNumber; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/InventoryListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/InventoryListener.java deleted file mode 100644 index 12d99267..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/InventoryListener.java +++ /dev/null @@ -1,173 +0,0 @@ -package de.rettichlp.ucutils.listener.impl; - -import de.rettichlp.ucutils.common.models.Ingredient; -import de.rettichlp.ucutils.common.models.Purity; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IScreenOpenListener; -import lombok.NonNull; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.component.type.LoreComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.GenericContainerScreenHandler; -import net.minecraft.screen.HopperScreenHandler; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.screen.slot.Slot; -import net.minecraft.util.collection.DefaultedList; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; - -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.models.Ingredient.ANTIBIOTICS; -import static de.rettichlp.ucutils.common.models.Ingredient.COUGH_SYRUP; -import static de.rettichlp.ucutils.common.models.Ingredient.CRYSTALS; -import static de.rettichlp.ucutils.common.models.Ingredient.GUNPOWDER; -import static de.rettichlp.ucutils.common.models.Ingredient.HERBS; -import static de.rettichlp.ucutils.common.models.Ingredient.IRON; -import static de.rettichlp.ucutils.common.models.Ingredient.KEVLAR_FIBERS; -import static de.rettichlp.ucutils.common.models.Ingredient.MASK; -import static de.rettichlp.ucutils.common.models.Ingredient.MEDICINAL_HERBS; -import static de.rettichlp.ucutils.common.models.Ingredient.PAINKILLERS; -import static de.rettichlp.ucutils.common.models.Ingredient.SURPRISE_BAG; -import static de.rettichlp.ucutils.common.models.Ingredient.fromDisplayName; -import static de.rettichlp.ucutils.common.models.Purity.BEST; -import static java.lang.Integer.parseInt; -import static java.util.regex.Pattern.compile; -import static net.minecraft.component.DataComponentTypes.LORE; -import static net.minecraft.screen.slot.SlotActionType.PICKUP; - -@UCUtilsListener -public class InventoryListener implements IScreenOpenListener { - - public static Ingredient inventorySyncStep = null; - - @Override - public void onScreenOpen(Screen screen, int scaledWidth, int scaledHeight) { - if (!(screen instanceof HandledScreen handledScreen)) { - return; - } - - String title = handledScreen.getTitle().getString(); - ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager; - - if (inventorySyncStep == null || interactionManager == null) { - return; - } - - ScreenHandler screenHandler = handledScreen.getScreenHandler(); - - if (screenHandler instanceof GenericContainerScreenHandler genericContainerScreenHandler) { - if (!title.equals("Inventar")) { - return; - } - - utilService.delayedAction(() -> { - switch (inventorySyncStep) { - case POWDER -> { - interactionManager.clickSlot(genericContainerScreenHandler.syncId, 0, 0, PICKUP, player); - return; - } - case HERBS -> { - interactionManager.clickSlot(genericContainerScreenHandler.syncId, 1, 0, PICKUP, player); - return; - } - case CRYSTALS -> { - interactionManager.clickSlot(genericContainerScreenHandler.syncId, 3, 0, PICKUP, player); - return; - } - default -> { - } - } - - ItemStack medicinalHerbsItemStack = genericContainerScreenHandler.slots.get(2).getStack(); - int medicinalHerbsAmount = getAmount(medicinalHerbsItemStack, 0); - storage.getInventory().put(MEDICINAL_HERBS, Map.of(BEST, medicinalHerbsAmount)); - - ItemStack surpriseBagItemStack = genericContainerScreenHandler.slots.get(4).getStack(); - int surpriseBagAmount = getAmount(surpriseBagItemStack, 0); - storage.getInventory().put(SURPRISE_BAG, Map.of(BEST, surpriseBagAmount)); - - ItemStack coughSyrupItemStack = genericContainerScreenHandler.slots.get(9).getStack(); - int coughSyrupAmount = getAmount(coughSyrupItemStack, 0); - storage.getInventory().put(COUGH_SYRUP, Map.of(BEST, coughSyrupAmount)); - - ItemStack painkillersItemStack = genericContainerScreenHandler.slots.get(10).getStack(); - int painkillersAmount = getAmount(painkillersItemStack, 0); - storage.getInventory().put(PAINKILLERS, Map.of(BEST, painkillersAmount)); - - ItemStack antibioticsItemStack = genericContainerScreenHandler.slots.get(11).getStack(); - int antibioticsAmount = getAmount(antibioticsItemStack, 0); - storage.getInventory().put(ANTIBIOTICS, Map.of(BEST, antibioticsAmount)); - - ItemStack maskItemStack = genericContainerScreenHandler.slots.get(18).getStack(); - int maskAmount = getAmount(maskItemStack, 0); - storage.getInventory().put(MASK, Map.of(BEST, maskAmount)); - - ItemStack ironItemStack = genericContainerScreenHandler.slots.get(19).getStack(); - int ironAmount = getAmount(ironItemStack, 0); - storage.getInventory().put(IRON, Map.of(BEST, ironAmount)); - - ItemStack gunpowderItemStack = genericContainerScreenHandler.slots.get(20).getStack(); - int gunpowderAmount = getAmount(gunpowderItemStack, 0); - storage.getInventory().put(GUNPOWDER, Map.of(BEST, gunpowderAmount)); - - ItemStack kevlarFibersItemStack = genericContainerScreenHandler.slots.get(21).getStack(); - int kevlarFibersAmount = getAmount(kevlarFibersItemStack, 0); - storage.getInventory().put(KEVLAR_FIBERS, Map.of(BEST, kevlarFibersAmount)); - - inventorySyncStep = null; - player.closeScreen(); - }, 250); - - return; - } - - if (screenHandler instanceof HopperScreenHandler hopperScreenHandler) { - utilService.delayedAction(() -> fromDisplayName(title).ifPresent(ingredient -> { - Map purityAmounts = new HashMap<>(); - - DefaultedList slots = hopperScreenHandler.slots; - for (int i = 0; i < 4; i++) { - ItemStack itemStack = slots.get(i).getStack(); - int amount = getAmount(itemStack, 2); - purityAmounts.put(Purity.values()[i], amount); - } - - storage.getInventory().put(ingredient, purityAmounts); - switch (inventorySyncStep) { - case POWDER -> { - inventorySyncStep = HERBS; - interactionManager.clickSlot(hopperScreenHandler.syncId, 4, 0, PICKUP, player); - } - case HERBS -> { - inventorySyncStep = CRYSTALS; - interactionManager.clickSlot(hopperScreenHandler.syncId, 4, 0, PICKUP, player); - } - case CRYSTALS -> { - inventorySyncStep = MEDICINAL_HERBS; - interactionManager.clickSlot(hopperScreenHandler.syncId, 4, 0, PICKUP, player); - } - default -> inventorySyncStep = null; - } - }), 250); - } - } - - private int getAmount(@NonNull ItemStack itemStack, int loreLineIndex) { - LoreComponent loreComponent = itemStack.get(LORE); - - if (loreComponent == null) { - return 0; - } - - String amountString = loreComponent.lines().get(loreLineIndex).getString(); - Matcher matcher = compile("\\d+").matcher(amountString); - return matcher.find() ? parseInt(matcher.group()) : 0; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/KarmaListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/KarmaListener.java deleted file mode 100644 index 2d47f376..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/KarmaListener.java +++ /dev/null @@ -1,86 +0,0 @@ -package de.rettichlp.ucutils.listener.impl; - -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; - -import java.time.LocalTime; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.common.services.MessageService.TIME_FORMAT; -import static java.lang.Integer.parseInt; -import static java.lang.String.valueOf; -import static java.time.LocalTime.now; -import static java.util.regex.Pattern.compile; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.literal; -import static net.minecraft.util.Formatting.AQUA; -import static net.minecraft.util.Formatting.BLUE; -import static net.minecraft.util.Formatting.DARK_GRAY; - -@UCUtilsListener -public class KarmaListener implements IMessageReceiveListener { - - private static final Pattern KARMA_CHANGED_PATTERN = compile("^\\[Karma] (?[+-]\\d+) Karma\\.$"); - private static final Pattern KARMA_PATTERN = compile("^\\[Karma] Du hast ein Karma von (?[+-]\\d+)\\.$"); - - private int lastKarmaChange = 0; - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher karmaChangedMatcher = KARMA_CHANGED_PATTERN.matcher(message); - if (karmaChangedMatcher.find()) { - boolean showEnrichedKarma = configuration.getOptions().showEnrichedKarma(); - if (!showEnrichedKarma) { - return true; - } - - // show enriched karma message - this.lastKarmaChange = parseInt(karmaChangedMatcher.group("amount")); - commandService.sendCommandWithAfkCheck("karma"); - return false; - } - - Matcher karmaMatcher = KARMA_PATTERN.matcher(message); - if (karmaMatcher.find()) { - // show default message if no karma was changed - if (this.lastKarmaChange == 0) { - return true; - } - - int currentKarma = parseInt(karmaMatcher.group("amount")); - - MutableText enrichedKarmaMessage = empty() - .append(literal("[").formatted(DARK_GRAY)) - .append(literal("Karma").formatted(BLUE)) - .append(literal("] ").formatted(DARK_GRAY)) - .append(literal((this.lastKarmaChange > 0 ? "+" : "") + this.lastKarmaChange + " ").formatted(AQUA)) - .append(literal("Karma ").formatted(AQUA)) - .append(literal("(").formatted(DARK_GRAY)) - .append(literal(valueOf(currentKarma)).formatted(AQUA)) - .append(literal("/").formatted(DARK_GRAY)) - .append(literal("100").formatted(AQUA)) - .append(literal(")").formatted(DARK_GRAY)); - - // add despawn time if available - if (this.lastKarmaChange < 0) { - LocalTime despawnTime = now().plusMinutes(5); - enrichedKarmaMessage - .append(literal(" (").formatted(DARK_GRAY)) - .append(literal(TIME_FORMAT.format(despawnTime)).formatted(AQUA)) - .append(literal(")").formatted(DARK_GRAY)); - } - - player.sendMessage(enrichedKarmaMessage, false); - this.lastKarmaChange = 0; - return false; - } - - return true; - } -} \ No newline at end of file diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/MobileListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/MobileListener.java index 0aa8baec..6551c205 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/MobileListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/MobileListener.java @@ -8,40 +8,17 @@ import java.util.regex.Pattern; import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.UCUtils.utilService; import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; -import static java.lang.Integer.parseInt; import static java.util.regex.Pattern.compile; @UCUtilsListener public class MobileListener implements IMessageReceiveListener { - private static final Pattern MOBILE_NUMBER_PATTERN = compile("^Nummer von (?:\\[UC])?(?[a-zA-Z0-9_]+): (?\\d+)$"); - private static final Pattern MOBILE_SMS_RECEIVE_PATTERN = compile("^Dein Handy klingelt! Eine Nachricht von (?:\\[UC])?(?[a-zA-Z0-9_]+) \\((?\\d+)\\)\\.$"); private static final Pattern MOBILE_OFF_PATTERN = compile("^Dein Handy ist ausgeschaltet\\.$"); @Override public boolean onMessageReceive(Text text, String message) { - Matcher mobileNumberMatcher = MOBILE_NUMBER_PATTERN.matcher(message); - if (mobileNumberMatcher.find()) { - String playerName = mobileNumberMatcher.group("playerName"); - int number = parseInt(mobileNumberMatcher.group("number")); - storage.getRetrievedNumbers().put(playerName, number); - return true; - } - - Matcher mobileSmsReceiveMatcher = MOBILE_SMS_RECEIVE_PATTERN.matcher(message); - if (mobileSmsReceiveMatcher.find()) { - String playerName = mobileSmsReceiveMatcher.group("playerName"); - int number = parseInt(mobileSmsReceiveMatcher.group("number")); - - storage.getRetrievedNumbers().put(playerName, number); - storage.setLastReceivedSmsNumber(number); - - return true; - } - Matcher mobileOffMatcher = MOBILE_OFF_PATTERN.matcher(message); if (mobileOffMatcher.find()) { utilService.delayedAction(() -> commandService.sendCommand("togglephone"), COMMAND_COOLDOWN_MILLIS); diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/PlayerListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/PlayerListener.java index 9c7acee6..80b7f074 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/PlayerListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/PlayerListener.java @@ -2,7 +2,6 @@ import de.rettichlp.ucutils.common.models.Countdown; import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IAbsorptionGetListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; import de.rettichlp.ucutils.listener.ITickListener; import net.minecraft.network.ClientConnection; @@ -20,7 +19,6 @@ import static de.rettichlp.ucutils.UCUtils.nameTagService; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; import static de.rettichlp.ucutils.common.models.ShutdownReason.CEMETERY; import static de.rettichlp.ucutils.common.models.ShutdownReason.JAIL; import static java.lang.Double.parseDouble; @@ -36,10 +34,9 @@ import static net.minecraft.util.Formatting.RED; @UCUtilsListener -public class PlayerListener implements IAbsorptionGetListener, IMessageReceiveListener, ITickListener { +public class PlayerListener implements IMessageReceiveListener, ITickListener { private static final String SHUTDOWN_TIMEOUT = "5"; - private static final int PRAY_DELAY_IN_SECONDS = 30; // dead private static final Pattern DEAD_PATTERN = compile("^Du bist nun für (?\\d+) Minuten auf dem Friedhof\\.$"); @@ -56,18 +53,13 @@ public class PlayerListener implements IAbsorptionGetListener, IMessageReceiveLi private static final Pattern JAIL_PATTERN = compile("^\\[Gefängnis] Du bist nun für (?\\d+) Minuten im Gefängnis\\.$"); private static final Pattern JAIL_UNJAIL_PATTERN = compile("^\\[Gefängnis] Du bist nun wieder frei!$"); - // pray - private static final Pattern PRAY_START_PATTERN = compile("^\\[Kirche] Du fängst an für (?:\\[UC])?(?[a-zA-Z0-9_]+) zu beten\\.$"); + // premium + private static final Pattern PREMIUM_PATTERN = compile("^\\[Premium] Dein Premium Account ist noch .+ aktiv\\.$"); // requests private static final Pattern ACCEPT_PATTERN = compile("^\\[Deal] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat den Deal angenommen\\.$"); private static final Pattern DECLINE_PATTERN = compile("^\\[Deal] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat das Angebot abgelehnt\\.$"); - @Override - public void onAbsorptionGet() { - storage.getCountdowns().add(new Countdown("Absorption", ofMinutes(3))); - } - @Override public boolean onMessageReceive(Text text, String message) { Matcher deadAReviveMatcher = DEAD_AREVIVE_PATTERN.matcher(message); @@ -143,9 +135,9 @@ public boolean onMessageReceive(Text text, String message) { return true; } - Matcher prayStartMatcher = PRAY_START_PATTERN.matcher(message); - if (prayStartMatcher.find()) { - utilService.delayedAction(() -> commandService.sendCommand("beten"), PRAY_DELAY_IN_SECONDS * 1000L); + Matcher premiumMatcher = PREMIUM_PATTERN.matcher(message); + if (premiumMatcher.find()) { + storage.setPremium(true); return true; } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/SoundTriggerListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/SoundTriggerListener.java new file mode 100644 index 00000000..d435e368 --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/SoundTriggerListener.java @@ -0,0 +1,66 @@ +package de.rettichlp.ucutils.listener.impl; + +import de.rettichlp.ucutils.common.models.Faction; +import de.rettichlp.ucutils.common.registry.UCUtilsListener; +import de.rettichlp.ucutils.listener.IMessageReceiveListener; +import net.minecraft.text.Text; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static de.rettichlp.ucutils.UCUtils.configuration; +import static de.rettichlp.ucutils.UCUtils.player; +import static de.rettichlp.ucutils.UCUtils.storage; +import static de.rettichlp.ucutils.common.models.Sound.BANK_ROBBERY; +import static de.rettichlp.ucutils.common.models.Sound.BOMB_SOUND; +import static de.rettichlp.ucutils.common.models.Sound.CONTRACT_FULFILLED; +import static de.rettichlp.ucutils.common.models.Sound.CONTRACT_SET; +import static de.rettichlp.ucutils.common.models.Sound.FIRE; +import static java.util.regex.Pattern.compile; + +@UCUtilsListener +public class SoundTriggerListener implements IMessageReceiveListener { + + private static final Pattern BANK_ROBBERY_PATTERN = compile("^News: Es wurde ein Raub in der Staatsbank gemeldet!$"); + private static final Pattern BOMB_FOUND_PATTERN = compile("^News: ACHTUNG! Es wurde eine Bombe in der Nähe von (?.+) gefunden!$"); + private static final Pattern CONTRACT_ADD_PATTERN = compile("^\\[Contract] Es wurde ein Kopfgeld auf (?:\\[UC])?(?[a-zA-Z0-9_]+) \\((?\\d+)\\$\\) ausgesetzt\\.$"); + private static final Pattern CONTRACT_KILL_PATTERN = compile("^\\[Contract] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat (?:\\[UC])?(?[a-zA-Z0-9_]+) getötet\\. Kopfgeld: (?\\d+)\\$$"); + private static final Pattern FIRE_START_PATTERN = compile("^News: Es wurde ein Feuer bei .+ gemeldet!$"); + + @Override + public boolean onMessageReceive(Text text, String message) { + Faction playerFaction = storage.getFaction(player.getGameProfile().name()); + + Matcher bankRobberyMatcher = BANK_ROBBERY_PATTERN.matcher(message); + if (bankRobberyMatcher.find() && configuration.getOptions().sound().bankRobbery().verify(playerFaction)) { + BANK_ROBBERY.play(); + return true; + } + + Matcher bombFoundMatcher = BOMB_FOUND_PATTERN.matcher(message); + if (bombFoundMatcher.find() && configuration.getOptions().sound().bomb().verify(playerFaction)) { + BOMB_SOUND.play(); + return true; + } + + Matcher contractAddMatcher = CONTRACT_ADD_PATTERN.matcher(message); + if (contractAddMatcher.find() && configuration.getOptions().sound().contractSet()) { + CONTRACT_SET.play(); + return true; + } + + Matcher contractKillMatcher = CONTRACT_KILL_PATTERN.matcher(message); + if (contractKillMatcher.find() && configuration.getOptions().sound().contractFulfilled()) { + CONTRACT_FULFILLED.play(); + return true; + } + + Matcher fireStartMatcher = FIRE_START_PATTERN.matcher(message); + if (fireStartMatcher.find() && configuration.getOptions().sound().fire().verify(playerFaction)) { + FIRE.play(); + return true; + } + + return true; + } +} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BadFactionListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BadFactionListener.java new file mode 100644 index 00000000..7a0502cc --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BadFactionListener.java @@ -0,0 +1,59 @@ +package de.rettichlp.ucutils.listener.impl.faction; + +import de.rettichlp.ucutils.common.registry.UCUtilsListener; +import de.rettichlp.ucutils.listener.IMessageReceiveListener; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static de.rettichlp.ucutils.UCUtils.player; +import static de.rettichlp.ucutils.UCUtils.storage; +import static java.lang.Integer.parseInt; +import static java.util.regex.Pattern.compile; +import static net.minecraft.text.Text.literal; +import static net.minecraft.util.Formatting.BOLD; +import static net.minecraft.util.Formatting.DARK_RED; + +@UCUtilsListener +public class BadFactionListener implements IMessageReceiveListener { + + private static final Pattern BLACK_MARKET_DEALER_ENTRY_PATTERN = compile("^» (?.+) – (gerade eben|vor \\d+ \\w+) {2}\\[Navi]$"); + + @Override + public boolean onMessageReceive(Text text, String message) { + Matcher blackMarketDealerEntryMatcher = BLACK_MARKET_DEALER_ENTRY_PATTERN.matcher(message); + if (blackMarketDealerEntryMatcher.find()) { + Vec3d blackMarketPosition = storage.getBlackMarketPosition(); + Vec3d dealerPosition = storage.getDealerPosition(); + + // extract location from message + Text last = text.getSiblings().getLast(); + ClickEvent clickEvent = last.getStyle().getClickEvent(); + if (!(clickEvent instanceof ClickEvent.RunCommand(String command))) { + return true; + } + + String[] locationPieces = command.replace("/navi ", "").split("/"); + + if (locationPieces.length != 3) { + return true; + } + + Vec3d extractedPosition = new Vec3d(parseInt(locationPieces[0]), parseInt(locationPieces[1]), parseInt(locationPieces[2])); + + if ((blackMarketPosition != null && extractedPosition.distanceTo(blackMarketPosition) < 5) || (dealerPosition != null && extractedPosition.distanceTo(dealerPosition) < 5)) { + MutableText text1 = text.copy().append(literal(" ⯐").formatted(DARK_RED, BOLD)); + player.sendMessage(text1, false); + return false; + } + + return true; + } + + return true; + } +} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BlacklistListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BlacklistListener.java deleted file mode 100644 index 906046f7..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BlacklistListener.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.faction; - -import de.rettichlp.ucutils.common.models.BlacklistEntry; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.minecraft.text.Text; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; -import static java.lang.Integer.parseInt; -import static java.util.regex.Pattern.compile; - -@UCUtilsListener -public class BlacklistListener implements IMessageReceiveListener { - - private static final Pattern BLACKLIST_HEADER_PATTERN = compile("^==== Blacklist .+ ====$"); - private static final Pattern BLACKLIST_ENTRY_PATTERN = compile("^» (?:\\[UC])?(?[a-zA-Z0-9_]+) \\| (?.+) \\| (?.+) \\| (?\\d+) Kills \\| (?\\d+)\\$(| \\(AFK\\))$"); - private static final Pattern BLACKLIST_ENTRY_ADD = compile("^\\[Blacklist] (?:\\[UC])?(?[a-zA-Z0-9_]+) wurde von (?:\\[UC])?(?[a-zA-Z0-9_]+) auf die Blacklist gesetzt!$"); - private static final Pattern BLACKLIST_ENTRY_REMOVE = compile("^\\[Blacklist] (?:\\[UC])?(?[a-zA-Z0-9_]+) wurde von (?:\\[UC])?(?[a-zA-Z0-9_]+) von der Blacklist gelöscht!$"); - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher blacklistHeaderMatcher = BLACKLIST_HEADER_PATTERN.matcher(message); - if (blacklistHeaderMatcher.find()) { - storage.getBlacklistEntries().clear(); - return commandService.showCommandOutputMessage("blacklist"); - } - - Matcher blacklistEntryMatcher = BLACKLIST_ENTRY_PATTERN.matcher(message); - if (blacklistEntryMatcher.find()) { - String playerName = blacklistEntryMatcher.group("playerName"); - String reason = blacklistEntryMatcher.group("reason"); - boolean outlaw = reason.toLowerCase().contains("(vf)") || reason.toLowerCase().contains("(vogelfrei)"); - int kills = parseInt(blacklistEntryMatcher.group("kills")); - int price = parseInt(blacklistEntryMatcher.group("price")); - - BlacklistEntry blacklistEntry = new BlacklistEntry(playerName, reason, outlaw, kills, price); - storage.getBlacklistEntries().add(blacklistEntry); - return commandService.showCommandOutputMessage("blacklist"); - } - - Matcher blacklistEntryAddMatcher = BLACKLIST_ENTRY_ADD.matcher(message); - if (blacklistEntryAddMatcher.find()) { - // show all entries to sync - utilService.delayedAction(() -> commandService.sendCommandWithHiddenOutput("blacklist"), COMMAND_COOLDOWN_MILLIS); - return true; - } - - Matcher blacklistEntryRemoveMatcher = BLACKLIST_ENTRY_REMOVE.matcher(message); - if (blacklistEntryRemoveMatcher.find()) { - String targetName = blacklistEntryRemoveMatcher.group("targetName"); - storage.getBlacklistEntries().removeIf(blacklistEntry -> blacklistEntry.getPlayerName().equals(targetName)); - return true; - } - - return true; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/ContractListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/ContractListener.java deleted file mode 100644 index 6413652c..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/ContractListener.java +++ /dev/null @@ -1,81 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.faction; - -import de.rettichlp.ucutils.common.models.ContractEntry; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.minecraft.text.Text; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.models.Sound.CONTRACT_FULFILLED; -import static de.rettichlp.ucutils.common.models.Sound.CONTRACT_SET; -import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; -import static java.lang.Integer.parseInt; -import static java.util.regex.Pattern.compile; - -@UCUtilsListener -public class ContractListener implements IMessageReceiveListener { - - private static final Pattern CONTRACT_HEADER_PATTERN = compile("^\\[Contracts] Kopfgelder:$"); - private static final Pattern CONTRACT_ENTRY_PATTERN = compile("^- (?:\\[UC])?(?[a-zA-Z0-9_]+) \\[(?\\d+)\\$](?: \\(AFK\\))?$"); - private static final Pattern CONTRACT_ADD_PATTERN = compile("^\\[Contract] Es wurde ein Kopfgeld auf (?:\\[UC])?(?[a-zA-Z0-9_]+) \\((?\\d+)\\$\\) ausgesetzt\\.$"); - private static final Pattern CONTRACT_REMOVE_PATTERN = compile("^\\[Contract] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat (?:\\[UC])?(?[a-zA-Z0-9_]+) von der Contract Liste gelöscht\\. \\[-(?\\d+)\\$]$"); - private static final Pattern CONTRACT_KILL_PATTERN = compile("^\\[Contract] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat (?:\\[UC])?(?[a-zA-Z0-9_]+) getötet\\. Kopfgeld: (?\\d+)\\$$"); - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher contractHeaderMatcher = CONTRACT_HEADER_PATTERN.matcher(message); - if (contractHeaderMatcher.find()) { - storage.getContractEntries().clear(); - return commandService.showCommandOutputMessage("contractlist"); - } - - Matcher contractEntryMatcher = CONTRACT_ENTRY_PATTERN.matcher(message); - if (contractEntryMatcher.find()) { - String playerName = contractEntryMatcher.group("playerName"); - int price = parseInt(contractEntryMatcher.group("price")); - - ContractEntry contractEntry = new ContractEntry(playerName, price); - storage.getContractEntries().add(contractEntry); - return commandService.showCommandOutputMessage("contractlist"); - } - - Matcher contractAddMatcher = CONTRACT_ADD_PATTERN.matcher(message); - if (contractAddMatcher.find()) { - // show all entries to sync - utilService.delayedAction(() -> commandService.sendCommandWithHiddenOutput("contractlist"), COMMAND_COOLDOWN_MILLIS); - - if (configuration.getOptions().sound().contractSet()) { - CONTRACT_SET.play(); - } - - return true; - } - - Matcher contractRemoveMatcher = CONTRACT_REMOVE_PATTERN.matcher(message); - if (contractRemoveMatcher.find()) { - String targetName = contractRemoveMatcher.group("targetName"); - storage.getContractEntries().removeIf(contractEntry -> contractEntry.getPlayerName().equals(targetName)); - return true; - } - - Matcher contractKillMatcher = CONTRACT_KILL_PATTERN.matcher(message); - if (contractKillMatcher.find()) { - String targetName = contractKillMatcher.group("targetName"); - storage.getContractEntries().removeIf(contractEntry -> contractEntry.getPlayerName().equals(targetName)); - - if (configuration.getOptions().sound().contractFulfilled()) { - CONTRACT_FULFILLED.play(); - } - - return true; - } - - return true; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/EmergencyServiceListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/EmergencyServiceListener.java index 72d7bd6e..99517535 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/EmergencyServiceListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/EmergencyServiceListener.java @@ -2,15 +2,12 @@ import de.rettichlp.ucutils.common.registry.UCUtilsListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import de.rettichlp.ucutils.listener.INaviSpotReachedListener; import net.minecraft.text.Text; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static de.rettichlp.ucutils.UCUtils.commandService; import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.common.models.Sound.SERVICE; import static java.lang.Integer.parseInt; @@ -18,19 +15,15 @@ import static java.util.regex.Pattern.compile; @UCUtilsListener -public class EmergencyServiceListener implements IMessageReceiveListener, INaviSpotReachedListener { +public class EmergencyServiceListener implements IMessageReceiveListener { private static final Pattern SERVICE_PATTERN = compile("Ein Notruf von (?:\\[UC])?(?[a-zA-Z0-9_]+) \\((?\\d+)\\): \"(?.+)\""); private static final Pattern SERVICE_ACCEPTED_PATTERN = compile("^(?:HQ: )?(?:\\[UC])?(?[a-zA-Z0-9_]+) hat den Notruf von (?:\\[UC])?(?[a-zA-Z0-9_]+) angenommen\\. \\((?\\d+)m entfernt\\)$"); private static final Pattern SERVICE_REQUEUED_PATTERN = compile("^(?:\\[UC])?(?[a-zA-Z0-9_]+) hat den Notruf von (?:\\[UC])?(?[a-zA-Z0-9_]+) \\((?\\d+)\\) wieder geöffnet\\.$"); - private static final Pattern SERVICE_DONE_PATTERN = compile("^Du hast den Service von (?:\\[UC])?(?[a-zA-Z0-9_]+) als 'Erledigt' markiert!$"); private static final Pattern SERVICE_ABORTED_PATTERN = compile("^Der Service von (?:\\[UC])?(?[a-zA-Z0-9_]+) wurde abgebrochen\\.$"); private static final Pattern SERVICE_DELETED_PATTERN = compile("^Der Notruf von (?:\\[UC])?(?[a-zA-Z0-9_]+) wurde von (?:\\[UC])?(?[a-zA-Z0-9_]+) gelöscht\\.$"); private static final Pattern SERVICE_COUNT_PATTERN = compile("^Offene Notrufe \\((?\\d+)\\):"); private static final Pattern SERVICE_NONE_PATTERN = compile("^Fehler: Es ist kein Service offen\\.$"); - private static final Pattern SERVICE_NONE_FOR_PLAYER_PATTERN = compile("^Fehler: Es wurde kein Service von dir akzeptiert\\.$"); - - private boolean activeService = false; @Override public boolean onMessageReceive(Text text, String message) { @@ -48,30 +41,12 @@ public boolean onMessageReceive(Text text, String message) { Matcher serviceAcceptedMatcher = SERVICE_ACCEPTED_PATTERN.matcher(message); if (serviceAcceptedMatcher.find()) { storage.setActiveServices(max(0, storage.getActiveServices() - 1)); - - String playerName = serviceAcceptedMatcher.group("playerName"); - if (playerName.equals(player.getGameProfile().name())) { - this.activeService = true; - } - return true; } Matcher serviceRequeuedMatcher = SERVICE_REQUEUED_PATTERN.matcher(message); if (serviceRequeuedMatcher.find()) { storage.setActiveServices(storage.getActiveServices() + 1); - - String playerName = serviceRequeuedMatcher.group("playerName"); - if (playerName.equals(player.getGameProfile().name())) { - this.activeService = false; - } - - return true; - } - - Matcher serviceDoneMatcher = SERVICE_DONE_PATTERN.matcher(message); - if (serviceDoneMatcher.find()) { - this.activeService = false; return true; } @@ -100,19 +75,6 @@ public boolean onMessageReceive(Text text, String message) { return true; } - Matcher serviceNoneForPlayerMatcher = SERVICE_NONE_FOR_PLAYER_PATTERN.matcher(message); - if (serviceNoneForPlayerMatcher.find()) { - this.activeService = false; - return true; - } - return true; } - - @Override - public void onNaviSpotReached() { - if (this.activeService) { - commandService.sendCommand("doneservice"); - } - } } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionDoorListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionDoorListener.java deleted file mode 100644 index b702cf75..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionDoorListener.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.faction; - -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IBlockRightClickListener; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import java.util.Map; -import java.util.Set; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Faction.FBI; -import static de.rettichlp.ucutils.common.models.Faction.KERZAKOV_FAMILIE; -import static de.rettichlp.ucutils.common.models.Faction.WESTSIDE_BALLAS; -import static java.util.Collections.emptySet; -import static net.minecraft.util.Hand.MAIN_HAND; - -@UCUtilsListener -public class FactionDoorListener implements IBlockRightClickListener { - - private static final Map> FACTION_DOOR_POSITIONS = Map.of( - FBI, Set.of(new BlockPos(879, 62, -87)), - KERZAKOV_FAMILIE, Set.of(new BlockPos(936, 69, 191), new BlockPos(936, 69, 174)), - WESTSIDE_BALLAS, Set.of(new BlockPos(-166, 68, 205))); - private static final int DISTANCE = 4; - - @Override - public void onBlockRightClick(World world, Hand hand, BlockHitResult hitResult) { - if (!player.getStackInHand(MAIN_HAND).isEmpty()) { - return; - } - - Faction faction = storage.getFaction(player.getGameProfile().name()); - Set factionDoorPositions = FACTION_DOOR_POSITIONS.getOrDefault(faction, emptySet()); - - factionDoorPositions.stream() - .filter(blockPos -> blockPos.isWithinDistance(hitResult.getBlockPos(), DISTANCE)) - .findAny() - .ifPresent(blockPos -> commandService.sendCommand("fdoor")); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionListener.java index ff712ebe..762d49bd 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/FactionListener.java @@ -1,38 +1,27 @@ package de.rettichlp.ucutils.listener.impl.faction; import de.rettichlp.ucutils.common.Storage; -import de.rettichlp.ucutils.common.models.BlackMarket; -import de.rettichlp.ucutils.common.models.Dealer; import de.rettichlp.ucutils.common.models.FactionMember; import de.rettichlp.ucutils.common.registry.UCUtilsListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; import de.rettichlp.ucutils.listener.IMessageSendListener; -import de.rettichlp.ucutils.listener.IMoveListener; import lombok.NonNull; import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.text.Text; import net.minecraft.text.TextColor; import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; import java.util.List; import java.util.Optional; -import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static de.rettichlp.ucutils.UCUtils.LOGGER; import static de.rettichlp.ucutils.UCUtils.commandService; import static de.rettichlp.ucutils.UCUtils.configuration; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.common.Storage.ToggledChat.NONE; import static de.rettichlp.ucutils.common.configuration.options.Options.ReinforcementType.UNICACITYADDON; -import static java.lang.System.currentTimeMillis; -import static java.time.LocalDateTime.now; -import static java.util.Arrays.stream; import static java.util.Optional.ofNullable; import static java.util.regex.Pattern.compile; import static net.minecraft.text.Text.empty; @@ -46,7 +35,7 @@ import static net.minecraft.util.Formatting.RED; @UCUtilsListener -public class FactionListener implements IMessageReceiveListener, IMessageSendListener, IMoveListener { +public class FactionListener implements IMessageReceiveListener, IMessageSendListener { private static final Pattern REINFORCEMENT_PATTERN = compile("^(?:(?.+)! )?(?.+) (?:\\[UC])?(?[a-zA-Z0-9_]+) benötigt Unterstützung in der Nähe von (?.+)! \\((?\\d+) Meter entfernt\\)$"); private static final Pattern REINFORCEMENT_BUTTON_PATTERN = compile("^ §7» §cRoute anzeigen §7\\| §cUnterwegs$"); @@ -71,8 +60,6 @@ public class FactionListener implements IMessageReceiveListener, IMessageSendLis .append(of(distance + "m").copy().formatted(DARK_AQUA)) .append(of(")").copy().formatted(GRAY)); - private long lastBlackMarketAndDealerCheck = 0; - @Override public boolean onMessageReceive(Text text, String message) { Matcher reinforcementMatcher = REINFORCEMENT_PATTERN.matcher(message); @@ -173,56 +160,6 @@ public boolean onMessageSend(String message) { return true; } - @Override - public void onMove(BlockPos blockPos) { - // mark the black market spot as visited if within 60 blocks - if (currentTimeMillis() - this.lastBlackMarketAndDealerCheck >= 3000) { // every 3 seconds to reduce performance impact - this.lastBlackMarketAndDealerCheck = currentTimeMillis(); - - stream(BlackMarket.Type.values()) - .filter(type -> type.getBlockPos().isWithinDistance(blockPos, 60)) - .forEach(type -> { - // remove old type association if exists - storage.getBlackMarkets().removeIf(blackMarket -> blackMarket.getType() == type); - - // check if black market was found there - Box box = player.getBoundingBox().expand(60); - Predicate isBlackMarket = villagerEntity -> ofNullable(villagerEntity.getCustomName()) - .map(text -> text.getString().contains("Schwarzmarkt")) - .orElse(false); - - assert MinecraftClient.getInstance().world != null; // cannot be null at this point - boolean found = !MinecraftClient.getInstance().world.getEntitiesByClass(VillagerEntity.class, box, isBlackMarket).isEmpty(); - - // add new black market entry - BlackMarket blackMarket = new BlackMarket(type, now(), found); - storage.getBlackMarkets().add(blackMarket); - LOGGER.info("Marked black market spot as visited: {}", type); - }); - - stream(Dealer.Type.values()) - .filter(type -> type.getBlockPos().isWithinDistance(blockPos, 60)) - .forEach(type -> { - // remove old type association if exists - storage.getDealers().removeIf(dealer -> dealer.getType() == type); - - // check if black market was found there - Box box = player.getBoundingBox().expand(60); - Predicate isBlackMarket = villagerEntity -> ofNullable(villagerEntity.getCustomName()) - .map(text -> text.getString().contains("Dealer")) - .orElse(false); - - assert MinecraftClient.getInstance().world != null; // cannot be null at this point - boolean found = !MinecraftClient.getInstance().world.getEntitiesByClass(VillagerEntity.class, box, isBlackMarket).isEmpty(); - - // add new black market entry - Dealer dealer = new Dealer(type, now(), found); - storage.getDealers().add(dealer); - LOGGER.info("Marked dealer spot as visited: {}", type); - }); - } - } - private boolean messageMatchesColor(@NonNull List siblings, Formatting primaryFormatting, Formatting secondaryFormatting) { TextColor primaryFormattingCurrent = siblings.get(0).getStyle().getColor(); TextColor secondaryFormattingCurrent = siblings.get(2).getStyle().getColor(); diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MajorEventListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MajorEventListener.java deleted file mode 100644 index 1e5a7f48..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MajorEventListener.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.faction; - -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IHudRenderListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.RenderTickCounter; -import net.minecraft.text.Text; - -import java.time.LocalDateTime; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Sound.BANK_ROBBERY; -import static de.rettichlp.ucutils.common.models.Sound.BOMB_SOUND; -import static java.lang.String.format; -import static java.time.Duration.between; -import static java.time.LocalDateTime.now; -import static java.util.Objects.isNull; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.regex.Pattern.compile; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.literal; -import static net.minecraft.util.Formatting.BOLD; -import static net.minecraft.util.Formatting.GOLD; -import static net.minecraft.util.Formatting.GRAY; -import static net.minecraft.util.Formatting.RED; - -@UCUtilsListener -public class MajorEventListener implements IMessageReceiveListener, IHudRenderListener { - - private static final Pattern BANK_ROBBERY_PATTERN = compile("^News: Es wurde ein Raub in der Staatsbank gemeldet!$"); - private static final Pattern BOMB_FOUND_PATTERN = compile("^News: ACHTUNG! Es wurde eine Bombe in der Nähe von (?.+) gefunden!$"); - private static final Pattern BOMB_STOP_PATTERN = compile("^News: Die Bombe konnte (erfolgreich|nicht) entschärft werden!"); - - private LocalDateTime bombPlantedTime = null; - private String bombLocationString = ""; - - @Override - public boolean onMessageReceive(Text text, String message) { - Faction playerFaction = storage.getFaction(player.getGameProfile().name()); - - Matcher bankRobberyMatcher = BANK_ROBBERY_PATTERN.matcher(message); - if (bankRobberyMatcher.find() && configuration.getOptions().sound().bankRobbery().verify(playerFaction)) { - BANK_ROBBERY.play(); - } - - Matcher bombFoundMatcher = BOMB_FOUND_PATTERN.matcher(message); - if (bombFoundMatcher.find()) { - this.bombPlantedTime = now(); - this.bombLocationString = bombFoundMatcher.group("location"); - - if (configuration.getOptions().sound().bomb().verify(playerFaction)) { - BOMB_SOUND.play(); - } - - return true; - } - - Matcher bombStopMatcher = BOMB_STOP_PATTERN.matcher(message); - if (bombStopMatcher.find()) { - this.bombPlantedTime = null; - this.bombLocationString = ""; - return true; - } - - return true; - } - - @Override - public void onHudRender(DrawContext drawContext, RenderTickCounter renderTickCounter) { - if (isNull(this.bombPlantedTime)) { - return; - } - - long elapsedTimeInMillis = between(this.bombPlantedTime, now()).toMillis(); - long minutes = MILLISECONDS.toMinutes(elapsedTimeInMillis); - long seconds = MILLISECONDS.toSeconds(elapsedTimeInMillis) % 60; - - if (minutes >= 20) { - this.bombPlantedTime = null; - } - - Text timerText = empty() - .append(literal("Bombe").formatted(RED)) - .append(literal(":").formatted(GRAY)).append(" ") - .append(literal(this.bombLocationString).formatted(GOLD)).append(" ") - .append(literal("|").formatted(GRAY)).append(" ") - .append(literal(format("%02d:%02d", minutes, seconds)).formatted(RED, BOLD)); - - MinecraftClient client = MinecraftClient.getInstance(); - TextRenderer textRenderer = client.textRenderer; - - int textWidth = textRenderer.getWidth(timerText); - int x = (client.getWindow().getScaledWidth() - textWidth) / 2; - int y = 15; - - drawContext.drawTextWithShadow(textRenderer, timerText, x, y, 0xFFFFFFFF); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MedicListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MedicListener.java index 44330438..3e839209 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MedicListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/MedicListener.java @@ -1,37 +1,40 @@ package de.rettichlp.ucutils.listener.impl.faction; import de.rettichlp.ucutils.common.models.Countdown; -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.models.HousebanEntry; import de.rettichlp.ucutils.common.registry.UCUtilsListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import org.jetbrains.annotations.NotNull; +import net.minecraft.util.Formatting; +import java.awt.Color; import java.time.Duration; -import java.time.LocalDateTime; -import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.messageService; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.UCUtils.utilService; -import static de.rettichlp.ucutils.common.models.Sound.FIRE; import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; import static java.lang.Integer.parseInt; +import static java.lang.String.valueOf; import static java.time.Duration.ofMinutes; import static java.time.LocalDateTime.now; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static java.util.Optional.ofNullable; import static java.util.regex.Pattern.compile; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.AQUA; +import static net.minecraft.text.Text.empty; +import static net.minecraft.text.Text.literal; +import static net.minecraft.util.Formatting.BOLD; +import static net.minecraft.util.Formatting.DARK_AQUA; +import static net.minecraft.util.Formatting.DARK_GRAY; +import static net.minecraft.util.Formatting.DARK_GREEN; +import static net.minecraft.util.Formatting.GOLD; +import static net.minecraft.util.Formatting.GRAY; +import static net.minecraft.util.Formatting.GREEN; +import static net.minecraft.util.Formatting.RED; +import static net.minecraft.util.Formatting.YELLOW; @UCUtilsListener public class MedicListener implements IMessageReceiveListener { @@ -44,14 +47,16 @@ public class MedicListener implements IMessageReceiveListener { private static final Pattern MEDIC_PILL_PATTERN = compile("^\\[Medic] Doktor (?:\\[UC])?(?[a-zA-Z0-9_]+) hat dir Schmerzpillen verabreicht\\.$"); private static final Pattern MEDIC_PILL_GIVE_PATTERN = compile("^\\[Medic] Du hast (?:\\[UC])?(?[a-zA-Z0-9_]+) Schmerzpillen verabreicht\\.$"); private static final Pattern MEDIC_REVIVE_START_PATTERN = compile("^Du beginnst mit der Wiederbelebung von (?:\\[UC])?(?[a-zA-Z0-9_]+)\\.\\.\\.$"); - private static final Pattern HOUSEBAN_HEADER_PATTERN = compile("^=== Hausverbote \\(\\d+\\) ===$"); - private static final Pattern HOUSEBAN_ENTRY_PATTERN = compile("^» (?:\\[UC])?(?[a-zA-Z0-9_]+) ➲ (?.+) ➲ \\d+d \\((?\\d+)\\.(?\\d+)\\.(?\\d+) (?\\d+):(?\\d+)\\)$"); - private static final Pattern HOUSEBAN_ADD_PATTERN = compile("^\\[HV] » (?:\\[UC])?(?[a-zA-Z0-9_]+) hat (?:\\[UC])?(?[a-zA-Z0-9_]+)s Hausverbot gegeben\\. » (?.+) » \\d+d \\((?\\d+)\\.(?\\d+)\\.(?\\d+) (?\\d+):(?\\d+)\\)$"); - private static final Pattern HOUSEBAN_REMOVE_PATTERN = compile("^\\[HV] » (?:\\[UC])?(?[a-zA-Z0-9_]+) hat (?:\\[UC])?(?[a-zA-Z0-9_]+)s Hausverbot aufgehoben\\.$"); - private static final Pattern FIRST_AID_PATTERN = compile("^\\[Erste-Hilfe] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat dir ein Erste-Hilfe-Schein für 14 Tage ausgestellt\\.$"); - private static final Pattern FIRST_AID_LICENCES_PATTERN = compile("^- Erste-Hilfe-Schein: Vorhanden$"); private static final Pattern LABOR_TRANSPORT_STARTED_PATTERN = compile("^\\[ʟᴀʙᴏʀ] Transport gestartet: (?\\d+) ᴋɪsᴛᴇɴ mit (?\\d+) (?.+)$"); - private static final Pattern FIRE_START_PATTERN = compile("^News: Es wurde ein Feuer bei .+ gemeldet!$"); + private static final Pattern STORAGE_INGREDIENT_SHARE_PATTERN = compile("^.+ (?:\\[UC])?(?[a-zA-Z0-9_]+): (?\\d+)x Wirkstoff \\| (?\\d+)x Trägerstoff \\| (?\\d+)x Zusatzstoff$"); + private static final Pattern STORAGE_INGREDIENT_ACCEPT_PATTERN = compile("^.+ (?:\\[UC])?(?[a-zA-Z0-9_]+): Ich nehme (?Wirkstoff|Trägerstoff|Zusatzstoff)! \\(geschätzt: (?\\d+) → (?\\d+)\\)$"); + + private static final MutableText STORAGE_TEXT = empty() + .append(literal("ʟ").withColor(Color.decode("#AA0000").getRGB())) + .append(literal("ᴀ").withColor(Color.decode("#BF1515").getRGB())) + .append(literal("ʙ").withColor(Color.decode("#D52B2B").getRGB())) + .append(literal("ᴏ").withColor(Color.decode("#EA4040").getRGB())) + .append(literal("ʀ").withColor(Color.decode("#FF5555").getRGB())); @Override public boolean onMessageReceive(Text text, String message) { @@ -87,89 +92,92 @@ public boolean onMessageReceive(Text text, String message) { return true; } - Matcher housebanHeaderMatcher = HOUSEBAN_HEADER_PATTERN.matcher(message); - if (housebanHeaderMatcher.find()) { - storage.getHousebanEntries().clear(); - return commandService.showCommandOutputMessage("hausverbot"); - } - - Matcher housebanEntryMatcher = HOUSEBAN_ENTRY_PATTERN.matcher(message); - if (housebanEntryMatcher.find()) { - HousebanEntry housebanEntry = getHousebanEntry(housebanEntryMatcher); - storage.getHousebanEntries().add(housebanEntry); - return commandService.showCommandOutputMessage("hausverbot"); - } - - Matcher housebanAddMatcher = HOUSEBAN_ADD_PATTERN.matcher(message); - if (housebanAddMatcher.find()) { - String playerName = housebanAddMatcher.group("playerName"); - String reason = housebanAddMatcher.group("reason"); - int expireDateDay = parseInt(housebanAddMatcher.group("expireDateDay")); - int expireDateMonth = parseInt(housebanAddMatcher.group("expireDateMonth")); - int expireDateYear = parseInt(housebanAddMatcher.group("expireDateYear")); - int expireTimeHour = parseInt(housebanAddMatcher.group("expireTimeHour")); - int expireTimeMinute = parseInt(housebanAddMatcher.group("expireTimeMinute")); - - storage.getHousebanEntries().removeIf(housebanEntry -> housebanEntry.getPlayerName().equals(playerName)); - LocalDateTime unbanDateTime = LocalDateTime.of(expireDateYear, expireDateMonth, expireDateDay, expireTimeHour, expireTimeMinute); - HousebanEntry housebanEntry = new HousebanEntry(playerName, singletonList(reason), unbanDateTime); - storage.getHousebanEntries().add(housebanEntry); + Matcher laborTransportStartedMatcher = LABOR_TRANSPORT_STARTED_PATTERN.matcher(message); + if (laborTransportStartedMatcher.find()) { + Duration duration = ofMinutes(5).plusSeconds(56); // please don't ask why it is like this + storage.getCountdowns().add(new Countdown("Labor Transport", duration, () -> {})); return true; } - Matcher housebanRemoveMatcher = HOUSEBAN_REMOVE_PATTERN.matcher(message); - if (housebanRemoveMatcher.find()) { - String playerName = housebanRemoveMatcher.group("playerName"); - storage.getHousebanEntries().removeIf(housebanEntry -> housebanEntry.getPlayerName().equals(playerName)); - return true; - } + Matcher storageIngredientShareMatcher = STORAGE_INGREDIENT_SHARE_PATTERN.matcher(message); + if (storageIngredientShareMatcher.find()) { + String playerName = storageIngredientShareMatcher.group("playerName"); + int ingredient1 = parseInt(storageIngredientShareMatcher.group("ingredient1")); + int ingredient2 = parseInt(storageIngredientShareMatcher.group("ingredient2")); + int ingredient3 = parseInt(storageIngredientShareMatcher.group("ingredient3")); - Matcher firstAidMatcher = FIRST_AID_PATTERN.matcher(message); - if (firstAidMatcher.find()) { - configuration.setFirstAidLicenseExpireDateTime(now().plusDays(14)); - return true; - } + player.sendMessage(empty(), false); - Matcher firstAidLicencesMatcher = FIRST_AID_LICENCES_PATTERN.matcher(message); - if (firstAidLicencesMatcher.find()) { - MutableText overwriteText = text.copy().append(" ") - .append(of("bis " + ofNullable(configuration.getFirstAidLicenseExpireDateTime()) - .map(messageService::dateTimeToFriendlyString) - .orElse("Unbekannt")).copy().formatted(AQUA)); + MutableText storageText = empty() + .append(literal("[").formatted(DARK_GRAY)) + .append(STORAGE_TEXT) + .append(literal("] ").formatted(DARK_GRAY)) + .append(literal("Aktueller Bestand (geteilt von " + playerName + ")").formatted(GRAY)) + .append(literal(":").formatted(DARK_GRAY)); - player.sendMessage(overwriteText, false); - return false; // hide message - } + player.sendMessage(storageText, false); - Matcher laborTransportStartedMatcher = LABOR_TRANSPORT_STARTED_PATTERN.matcher(message); - if (laborTransportStartedMatcher.find()) { - Duration duration = ofMinutes(5).plusSeconds(56); // please don't ask why it is like this - storage.getCountdowns().add(new Countdown("Labor Transport", duration, () -> {})); - return true; + player.sendMessage(getIngredientText("Wirkstoff", ingredient1), false); + player.sendMessage(getIngredientText("Trägerstoff", ingredient2), false); + player.sendMessage(getIngredientText("Zusatzstoff", ingredient3), false); + + player.sendMessage(empty(), false); + return false; } - Faction playerFaction = storage.getFaction(player.getGameProfile().name()); - Matcher fireStartMatcher = FIRE_START_PATTERN.matcher(message); - if (fireStartMatcher.find() && configuration.getOptions().sound().fire().verify(playerFaction)) { - FIRE.play(); - return true; + Matcher storageIngredientAcceptMatcher = STORAGE_INGREDIENT_ACCEPT_PATTERN.matcher(message); + if (storageIngredientAcceptMatcher.find()) { + String playerName = storageIngredientAcceptMatcher.group("playerName"); + String ingredient = storageIngredientAcceptMatcher.group("ingredient"); + int amountBefore = parseInt(storageIngredientAcceptMatcher.group("amountBefore")); + int amountAfter = parseInt(storageIngredientAcceptMatcher.group("amountAfter")); + + player.sendMessage(empty() + .append(literal("[").formatted(DARK_GRAY)) + .append(STORAGE_TEXT) + .append(literal("] ").formatted(DARK_GRAY)) + .append(literal(playerName).formatted(RED)) + .append(literal(" übernimmt ").formatted(GRAY)) + .append(literal(ingredient).formatted(RED)) + .append(literal(":").formatted(DARK_GRAY)), false); + + player.sendMessage(empty() + .append(literal(" > ").formatted(DARK_GRAY)) + .append(literal("Geschätzte Menge nach Transport").formatted(GRAY)) + .append(literal(": ").formatted(DARK_GRAY)) + .append(literal(amountBefore + " → ").formatted(GRAY)) + .append(literal(valueOf(amountAfter)).formatted(getColor(amountAfter), BOLD)), false); + return false; } return true; } - private @NotNull HousebanEntry getHousebanEntry(@NotNull MatchResult housebanEntryMatcher) { - String playerName = housebanEntryMatcher.group("playerName"); - String reasonsRaw = housebanEntryMatcher.group("reasons"); - int expireDateDay = parseInt(housebanEntryMatcher.group("expireDateDay")); - int expireDateMonth = parseInt(housebanEntryMatcher.group("expireDateMonth")); - int expireDateYear = parseInt(housebanEntryMatcher.group("expireDateYear")); - int expireTimeHour = parseInt(housebanEntryMatcher.group("expireTimeHour")); - int expireTimeMinute = parseInt(housebanEntryMatcher.group("expireTimeMinute")); - - String[] reasons = reasonsRaw.split(" \\+ "); + private MutableText getIngredientText(String ingredient, int amount) { + return empty() + .append(literal(" > ").formatted(DARK_GRAY)) + .append(literal("[").formatted(DARK_GRAY)) + .append(literal("Ich übernehme!").styled(style -> style + .withFormatting(DARK_AQUA) + .withHoverEvent(new HoverEvent.ShowText(literal("Klicke um bescheid zu sagen, dass Du den Transport übernimmst"))) + .withClickEvent(new ClickEvent.RunCommand("/f Ich nehme " + ingredient + "! (geschätzt: " + amount + " → " + (amount + 20) + ")")))) + .append(literal("] ").formatted(DARK_GRAY)) + .append(literal(ingredient).formatted(GRAY)) + .append(literal(": ").formatted(DARK_GRAY)) + .append(literal(valueOf(amount)).formatted(getColor(amount), BOLD)); + } - LocalDateTime unbanDateTime = LocalDateTime.of(expireDateYear, expireDateMonth, expireDateDay, expireTimeHour, expireTimeMinute); - return new HousebanEntry(playerName, asList(reasons), unbanDateTime); + private Formatting getColor(int amount) { + if (amount >= 80) { + return DARK_GREEN; + } else if (amount >= 60) { + return GREEN; + } else if (amount >= 40) { + return YELLOW; + } else if (amount >= 20) { + return GOLD; + } else { + return RED; + } } } diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/PlantListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/PlantListener.java deleted file mode 100644 index b7ca5645..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/PlantListener.java +++ /dev/null @@ -1,209 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.faction; - -import de.rettichlp.ucutils.common.models.PlantEntry; -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IBlockRightClickListener; -import de.rettichlp.ucutils.listener.IEntityRenderListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import de.rettichlp.ucutils.listener.IScreenOpenListener; -import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderContext; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.HopperScreen; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.messageService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.renderService; -import static de.rettichlp.ucutils.UCUtils.storage; -import static java.time.Duration.between; -import static java.time.LocalDateTime.now; -import static java.util.Objects.nonNull; -import static java.util.regex.Pattern.compile; -import static net.minecraft.block.Blocks.FERN; -import static net.minecraft.block.Blocks.PODZOL; -import static net.minecraft.entity.EquipmentSlot.MAINHAND; -import static net.minecraft.item.Items.BEETROOT_SEEDS; -import static net.minecraft.item.Items.BONE_MEAL; -import static net.minecraft.item.Items.WATER_BUCKET; -import static net.minecraft.screen.slot.SlotActionType.PICKUP; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.AQUA; -import static net.minecraft.util.Formatting.BLUE; -import static net.minecraft.util.Formatting.GOLD; -import static net.minecraft.util.Formatting.GRAY; -import static net.minecraft.util.Formatting.GREEN; -import static net.minecraft.util.Formatting.RED; - -@UCUtilsListener -public class PlantListener implements IBlockRightClickListener, IEntityRenderListener, IMessageReceiveListener, IScreenOpenListener { - - private static final String PLANT_TEXT = "Plantage"; - private static final Pattern PLANT_PLANT_PATTERN = compile("^\\[Plantage] (?:\\[UC])?(?[a-zA-Z0-9_]+) hat eine (Kräuter|Pulver)-Plantage gelegt\\. \\[\\d+/10]$"); - private static final Pattern PLANT_WATER_PATTERN = compile("^\\[Plantage] Eine (Kräuter|Pulver)-Plantage wurde von (?:\\[UC])?(?[a-zA-Z0-9_]+) gewässert\\.$"); - private static final Pattern PLANT_FERTILIZE_PATTERN = compile("^\\[Plantage] Eine (Kräuter|Pulver)-Plantage wurde von (?:\\[UC])?(?[a-zA-Z0-9_]+) gedüngt\\.$"); - - private static final int PLANT_WATERING_INTERVAL_MINUTES = 40; - private static final int PLANT_FERTILIZING_INTERVAL_MINUTES = 45; - - @Override - public void onBlockRightClick(World world, Hand hand, BlockHitResult hitResult) { - BlockPos blockPos = hitResult.getBlockPos(); - - boolean targetBlockIsPlant = world.getBlockState(blockPos).getBlock().equals(FERN) && world.getBlockState(blockPos.down()).getBlock().equals(PODZOL); - if (!targetBlockIsPlant) { - // check for plant placing - ItemStack mainHandStack = player.getEquippedStack(MAINHAND); - - if (player.isSneaking() && (mainHandStack.isOf(BEETROOT_SEEDS))) { - commandService.sendCommand("plant plant"); - } - - return; - } - - boolean isStandingOnPlant = player.getBlockPos().equals(blockPos); - if (!isStandingOnPlant) { - messageService.sendModMessage("Du musst auf der Plantage stehen, um sie via UCUtils zu verwalten.", false); - return; - } - - commandService.sendCommand("plant"); - } - - @Override - public void onEntityRender(WorldRenderContext context) { - MatrixStack matrices = context.matrices(); - VertexConsumerProvider vertexConsumers = context.consumers(); - ClientWorld world = MinecraftClient.getInstance().world; - - if (nonNull(matrices) && nonNull(vertexConsumers) && nonNull(world)) { - // create a copy to avoid ConcurrentModificationException - new ArrayList<>(storage.getPlantEntries()).forEach(plantEntry -> { - Vec3d centerBlockPos = plantEntry.getBlockPos().toCenterPos(); - double x = centerBlockPos.x; - double y = centerBlockPos.y; - double z = centerBlockPos.z; - - // only render if the player is nearby - if (!player.getBlockPos().isWithinDistance(plantEntry.getBlockPos(), 15)) { - return; - } - - Text waterText; - LocalDateTime lastWateredAt = plantEntry.getLastWateredAt(); - if (nonNull(lastWateredAt)) { - LocalDateTime nextWateringAt = lastWateredAt.plusMinutes(PLANT_WATERING_INTERVAL_MINUTES); - Duration durationUntilNextWatering = between(now(), nextWateringAt); - long millis = durationUntilNextWatering.toMillis(); - - waterText = empty() - .append(of("🫗").copy().formatted(BLUE)).append(" ") - .append(of(messageService.millisToFriendlyString(millis)).copy().formatted(getTextColor(millis))); - } else { - waterText = of("↓").copy().formatted(AQUA); - } - - Text fertilizeText; - LocalDateTime lastFertilizedAt = plantEntry.getLastFertilizedAt(); - if (nonNull(lastFertilizedAt)) { - LocalDateTime nextFertilizingAt = lastFertilizedAt.plusMinutes(PLANT_FERTILIZING_INTERVAL_MINUTES); - Duration durationUntilNextFertilizing = between(now(), nextFertilizingAt); - long millis = durationUntilNextFertilizing.toMillis(); - - fertilizeText = empty() - .append(of("🫘").copy().formatted(GOLD)).append(" ") - .append(of(messageService.millisToFriendlyString(millis)).copy().formatted(getTextColor(millis))); - } else { - fertilizeText = of("↓").copy().formatted(AQUA); - } - - renderService.renderTextAt(matrices, vertexConsumers, x, y + 0.75, z, waterText, 0.015f); - renderService.renderTextAt(matrices, vertexConsumers, x, y + 0.6, z, fertilizeText, 0.015f); - }); - } - } - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher plantPlantMatcher = PLANT_PLANT_PATTERN.matcher(message); - if (plantPlantMatcher.find() && player.getGameProfile().name().equals(plantPlantMatcher.group("playerName"))) { - BlockPos blockPos = player.getBlockPos(); - - PlantEntry plantEntry = new PlantEntry(blockPos, now()); - storage.getPlantEntries().add(plantEntry); - - return true; - } - - Matcher plantFertilizeMatcher = PLANT_FERTILIZE_PATTERN.matcher(message); - if (plantFertilizeMatcher.find()) { - BlockPos blockPos = player.getBlockPos(); - - storage.getPlantEntries().stream() - .filter(plantEntry -> plantEntry.getBlockPos().equals(blockPos)) - .findAny().ifPresent(plantEntry -> plantEntry.setLastFertilizedAt(now())); - - return true; - } - - Matcher plantWaterMatcher = PLANT_WATER_PATTERN.matcher(message); - if (plantWaterMatcher.find()) { - BlockPos blockPos = player.getBlockPos(); - - storage.getPlantEntries().stream() - .filter(plantEntry -> plantEntry.getBlockPos().equals(blockPos)) - .findAny().ifPresent(plantEntry -> plantEntry.setLastWateredAt(now())); - - return true; - } - - return true; - } - - @Override - public void onScreenOpen(Screen screen, int scaledWidth, int scaledHeight) { - ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager; - - if (interactionManager != null && screen instanceof HopperScreen hopperScreen && PLANT_TEXT.equals(hopperScreen.getTitle().getString())) { - ItemStack mainHandStack = player.getEquippedStack(MAINHAND); - - int syncId = hopperScreen.getScreenHandler().syncId; - // // https://i.imgur.com/b8INthP.png - if (mainHandStack.isOf(WATER_BUCKET)) { - interactionManager.clickSlot(syncId, 4, 0, PICKUP, player); - } else if (mainHandStack.isOf(BONE_MEAL)) { - interactionManager.clickSlot(syncId, 3, 0, PICKUP, player); - } - } - } - - private Formatting getTextColor(long millis) { - if (millis < 0) { - return RED; - } else if (millis <= 3 * 60 * 1000) { - return GREEN; - } else { - return GRAY; - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/job/AnglerListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/job/AnglerListener.java new file mode 100644 index 00000000..33e683c1 --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/job/AnglerListener.java @@ -0,0 +1,108 @@ +package de.rettichlp.ucutils.listener.impl.job; + +import de.rettichlp.ucutils.common.registry.UCUtilsListener; +import de.rettichlp.ucutils.listener.IMessageReceiveListener; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.component.type.MapIdComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.item.map.MapState; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static de.rettichlp.ucutils.UCUtils.LOGGER; +import static de.rettichlp.ucutils.UCUtils.player; +import static de.rettichlp.ucutils.UCUtils.storage; +import static de.rettichlp.ucutils.UCUtils.utilService; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import static java.util.regex.Pattern.compile; +import static javax.imageio.ImageIO.write; +import static net.minecraft.block.MapColor.getRenderColor; +import static net.minecraft.component.DataComponentTypes.MAP_ID; +import static net.minecraft.item.FilledMapItem.getMapState; +import static net.minecraft.item.Items.FILLED_MAP; +import static net.minecraft.item.Items.FISHING_ROD; +import static net.minecraft.util.Hand.MAIN_HAND; + +@UCUtilsListener +public class AnglerListener implements IMessageReceiveListener { + + private static final Pattern ANGLER_CAPTCHA_PATTERN = compile("^Lies den Code auf der Karte in deiner Nebenhand ab und schreib ihn in den Chat\\.$"); + private static final Pattern ANGLER_CAPTCHA_CONTINUED_PATTERN = compile("^Deine Combo wurde fortgesetzt! \\(\\d+\\)$"); + + @Override + public boolean onMessageReceive(Text text, String message) { + MinecraftClient client = MinecraftClient.getInstance(); + + Matcher anglerCaptchaMatcher = ANGLER_CAPTCHA_PATTERN.matcher(message); + if (anglerCaptchaMatcher.find()) { + utilService.delayedAction(() -> { + ItemStack offHandStack = player.getOffHandStack(); + if (offHandStack.isOf(FILLED_MAP)) { + MapIdComponent captchaMap = offHandStack.get(MAP_ID); + storage.setCaptchaMap(captchaMap); + saveCaptchaImage(captchaMap); + } + }, 500); + + return true; + } + + Matcher anglerCaptchaContinuedMatcher = ANGLER_CAPTCHA_CONTINUED_PATTERN.matcher(message); + if (anglerCaptchaContinuedMatcher.find()) { + storage.setCaptchaMap(null); + + ClientPlayerInteractionManager interactionManager = client.interactionManager; + if (interactionManager == null || !player.getMainHandStack().isOf(FISHING_ROD)) { + return true; + } + + interactionManager.interactItem(player, MAIN_HAND); + player.swingHand(MAIN_HAND); + return true; + } + + return true; + } + + private void saveCaptchaImage(MapIdComponent captchaMap) { + BufferedImage mapImage = getMapImage(captchaMap); + if (mapImage == null) { + return; + } + + File outputFile = new File("screenshots/ucutils/captcha.png"); + + try { + outputFile.mkdirs(); + outputFile.createNewFile(); + write(mapImage, "PNG", outputFile); + } catch (Exception e) { + LOGGER.error("Failed to save captcha image", e); + } + } + + private @Nullable BufferedImage getMapImage(MapIdComponent mapIdComponent) { + MapState mapState = getMapState(mapIdComponent, MinecraftClient.getInstance().world); + if (mapState == null) { + return null; + } + + BufferedImage mapImage = new BufferedImage(128, 128, TYPE_INT_RGB); + + for (int i = 0; i < mapState.colors.length; i++) { + int x = i % 128; + int y = i / 128; + + int argb = getRenderColor(mapState.colors[i]); + mapImage.setRGB(x, y, argb); + } + + return mapImage; + } +} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/job/DeepSeaFisherListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/job/DeepSeaFisherListener.java new file mode 100644 index 00000000..c520b8e8 --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/job/DeepSeaFisherListener.java @@ -0,0 +1,138 @@ +package de.rettichlp.ucutils.listener.impl.job; + +import de.rettichlp.ucutils.common.registry.UCUtilsListener; +import de.rettichlp.ucutils.listener.IMessageReceiveListener; +import de.rettichlp.ucutils.listener.INaviSpotReachedListener; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static de.rettichlp.ucutils.UCUtils.commandService; +import static de.rettichlp.ucutils.UCUtils.player; +import static java.lang.Double.compare; +import static java.util.Arrays.stream; +import static java.util.regex.Pattern.compile; + +@UCUtilsListener +public class DeepSeaFisherListener implements IMessageReceiveListener, INaviSpotReachedListener { + + private static final Pattern DEEP_SEA_FISHER_START_PATTERN = compile("^\\[Fischer] Mit /findschwarm kannst du dir den nächsten Fischschwarm anzeigen lassen\\.$"); + private static final Pattern DEEP_SEA_FISHER_SPOT_FOUND_PATTERN = compile("^\\[Fischer] Du hast einen Fischschwarm gefunden!$"); + private static final Pattern DEEP_SEA_FISHER_SPOT_LOST_PATTERN = compile("^\\[Fischer] Du hast dich dem Fischschwarm zu weit entfernt\\.$"); + private static final Pattern DEEP_SEA_FISHER_CATCH_SUCCESS_PATTERN = compile("^\\[Fischer] Du hast \\d+kg frischen Fisch gefangen! \\(\\d+kg\\)$"); + private static final Pattern DEEP_SEA_FISHER_CATCH_FAILURE_PATTERN = compile("^\\[Fischer] Du hast das Fischernetz verloren\\.\\.\\.$"); + private static final int NET_AMOUNT = 5; + + private Collection visitedDeepSeaFisherJobSpots = new ArrayList<>(); + private boolean onDeepSeaFisherSpot = false; + private boolean canCatchFish = true; + + @Override + public boolean onMessageReceive(Text text, String message) { + Matcher deepSeaFisherStartMatcher = DEEP_SEA_FISHER_START_PATTERN.matcher(message); + if (deepSeaFisherStartMatcher.find()) { + this.visitedDeepSeaFisherJobSpots = new ArrayList<>(); + DeepSeaFisherJobSpot.SPOT_1.startNavigation(); + return true; + } + + Matcher deepSeaFisherSpotFoundMatcher = DEEP_SEA_FISHER_SPOT_FOUND_PATTERN.matcher(message); + if (deepSeaFisherSpotFoundMatcher.find()) { + commandService.sendCommand("stoproute"); + this.onDeepSeaFisherSpot = true; + + if (this.canCatchFish) { + startFishing(); + } + + return true; + } + + Matcher deepSeaFisherSpotLostMatcher = DEEP_SEA_FISHER_SPOT_LOST_PATTERN.matcher(message); + if (deepSeaFisherSpotLostMatcher.find()) { + this.onDeepSeaFisherSpot = false; + return true; + } + + Matcher deepSeaFisherCatchSuccessMatcher = DEEP_SEA_FISHER_CATCH_SUCCESS_PATTERN.matcher(message); + Matcher deepSeaFisherCatchFailureMatcher = DEEP_SEA_FISHER_CATCH_FAILURE_PATTERN.matcher(message); + if (deepSeaFisherCatchSuccessMatcher.find() || deepSeaFisherCatchFailureMatcher.find()) { + this.canCatchFish = true; + + // if already on the next fishing spot, start fishing again + if (this.onDeepSeaFisherSpot) { + startFishing(); + } + } + + return true; + } + + @Override + public void onNaviSpotReached() { + if (this.visitedDeepSeaFisherJobSpots.size() == NET_AMOUNT) { + this.visitedDeepSeaFisherJobSpots = new ArrayList<>(); + commandService.sendCommand("dropfish"); + } + } + + private void startFishing() { + this.onDeepSeaFisherSpot = false; + this.canCatchFish = false; + commandService.sendCommand("catchfish"); + + // add the current spot to visited spots + getNearestFisherJobSpot(getNotVisitedFisherJobSpots()).ifPresent(this.visitedDeepSeaFisherJobSpots::add); + + if (this.visitedDeepSeaFisherJobSpots.size() == NET_AMOUNT) { + return; + } + + // get nearest next spot and start navigation + Optional nearestNextFisherJobSpot = getNearestFisherJobSpot(getNotVisitedFisherJobSpots()); + nearestNextFisherJobSpot.ifPresent(DeepSeaFisherJobSpot::startNavigation); + } + + private @NotNull Optional getNearestFisherJobSpot(@NotNull Collection deepSeaFisherJobSpots) { + return deepSeaFisherJobSpots.stream() + .min((spot1, spot2) -> { + double distance1 = player.squaredDistanceTo(spot1.getPosition().getX(), spot1.getPosition().getY(), spot1.getPosition().getZ()); + double distance2 = player.squaredDistanceTo(spot2.getPosition().getX(), spot2.getPosition().getY(), spot2.getPosition().getZ()); + return compare(distance1, distance2); + }); + } + + private @NotNull @Unmodifiable List getNotVisitedFisherJobSpots() { + return stream(DeepSeaFisherJobSpot.values()) + .filter(deepSeaFisherJobSpot -> !this.visitedDeepSeaFisherJobSpots.contains(deepSeaFisherJobSpot)) + .toList(); + } + + @Getter + @AllArgsConstructor + private enum DeepSeaFisherJobSpot { + + SPOT_1(new BlockPos(-571, 63, 160)), + SPOT_2(new BlockPos(-554, 63, 107)), + SPOT_3(new BlockPos(-568, 63, 50)), + SPOT_4(new BlockPos(-522, 63, 10)), + SPOT_5(new BlockPos(-521, 63, 78)); + + private final BlockPos position; + + public void startNavigation() { + String naviCommandString = "navi " + this.position.getX() + "/" + this.position.getY() + "/" + this.position.getZ(); + commandService.sendCommand(naviCommandString); + } + } +} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/job/FisherListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/job/FisherListener.java deleted file mode 100644 index e4c211bc..00000000 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/job/FisherListener.java +++ /dev/null @@ -1,138 +0,0 @@ -package de.rettichlp.ucutils.listener.impl.job; - -import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import de.rettichlp.ucutils.listener.INaviSpotReachedListener; -import lombok.AllArgsConstructor; -import lombok.Getter; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Unmodifiable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.player; -import static java.lang.Double.compare; -import static java.util.Arrays.stream; -import static java.util.regex.Pattern.compile; - -@UCUtilsListener -public class FisherListener implements IMessageReceiveListener, INaviSpotReachedListener { - - private static final Pattern FISHER_START = compile("^\\[Fischer] Mit /findschwarm kannst du dir den nächsten Fischschwarm anzeigen lassen\\.$"); - private static final Pattern FISHER_SPOT_FOUND_PATTERN = compile("^\\[Fischer] Du hast einen Fischschwarm gefunden!$"); - private static final Pattern FISHER_SPOT_LOST_PATTERN = compile("^\\[Fischer] Du hast dich dem Fischschwarm zu weit entfernt\\.$"); - private static final Pattern FISHER_CATCH_SUCCESS = compile("^\\[Fischer] Du hast \\d+kg frischen Fisch gefangen! \\(\\d+kg\\)$"); - private static final Pattern FISHER_CATCH_FAILURE = compile("^\\[Fischer] Du hast das Fischernetz verloren\\.\\.\\.$"); - private static final int NET_AMOUNT = 5; - - private Collection visitedFisherJobSpots = new ArrayList<>(); - private boolean onFisherSpot = false; - private boolean canCatchFish = true; - - @Override - public boolean onMessageReceive(Text text, String message) { - Matcher fisherStartMatcher = FISHER_START.matcher(message); - if (fisherStartMatcher.find()) { - this.visitedFisherJobSpots = new ArrayList<>(); - FisherJobSpot.SPOT_1.startNavigation(); - return true; - } - - Matcher fisherSpotFoundMatcher = FISHER_SPOT_FOUND_PATTERN.matcher(message); - if (fisherSpotFoundMatcher.find()) { - commandService.sendCommand("stoproute"); - this.onFisherSpot = true; - - if (this.canCatchFish) { - startFishing(); - } - - return true; - } - - Matcher fisherSpotLostMatcher = FISHER_SPOT_LOST_PATTERN.matcher(message); - if (fisherSpotLostMatcher.find()) { - this.onFisherSpot = false; - return true; - } - - Matcher fisherCatchSuccessMatcher = FISHER_CATCH_SUCCESS.matcher(message); - Matcher fisherCatchFailureMatcher = FISHER_CATCH_FAILURE.matcher(message); - if (fisherCatchSuccessMatcher.find() || fisherCatchFailureMatcher.find()) { - this.canCatchFish = true; - - // if already on the next fishing spot, start fishing again - if (this.onFisherSpot) { - startFishing(); - } - } - - return true; - } - - @Override - public void onNaviSpotReached() { - if (this.visitedFisherJobSpots.size() == NET_AMOUNT) { - this.visitedFisherJobSpots = new ArrayList<>(); - commandService.sendCommand("dropfish"); - } - } - - private void startFishing() { - this.onFisherSpot = false; - this.canCatchFish = false; - commandService.sendCommand("catchfish"); - - // add the current spot to visited spots - getNearestFisherJobSpot(getNotVisitedFisherJobSpots()).ifPresent(this.visitedFisherJobSpots::add); - - if (this.visitedFisherJobSpots.size() == NET_AMOUNT) { - return; - } - - // get nearest next spot and start navigation - Optional nearestNextFisherJobSpot = getNearestFisherJobSpot(getNotVisitedFisherJobSpots()); - nearestNextFisherJobSpot.ifPresent(FisherJobSpot::startNavigation); - } - - private @NotNull Optional getNearestFisherJobSpot(@NotNull Collection fisherJobSpots) { - return fisherJobSpots.stream() - .min((spot1, spot2) -> { - double distance1 = player.squaredDistanceTo(spot1.getPosition().getX(), spot1.getPosition().getY(), spot1.getPosition().getZ()); - double distance2 = player.squaredDistanceTo(spot2.getPosition().getX(), spot2.getPosition().getY(), spot2.getPosition().getZ()); - return compare(distance1, distance2); - }); - } - - private @NotNull @Unmodifiable List getNotVisitedFisherJobSpots() { - return stream(FisherJobSpot.values()) - .filter(fisherJobSpot -> !this.visitedFisherJobSpots.contains(fisherJobSpot)) - .toList(); - } - - @Getter - @AllArgsConstructor - private enum FisherJobSpot { - - SPOT_1(new BlockPos(-571, 63, 160)), - SPOT_2(new BlockPos(-554, 63, 107)), - SPOT_3(new BlockPos(-568, 63, 50)), - SPOT_4(new BlockPos(-522, 63, 10)), - SPOT_5(new BlockPos(-521, 63, 78)); - - private final BlockPos position; - - public void startNavigation() { - String naviCommandString = "navi " + this.position.getX() + "/" + this.position.getY() + "/" + this.position.getZ(); - commandService.sendCommand(naviCommandString); - } - } -} diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/job/JobListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/job/JobListener.java index c4610d1f..dac213bb 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/job/JobListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/job/JobListener.java @@ -4,7 +4,6 @@ import de.rettichlp.ucutils.common.models.Job; import de.rettichlp.ucutils.common.registry.UCUtilsListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import de.rettichlp.ucutils.listener.IMoveListener; import de.rettichlp.ucutils.listener.INaviSpotReachedListener; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; @@ -20,7 +19,6 @@ import static de.rettichlp.ucutils.UCUtils.utilService; import static de.rettichlp.ucutils.common.models.Job.PIZZA_DELIVERY; import static de.rettichlp.ucutils.common.models.Job.TOBACCO_PLANTATION; -import static de.rettichlp.ucutils.common.models.Job.URANIUM_TRANSPORT; import static java.lang.Integer.parseInt; import static java.time.Duration.between; import static java.time.LocalDateTime.now; @@ -30,7 +28,7 @@ import static java.util.regex.Pattern.compile; @UCUtilsListener -public class JobListener implements IMessageReceiveListener, IMoveListener, INaviSpotReachedListener { +public class JobListener implements IMessageReceiveListener, INaviSpotReachedListener { private static final String MINING_BOOSTER_COUNTDOWN_TITLE = "Mining XP-Booster"; private static final Pattern TRANSPORT_DELIVER_PATTERN = compile("^\\[Transport] Du hast (eine Holz Lieferung|eine Kiste|eine Waffenkiste|ein Weizen Paket|eine Schwarzpulverkiste) abgeliefert( bei .+)?\\.$"); @@ -89,17 +87,6 @@ public boolean onMessageReceive(Text text, String message) { return true; } - @Override - public void onMove(BlockPos blockPos) { - if (isNull(storage.getCurrentJob())) { - return; - } - - if (storage.getCurrentJob() == URANIUM_TRANSPORT && player.getBlockPos().isWithinDistance(new BlockPos(1132, 68, 396), 2)) { - commandService.sendCommand("dropuran"); - } - } - @Override public void onNaviSpotReached() { if (isNull(storage.getCurrentJob())) { diff --git a/src/main/java/de/rettichlp/ucutils/mixin/AbstractMinecartEntityRendererMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/AbstractMinecartEntityRendererMixin.java new file mode 100644 index 00000000..c68410d7 --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/mixin/AbstractMinecartEntityRendererMixin.java @@ -0,0 +1,32 @@ +package de.rettichlp.ucutils.mixin; + +import net.minecraft.client.render.entity.AbstractMinecartEntityRenderer; +import net.minecraft.client.render.entity.state.MinecartEntityRenderState; +import net.minecraft.entity.vehicle.AbstractMinecartEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static de.rettichlp.ucutils.UCUtils.configuration; +import static de.rettichlp.ucutils.UCUtils.storage; + +@Mixin(AbstractMinecartEntityRenderer.class) +public class AbstractMinecartEntityRendererMixin { + + @Inject(method = "updateRenderState(Lnet/minecraft/entity/vehicle/AbstractMinecartEntity;Lnet/minecraft/client/render/entity/state/MinecartEntityRenderState;F)V", + at = @At("TAIL")) + private void ucutils$updateRenderStateTail(T entity, S state, float tickDelta, CallbackInfo ci) { + if (!storage.isUnicaCity()) { + return; + } + + if (!configuration.getOptions().car().highlight()) { + return; + } + + if (storage.getMinecartEntityToHighlight() != null && storage.getMinecartEntityToHighlight().getUuid().equals(entity.getUuid())) { + state.outlineColor = 0xFFFFAA00; + } + } +} diff --git a/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayNetworkHandlerMixin.java index 19e85849..ee81c8d5 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayNetworkHandlerMixin.java @@ -4,12 +4,18 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket; import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -22,14 +28,19 @@ import static de.rettichlp.ucutils.UCUtils.configuration; import static de.rettichlp.ucutils.UCUtils.notificationService; +import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static java.awt.Color.WHITE; +import static java.lang.System.currentTimeMillis; +import static java.util.Objects.requireNonNull; import static net.minecraft.text.Text.empty; import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; import static net.minecraft.util.Formatting.BLUE; import static net.minecraft.util.Formatting.DARK_GRAY; import static net.minecraft.util.Formatting.GOLD; +import static net.minecraft.util.Formatting.GRAY; +import static net.minecraft.util.Formatting.RED; import static net.minecraft.util.Formatting.YELLOW; import static org.spongepowered.asm.mixin.injection.At.Shift.AFTER; @@ -57,6 +68,50 @@ public abstract class ClientPlayNetworkHandlerMixin { @Unique private final Collection enrichedGameProfiles = new HashSet<>(); + @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) + private void onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci) { + if (!storage.isUnicaCity()) { + return; + } + + ClientWorld world = MinecraftClient.getInstance().world; + if (world == null) { + return; + } + + Entity entity = world.getEntityById(packet.id()); + if (!(entity instanceof VillagerEntity villager) || !villager.hasCustomName()) { + return; + } + + String customNameString = requireNonNull(villager.getCustomName()).getString(); + Vec3d entityPos = villager.getEntityPos(); + + // already notified check + if (entityPos.equals(storage.getDealerPosition()) || entityPos.equals(storage.getBlackMarketPosition())) { + return; + } + + switch (customNameString) { + case "Dealer" -> { + storage.setBlackMarketPosition(entityPos); + player.sendMessage(empty() + .append(literal("[").formatted(DARK_GRAY)) + .append(literal("Dealer").formatted(RED)) + .append(literal("] ").formatted(DARK_GRAY)) + .append(literal("Der Dealer ist in der Nähe!").formatted(GRAY)), false); + } + case "Schwarzmarkt" -> { + storage.setDealerPosition(entityPos); + player.sendMessage(empty() + .append(literal("[").formatted(DARK_GRAY)) + .append(literal("Schwarzmarkt").formatted(RED)) + .append(literal("] ").formatted(DARK_GRAY)) + .append(literal("Der Schwarzmarkt ist in der Nähe!").formatted(GRAY)), false); + } + } + } + @Inject(method = "onPlayerRemove", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/network/PacketApplyBatcher;)V", @@ -104,6 +159,12 @@ public abstract class ClientPlayNetworkHandlerMixin { EnrichedGameProfile enrichedGameProfile = new EnrichedGameProfile(profile, currentDisplayName, currentDisplayName); this.enrichedGameProfiles.removeIf(egp -> egp.getProfile().id().equals(profileId)); this.enrichedGameProfiles.add(enrichedGameProfile); + + // if the client joined the server few moments ago, hide notifications due to initial sync of player list + if (currentTimeMillis() - storage.getJoinTimestamp() < 1000) { + return; + } + sendChangeNotification(enrichedGameProfile, "ucutils.notification.player_join"); } case UPDATE_DISPLAY_NAME -> { diff --git a/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayerEntityMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayerEntityMixin.java index c48a2ea9..cb7891a2 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/ClientPlayerEntityMixin.java @@ -10,8 +10,7 @@ import java.util.List; -import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.networkHandler; +import static de.rettichlp.ucutils.UCUtils.commandService; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; import static net.minecraft.item.Items.GLASS_BOTTLE; @@ -36,8 +35,7 @@ public abstract class ClientPlayerEntityMixin { cir.setReturnValue(null); // execute command - LOGGER.info("UCUtils executing command: sell pfand"); - networkHandler.sendChatCommand("sell pfand"); + commandService.sendCommand("sell pfand"); } } diff --git a/src/main/java/de/rettichlp/ucutils/mixin/DialogScreenMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/DialogScreenMixin.java deleted file mode 100644 index de1ff763..00000000 --- a/src/main/java/de/rettichlp/ucutils/mixin/DialogScreenMixin.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.rettichlp.ucutils.mixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.dialog.DialogScreen; -import net.minecraft.dialog.DialogActionButtonData; -import net.minecraft.dialog.action.DynamicCustomDialogAction; -import net.minecraft.dialog.type.Dialog; -import net.minecraft.dialog.type.MultiActionDialog; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.network.packet.c2s.common.CustomClickActionC2SPacket; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; -import java.util.Optional; - -import static de.rettichlp.ucutils.UCUtils.storage; - -@Mixin(DialogScreen.class) -public abstract class DialogScreenMixin { - - @Shadow - @Final - private T dialog; - - @Inject(method = "init", at = @At("TAIL")) - public void ucutils$initTail(CallbackInfo ci) { - String fBankDepositReason = storage.getFBankDepositReason(); - if (fBankDepositReason.isBlank()) { - return; - } - - DialogScreen self = (DialogScreen) (Object) this; - - if (!(this.dialog instanceof MultiActionDialog multiActionDialog) || !self.getTitle().getString().equals("F-Bank Einzahlung")) { - return; - } - - List actions = multiActionDialog.actions(); - if (actions.isEmpty()) { - return; - } - - DialogActionButtonData dialogActionButtonData = actions.getFirst(); - if (dialogActionButtonData.action().isEmpty() || !(dialogActionButtonData.action().get() instanceof DynamicCustomDialogAction( - Identifier id, Optional additions - ))) { - return; - } - - additions.ifPresent(nbtCompound -> nbtCompound.putString("grund", fBankDepositReason)); - CustomClickActionC2SPacket customClickActionC2SPacket = new CustomClickActionC2SPacket(id, additions.map(nbt -> (NbtElement) nbt)); - - MinecraftClient client = MinecraftClient.getInstance(); - client.getNetworkHandler().sendPacket(customClickActionC2SPacket); - client.setScreen(null); - } -} diff --git a/src/main/java/de/rettichlp/ucutils/mixin/EntityMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/EntityMixin.java index 8bc08543..9f508ead 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/EntityMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/EntityMixin.java @@ -1,46 +1,21 @@ package de.rettichlp.ucutils.mixin; -import de.rettichlp.ucutils.common.configuration.options.NameTagOptions; -import de.rettichlp.ucutils.common.models.BlacklistEntry; -import de.rettichlp.ucutils.common.models.ContractEntry; -import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.models.HousebanEntry; -import de.rettichlp.ucutils.common.models.WantedEntry; -import de.rettichlp.ucutils.listener.callback.PlayerEnterVehicleCallback; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; import net.minecraft.entity.vehicle.MinecartEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.world.entity.UniquelyIdentifiable; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Optional; - +import static de.rettichlp.ucutils.UCUtils.commandService; import static de.rettichlp.ucutils.UCUtils.configuration; -import static de.rettichlp.ucutils.UCUtils.nameTagService; import static de.rettichlp.ucutils.UCUtils.player; import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Color.WHITE; -import static java.time.LocalDateTime.now; -import static net.minecraft.item.Items.SKELETON_SKULL; -import static net.minecraft.item.Items.WITHER_SKELETON_SKULL; -import static net.minecraft.text.Text.empty; -import static net.minecraft.text.Text.literal; -import static net.minecraft.text.Text.of; -import static net.minecraft.util.Formatting.DARK_GRAY; -import static net.minecraft.util.Formatting.DARK_RED; -import static net.minecraft.util.Formatting.GRAY; -import static net.minecraft.util.Formatting.RED; +import static de.rettichlp.ucutils.UCUtils.utilService; @Mixin(Entity.class) public abstract class EntityMixin { @@ -60,8 +35,18 @@ public abstract class EntityMixin { } UniquelyIdentifiable self = (Entity) (Object) this; - if (self.getUuid().equals(player.getUuid())) { - PlayerEnterVehicleCallback.EVENT.invoker().onEnter(vehicle); + if (self.getUuid().equals(player.getUuid()) && vehicle instanceof MinecartEntity) { + storage.setMinecartEntityToHighlight(null); + + if (configuration.getOptions().car().automatedStart() && !storage.isPremium()) { + // start the car with a small delay to ensure the player is fully in the vehicle + utilService.delayedAction(() -> commandService.sendCommand("car start"), 500); + } + + // lock the car after 1 second and the small delay if not already locked + if (!storage.isCarLocked() && configuration.getOptions().car().automatedLock() && !storage.isPremium()) { + utilService.delayedAction(() -> commandService.sendCommand("car lock"), 1500); + } } } @@ -76,101 +61,4 @@ public abstract class EntityMixin { storage.setMinecartEntityToHighlight(minecartEntity); } } - - @Inject(method = "getCustomName", at = @At("RETURN"), cancellable = true) - private void ucutils$getDisplayNameReturn(@NotNull CallbackInfoReturnable cir) { - if (!storage.isUnicaCity()) { - return; - } - - Entity self = (Entity) (Object) this; - if (!(self instanceof ItemEntity itemEntity) || !itemEntity.hasCustomName()) { - return; - } - - ItemStack itemStack = itemEntity.getStack(); - Text returnValue = cir.getReturnValue(); - if (returnValue == null || (!itemStack.isOf(SKELETON_SKULL) && !itemStack.isOf(WITHER_SKELETON_SKULL))) { - return; - } - - String displayNameString = returnValue.getString(); - - // extract player name (✟RettichLP -> RettichLP) - String playerName = displayNameString.substring(1); - - // enrich player name with faction information (RettichLP -> RettichLP ⌜✚⌟) - MutableText enrichedDisplayName = getEnrichedDisplayName(playerName); - - cir.setReturnValue(empty() - .append(literal("✟").copy().formatted(GRAY)) - .append(enrichedDisplayName)); - } - - @Unique - private MutableText getEnrichedDisplayName(String targetName) { - NameTagOptions nameTagOptions = configuration.getOptions().nameTag(); - Faction targetFaction = storage.getCachedFaction(targetName); - - Text newTargetDisplayNamePrefix = empty(); - Text newTargetDisplayName = literal(targetName); - Text newTargetDisplayNameSuffix = targetFaction.getNameTagSuffix(); - Formatting newTargetDisplayNameColor; - - // highlight factions - newTargetDisplayNameColor = WHITE.getFormatting(); - - // blacklist - Optional optionalTargetBlacklistEntry = storage.getBlacklistEntries().stream() - .filter(blacklistEntry -> blacklistEntry.getPlayerName().equals(targetName)) - .findAny(); - - if (optionalTargetBlacklistEntry.isPresent() && nameTagOptions.outlaw()) { - newTargetDisplayNameColor = RED; - newTargetDisplayNamePrefix = optionalTargetBlacklistEntry.get().isOutlaw() - ? empty() - .append(of("[").copy().formatted(DARK_GRAY)) - .append(of("V").copy().formatted(DARK_RED)) - .append(of("]").copy().formatted(DARK_GRAY)) - : empty(); - } - - // contract - Optional optionalTargetContractEntry = storage.getContractEntries().stream() - .filter(contractEntry -> contractEntry.getPlayerName().equals(targetName)) - .findAny(); - - if (optionalTargetContractEntry.isPresent()) { - newTargetDisplayNameColor = RED; - } - - // houseban - Optional optionalTargetHousebanEntry = storage.getHousebanEntries().stream() - .filter(housebanEntry -> housebanEntry.getPlayerName().equals(targetName)) - .filter(housebanEntry -> housebanEntry.getUnbanDateTime().isAfter(now())) - .findAny(); - - if (optionalTargetHousebanEntry.isPresent() && nameTagOptions.houseBan()) { - newTargetDisplayNamePrefix = empty() - .append(of("[").copy().formatted(DARK_GRAY)) - .append(of("HV").copy().formatted(DARK_RED)) - .append(of("]").copy().formatted(DARK_GRAY)); - } - - // wanted - Optional optionalTargetWantedEntry = storage.getWantedEntries().stream() - .filter(wantedEntry -> wantedEntry.getPlayerName().equals(targetName)) - .findAny(); - - if (optionalTargetWantedEntry.isPresent()) { - newTargetDisplayNameColor = nameTagService.getWantedPointColor(optionalTargetWantedEntry.get().getWantedPointAmount()); - } - - return empty() - .append(newTargetDisplayNamePrefix) - .append(" ") - .append(newTargetDisplayName.copy().formatted(newTargetDisplayNameColor)) - .append(" ") - .append(newTargetDisplayNameSuffix); - } } diff --git a/src/main/java/de/rettichlp/ucutils/mixin/HandledScreenMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/HandledScreenMixin.java new file mode 100644 index 00000000..8bb8606b --- /dev/null +++ b/src/main/java/de/rettichlp/ucutils/mixin/HandledScreenMixin.java @@ -0,0 +1,112 @@ +package de.rettichlp.ucutils.mixin; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.component.type.LoreComponent; +import net.minecraft.screen.GenericContainerScreenHandler; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.regex.Matcher; + +import static de.rettichlp.ucutils.UCUtils.LOGGER; +import static de.rettichlp.ucutils.UCUtils.commandService; +import static de.rettichlp.ucutils.UCUtils.configuration; +import static de.rettichlp.ucutils.UCUtils.player; +import static de.rettichlp.ucutils.UCUtils.storage; +import static java.lang.Integer.parseInt; +import static java.util.regex.Pattern.compile; +import static net.minecraft.component.DataComponentTypes.LORE; +import static net.minecraft.screen.slot.SlotActionType.PICKUP; +import static net.minecraft.text.Text.literal; + +@Mixin(HandledScreen.class) +public abstract class HandledScreenMixin extends Screen { + + @Shadow + protected int backgroundWidth; + + @Shadow + protected int backgroundHeight; + + protected HandledScreenMixin(Text title) { + super(title); + } + + @Inject(method = "render", at = @At("TAIL")) + private void ucutils$renderTail(DrawContext context, int mouseX, int mouseY, float deltaTicks, CallbackInfo ci) { + HandledScreen self = (HandledScreen) (Object) this; + ScreenHandler screenHandler = self.getScreenHandler(); + ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager; + + if (interactionManager == null) { + return; + } + + String title = self.getTitle().getString(); + + switch (screenHandler) { + case GenericContainerScreenHandler genericContainerScreenHandler -> { + switch (title) { + case "ʟᴀɢᴇʀ" -> { + int ingredient1StoredAmount = getStoredAmount(genericContainerScreenHandler, 11); + int ingredient2StoredAmount = getStoredAmount(genericContainerScreenHandler, 13); + int ingredient3StoredAmount = getStoredAmount(genericContainerScreenHandler, 15); + + int x = (this.width - this.backgroundWidth) / 2; + int y = (this.height - this.backgroundHeight) / 2; + int buttonX = x + this.backgroundWidth + 2; + + // render button right to the inventory + ButtonWidget buttonWidget = new ButtonWidget.Builder(literal("➤"), button -> commandService.sendCommand("f " + ingredient1StoredAmount + "x Wirkstoff | " + ingredient2StoredAmount + "x Trägerstoff | " + ingredient3StoredAmount + "x Zusatzstoff")) + .dimensions(buttonX, y, 20, 20) + .build(); + + if (ingredient1StoredAmount != 0 && ingredient2StoredAmount != 0 && ingredient3StoredAmount != 0) { + buttonWidget.render(context, mouseX, mouseY, deltaTicks); + addDrawableChild(buttonWidget); + } + } + case "ᴄᴀʀᴄᴏɴᴛʀᴏʟ" -> { + if (configuration.getOptions().car().fastLock() && !storage.isPremium()) { + interactionManager.clickSlot(genericContainerScreenHandler.syncId, 0, 0, PICKUP, player); + } + } + default -> { + if (commandService.isSuperUser()) { + LOGGER.info("Screen opened: {}", title); + } + } + } + } + case null, default -> { + } + } + } + + @Unique + private int getStoredAmount(@NotNull ScreenHandler screenHandler, int slotId) { + Slot slot = screenHandler.slots.get(slotId); + LoreComponent loreComponent = slot.getStack().get(LORE); + + if (loreComponent == null) { + return 0; + } + + String amountString = loreComponent.lines().get(1).getString(); + Matcher matcher = compile("\\d+").matcher(amountString); + return matcher.find() ? parseInt(matcher.group()) : 0; + } +} diff --git a/src/main/java/de/rettichlp/ucutils/mixin/InGameHudMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/InGameHudMixin.java index e9af07e5..5a62d371 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/InGameHudMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/InGameHudMixin.java @@ -1,13 +1,17 @@ package de.rettichlp.ucutils.mixin; import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import net.minecraft.util.profiler.Profilers; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -15,6 +19,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.io.InputStream; +import java.nio.file.Path; + +import static de.rettichlp.ucutils.UCUtils.LOGGER; import static de.rettichlp.ucutils.UCUtils.MOD_ID; import static de.rettichlp.ucutils.UCUtils.configuration; import static de.rettichlp.ucutils.UCUtils.nameTagService; @@ -26,7 +34,9 @@ import static java.lang.Math.clamp; import static java.lang.Math.round; import static java.lang.System.currentTimeMillis; +import static java.nio.file.Files.newInputStream; import static net.minecraft.client.gl.RenderPipelines.GUI_TEXTURED; +import static net.minecraft.client.texture.NativeImage.read; import static net.minecraft.item.Items.GOLDEN_HOE; import static net.minecraft.registry.tag.FluidTags.WATER; import static org.spongepowered.asm.mixin.injection.At.Shift.AFTER; @@ -43,9 +53,40 @@ public abstract class InGameHudMixin { @Unique private static final Identifier HYDRATION_FULL_TEXTURE = Identifier.of(MOD_ID, "textures/hud/hydration_full.png"); + @Unique + private static final Identifier CAPTCHA_IDENTIFIER = Identifier.of("ucutils", "captcha"); + + @Shadow + @Final + private MinecraftClient client; + @Shadow public abstract TextRenderer getTextRenderer(); + @Inject(method = "renderChat", at = @At("TAIL")) + private void ucutils$renderChatTail(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + if (storage.getCaptchaMap() == null) { + return; + } + + NativeImage nativeImage; + try (InputStream is = newInputStream(Path.of("screenshots/ucutils/captcha.png"))) { + nativeImage = read(is); + } catch (Exception e) { + LOGGER.error("Failed to read captcha image", e); + return; + } + + NativeImageBackedTexture nativeImageBackedTexture = new NativeImageBackedTexture(() -> "captcha", nativeImage); + this.client.getTextureManager().registerTexture(CAPTCHA_IDENTIFIER, nativeImageBackedTexture); + + int side = context.getScaledWindowWidth() / 4; + int x = context.getScaledWindowWidth() / 2 - side / 2; + int y = context.getScaledWindowHeight() / 4 - side / 2; + + context.drawTexture(GUI_TEXTURED, CAPTCHA_IDENTIFIER, x, y, 0, 0, side, side, side, side); + } + @Inject(method = "renderCrosshair", at = @At( value = "INVOKE", diff --git a/src/main/java/de/rettichlp/ucutils/mixin/MinecartEntityMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/MinecartEntityMixin.java index b887fbc1..47a43c29 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/MinecartEntityMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/MinecartEntityMixin.java @@ -15,6 +15,7 @@ import static de.rettichlp.ucutils.UCUtils.configuration; import static de.rettichlp.ucutils.UCUtils.storage; import static java.lang.System.currentTimeMillis; +import static net.minecraft.util.ActionResult.CONSUME; @Mixin(MinecartEntity.class) public abstract class MinecartEntityMixin { @@ -22,7 +23,7 @@ public abstract class MinecartEntityMixin { @Unique private long lastClick = 0; - @Inject(method = "interact", at = @At("HEAD")) + @Inject(method = "interact", at = @At("HEAD"), cancellable = true) private void ucutils$interactHead(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { if (!storage.isUnicaCity()) { return; @@ -32,6 +33,7 @@ public abstract class MinecartEntityMixin { if (configuration.getOptions().car().automatedCheckKfz() && entity instanceof MinecartEntity && player.isSneaking() && currentTimeMillis() - this.lastClick > 1000) { commandService.sendCommand("checkkfz"); this.lastClick = currentTimeMillis(); + cir.setReturnValue(CONSUME); } } } diff --git a/src/main/java/de/rettichlp/ucutils/mixin/MinecraftClientMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/MinecraftClientMixin.java deleted file mode 100644 index fa1bb70a..00000000 --- a/src/main/java/de/rettichlp/ucutils/mixin/MinecraftClientMixin.java +++ /dev/null @@ -1,75 +0,0 @@ -package de.rettichlp.ucutils.mixin; - -import com.mojang.brigadier.Message; -import lombok.NonNull; -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.ItemEntity; -import net.minecraft.text.Text; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Vec3d; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import static de.rettichlp.ucutils.UCUtils.commandService; -import static de.rettichlp.ucutils.UCUtils.player; -import static de.rettichlp.ucutils.UCUtils.storage; -import static de.rettichlp.ucutils.common.models.Faction.RETTUNGSDIENST; -import static net.minecraft.entity.projectile.ProjectileUtil.raycast; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin { - - @Unique - private static final int DISTANCE = 3; - - @Inject(method = "handleInputEvents", at = @At("HEAD")) - private void ucutils$handleInputEventsHead(CallbackInfo ci) { - if (!storage.isUnicaCity()) { - return; - } - - MinecraftClient client = MinecraftClient.getInstance(); - - if (client.options.useKey.wasPressed()) { - float partialTick = client.getRenderTickCounter().getTickProgress(true); - - Vec3d from = player.getCameraPosVec(partialTick); - - Vec3d direction = player.getRotationVec(partialTick); - Vec3d to = from.add(direction.multiply(DISTANCE)); - - Box box = player.getBoundingBox() - .stretch(direction.multiply(DISTANCE)) - .expand(1.0); - - EntityHitResult result = raycast(player, from, to, box, e -> e instanceof ItemEntity, DISTANCE * DISTANCE); - - if (result == null || !(result.getEntity() instanceof ItemEntity itemEntity) || !itemEntity.hasCustomName()) { - return; - } - - Text customName = itemEntity.getCustomName(); - assert customName != null; - String playerName = revertEnrichment(customName); - - if (player.isSneaking()) { - commandService.sendCommand("erstehilfe " + playerName); - } else if (storage.getFaction(player.getStringifiedName()) == RETTUNGSDIENST) { - commandService.sendCommand("revive " + playerName); - } - } - } - - @Unique - private String revertEnrichment(@NonNull Message text) { - String string = text.getString(); - String[] strings = string.split(" "); - - // if name contains faction information, the last index is faction information - return string.contains("⌜") ? strings[strings.length - 2] : strings[strings.length - 1]; - } -} diff --git a/src/main/java/de/rettichlp/ucutils/mixin/PlayerEntityRendererMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/PlayerEntityRendererMixin.java index 3567c55d..0359660b 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/PlayerEntityRendererMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/PlayerEntityRendererMixin.java @@ -17,8 +17,6 @@ import static de.rettichlp.ucutils.UCUtils.nameTagService; import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.common.services.NameTagService.AFK_TAG; -import static de.rettichlp.ucutils.common.services.NameTagService.A_DUTY_TAG; -import static de.rettichlp.ucutils.common.services.NameTagService.HOUSE_BAN_TAG; @Mixin(PlayerEntityRenderer.class) public abstract class PlayerEntityRendererMixin { @@ -54,25 +52,11 @@ public abstract class PlayerEntityRendererMixin { orderedRenderCommandQueue.submitLabel(matrixStack, playerEntityRenderState.nameLabelPos, 0, medicInformation, !playerEntityRenderState.sneaking, playerEntityRenderState.light, playerEntityRenderState.squaredDistanceToCamera, cameraRenderState); } - // handle admin duty tag - if (configuration.getOptions().nameTag().aDuty() && nameTagService.isADuty(playerName)) { - matrixStack.translate(0.0F, medicInformationPresent ? 0.8F : 2.6, 0.0F); - orderedRenderCommandQueue.submitLabel(matrixStack, playerEntityRenderState.nameLabelPos, 0, A_DUTY_TAG, !playerEntityRenderState.sneaking, playerEntityRenderState.light, playerEntityRenderState.squaredDistanceToCamera, cameraRenderState); - return; - } - // handle afk tag if (configuration.getOptions().nameTag().afk() && nameTagService.isAfk(playerName)) { matrixStack.translate(0.0F, medicInformationPresent ? 0.8F : 2.6, 0.0F); orderedRenderCommandQueue.submitLabel(matrixStack, playerEntityRenderState.nameLabelPos, 0, AFK_TAG, !playerEntityRenderState.sneaking, playerEntityRenderState.light, playerEntityRenderState.squaredDistanceToCamera, cameraRenderState); return; } - - // handle houseban tag - boolean hasHouseBan = storage.getHousebanEntries().stream().anyMatch(housebanEntry -> housebanEntry.getPlayerName().equals(playerName)); - if (configuration.getOptions().nameTag().houseBan() && hasHouseBan) { - matrixStack.translate(0.0F, medicInformationPresent ? 0.8F : 2.6, 0.0F); - orderedRenderCommandQueue.submitLabel(matrixStack, playerEntityRenderState.nameLabelPos, 0, HOUSE_BAN_TAG, !playerEntityRenderState.sneaking, playerEntityRenderState.light, playerEntityRenderState.squaredDistanceToCamera, cameraRenderState); - } } } diff --git a/src/main/java/de/rettichlp/ucutils/mixin/PlayerListHudMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/PlayerListHudMixin.java index 348b091f..1c972763 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/PlayerListHudMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/PlayerListHudMixin.java @@ -1,6 +1,5 @@ package de.rettichlp.ucutils.mixin; -import de.rettichlp.ucutils.common.models.BlacklistEntry; import net.minecraft.client.gui.hud.PlayerListHud; import net.minecraft.client.network.PlayerListEntry; import net.minecraft.text.MutableText; @@ -11,13 +10,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Optional; - import static de.rettichlp.ucutils.UCUtils.storage; import static net.minecraft.text.Text.literal; import static net.minecraft.util.Formatting.BOLD; import static net.minecraft.util.Formatting.RED; -import static net.minecraft.util.Formatting.WHITE; @Mixin(PlayerListHud.class) public abstract class PlayerListHudMixin { @@ -36,14 +32,8 @@ public abstract class PlayerListHudMixin { boolean isWanted = storage.getWantedEntries().stream() .anyMatch(wantedEntry -> wantedEntry.getPlayerName().equals(playerName)); - Optional optionalBlacklistEntry = storage.getBlacklistEntries().stream() - .filter(be -> be.getPlayerName().equals(playerName)) - .findFirst(); - if (isWanted) { text = literal(" 🔍").formatted(RED, BOLD); - } else if (optionalBlacklistEntry.isPresent()) { - text = literal(" 💀").formatted(optionalBlacklistEntry.get().isOutlaw() ? RED : WHITE, BOLD); } if (text != null) { diff --git a/src/main/resources/assets/ucutils/lang/de_de.json b/src/main/resources/assets/ucutils/lang/de_de.json index 7a0b1810..e7f854d5 100644 --- a/src/main/resources/assets/ucutils/lang/de_de.json +++ b/src/main/resources/assets/ucutils/lang/de_de.json @@ -16,11 +16,6 @@ "ucutils.color.yellow": "Gelb", "ucutils.color.white": "Weiß", - "ucutils.inventory.powder": "Pulver", - "ucutils.inventory.herbs": "Kräuter", - "ucutils.inventory.crystals": "Kristalle", - "ucutils.inventory.grab_bag": "Wundertüte", - "ucutils.notification.error.api": "Fehler bei der API Abfrage (%s)", "ucutils.notification.error.configuration": "Konfiguration konnte nicht geladen werden", "ucutils.notification.info.new_version": "Neue UCUtils Version verfügbar", @@ -38,20 +33,17 @@ "ucutils.notification.player_enter_report": "%s ist jetzt im Report", "ucutils.notification.player_leave_report": "%s ist nicht mehr im Report", - "ucutils.options.text.amount": "Menge", - "ucutils.options.text.automation": "Automatisierung", "ucutils.options.text.chat": "Chat", "ucutils.options.text.car": "Auto", "ucutils.options.text.faction": "Fraktion", "ucutils.options.text.general": "Allgemein", "ucutils.options.text.nametag": "Nametag", - "ucutils.options.text.personal_use": "Eigenbedarf", "ucutils.options.text.position": "Position", - "ucutils.options.text.purity": "Reinheit", "ucutils.options.text.widgets": "Widgets", "ucutils.options.text.sounds": "Sounds", "ucutils.options.text.notifications": "Benachrichtigungen", + "ucutils.options.car.premium_info": "Diese Einstellungen sind nur ohne Premium relevant. Für Premium Spieler können diese Einstellungen auf UnicaCity mit '/settings' getätigt werden.", "ucutils.options.car.general.fast_find.name": "Instant finden", "ucutils.options.car.general.fast_find.tooltip": "Findet das Auto sofort, wenn '/car find' ausgeführt wird", "ucutils.options.car.general.fast_lock.name": "Instant abschließen", @@ -64,14 +56,8 @@ "ucutils.options.car.automation.start.tooltip": "Startet das Auto automatisch, wenn du einsteigst", "ucutils.options.car.automation.check_kfz.name": "Automatisches /checkkfz", "ucutils.options.car.automation.check_kfz.tooltip": "Führt /checkkfz aus wenn du ein Auto rechtsklickst während du schleichst", - "ucutils.options.nametag.a_duty.name": "Admin-Dienst", - "ucutils.options.nametag.a_duty.tooltip": "Zeigt eine Information an über dem Namen von Spielern, die im Admin-Dienst sind", "ucutils.options.nametag.afk.name": "AFK", "ucutils.options.nametag.afk.tooltip": "Zeigt eine Information an über dem Namen von Spielern, die AFK sind", - "ucutils.options.nametag.house_ban.name": "Hausverbot", - "ucutils.options.nametag.house_ban.tooltip": "Zeigt eine Information über dem Namen von Spielern an, die ein Hausverbot haben", - "ucutils.options.nametag.outlaw.name": "Vogelfrei", - "ucutils.options.nametag.outlaw.tooltip": "Zeigt eine Information über dem Namen von Spielern an, die Vogelfrei sind", "ucutils.options.nametag.medical_information.name": "Information für Ärzte", "ucutils.options.nametag.medical_information.tooltip": "Zeigt die restliche Wirkungsdauer von Bandagen und Schmerzpillen unter dem Spielernamen an", "ucutils.options.notifications.join_quit.name": "Beitreten und Verlassen", @@ -96,8 +82,6 @@ "ucutils.options.hydration.tooltip": "Zeigt deinen Durst über der Hungeranzeige an", "ucutils.options.check_unicacity_server.name": "UnicaCity Check", "ucutils.options.check_unicacity_server.tooltip": "Überprüft ob du auf UnicaCity spielst. Wenn aktiviert sind bestimmte Funktionen nur auf UnicaCity aktiviert um Probleme mit anderen Servern zu vermeiden.", - "ucutils.options.enriched_karma.name": "Erweiterte Karma Nachricht", - "ucutils.options.enriched_karma.tooltip": "Zeigt zusätzliche Informationen in der Karma Nachricht an, wie die Gesamt-Karma-Menge oder die Zeit wenn ein Spieler despawnen sollte bei einem Kill", "ucutils.options.faction_chat_color.name": "Farbe des Fraktionschats", "ucutils.options.faction_chat_color.tooltip": "Ändert die Farbe des Fraktionschats", "ucutils.options.faction_chat_color_primary.name": "Primäre Farbe des Fraktionschats", @@ -124,18 +108,6 @@ "ucutils.options.widgets.service_count.options.name": "Notrufe", "ucutils.options.widgets.service_count.options.tooltip": "Zeigt an wie viele Notrufe gerade offen sind", - "ucutils.purity.best": "Höchste", - "ucutils.purity.good": "Gute", - "ucutils.purity.medium": "Mittlere", - "ucutils.purity.bad": "Schlechte", - - "ucutils.screen.data_usage_confirmation.message": "UCUtils kommuniziert mit einem externen Server. Dies ist notwendig, damit einige Funktionen richtig arbeiten. Mit dem Klick auf Zustimmen stimmst du der Datennutzung zu.", - "ucutils.screen.faction.button.activity.name": "Aktivitäten", - "ucutils.screen.faction.button.equip.name": "Equip", - "ucutils.screen.faction.button.blacklist.name": "Blacklist Gründe", - "ucutils.screen.faction.blacklist.header.reason": "Grund", - "ucutils.screen.faction.blacklist.header.price": "Preis", - "ucutils.screen.faction.blacklist.header.kills": "Tode", "ucutils.screen.shutdown_abort.button.name": "Herunterfahren abbrechen", "ucutils.select_state.always.name": "Immer", diff --git a/src/main/resources/assets/ucutils/lang/en_gb.json b/src/main/resources/assets/ucutils/lang/en_gb.json index 92dcf151..94837d9d 100644 --- a/src/main/resources/assets/ucutils/lang/en_gb.json +++ b/src/main/resources/assets/ucutils/lang/en_gb.json @@ -16,11 +16,6 @@ "ucutils.color.yellow": "Yellow", "ucutils.color.white": "White", - "ucutils.inventory.powder": "Powder", - "ucutils.inventory.herbs": "Herbs", - "ucutils.inventory.crystals": "Crystals", - "ucutils.inventory.grab_bag": "Grab bag", - "ucutils.notification.error.api": "API request error (%s)", "ucutils.notification.error.configuration": "Configuration could not be loaded", "ucutils.notification.info.new_version": "New UCUtils version available", @@ -38,20 +33,17 @@ "ucutils.notification.player_enter_report": "%s is now in a report", "ucutils.notification.player_leave_report": "%s is no longer in a report", - "ucutils.options.text.amount": "Amount", - "ucutils.options.text.automation": "Automation", "ucutils.options.text.chat": "Chat", "ucutils.options.text.car": "Car", "ucutils.options.text.faction": "Faction", "ucutils.options.text.general": "General", "ucutils.options.text.nametag": "Nametag", - "ucutils.options.text.personal_use": "Personal use", "ucutils.options.text.position": "Position", - "ucutils.options.text.purity": "Purity", "ucutils.options.text.widgets": "Widgets", "ucutils.options.text.sounds": "Sounds", "ucutils.options.text.notifications": "Notifications", + "ucutils.options.car.premium_info": "These settings are only relevant if you do not have Premium. For Premium players, these settings can be configured on UnicaCity using '/settings'.", "ucutils.options.car.general.fast_find.name": "Fast find", "ucutils.options.car.general.fast_find.tooltip": "Finds your car immediately when execution '/car find'", "ucutils.options.car.general.fast_lock.name": "Fast lock", @@ -64,14 +56,8 @@ "ucutils.options.car.automation.start.tooltip": "Starts the car automatically when you enter it", "ucutils.options.car.automation.check_kfz.name": "Automated /checkkfz", "ucutils.options.car.automation.check_kfz.tooltip": "Automatically executes /checkkfz when you right click your car while sneaking", - "ucutils.options.nametag.a_duty.name": "Admin duty", - "ucutils.options.nametag.a_duty.tooltip": "Shows an information above the players name of players in admin duty", "ucutils.options.nametag.afk.name": "AFK", "ucutils.options.nametag.afk.tooltip": "Shows an information above the players name of afk players", - "ucutils.options.nametag.house_ban.name": "House ban", - "ucutils.options.nametag.house_ban.tooltip": "Shows an information above the players name of players with a house ban", - "ucutils.options.nametag.outlaw.name": "Outlaw", - "ucutils.options.nametag.outlaw.tooltip": "Shows an information above the players name of outlaw players", "ucutils.options.nametag.medical_information.name": "Medical information", "ucutils.options.nametag.medical_information.tooltip": "Shows the cooldown of bandages and pills below the players name", "ucutils.options.notifications.join_quit.name": "Join and Quit", @@ -96,8 +82,6 @@ "ucutils.options.hydration.tooltip": "Displays your hydration above your hunger bar", "ucutils.options.check_unicacity_server.name": "Check for UnicaCity", "ucutils.options.check_unicacity_server.tooltip": "Checks if you are playing on the UnicaCity server. If enabled, certain features will only be available on the UnicaCity server to prevent issues on other servers.", - "ucutils.options.enriched_karma.name": "Enriched karma message", - "ucutils.options.enriched_karma.tooltip": "Populates the karma message with additional information such as the current overall karma amount and the time until a player despawns in case of a kill", "ucutils.options.faction_chat_color.name": "Faction chat color", "ucutils.options.faction_chat_color.tooltip": "Changes the color of the faction chat", "ucutils.options.faction_chat_color_primary.name": "Faction chat primary color", @@ -124,18 +108,6 @@ "ucutils.options.widgets.service_count.options.name": "Service Count", "ucutils.options.widgets.service_count.options.tooltip": "Shows the number of active services", - "ucutils.purity.best": "Best", - "ucutils.purity.good": "Good", - "ucutils.purity.medium": "Medium", - "ucutils.purity.bad": "Bad", - - "ucutils.screen.data_usage_confirmation.message": "UCUtils sends and receives data from an external server. This is required for certain features to function properly. By clicking Agree, you agree to this data usage.", - "ucutils.screen.faction.button.activity.name": "Activities", - "ucutils.screen.faction.button.equip.name": "Equip", - "ucutils.screen.faction.button.blacklist.name": "Blacklist reasons", - "ucutils.screen.faction.blacklist.header.reason": "Reason", - "ucutils.screen.faction.blacklist.header.price": "Price", - "ucutils.screen.faction.blacklist.header.kills": "Kills", "ucutils.screen.shutdown_abort.button.name": "Abort shutdown", "ucutils.select_state.always.name": "Always", diff --git a/src/main/resources/assets/ucutils/lang/en_us.json b/src/main/resources/assets/ucutils/lang/en_us.json index 92dcf151..94837d9d 100644 --- a/src/main/resources/assets/ucutils/lang/en_us.json +++ b/src/main/resources/assets/ucutils/lang/en_us.json @@ -16,11 +16,6 @@ "ucutils.color.yellow": "Yellow", "ucutils.color.white": "White", - "ucutils.inventory.powder": "Powder", - "ucutils.inventory.herbs": "Herbs", - "ucutils.inventory.crystals": "Crystals", - "ucutils.inventory.grab_bag": "Grab bag", - "ucutils.notification.error.api": "API request error (%s)", "ucutils.notification.error.configuration": "Configuration could not be loaded", "ucutils.notification.info.new_version": "New UCUtils version available", @@ -38,20 +33,17 @@ "ucutils.notification.player_enter_report": "%s is now in a report", "ucutils.notification.player_leave_report": "%s is no longer in a report", - "ucutils.options.text.amount": "Amount", - "ucutils.options.text.automation": "Automation", "ucutils.options.text.chat": "Chat", "ucutils.options.text.car": "Car", "ucutils.options.text.faction": "Faction", "ucutils.options.text.general": "General", "ucutils.options.text.nametag": "Nametag", - "ucutils.options.text.personal_use": "Personal use", "ucutils.options.text.position": "Position", - "ucutils.options.text.purity": "Purity", "ucutils.options.text.widgets": "Widgets", "ucutils.options.text.sounds": "Sounds", "ucutils.options.text.notifications": "Notifications", + "ucutils.options.car.premium_info": "These settings are only relevant if you do not have Premium. For Premium players, these settings can be configured on UnicaCity using '/settings'.", "ucutils.options.car.general.fast_find.name": "Fast find", "ucutils.options.car.general.fast_find.tooltip": "Finds your car immediately when execution '/car find'", "ucutils.options.car.general.fast_lock.name": "Fast lock", @@ -64,14 +56,8 @@ "ucutils.options.car.automation.start.tooltip": "Starts the car automatically when you enter it", "ucutils.options.car.automation.check_kfz.name": "Automated /checkkfz", "ucutils.options.car.automation.check_kfz.tooltip": "Automatically executes /checkkfz when you right click your car while sneaking", - "ucutils.options.nametag.a_duty.name": "Admin duty", - "ucutils.options.nametag.a_duty.tooltip": "Shows an information above the players name of players in admin duty", "ucutils.options.nametag.afk.name": "AFK", "ucutils.options.nametag.afk.tooltip": "Shows an information above the players name of afk players", - "ucutils.options.nametag.house_ban.name": "House ban", - "ucutils.options.nametag.house_ban.tooltip": "Shows an information above the players name of players with a house ban", - "ucutils.options.nametag.outlaw.name": "Outlaw", - "ucutils.options.nametag.outlaw.tooltip": "Shows an information above the players name of outlaw players", "ucutils.options.nametag.medical_information.name": "Medical information", "ucutils.options.nametag.medical_information.tooltip": "Shows the cooldown of bandages and pills below the players name", "ucutils.options.notifications.join_quit.name": "Join and Quit", @@ -96,8 +82,6 @@ "ucutils.options.hydration.tooltip": "Displays your hydration above your hunger bar", "ucutils.options.check_unicacity_server.name": "Check for UnicaCity", "ucutils.options.check_unicacity_server.tooltip": "Checks if you are playing on the UnicaCity server. If enabled, certain features will only be available on the UnicaCity server to prevent issues on other servers.", - "ucutils.options.enriched_karma.name": "Enriched karma message", - "ucutils.options.enriched_karma.tooltip": "Populates the karma message with additional information such as the current overall karma amount and the time until a player despawns in case of a kill", "ucutils.options.faction_chat_color.name": "Faction chat color", "ucutils.options.faction_chat_color.tooltip": "Changes the color of the faction chat", "ucutils.options.faction_chat_color_primary.name": "Faction chat primary color", @@ -124,18 +108,6 @@ "ucutils.options.widgets.service_count.options.name": "Service Count", "ucutils.options.widgets.service_count.options.tooltip": "Shows the number of active services", - "ucutils.purity.best": "Best", - "ucutils.purity.good": "Good", - "ucutils.purity.medium": "Medium", - "ucutils.purity.bad": "Bad", - - "ucutils.screen.data_usage_confirmation.message": "UCUtils sends and receives data from an external server. This is required for certain features to function properly. By clicking Agree, you agree to this data usage.", - "ucutils.screen.faction.button.activity.name": "Activities", - "ucutils.screen.faction.button.equip.name": "Equip", - "ucutils.screen.faction.button.blacklist.name": "Blacklist reasons", - "ucutils.screen.faction.blacklist.header.reason": "Reason", - "ucutils.screen.faction.blacklist.header.price": "Price", - "ucutils.screen.faction.blacklist.header.kills": "Kills", "ucutils.screen.shutdown_abort.button.name": "Abort shutdown", "ucutils.select_state.always.name": "Always", diff --git a/src/main/resources/ucutils.mixins.json b/src/main/resources/ucutils.mixins.json index 98728688..085e908f 100644 --- a/src/main/resources/ucutils.mixins.json +++ b/src/main/resources/ucutils.mixins.json @@ -14,13 +14,13 @@ "requireAnnotations": true }, "client": [ + "AbstractMinecartEntityRendererMixin", "ChatScreenMixin", "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerMixin", - "DialogScreenMixin", "GameMenuScreenMixin", + "HandledScreenMixin", "InGameHudMixin", - "MinecraftClientMixin", "PlayerEntityRendererMixin", "PlayerListHudMixin" ]