diff --git a/src/main/java/de/rettichlp/ucutils/UCUtils.java b/src/main/java/de/rettichlp/ucutils/UCUtils.java index 3f4be9f5..4cc385b4 100644 --- a/src/main/java/de/rettichlp/ucutils/UCUtils.java +++ b/src/main/java/de/rettichlp/ucutils/UCUtils.java @@ -64,7 +64,7 @@ public void onInitialize() { client.execute(() -> { this.registry.registerListeners(); renderService.initializeWidgets(); - syncService.sync(true); + syncService.checkForUpdates(); }); }); diff --git a/src/main/java/de/rettichlp/ucutils/command/ModCommand.java b/src/main/java/de/rettichlp/ucutils/command/ModCommand.java index 0258ec30..531f12aa 100644 --- a/src/main/java/de/rettichlp/ucutils/command/ModCommand.java +++ b/src/main/java/de/rettichlp/ucutils/command/ModCommand.java @@ -80,11 +80,11 @@ public LiteralArgumentBuilder execute(@NotNull Litera .then(literal("sync") .then(literal("faction") .executes(context -> { - syncService.syncFactionMembersWithCommandResponse(); + syncService.syncFactionMembersWithCommand(() -> {}); return 1; })) .executes(context -> { - syncService.sync(true); + syncService.checkForUpdates(); syncService.syncFactionSpecificData(); return 1; })) diff --git a/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java b/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java index 2cfac115..bf94373b 100644 --- a/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java +++ b/src/main/java/de/rettichlp/ucutils/command/money/DepositCommand.java @@ -15,6 +15,7 @@ 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; @@ -38,7 +39,7 @@ public LiteralArgumentBuilder execute(@NotNull Litera } else { commandService.sendCommand("bank einzahlen " + amount); } - }, 1000); + }, COMMAND_COOLDOWN_MILLIS); return 1; }); diff --git a/src/main/java/de/rettichlp/ucutils/command/money/RichTaxesCommand.java b/src/main/java/de/rettichlp/ucutils/command/money/RichTaxesCommand.java index c3a9dd4e..f7b589f0 100644 --- a/src/main/java/de/rettichlp/ucutils/command/money/RichTaxesCommand.java +++ b/src/main/java/de/rettichlp/ucutils/command/money/RichTaxesCommand.java @@ -11,6 +11,7 @@ import static de.rettichlp.ucutils.UCUtils.messageService; 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; @UCUtilsCommand(label = "reichensteuer") public class RichTaxesCommand extends CommandBase { @@ -25,7 +26,7 @@ public LiteralArgumentBuilder execute(@NotNull Litera commandService.sendCommand("bank info"); // execute command to check money in atm - utilService.delayedAction(() -> commandService.sendCommand("atminfo"), 1000); + utilService.delayedAction(() -> commandService.sendCommand("atminfo"), COMMAND_COOLDOWN_MILLIS); // handle money withdraw utilService.delayedAction(() -> { @@ -52,7 +53,7 @@ public LiteralArgumentBuilder execute(@NotNull Litera commandService.sendCommand("bank abbuchen " + moneyAtmAmount); messageService.sendModMessage("Du musst noch " + (moneyThatNeedsToBeWithdrawn - moneyAtmAmount) + "$ abbuchen.", false); } - }, 2000); + }, COMMAND_COOLDOWN_MILLIS * 2); return 1; }); diff --git a/src/main/java/de/rettichlp/ucutils/common/Storage.java b/src/main/java/de/rettichlp/ucutils/common/Storage.java index e5d513af..fad25442 100644 --- a/src/main/java/de/rettichlp/ucutils/common/Storage.java +++ b/src/main/java/de/rettichlp/ucutils/common/Storage.java @@ -3,7 +3,6 @@ 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.CommandResponseRetriever; import de.rettichlp.ucutils.common.models.ContractEntry; import de.rettichlp.ucutils.common.models.Countdown; import de.rettichlp.ucutils.common.models.Faction; @@ -48,9 +47,6 @@ public class Storage { @Getter private final List blackMarkets = new ArrayList<>(); - @Getter - private final List commandResponseRetrievers = new ArrayList<>(); - @Getter private final List contractEntries = new ArrayList<>(); @@ -130,8 +126,6 @@ public void print() { this.blacklistReasons.forEach((faction, blacklistReasons) -> LOGGER.info("blacklistReasons[{}:{}]: {}", faction, blacklistReasons.size(), blacklistReasons)); // blackMarkets LOGGER.info("blackMarkets[{}]: {}", this.blackMarkets.size(), this.blackMarkets); - // commandResponseRetrievers - LOGGER.info("commandResponseRetrievers[{}]: {}", this.commandResponseRetrievers.size(), this.commandResponseRetrievers); // contractEntries LOGGER.info("contractEntries[{}]: {}", this.contractEntries.size(), this.contractEntries); // countdowns diff --git a/src/main/java/de/rettichlp/ucutils/common/api/Api.java b/src/main/java/de/rettichlp/ucutils/common/api/Api.java index dae81f07..b6074cff 100644 --- a/src/main/java/de/rettichlp/ucutils/common/api/Api.java +++ b/src/main/java/de/rettichlp/ucutils/common/api/Api.java @@ -25,7 +25,6 @@ import java.util.function.Consumer; import static de.rettichlp.ucutils.UCUtils.LOGGER; -import static de.rettichlp.ucutils.UCUtils.syncService; import static de.rettichlp.ucutils.UCUtils.utilService; import static java.lang.String.valueOf; import static java.net.URI.create; @@ -80,11 +79,6 @@ private void get(@NotNull String uri, TypeToken typeToken, Consumer ca } private void sendRequest(HttpRequest httpRequest, TypeToken typeToken, Consumer callback) { - if (!syncService.dataUsageConfirmed()) { - LOGGER.warn("Data usage not confirmed, skipping API request: [{}] {}", httpRequest.method(), httpRequest.uri().toString()); - return; - } - this.httpClient.sendAsync(httpRequest, ofString()) .thenApply(this::catchDefaultApiError) .thenApply(response -> ofNullable(typeToken) 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 9d1dd66f..bb99024a 100644 --- a/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java +++ b/src/main/java/de/rettichlp/ucutils/common/configuration/Configuration.java @@ -40,7 +40,6 @@ public class Configuration { private int predictedPayDayExp = 0; @Nullable private LocalDateTime firstAidLicenseExpireDateTime = null; - private int dataUsageConfirmationUID = 0; private Set halloweenClickedDoors = new HashSet<>(); public void addMinutesSinceLastPayDay(int minutes) { diff --git a/src/main/java/de/rettichlp/ucutils/common/models/CommandResponseRetriever.java b/src/main/java/de/rettichlp/ucutils/common/models/CommandResponseRetriever.java deleted file mode 100644 index d847aa83..00000000 --- a/src/main/java/de/rettichlp/ucutils/common/models/CommandResponseRetriever.java +++ /dev/null @@ -1,72 +0,0 @@ -package de.rettichlp.ucutils.common.models; - -import lombok.AllArgsConstructor; -import lombok.RequiredArgsConstructor; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.function.Consumer; -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 java.time.LocalDateTime.now; -import static java.time.temporal.ChronoUnit.MILLIS; -import static java.util.Objects.nonNull; - -@AllArgsConstructor -@RequiredArgsConstructor -public class CommandResponseRetriever { - - private final List response = new ArrayList<>(); - private final String commandToExecute; - private final Pattern pattern; - private final Consumer> consumer; - - private long timeoutMillis = 1000; - private boolean hideMessage = false; - private LocalDateTime startedAt; - - public CommandResponseRetriever(String commandToExecute, Pattern pattern, Consumer> consumer, boolean hideMessage) { - this.commandToExecute = commandToExecute; - this.pattern = pattern; - this.consumer = consumer; - this.hideMessage = hideMessage; - } - - public void execute() { - storage.getCommandResponseRetrievers().add(this); - - if (!commandService.sendCommandWithAfkCheck(this.commandToExecute)) { - return; - } - - this.startedAt = now(); - - new Timer().schedule(new TimerTask() { - @Override - public void run() { - CommandResponseRetriever.this.consumer.accept(CommandResponseRetriever.this.response); - } - }, this.timeoutMillis); - } - - public boolean addAsResultIfMatch(CharSequence message) { - Matcher matcher = this.pattern.matcher(message); - - if (matcher.find()) { - this.response.add(matcher); - return this.hideMessage; - } - - return false; - } - - public boolean isActive() { - return nonNull(this.startedAt) && now().isBefore(this.startedAt.plus(this.timeoutMillis, MILLIS)); - } -} 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 f39604f2..689d5b45 100644 --- a/src/main/java/de/rettichlp/ucutils/common/models/Faction.java +++ b/src/main/java/de/rettichlp/ucutils/common/models/Faction.java @@ -6,12 +6,12 @@ import net.minecraft.util.Formatting; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; -import java.util.Set; import static de.rettichlp.ucutils.UCUtils.storage; import static java.util.Arrays.stream; -import static java.util.Collections.emptySet; import static net.minecraft.text.Text.empty; import static net.minecraft.util.Formatting.AQUA; import static net.minecraft.util.Formatting.BLUE; @@ -69,17 +69,17 @@ public Text getNameTagSuffix() { .formatted(DARK_GRAY)); } - public Set getMembers() { + public List getMembers() { return storage.getFactionEntries().stream() .filter(factionEntry -> factionEntry.faction() == this) .findFirst() .map(FactionEntry::members) - .orElse(emptySet()); + .orElse(new ArrayList<>()); } public static @NotNull Optional fromDisplayName(String displayName) { return stream(values()) - .filter(faction -> displayName.contains(faction.getDisplayName())) + .filter(faction -> faction.getDisplayName().equals(displayName)) .findFirst(); } } diff --git a/src/main/java/de/rettichlp/ucutils/common/models/FactionEntry.java b/src/main/java/de/rettichlp/ucutils/common/models/FactionEntry.java index e86b9e65..49804038 100644 --- a/src/main/java/de/rettichlp/ucutils/common/models/FactionEntry.java +++ b/src/main/java/de/rettichlp/ucutils/common/models/FactionEntry.java @@ -1,7 +1,7 @@ package de.rettichlp.ucutils.common.models; -import java.util.Set; +import java.util.List; -public record FactionEntry(Faction faction, Set members) { +public record FactionEntry(Faction faction, List members) { } 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 db024055..dc8f2ebe 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/CommandService.java @@ -18,6 +18,8 @@ public class CommandService { + public static long COMMAND_COOLDOWN_MILLIS = 500; + private static final String UUID_RETTICHLP = "25855f4d-3874-4a7f-a6ad-e9e4f3042e19"; public void sendCommand(String command) { @@ -37,6 +39,10 @@ public boolean sendCommandWithAfkCheck(String command) { } public void sendCommands(List commandStrings) { + sendCommands(commandStrings, COMMAND_COOLDOWN_MILLIS); + } + + public void sendCommands(List commandStrings, long cooldownMillis) { // to modifiable list List commands = new ArrayList<>(commandStrings); @@ -50,7 +56,7 @@ public void run() { sendCommand(commands.removeFirst()); } - }, 0, 1000); + }, 0, cooldownMillis); } public boolean isSuperUser() { @@ -61,6 +67,6 @@ public void retrieveNumberAndRun(String playerName, Consumer runWithNum sendCommand("nummer " + playerName); utilService.delayedAction(() -> ofNullable(storage.getRetrievedNumbers().get(playerName)) - .ifPresentOrElse(runWithNumber, () -> messageService.sendModMessage("Die Nummer von " + playerName + " konnte nicht abgerufen werden.", false)), 1000); + .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/SyncService.java b/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java index d885436e..bcdf3f0e 100644 --- a/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java +++ b/src/main/java/de/rettichlp/ucutils/common/services/SyncService.java @@ -1,44 +1,29 @@ package de.rettichlp.ucutils.common.services; -import de.rettichlp.ucutils.common.models.CommandResponseRetriever; import de.rettichlp.ucutils.common.models.Faction; -import de.rettichlp.ucutils.common.models.FactionEntry; -import de.rettichlp.ucutils.common.models.FactionMember; import lombok.Getter; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.PopupScreen; -import net.minecraft.client.gui.screen.Screen; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; import java.time.LocalDateTime; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; -import static de.rettichlp.ucutils.UCUtils.LOGGER; import static de.rettichlp.ucutils.UCUtils.api; import static de.rettichlp.ucutils.UCUtils.commandService; -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 de.rettichlp.ucutils.UCUtils.utilService; import static de.rettichlp.ucutils.common.models.Faction.NULL; +import static de.rettichlp.ucutils.common.services.CommandService.COMMAND_COOLDOWN_MILLIS; import static java.awt.Color.MAGENTA; -import static java.lang.Integer.parseInt; import static java.time.LocalDateTime.MIN; import static java.time.LocalDateTime.now; import static java.util.Arrays.stream; import static java.util.Objects.nonNull; import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.regex.Pattern.compile; import static net.minecraft.text.Text.empty; import static net.minecraft.text.Text.of; -import static net.minecraft.text.Text.translatable; import static net.minecraft.util.Formatting.DARK_GRAY; import static net.minecraft.util.Formatting.GRAY; import static net.minecraft.util.Formatting.GREEN; @@ -46,57 +31,26 @@ public class SyncService { - private static final Pattern FACTION_MEMBER_ALL_ENTRY = compile("^\\s*-\\s*(?\\d)\\s*\\|\\s*(?.+)$"); - private static final int REQUIRED_DATA_USAGE_CONFIRMATION_UID = 1; - @Getter private LocalDateTime lastSyncTimestamp = MIN; @Getter private boolean gameSyncProcessActive = false; - public boolean dataUsageConfirmed() { - int currentDataUsageConfirmationUID = configuration.getDataUsageConfirmationUID(); - return true; // TODO currentDataUsageConfirmationUID >= REQUIRED_DATA_USAGE_CONFIRMATION_UID; - } - - public void updateDataUsageConfirmedUID() { - configuration.setDataUsageConfirmationUID(REQUIRED_DATA_USAGE_CONFIRMATION_UID); - } - - public void sync(boolean showPopupIfNotGiven) { - boolean dataUsageConfirmed = dataUsageConfirmed(); - - if (dataUsageConfirmed) { - LOGGER.info("Data usage confirmed, proceeding with sync..."); - - // check for updates - checkForUpdates(); - - // login to UCUtils API -// api.postUserRegister(); - } else if (showPopupIfNotGiven) { - LOGGER.info("Data usage not yet confirmed, showing confirmation popup"); - showDataUsageConfirmationPopup(); - } else { - LOGGER.info("Data usage not confirmed, skipping sync"); - } - } + public void syncFactionMembersWithCommand(Runnable runAfter) { + this.gameSyncProcessActive = true; - public void syncFactionMembersWithCommandResponse() { - List commandResponseRetrievers = stream(Faction.values()) + List factionMemberInfoCommands = stream(Faction.values()) .filter(faction -> faction != NULL) - .map(this::syncFactionMembersWithCommandResponse) + .map(faction -> "memberinfoall " + faction.getDisplayName()) .toList(); - for (int i = 0; i < commandResponseRetrievers.size(); i++) { - CommandResponseRetriever commandResponseRetriever = commandResponseRetrievers.get(i); - utilService.delayedAction(commandResponseRetriever::execute, i * 1000L); - } + commandService.sendCommands(factionMemberInfoCommands, 1000); utilService.delayedAction(() -> { -// api.postFactionMembers(); - storage.getPlayerFactionCache().clear(); - }, commandResponseRetrievers.size() * 1000L + 1200); + this.gameSyncProcessActive = false; + notificationService.sendSuccessNotification("Fraktionsmitglieder synchronisiert"); + runAfter.run(); + }, Faction.values().length * 1000L + 1000); } public void syncFactionSpecificData() { @@ -109,16 +63,19 @@ public void syncFactionSpecificData() { switch (faction) { case FBI, POLIZEI -> commandService.sendCommand("wanteds"); case HITMAN -> commandService.sendCommand("contractlist"); - case RETTUNGSDIENST -> commandService.sendCommand("hausverbot list"); + case RETTUNGSDIENST -> commandService.sendCommand("hausverbot"); default -> { if (faction.isBadFaction()) { commandService.sendCommand("blacklist"); } } } - }, 1000); + }, COMMAND_COOLDOWN_MILLIS); - utilService.delayedAction(() -> this.gameSyncProcessActive = false, 2000); + utilService.delayedAction(() -> { + this.gameSyncProcessActive = false; + notificationService.sendSuccessNotification("Fraktionsdaten synchronisiert"); + }, COMMAND_COOLDOWN_MILLIS * 2); } public void checkForUpdates() { @@ -141,43 +98,4 @@ public void checkForUpdates() { } }); } - - private void showDataUsageConfirmationPopup() { - MinecraftClient client = MinecraftClient.getInstance(); - - PopupScreen dataUsageConfirmationScreen = new PopupScreen.Builder(client.currentScreen, empty().append(of("UCUtils")).append(" ").append(translatable("mco.terms.sentence.2"))) - .message(translatable("ucutils.screen.data_usage_confirmation.message")) - .button(translatable("mco.terms.buttons.agree"), popupScreen -> { - updateDataUsageConfirmedUID(); - sync(false); - popupScreen.close(); - }) - .button(translatable("mco.terms.buttons.disagree"), Screen::close) - .build(); - - client.execute(() -> client.setScreen(dataUsageConfirmationScreen)); - } - - @Contract("_ -> new") - private @NotNull CommandResponseRetriever syncFactionMembersWithCommandResponse(@NotNull Faction faction) { - String commandToExecute = "memberinfoall " + faction.getDisplayName(); - return new CommandResponseRetriever(commandToExecute, FACTION_MEMBER_ALL_ENTRY, matchers -> { - Set factionMembers = new HashSet<>(); - - matchers.forEach(matcher -> { - int rank = parseInt(matcher.group("rank")); - String[] playerNames = matcher.group("playerNames").split(", "); - - for (String playerName : playerNames) { - FactionMember factionMember = new FactionMember(playerName, rank); - factionMembers.add(factionMember); - } - }); - - FactionEntry factionEntry = new FactionEntry(faction, factionMembers); - storage.getFactionEntries().removeIf(fe -> fe.faction() == faction); - storage.getFactionEntries().add(factionEntry); - LOGGER.info("Retrieved {} members for faction {} from command", factionMembers.size(), faction.name()); - }, true); - } } 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 697abc3c..aaba2e06 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/CommandListener.java @@ -1,10 +1,7 @@ package de.rettichlp.ucutils.listener.impl; -import de.rettichlp.ucutils.common.models.CommandResponseRetriever; import de.rettichlp.ucutils.common.registry.UCUtilsListener; import de.rettichlp.ucutils.listener.ICommandSendListener; -import de.rettichlp.ucutils.listener.IMessageReceiveListener; -import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; import java.util.StringJoiner; @@ -12,12 +9,11 @@ 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; @UCUtilsListener -public class CommandListener implements ICommandSendListener, IMessageReceiveListener { +public class CommandListener implements ICommandSendListener { private static final Pattern COMMAND_NAVI_HOUSE_NUMBER_PATTERN = compile("^navi (?\\d+)$"); @@ -50,13 +46,6 @@ public boolean onCommandSend(@NotNull String command) { return true; } - @Override - public boolean onMessageReceive(Text text, String message) { - return storage.getCommandResponseRetrievers().stream() - .filter(CommandResponseRetriever::isActive) - .noneMatch(commandResponseRetriever -> commandResponseRetriever.addAsResultIfMatch(message)); - } - private boolean containsUppercase(@NotNull String input) { for (char c : input.toCharArray()) { if (isUpperCase(c)) { diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/SyncListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/SyncListener.java index 235b9a21..bb1b2086 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/SyncListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/SyncListener.java @@ -16,12 +16,12 @@ @UCUtilsListener public class SyncListener implements ICommandSendListener, IMessageReceiveListener { - private static final Pattern SERVER_PASSWORD_MISSING_PATTERN = compile("^» Schütze deinen Account mit /passwort new \\[Passwort]$"); + private static final Pattern SERVER_PASSWORD_MISSING_PATTERN = compile("^» Schütze deinen Account mit /passwort new \\[Passwort].$"); private static final Pattern SERVER_PASSWORD_ACCEPTED_PATTERN = compile("^Du hast deinen Account freigeschaltet\\.$"); @Override public boolean onCommandSend(@NotNull String command) { - if (syncService.isGameSyncProcessActive() && !command.contains("wanteds") && !command.contains("contractlist") && !command.contains("hausverbot list") && !command.contains("blacklist")) { + if (syncService.isGameSyncProcessActive() && !command.contains("memberinfoall") && !command.contains("wanteds") && !command.contains("contractlist") && !command.contains("hausverbot") && !command.contains("blacklist")) { notificationService.sendWarningNotification("Synchronisierung aktiv - Befehle blockiert"); return false; } @@ -36,14 +36,14 @@ public boolean onMessageReceive(Text text, String message) { // if a password is not set, start the game sync process Matcher serverPasswordMissingMatcher = SERVER_PASSWORD_MISSING_PATTERN.matcher(message); if (serverPasswordMissingMatcher.find()) { - syncService.syncFactionSpecificData(); + syncService.syncFactionMembersWithCommand(syncService::syncFactionSpecificData); return true; } // if a password is accepted, start the game sync process Matcher serverPasswordAcceptedMatcher = SERVER_PASSWORD_ACCEPTED_PATTERN.matcher(message); if (serverPasswordAcceptedMatcher.find()) { - syncService.syncFactionSpecificData(); + syncService.syncFactionMembersWithCommand(syncService::syncFactionSpecificData); 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 index efd706ad..5e179594 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BlacklistListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/BlacklistListener.java @@ -12,6 +12,7 @@ import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.UCUtils.syncService; 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.lang.System.currentTimeMillis; import static java.util.regex.Pattern.compile; @@ -51,7 +52,7 @@ public boolean onMessageReceive(Text text, String message) { Matcher blacklistEntryAddMatcher = BLACKLIST_ENTRY_ADD.matcher(message); if (blacklistEntryAddMatcher.find()) { // show all entries to sync - utilService.delayedAction(() -> commandService.sendCommandWithAfkCheck("blacklist"), 1000); + utilService.delayedAction(() -> commandService.sendCommandWithAfkCheck("blacklist"), COMMAND_COOLDOWN_MILLIS); 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 index f92e62aa..f335b396 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/ContractListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/ContractListener.java @@ -14,6 +14,7 @@ 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.lang.System.currentTimeMillis; import static java.util.regex.Pattern.compile; @@ -51,7 +52,7 @@ public boolean onMessageReceive(Text text, String message) { Matcher contractAddMatcher = CONTRACT_ADD_PATTERN.matcher(message); if (contractAddMatcher.find()) { // show all entries to sync - utilService.delayedAction(() -> commandService.sendCommandWithAfkCheck("contractlist"), 1000); + utilService.delayedAction(() -> commandService.sendCommandWithAfkCheck("contractlist"), COMMAND_COOLDOWN_MILLIS); CONTRACT_SET.play(); return true; } 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 ebc8d2c8..baaf5739 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 @@ -3,9 +3,10 @@ import de.rettichlp.ucutils.common.Storage; import de.rettichlp.ucutils.common.models.BlackMarket; 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.Reinforcement; import de.rettichlp.ucutils.common.registry.UCUtilsListener; -import de.rettichlp.ucutils.listener.IKeyPressListener; import de.rettichlp.ucutils.listener.IMessageReceiveListener; import de.rettichlp.ucutils.listener.IMessageSendListener; import de.rettichlp.ucutils.listener.IMoveListener; @@ -17,6 +18,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Predicate; @@ -28,10 +30,13 @@ 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.UCUtils.syncService; import static de.rettichlp.ucutils.common.Storage.ToggledChat.NONE; import static de.rettichlp.ucutils.common.configuration.options.Options.ReinforcementType.UNICACITYADDON; import static de.rettichlp.ucutils.common.models.Faction.FBI; import static de.rettichlp.ucutils.common.models.Faction.RETTUNGSDIENST; +import static de.rettichlp.ucutils.common.models.Faction.fromDisplayName; +import static java.lang.Integer.parseInt; import static java.lang.System.currentTimeMillis; import static java.time.LocalDateTime.now; import static java.util.Arrays.stream; @@ -48,11 +53,15 @@ import static net.minecraft.util.Formatting.RED; @UCUtilsListener -public class FactionListener implements IKeyPressListener, IMessageReceiveListener, IMessageSendListener, IMoveListener { +public class FactionListener implements IMessageReceiveListener, IMessageSendListener, IMoveListener { + + private static final Pattern FACTION_MEMBER_ALL_HEADER = compile("^==== Mitglieder von (?.+) \\(\\d+/\\d+\\) ====$"); + private static final Pattern FACTION_MEMBER_ALL_ENTRY = compile("^\\s*-\\s*(?\\d)\\s*\\|\\s*(?.+)$"); 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$"); private static final Pattern REINFORCMENT_ON_THE_WAY_PATTERN = compile("^(?.+) (?:\\[UC])?(?[a-zA-Z0-9_]+) kommt zum Verstärkungsruf von (?:\\[UC])?(?[a-zA-Z0-9_]+)! \\((?\\d+) Meter entfernt\\)$"); + private static final Pattern EQUIP_PATTERN = compile("^\\[Equip] Du hast dich mit (?.+) equipt!$"); private static final ReinforcementConsumer REINFORCEMENT = (type, sender, naviPoint, distance) -> empty() @@ -72,32 +81,46 @@ public class FactionListener implements IKeyPressListener, IMessageReceiveListen .append(of(distance + "m").copy().formatted(DARK_AQUA)) .append(of(")").copy().formatted(GRAY)); - private long lastFactionScreenExecution = 0; + private Faction factionToCheck; private long lastBlackMarketCheck = 0; @Override - public void onSwapHandsKeyPress() { - long now = currentTimeMillis(); - boolean isCooldownOver = now - this.lastFactionScreenExecution > 5000; - if (player.isSneaking() && isCooldownOver) { - this.lastFactionScreenExecution = currentTimeMillis(); - - Faction faction = storage.getFaction(player.getGameProfile().name()); -// api.getFactionResetTime(faction, weeklyTime -> { -// MinecraftClient client = MinecraftClient.getInstance(); -// -// LocalDateTime to = weeklyTime.nextOccurrence(); -// LocalDateTime from = to.minusWeeks(1); -// api.getFactionPlayerData(from, to, faction.getMembers().stream().map(FactionMember::playerName).toList(), factionPlayerDataResponse -> client.execute(() -> { -// FactionActivityScreen factionActivityScreen = new FactionActivityScreen(faction, from, to, factionPlayerDataResponse, RANK, DESCENDING); -// client.setScreen(factionActivityScreen); -// })); -// }); + public boolean onMessageReceive(Text text, String message) { + Matcher factionMemberAllHeaderMatcher = FACTION_MEMBER_ALL_HEADER.matcher(message); + if (factionMemberAllHeaderMatcher.find()) { + String factionDisplayName = factionMemberAllHeaderMatcher.group("faction"); + fromDisplayName(factionDisplayName).ifPresentOrElse(faction -> this.factionToCheck = faction, + () -> LOGGER.warn("Could not find faction for display name '{}'", factionDisplayName)); + + // clear old faction entry + storage.getFactionEntries().removeIf(factionEntry -> factionEntry.faction() == this.factionToCheck); + storage.getFactionEntries().add(new FactionEntry(this.factionToCheck, new ArrayList<>())); + + return !syncService.isGameSyncProcessActive(); + } + + Matcher factionMemberAllEntryMatcher = FACTION_MEMBER_ALL_ENTRY.matcher(message); + if (factionMemberAllEntryMatcher.find() && this.factionToCheck != null) { + int rank = parseInt(factionMemberAllEntryMatcher.group("rank")); + String[] playerNames = factionMemberAllEntryMatcher.group("playerNames").split(", "); + + List factionMembersForRank = stream(playerNames) + .map(playerName -> new FactionMember(playerName, rank)) + .toList(); + + storage.getFactionEntries().stream() + .filter(factionEntry -> factionEntry.faction() == this.factionToCheck) + .findFirst() + .ifPresent(factionEntry -> factionEntry.members().addAll(factionMembersForRank)); + + LOGGER.info("Retrieved {} members for faction {}[rank={}] from command", factionMembersForRank.size(), this.factionToCheck.name(), rank); + + // clear nametag render cache + storage.getPlayerFactionCache().clear(); + + return !syncService.isGameSyncProcessActive(); } - } - @Override - public boolean onMessageReceive(Text text, String message) { Matcher reinforcementMatcher = REINFORCEMENT_PATTERN.matcher(message); if (reinforcementMatcher.find()) { String type = ofNullable(reinforcementMatcher.group("type")).orElse("Reinforcement"); 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 6e5b8dae..2a0a3c0a 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 @@ -20,6 +20,7 @@ import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.UCUtils.syncService; 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.lang.System.currentTimeMillis; import static java.time.Duration.between; @@ -66,7 +67,7 @@ public boolean onMessageReceive(Text text, String message) { Matcher medicReviveStartMatcher = MEDIC_REVIVE_START.matcher(message); if (medicReviveStartMatcher.find()) { this.lastReviveStartetAt = now(); - utilService.delayedAction(() -> commandService.sendCommand("dinfo"), 1000); + utilService.delayedAction(() -> commandService.sendCommand("dinfo"), COMMAND_COOLDOWN_MILLIS); } Matcher housebanHeaderMatcher = HOUSEBAN_HEADER_PATTERN.matcher(message); diff --git a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/WantedListener.java b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/WantedListener.java index 39b9bd82..66c00978 100644 --- a/src/main/java/de/rettichlp/ucutils/listener/impl/faction/WantedListener.java +++ b/src/main/java/de/rettichlp/ucutils/listener/impl/faction/WantedListener.java @@ -18,6 +18,7 @@ import static de.rettichlp.ucutils.UCUtils.storage; import static de.rettichlp.ucutils.UCUtils.syncService; 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.lang.String.valueOf; import static java.lang.System.currentTimeMillis; @@ -200,7 +201,7 @@ public boolean onMessageReceive(Text text, String message) { Matcher carCheckMatcher = CAR_CHECK_PATTERN.matcher(message); if (carCheckMatcher.find()) { String playerName = carCheckMatcher.group("playerName"); - utilService.delayedAction(() -> commandService.sendCommand("memberinfo " + playerName), 1000); + utilService.delayedAction(() -> commandService.sendCommand("memberinfo " + playerName), COMMAND_COOLDOWN_MILLIS); } Matcher carParkticketMatcher = CAR_PARKTICKET_PATTERN.matcher(message); diff --git a/src/main/java/de/rettichlp/ucutils/mixin/EntityRendererMixin.java b/src/main/java/de/rettichlp/ucutils/mixin/EntityRendererMixin.java index cfdb6633..436246cd 100644 --- a/src/main/java/de/rettichlp/ucutils/mixin/EntityRendererMixin.java +++ b/src/main/java/de/rettichlp/ucutils/mixin/EntityRendererMixin.java @@ -6,18 +6,21 @@ import de.rettichlp.ucutils.common.models.Faction; import de.rettichlp.ucutils.common.models.HousebanEntry; import de.rettichlp.ucutils.common.models.WantedEntry; -import net.minecraft.client.font.TextRenderer; import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.state.EntityRenderState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.scoreboard.Team; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.text.TextColor; import net.minecraft.util.Formatting; import org.jetbrains.annotations.NotNull; -import org.spongepowered.asm.mixin.Final; 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.CallbackInfoReturnable; import java.util.List; import java.util.Optional; @@ -37,89 +40,16 @@ import static net.minecraft.util.Formatting.RED; @Mixin(EntityRenderer.class) -public abstract class EntityRendererMixin { - - @Final - @Shadow - private TextRenderer textRenderer; - -// @ModifyVariable( -// method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/command/OrderedRenderCommandQueue;Lnet/minecraft/client/render/state/CameraRenderState)V", -// at = @At("HEAD"), -// argsOnly = true -// ) -// private EntityRenderState renderLabelIfPresent(EntityRenderState value) { -// if (!storage.isUnicaCity()) { -// return original; -// } -// -// if (state instanceof PlayerEntityRenderState playerEntityRenderState && nonNull(playerEntityRenderState.displayName)) { -// Text targetDisplayName = playerEntityRenderState.displayName; -// String targetName = playerEntityRenderState.name; -// return getFormattedTargetDisplayName(targetDisplayName, targetName); -// } else if (state instanceof ItemEntityRenderState itemDisplayEntityRenderState && nonNull(itemDisplayEntityRenderState.displayName) && itemDisplayEntityRenderState.stack.isOf(Items.SKELETON_SKULL)) { -// Text targetDisplayName = itemDisplayEntityRenderState.displayName; -// String targetName = targetDisplayName.getString().substring(1); // ✞RettichLP -> RettichLP -// -// LOGGER.debug("Original: {} -> {}, already modified: {}", targetDisplayName.getString(), targetName, targetName.contains(" ")); -// // only modify names if not containing space with the faction info prefix - avoid duplicated rendering -// return targetName.contains(" ") ? original : getFormattedTargetDisplayName(targetDisplayName, targetName); -// } -// -// return original; -// } -// -// @Inject( -// method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", -// at = @At("TAIL") -// ) -// private void renderLabelIfPresent(EntityRenderState state, -// Text original, -// MatrixStack matrices, -// VertexConsumerProvider vertexConsumers, -// int light, -// CallbackInfo ci) { -// if (!storage.isUnicaCity()) { -// return; -// } -// -// if (!(state instanceof PlayerEntityRenderState playerEntityRenderState && nonNull(playerEntityRenderState.displayName))) { -// return; -// } -// -// String targetName = playerEntityRenderState.name; -// -// // afk -// if (!configuration.getOptions().nameTag().additionalAfk() || !isAfk(targetName)) { -// return; -// } -// -// Vec3d vec3d = state.nameLabelPos; -// if (vec3d == null) { -// return; -// } -// -// boolean sneaking = !state.sneaking; -// matrices.push(); -// matrices.translate(vec3d.x, vec3d.y + 0.5F, vec3d.z); -// matrices.multiply(this.dispatcher.getRotation()); -// matrices.scale(0.02F, -0.02F, 0.02F); -// -// Matrix4f matrix4f = matrices.peek().getPositionMatrix(); -// -// TextRenderer textRenderer = this.textRenderer; -// -// Text text = of("ᴀꜰᴋ").copy().formatted(GOLD); -// -// float x = (-textRenderer.getWidth(text)) / 2.0F; -// -// textRenderer.draw(text, x, -12.5f, -2130706433, true, matrix4f, vertexConsumers, sneaking ? SEE_THROUGH : NORMAL, 0, light); -// if (sneaking) { -// textRenderer.draw(text, x, -12.5f, -1, true, matrix4f, vertexConsumers, NORMAL, 0, applyEmission(light, 2)); -// } -// -// matrices.pop(); -// } +public abstract class EntityRendererMixin { + + @Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true) + private void ucutils$getDisplayNameHead(T entity, CallbackInfoReturnable cir) { + Text originalDisplayName = entity.getDisplayName(); + Text formattedDisplayName = entity instanceof PlayerEntity playerEntity && originalDisplayName != null + ? getFormattedTargetDisplayName(originalDisplayName, playerEntity.getGameProfile().name()) + : originalDisplayName; + cir.setReturnValue(formattedDisplayName); + } @Unique private MutableText getFormattedTargetDisplayName(@NotNull Text targetDisplayName, String targetName) {