From 36fac05e23b3e0de44526c7153c59179f54d0cbf Mon Sep 17 00:00:00 2001 From: tmbRandy Date: Sun, 6 Oct 2024 22:25:41 +0200 Subject: [PATCH] - Cleaned project and reduced boilerplate code - Added visual hopper connections - Added Hopper connection mode widget - Added mod counter to "nearby" widget - Fixed a bug. /fahndung now works correctly --- README.md | 11 +- api/build.gradle.kts | 16 +- build.gradle.kts | 94 ++--- core/build.gradle.kts | 33 +- .../tmb/randy/tmbgriefergames/core/Addon.java | 66 +++- .../randy/tmbgriefergames/core/CBtracker.java | 57 +++ .../tmbgriefergames/core/FileManager.java | 75 ++++ .../randy/tmbgriefergames/core/IBridge.java | 8 +- .../core/commands/PlayerTracerCommand.java | 8 +- .../core/config/Configuration.java | 25 +- .../core/config/HopperSubConfig.java | 18 + .../randy/tmbgriefergames/core/enums/CBs.java | 46 +++ .../core/enums/HopperState.java | 5 + .../core/events/CbChangedEvent.java | 6 + .../core/events/HopperStateChangedEvent.java | 17 + .../core}/util/AccountUnity.java | 12 +- .../core/util/HopperTracker.java | 45 +++ .../core}/util/ItemClearTimerListener.java | 17 +- .../tmbgriefergames/core}/util/ItemSaver.java | 9 +- .../core/util/PlayerTracer.java | 122 ++++++ .../core}/util/PlotSwitch.java | 26 +- .../core}/util/chat/ChatCleaner.java | 19 +- .../core}/util/chat/CooldownNotifier.java | 14 +- .../core}/util/chat/EmptyLinesRemover.java | 8 +- .../core}/util/chat/MsgTabs.java | 16 +- .../core}/util/chat/NewsBlocker.java | 7 +- .../core}/util/chat/PaymentValidator.java | 14 +- .../core}/util/chat/StreamerMute.java | 9 +- .../core}/util/chat/TypeCorrection.java | 6 +- .../core/widgets/FlyTimerWidget.java | 7 +- .../core/widgets/GameInfoWidget.java | 7 +- .../core/widgets/HopperModeWidget.java | 65 ++++ .../core/widgets/ItemClearWidget.java | 12 +- .../core/widgets/NearbyWidget.java | 230 ++++++++++- .../assets/tmbgriefergames/i18n/de_de.json | 251 +++++++----- .../assets/tmbgriefergames/i18n/en_us.json | 77 +++- .../tmbgriefergames/textures/settings.png | Bin 57316 -> 61797 bytes .../themes/fancy/textures/settings.png | Bin 57316 -> 61797 bytes .../themes/vanilla/textures/settings.png | Bin 57316 -> 61797 bytes game-runner/gradle.properties | 1 + .../v1_12_2/util/AutoComp.java | 2 +- .../util/AutoCrafter/AutoCrafterV1.java | 18 +- .../util/AutoCrafter/AutoCrafterV3.java | 22 +- .../util/{ => AutoCrafter}/Simulator.java | 6 +- .../v1_12_2/util/AutoDecomp.java | 36 +- .../v1_12_2/util/AutoLoot.java | 150 ++++++++ .../v1_12_2/util/CBTracker.java | 74 ---- .../tmbgriefergames/v1_12_2/util/HABK.java | 4 +- .../v1_12_2/util/HopperConnections.java | 362 ++++++++++++++++++ .../v1_12_2/util/ItemClearTimerListener.java | 56 --- .../v1_12_2/util/NatureBordersRenderer.java | 12 +- .../v1_12_2/util/PlayerTracer.java | 99 ----- .../tmbgriefergames/v1_12_2/util/VABK.java | 2 +- .../v1_12_2/util/VersionisedBridge.java | 130 +++---- .../v1_12_2/util/chat/ChatCleaner.java | 57 --- .../v1_12_2/util/chat/EmptyLinesRemover.java | 33 -- .../v1_12_2/util/chat/MsgTabs.java | 177 --------- .../v1_12_2/util/chat/NewsBlocker.java | 28 -- .../v1_12_2/util/chat/PaymentValidator.java | 31 -- .../v1_12_2/util/chat/StreamerMute.java | 15 - .../v1_12_2/util/chat/TypeCorrection.java | 125 ------ .../v1_8_9/util/AccountUnity.java | 18 - .../tmbgriefergames/v1_8_9/util/AutoComp.java | 14 +- .../util/AutoCrafter/AutoCrafterV1.java | 31 +- .../util/AutoCrafter/AutoCrafterV3.java | 20 +- .../util/{ => AutoCrafter}/Simulator.java | 6 +- .../v1_8_9/util/AutoDecomp.java | 30 +- .../v1_8_9/util/AutoHopper.java | 15 - .../tmbgriefergames/v1_8_9/util/AutoLoot.java | 150 ++++++++ .../v1_8_9/util/CBTracker.java | 73 ---- .../tmbgriefergames/v1_8_9/util/HABK.java | 4 +- .../v1_8_9/util/HopperConnections.java | 362 ++++++++++++++++++ .../v1_8_9/util/ItemSaver.java | 107 ------ .../v1_8_9/util/NatureBordersRenderer.java | 12 +- .../v1_8_9/util/PlayerTracer.java | 99 ----- .../v1_8_9/util/PlotSwitch.java | 148 ------- .../v1_8_9/util/TooltipExtension.java | 4 +- .../tmbgriefergames/v1_8_9/util/VABK.java | 2 +- .../v1_8_9/util/VersionisedBridge.java | 126 +++--- .../v1_8_9/util/chat/CooldownNotifier.java | 59 --- gradle.properties | 3 +- gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle.kts | 16 +- 83 files changed, 2372 insertions(+), 1829 deletions(-) create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/CBtracker.java create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/FileManager.java create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/enums/CBs.java create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/enums/HopperState.java create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/events/CbChangedEvent.java create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/events/HopperStateChangedEvent.java rename {game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/AccountUnity.java (69%) create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/util/HopperTracker.java rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/ItemClearTimerListener.java (87%) rename {game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/ItemSaver.java (97%) create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlayerTracer.java rename {game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/PlotSwitch.java (88%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/ChatCleaner.java (85%) rename {game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/CooldownNotifier.java (93%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/EmptyLinesRemover.java (82%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/MsgTabs.java (94%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/NewsBlocker.java (80%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/PaymentValidator.java (68%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/StreamerMute.java (51%) rename {game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9 => core/src/main/java/tmb/randy/tmbgriefergames/core}/util/chat/TypeCorrection.java (91%) create mode 100644 core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/HopperModeWidget.java create mode 100644 game-runner/gradle.properties rename game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/{ => AutoCrafter}/Simulator.java (93%) create mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoLoot.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/CBTracker.java create mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HopperConnections.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemClearTimerListener.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlayerTracer.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/ChatCleaner.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/EmptyLinesRemover.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/MsgTabs.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/NewsBlocker.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/PaymentValidator.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/StreamerMute.java delete mode 100644 game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/TypeCorrection.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AccountUnity.java rename game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/{ => AutoCrafter}/Simulator.java (93%) create mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoLoot.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/CBTracker.java create mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HopperConnections.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemSaver.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlayerTracer.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlotSwitch.java delete mode 100644 game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/CooldownNotifier.java diff --git a/README.md b/README.md index 87c4c4a..69a361e 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,15 @@ Die Plotgrenzen auf den beiden Natur-CBs können mit Linien grafisch dargestellt ### Automatische Trichtereinstellung Wenn du eine Vielzahl an Trichtern einstellen musst, kannst du die gewünschten Einstellungen festlegen. Sobald du dann ein Trichtermenü öffnest, werden je nach Einstellung Filteritem, Einsaugradius, Stackgröße und Schlussaktion, wie die Verbindung mit einem anderen Trichter automatisch vorgenommen. Du kannst außerdem festlegen, dass du bei Rechtsklick auf einen Trichter automatisch sneakst. +### Optische Hilfe für Trichterverbindungen +Du kannst die Verbindungen von Trichtern mit Linien darstellen lassen. Direktverbindungen erscheinen blau, Multiverbindungen rot. Bei Multiverbindungen siehst du außerdem, welches Item wohin geleitet wird. Du siehst die Verbindungslinien, nachdem du eine Verbindung gesetzt hast, oder wenn du das entsprechende Trichtermenü öffnest. Beachte, dass die Linien nicht persistent gespeichert werden. Die Verbindungsgrenze von 30 Blöcken kannst du während des Verbindungsmodus außerdem durch eine rote Sphere darstellen lassen. So weißt du immer, wie weit du verbinden kannst. + ### Lobby automatisch überspringen Wenn du willst, kannst du direkt im Portalraum spawnen. +### Auto Loot +Deine /freekiste und /grieferboost kann das Addon automatisch für dich abholen. Es merkt sich, wenn diese abgeholt wurden und führt die Befehle automatisch aus, sobald die Cooldowns abgelaufen sind. Außerdem erinnert es dich, sobald du wieder /kopf nutzen kannst. + ### Automatische Annahme von /tpa und /tpahere Wenn du mehrere Accounts besitzt, kannst du dir von einem Account zum anderen eine /tpa oder /tpahere senden und diese wird sofort angenommen. Du musst dafür nur in LabyMod deine Accounts registrieren, was du normalerweise ohnehin schon getan hast. @@ -75,7 +81,10 @@ Wenn dich die große Anzeigetafel rechts stört, kannst du diese nun ausblenden. Wenn du wisst, kannst du dir nach Einnahme eines Flugtranks einen 15 Minuten Countdown einblenden lassen, sodass du immer siehst, wann dein Flugeffekt ausläuft. ### Widget In der Nähe -Dieses Widget zeigt dir eine Liste von Spielern in deiner unmittelbaren Umgebung an. +Dieses Widget zeigt dir eine Liste von Spielern in deiner unmittelbaren Umgebung an. Auch Mobs werden angezeigt und zählt diese sogar zusammen - selbst wenn sie gestackt sind. + +### Widget Verbindungsmodus +Beim Verbinden von Trichtern kann der Chat durch die Benachrichtigungen zum Verbindungsmodus des Trichters schnell unübersichtlich werden. Ziehe einfach das Widget "Verbindungsmodus" in deine GUI. Dadurch werden die Trichternachrichten unterdrückt und du siehst stattdessen per Symbol, ob du im Verbindungsmodus oder im Multi-Verbindungsmodus bist. ### Chatfunktionen diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 8fdb04e..64a17b0 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,18 +1,10 @@ -version = "0.1.0" - -plugins { - id("java-library") -} +import net.labymod.labygradle.common.extension.LabyModAnnotationProcessorExtension.ReferenceType dependencies { + labyProcessor() labyApi("api") } -labyModProcessor { - referenceType = net.labymod.gradle.core.processor.ReferenceType.INTERFACE -} - -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 +labyModAnnotationProcessor { + referenceType = ReferenceType.INTERFACE } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 1b437d0..e9cc553 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,91 +1,41 @@ plugins { - id("java-library") - id("net.labymod.gradle") - id("net.labymod.gradle.addon") + id("net.labymod.labygradle") + id("net.labymod.labygradle.addon") } -group = "tmb.randy" -version = "1.5.3" - -java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) +val versions = providers.gradleProperty("net.labymod.minecraft-versions").get().split(";") -tasks.withType { - options.encoding = "UTF-8" -} +group = "tmb.randy" +version = providers.environmentVariable("VERSION").getOrElse("1.6.0") labyMod { defaultPackageName = "tmb.randy.tmbgriefergames" - addonInfo { - namespace = "tmbgriefergames" - displayName = "GrieferGames Addon by TMB" - author = "TMB Clan" - description = "Eine Sammlung nützlicher Erweiterungen für das GrieferGames Netzwerk." - minecraftVersion = "1.8.9,1.12.2" - version = System.getenv().getOrDefault("VERSION", "1.1") - } minecraft { - registerVersions( - "1.8.9", - "1.12.2" - ) { version, provider -> - configureRun(provider, version) - } - - subprojects.forEach { - if (it.name != "game-runner") { - filter(it.name) + registerVersion(versions.toTypedArray()) { + runs { + getByName("client") { + // When the property is set to true, you can log in with a Minecraft account + // devLogin = true + } } } } - addonDev { - productionRelease() + addonInfo { + namespace = "tmbgriefergames" + displayName = "GrieferGames Addon by TMB" + author = "TMB Clan" + description = "Eine Sammlung nützlicher Erweiterungen für das GrieferGames Netzwerk." + minecraftVersion = "1.8.9,1.12.2" + version = rootProject.version.toString() } } subprojects { - plugins.apply("java-library") - plugins.apply("net.labymod.gradle") - plugins.apply("net.labymod.gradle.addon") - - repositories { - maven("https://libraries.minecraft.net/") - maven("https://repo.spongepowered.org/repository/maven-public/") - mavenLocal() - } -} + plugins.apply("net.labymod.labygradle") + plugins.apply("net.labymod.labygradle.addon") -fun configureRun(provider: net.labymod.gradle.core.minecraft.provider.VersionProvider, gameVersion: String) { - provider.runConfiguration { - mainClass = "net.minecraft.launchwrapper.Launch" - jvmArgs("-Dnet.labymod.running-version=${gameVersion}") - jvmArgs("-Dmixin.debug=true") - jvmArgs("-Dnet.labymod.debugging.all=true") - jvmArgs("-Dmixin.env.disableRefMap=true") - - args("--tweakClass", "net.labymod.core.loader.vanilla.launchwrapper.LabyModLaunchWrapperTweaker") - args("--labymod-dev-environment", "true") - args("--addon-dev-environment", "true") - } - - provider.javaVersion = when (gameVersion) { - else -> { - JavaVersion.VERSION_21 - } - } - - provider.mixin { - val mixinMinVersion = when (gameVersion) { - "1.8.9", "1.12.2", "1.16.5" -> { - "0.6.6" - } - - else -> { - "0.8.2" - } - } - - minVersion = mixinMinVersion - } + group = rootProject.group + version = rootProject.version } \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index c25c93d..f863d0e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,34 +1,13 @@ -version = "0.1.0" - -plugins { - id("java-library") -} - -tasks.withType { - options.encoding = "UTF-8" -} - -repositories { - mavenCentral() -} +import net.labymod.labygradle.common.extension.LabyModAnnotationProcessorExtension.ReferenceType dependencies { + labyProcessor() api(project(":api")) - // If you want to use external libraries, you can do that here. - // The dependencies that are specified here are loaded into your project but will also - // automatically be downloaded by labymod, but only if the repository is public. - // If it is private, you have to add and compile the dependency manually. - // You have to specify the repository, there are getters for maven central and sonatype, every - // other repository has to be specified with their url. Example: - // maven(mavenCentral(), "org.apache.httpcomponents:httpclient:4.5.13") -} - -labyModProcessor { - referenceType = net.labymod.gradle.core.processor.ReferenceType.DEFAULT + // An example of how to add an external dependency that is used by the addon. + // addonMavenDependency("org.jeasy:easy-random:5.0.0") } -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 +labyModAnnotationProcessor { + referenceType = ReferenceType.DEFAULT } \ No newline at end of file diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/Addon.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/Addon.java index 6492fb7..7a156ae 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/Addon.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/Addon.java @@ -2,6 +2,7 @@ import net.labymod.api.Laby; import net.labymod.api.addon.LabyAddon; +import net.labymod.api.client.gui.hud.binding.category.HudWidgetCategory; import net.labymod.api.client.gui.screen.activity.types.IngameOverlayActivity; import net.labymod.api.models.addon.annotation.AddonMain; import tmb.randy.tmbgriefergames.core.commands.AutocraftV2Command; @@ -12,8 +13,23 @@ import tmb.randy.tmbgriefergames.core.commands.PlayerTracerCommand; import tmb.randy.tmbgriefergames.core.config.Configuration; import tmb.randy.tmbgriefergames.core.generated.DefaultReferenceStorage; +import tmb.randy.tmbgriefergames.core.util.AccountUnity; +import tmb.randy.tmbgriefergames.core.util.HopperTracker; +import tmb.randy.tmbgriefergames.core.util.ItemClearTimerListener; +import tmb.randy.tmbgriefergames.core.util.ItemSaver; +import tmb.randy.tmbgriefergames.core.util.PlayerTracer; +import tmb.randy.tmbgriefergames.core.util.PlotSwitch; +import tmb.randy.tmbgriefergames.core.util.chat.ChatCleaner; +import tmb.randy.tmbgriefergames.core.util.chat.CooldownNotifier; +import tmb.randy.tmbgriefergames.core.util.chat.EmptyLinesRemover; +import tmb.randy.tmbgriefergames.core.util.chat.MsgTabs; +import tmb.randy.tmbgriefergames.core.util.chat.NewsBlocker; +import tmb.randy.tmbgriefergames.core.util.chat.PaymentValidator; +import tmb.randy.tmbgriefergames.core.util.chat.StreamerMute; +import tmb.randy.tmbgriefergames.core.util.chat.TypeCorrection; import tmb.randy.tmbgriefergames.core.widgets.FlyTimerWidget; import tmb.randy.tmbgriefergames.core.widgets.GameInfoWidget; +import tmb.randy.tmbgriefergames.core.widgets.HopperModeWidget; import tmb.randy.tmbgriefergames.core.widgets.ItemClearWidget; import tmb.randy.tmbgriefergames.core.widgets.NearbyWidget; import java.util.Objects; @@ -23,7 +39,24 @@ public class Addon extends LabyAddon { private IBridge bridge; private static Addon SharedInstance; - private GameInfoWidget gameInfoWidget; + private GameInfoWidget gameInfoWidget; + private final CBtracker CBtracker = new CBtracker(); + private final PlayerTracer playerTracer = new PlayerTracer(); + private final HopperTracker hopperTracker = new HopperTracker(); + private final PlotSwitch plotSwitch = new PlotSwitch(); + + private final ChatCleaner chatCleaner = new ChatCleaner(); + private final CooldownNotifier cooldownNotifier = new CooldownNotifier(); + private final EmptyLinesRemover emptyLinesRemover = new EmptyLinesRemover(); + private final MsgTabs msgTabs = new MsgTabs(); + private final NewsBlocker newsBlocker = new NewsBlocker(); + private final PaymentValidator paymentValidator = new PaymentValidator(); + private final StreamerMute streamerMute = new StreamerMute(); + private final TypeCorrection typeCorrection = new TypeCorrection(); + private final ItemSaver itemSaver = new ItemSaver(); + private final AccountUnity accountUnity = new AccountUnity(); + private final ItemClearTimerListener itemClearTimerListener = new ItemClearTimerListener(); + private final String ADDON_PREFIX = "§6[§5§l§oT§b§l§oM§5§l§oB§6] "; @Override @@ -32,6 +65,21 @@ protected void enable() { SharedInstance = this; bridge = getReferenceStorage().iBridge(); this.registerListener(bridge); + this.registerListener(CBtracker); + this.registerListener(playerTracer); + this.registerListener(chatCleaner); + this.registerListener(cooldownNotifier); + this.registerListener(emptyLinesRemover); + this.registerListener(msgTabs); + this.registerListener(newsBlocker); + this.registerListener(paymentValidator); + this.registerListener(streamerMute); + this.registerListener(typeCorrection); + this.registerListener(hopperTracker); + this.registerListener(plotSwitch); + this.registerListener(itemSaver); + this.registerListener(accountUnity); + this.registerListener(itemClearTimerListener); this.registerCommand(new DKsCommand()); this.registerCommand(new PayAllCommand()); @@ -40,12 +88,16 @@ protected void enable() { this.registerCommand(new AutocraftV3Command()); this.registerCommand(new EjectCommand()); - gameInfoWidget = new GameInfoWidget(); + HudWidgetCategory category = new HudWidgetCategory("tmbgriefergames"); + labyAPI().hudWidgetRegistry().categoryRegistry().register(category); + + gameInfoWidget = new GameInfoWidget(category); - labyAPI().hudWidgetRegistry().register(new FlyTimerWidget()); - labyAPI().hudWidgetRegistry().register(new ItemClearWidget()); + labyAPI().hudWidgetRegistry().register(new FlyTimerWidget(category)); + labyAPI().hudWidgetRegistry().register(new ItemClearWidget(category)); labyAPI().hudWidgetRegistry().register(gameInfoWidget); - labyAPI().hudWidgetRegistry().register(new NearbyWidget()); + labyAPI().hudWidgetRegistry().register(new NearbyWidget(category)); + labyAPI().hudWidgetRegistry().register(new HopperModeWidget(category)); this.logger().info("Enabled the Addon"); } @@ -91,4 +143,8 @@ public static boolean isChatGuiOpen() { return false; } + + public PlayerTracer getPlayerTracer() {return playerTracer;} + + } diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/CBtracker.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/CBtracker.java new file mode 100644 index 0000000..0644f67 --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/CBtracker.java @@ -0,0 +1,57 @@ +package tmb.randy.tmbgriefergames.core; + +import net.labymod.api.Laby; +import net.labymod.api.client.component.TextComponent; +import net.labymod.api.client.scoreboard.Scoreboard; +import net.labymod.api.client.scoreboard.ScoreboardTeam; +import net.labymod.api.event.Subscribe; +import net.labymod.api.event.client.scoreboard.ScoreboardTeamUpdateEvent; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import javax.inject.Singleton; + +@Singleton +public class CBtracker { + private static CBs currentCB = CBs.NONE; + + @Subscribe + public void worldEnterEvent(ScoreboardTeamUpdateEvent event) { + if(!Addon.isGG()) return; + Scoreboard scoreboard = Laby.labyAPI().minecraft().getScoreboard(); + for (ScoreboardTeam team : scoreboard.getTeams()) { + if(team.getTeamName().equals("server_value")) { + String CBString = ((TextComponent)team.getPrefix()).getText(); + + CBs newCB = CBs.NONE; + + try { + newCB = CBs.valueOf(CBString.toUpperCase()); + } catch (IllegalArgumentException e) { + Addon.getSharedInstance().logger().warn(e.getMessage()); + } + + if(newCB != currentCB) { + currentCB = newCB; + Addon.getSharedInstance().logger().info("Joined CityBuild " + newCB.getName()); + Laby.fireEvent(new CbChangedEvent(newCB)); + } + } + } + + } + + public static CBs getCurrentCB() {return currentCB;} + public static boolean isNatureWorldCB() {return currentCB == CBs.NATURE || currentCB == CBs.EXTREME;} + public static boolean isPlotworldCB() { + return switch (currentCB) { + case WASSER, LAVA, PORTAL, LOBBY, NONE -> false; + default -> true; + }; + } + public static boolean canSendPayment() { + return switch (currentCB) { + case PORTAL, LOBBY, NONE -> false; + default -> true; + }; + } +} diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/FileManager.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/FileManager.java new file mode 100644 index 0000000..045e98a --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/FileManager.java @@ -0,0 +1,75 @@ +package tmb.randy.tmbgriefergames.core; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import net.labymod.api.Laby; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class FileManager { + private static final File storageFile = new File(new File(Laby.labyAPI().labyModLoader().getGameDirectory().toFile(), "labymod-neo/configs/tmbgriefergames"), "tmbgriefergames.json"); + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + private static Map> playerData = new HashMap<>(); + + static { + loadData(); + } + + private static void saveData() { + try { + if (!storageFile.getParentFile().exists()) { + storageFile.getParentFile().mkdirs(); + } + if (!storageFile.exists()) { + storageFile.createNewFile(); + } + + try (FileWriter writer = new FileWriter(storageFile)) { + gson.toJson(playerData, writer); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void loadData() { + if (!storageFile.exists()) { + return; + } + + try (FileReader reader = new FileReader(storageFile)) { + Type type = new TypeToken>>() {}.getType(); + playerData = gson.fromJson(reader, type); + if (playerData == null) { + playerData = new HashMap<>(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void setValue(String key, Object value) { + if(Laby.labyAPI().minecraft().getClientPlayer() != null) { + UUID playerUUID = Laby.labyAPI().minecraft().getClientPlayer().profile().getUniqueId(); + Map values = playerData.computeIfAbsent(playerUUID, k -> new HashMap<>()); + values.put(key, value); + saveData(); + } + } + + public static Object getValue(String key) { + if(Laby.labyAPI().minecraft().getClientPlayer() != null) { + UUID playerUUID = Laby.labyAPI().minecraft().getClientPlayer().profile().getUniqueId(); + Map values = playerData.get(playerUUID); + return values != null ? values.get(key) : null; + } + return null; + } +} diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/IBridge.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/IBridge.java index 786d1eb..dc57e4f 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/IBridge.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/IBridge.java @@ -1,17 +1,19 @@ package tmb.randy.tmbgriefergames.core; +import net.labymod.api.client.gui.screen.key.Key; import net.labymod.api.reference.annotation.Referenceable; @Referenceable public interface IBridge { - void startPlayerTracer(String name); - void cbChanged(); boolean isFlyCountdownActive(); String getWidgetString(); - String getItemRemoverValue(); void startNewAutocrafter(); boolean isCompActive(); void changeSlot(int slot); void startAuswurf(); void startAutocrafterV3(); + void openChat(); + boolean isChatGuiOpen(); + void resetLines(); + boolean allKeysPressed(Key[] keys); } diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/commands/PlayerTracerCommand.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/commands/PlayerTracerCommand.java index 1ac8b6b..3054e64 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/commands/PlayerTracerCommand.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/commands/PlayerTracerCommand.java @@ -17,15 +17,13 @@ public boolean execute(String prefix, String[] arguments) { switch (arguments.length) { case 0 -> { Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.startedHopping")); - Addon.getSharedInstance().getBridge().startPlayerTracer(null); + Addon.getSharedInstance().getPlayerTracer().startTracer(null); } case 1 -> { Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.lookingForPlayer", arguments[0])); - Addon.getSharedInstance().getBridge().startPlayerTracer(arguments[0]); - } - default -> { - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.tooManyArguments")); + Addon.getSharedInstance().getPlayerTracer().startTracer(arguments[0]); } + default -> Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.tooManyArguments")); } return true; diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/config/Configuration.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/config/Configuration.java index f6ee09c..42e2808 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/config/Configuration.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/config/Configuration.java @@ -14,6 +14,8 @@ @SpriteTexture("settings") public class Configuration extends AddonConfig { + public static final int SPRITE_SIZE = 21; + public Configuration() { this.chatConfig = new ChatSubConfig(); this.tooltipConfig = new TooltipSubConfig(); @@ -24,35 +26,39 @@ public Configuration() { } @SwitchSetting - @SpriteSlot(size = 21) + @SpriteSlot(size = SPRITE_SIZE) private final ConfigProperty enabled = new ConfigProperty<>(true); @SwitchSetting - @SpriteSlot(size = 21, x = 2, y = 1) + @SpriteSlot(size = SPRITE_SIZE, x = 2, y = 1) private final ConfigProperty itemProtection = new ConfigProperty<>(true); - @SpriteSlot(size = 21, x = 5, y = 2) + @SpriteSlot(size = SPRITE_SIZE, x = 5, y = 2) private final AutoCrafterSubConfig autoCrafterConfig; - @SpriteSlot(size = 21, x = 1) + @SpriteSlot(size = SPRITE_SIZE, x = 1) private final ChatSubConfig chatConfig; - @SpriteSlot(size = 21, x = 3, y = 2) + @SpriteSlot(size = SPRITE_SIZE, x = 3, y = 2) private final NatureSubConfig natureSubConfig; - @SpriteSlot(size = 21, x = 3, y = 1) + @SpriteSlot(size = SPRITE_SIZE, x = 3, y = 1) private final TooltipSubConfig tooltipConfig; - @SpriteSlot(size = 21, x = 2, y = 2) + @SpriteSlot(size = SPRITE_SIZE, x = 2, y = 2) private final HopperSubConfig hopperSubConfig; - @SpriteSlot(size = 21, x = 1, y = 3) + @SpriteSlot(size = SPRITE_SIZE, x = 1, y = 3) private final SwordsSubConfig swordsSubConfig; @SwitchSetting - @SpriteSlot(size = 21, x = 4, y = 2) + @SpriteSlot(size = SPRITE_SIZE, x = 4, y = 2) private final ConfigProperty skipHub = new ConfigProperty<>(true); + @SpriteSlot(size = SPRITE_SIZE, x = 2, y = 3) + @SwitchSetting + private final ConfigProperty autoLoot = new ConfigProperty<>(true); + @SettingSection("plotSwitch") @MultiKeyBindSetting @@ -78,4 +84,5 @@ public ConfigProperty getItemProtection() { public NatureSubConfig getNatureSubConfig() {return natureSubConfig;} public AutoCrafterSubConfig getAutoCrafterConfig() {return autoCrafterConfig;} public SwordsSubConfig getSwordsSubConfig() {return swordsSubConfig;} + public ConfigProperty getAutoLoot() {return autoLoot;} } diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/config/HopperSubConfig.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/config/HopperSubConfig.java index 30911b7..11dc383 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/config/HopperSubConfig.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/config/HopperSubConfig.java @@ -1,16 +1,22 @@ package tmb.randy.tmbgriefergames.core.config; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget.ButtonSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.SliderWidget.SliderSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.dropdown.DropdownWidget.DropdownSetting; import net.labymod.api.configuration.loader.Config; import net.labymod.api.configuration.loader.annotation.ShowSettingInParent; import net.labymod.api.configuration.loader.property.ConfigProperty; +import net.labymod.api.configuration.settings.annotation.SettingSection; +import net.labymod.api.util.MethodOrder; +import tmb.randy.tmbgriefergames.core.Addon; import tmb.randy.tmbgriefergames.core.enums.HopperFinalAction; import tmb.randy.tmbgriefergames.core.enums.HopperItemStackSizeEnum; public class HopperSubConfig extends Config { + @SettingSection("auto") + @ShowSettingInParent @SwitchSetting private final ConfigProperty enabled = new ConfigProperty<>(false); @@ -25,6 +31,16 @@ public class HopperSubConfig extends Config { @SwitchSetting private final ConfigProperty autoSneak = new ConfigProperty<>(false); + @SettingSection("visual") + + @SwitchSetting + private final ConfigProperty showLines = new ConfigProperty<>(true); + @SwitchSetting + private final ConfigProperty showRadius = new ConfigProperty<>(true); + @MethodOrder(after = "showRadius") + @ButtonSetting + public void resetLines() {Addon.getSharedInstance().getBridge().resetLines();} + public ConfigProperty getEnabled() { return this.enabled; } @@ -39,4 +55,6 @@ public ConfigProperty getRadius() { public ConfigProperty getAutoSneak() { return this.autoSneak; } + public ConfigProperty getShowLines() {return showLines;} + public ConfigProperty getShowRadius() {return showRadius;} } \ No newline at end of file diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/CBs.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/CBs.java new file mode 100644 index 0000000..34713e9 --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/CBs.java @@ -0,0 +1,46 @@ +package tmb.randy.tmbgriefergames.core.enums; + +public enum CBs { + LOBBY("LOBBY"), + PORTAL("PORTAL"), + EXTREME("EXTREME"), + CBE("CBE"), + NATURE("NATURE"), + CB1("CB1"), + CB2("CB2"), + CB3("CB3"), + CB4("CB4"), + CB5("CB5"), + CB6("CB6"), + CB7("CB7"), + CB8("CB8"), + CB9("CB9"), + CB10("CB10"), + CB11("CB11"), + CB12("CB12"), + CB13("CB13"), + CB14("CB14"), + CB15("CB15"), + CB16("CB16"), + CB17("CB17"), + CB18("CB18"), + CB19("CB19"), + CB20("CB20"), + CB21("CB21"), + CB22("CB22"), + LAVA("LAVA"), + WASSER("WASSER"), + EVENT("EVENT"), + NONE("NONE"); + + private final String name; + + CBs(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} + diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/HopperState.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/HopperState.java new file mode 100644 index 0000000..e84ef58 --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/enums/HopperState.java @@ -0,0 +1,5 @@ +package tmb.randy.tmbgriefergames.core.enums; + +public enum HopperState { + NONE, CONNECT, MULTI_CONNECT +} diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/events/CbChangedEvent.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/events/CbChangedEvent.java new file mode 100644 index 0000000..7d2c926 --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/events/CbChangedEvent.java @@ -0,0 +1,6 @@ +package tmb.randy.tmbgriefergames.core.events; + +import net.labymod.api.event.Event; +import tmb.randy.tmbgriefergames.core.enums.CBs; + +public record CbChangedEvent(CBs CB) implements Event { } diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/events/HopperStateChangedEvent.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/events/HopperStateChangedEvent.java new file mode 100644 index 0000000..4bfc0bf --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/events/HopperStateChangedEvent.java @@ -0,0 +1,17 @@ +package tmb.randy.tmbgriefergames.core.events; + +import net.labymod.api.event.Event; +import tmb.randy.tmbgriefergames.core.enums.HopperState; + +public class HopperStateChangedEvent implements Event { + private final HopperState oldState; + private final HopperState newState; + + public HopperStateChangedEvent(HopperState oldState, HopperState newState) { + this.oldState = oldState; + this.newState = newState; + } + + public HopperState getOldState() {return oldState;} + public HopperState getNewState() {return newState;} +} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AccountUnity.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/AccountUnity.java similarity index 69% rename from game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AccountUnity.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/AccountUnity.java index 8ce354f..b651a65 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AccountUnity.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/AccountUnity.java @@ -1,19 +1,23 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; +package tmb.randy.tmbgriefergames.core.util; import net.labymod.api.Laby; import net.labymod.api.account.Account; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; +import tmb.randy.tmbgriefergames.core.Addon; public class AccountUnity { + @Subscribe public void messageReceived(ChatReceiveEvent event) { + if(!Addon.isGG()) + return; for (Account account : Laby.references().accountService().getAccounts()) { String name = account.getUsername(); if(event.chatMessage().getPlainText().endsWith(name + " möchte sich zu dir teleportieren.") || event.chatMessage().getPlainText().endsWith(name + " möchte, dass du dich zu der Person teleportierst.")) { - VersionisedBridge.sendCommand("/tpaccept"); + Laby.references().chatExecutor().chat("/tpaccept"); } } } -} - +} \ No newline at end of file diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/util/HopperTracker.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/HopperTracker.java new file mode 100644 index 0000000..2f2fb7e --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/HopperTracker.java @@ -0,0 +1,45 @@ +package tmb.randy.tmbgriefergames.core.util; + +import net.labymod.api.Laby; +import net.labymod.api.event.Subscribe; +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.enums.HopperState; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import tmb.randy.tmbgriefergames.core.events.HopperStateChangedEvent; + +public class HopperTracker { + private static HopperState currentHopperState = HopperState.NONE; + + @Subscribe + public void cbSwitch(CbChangedEvent event) { + setCurrentHopperState(HopperState.NONE); + } + + @Subscribe + public void messageReceived(ChatReceiveEvent event) { + if(!Addon.isGG()) + return; + + String message = event.chatMessage().getPlainText(); + + setCurrentHopperState(switch (message) { + case "[Trichter] Das Multi-Verbinden wurde aktiviert. Klicke mit dem gewünschten Item auf den gewünschten Endpunkt." -> HopperState.MULTI_CONNECT; + case "[Trichter] Das Verbinden wurde aktiviert. Klicke auf den gewünschten Endpunkt." -> HopperState.CONNECT; + case "[Trichter] Der Trichter wurde erfolgreich verbunden.", + "[Trichter] Der Verbindungsmodus wurde beendet.", + "[Trichter] Der Startpunkt ist zu weit entfernt. Bitte starte erneut." -> HopperState.NONE; + default -> currentHopperState; + }); + } + + public static HopperState getCurrentHopperState() {return currentHopperState;} + + public static void setCurrentHopperState(HopperState newHopperState) { + if(currentHopperState != newHopperState) { + HopperState oldVal = currentHopperState; + currentHopperState = newHopperState; + Laby.fireEvent(new HopperStateChangedEvent(oldVal, newHopperState)); + } + } +} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemClearTimerListener.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemClearTimerListener.java similarity index 87% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemClearTimerListener.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemClearTimerListener.java index 642cfc4..b09f1f9 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemClearTimerListener.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemClearTimerListener.java @@ -1,14 +1,17 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; +package tmb.randy.tmbgriefergames.core.util; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.TimeUnit; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.network.server.NetworkPayloadEvent; import net.labymod.api.event.client.network.server.NetworkPayloadEvent.Side; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; public class ItemClearTimerListener { private static int itemRemover = -1; private static long endTime = -1L; + @Subscribe public void networkPayloadEvent(NetworkPayloadEvent event) { if(event.side() == Side.RECEIVE) { byte[] packetBuffer = event.getPayload().clone(); @@ -24,8 +27,10 @@ public void networkPayloadEvent(NetworkPayloadEvent event) { } } - public static int getItemRemover() {return itemRemover;} - public static void resetItemRemover() {itemRemover = -1;} + @Subscribe + public void CbChanged(CbChangedEvent event) { + itemRemover = -1; + } private int extractUntilValue(String input) { String pattern = "until\":(\\d+)"; @@ -53,4 +58,4 @@ public static String getDisplayValue() { return (minutes > 0) ? String.format("%02d:%02d", minutes, seconds) : String.format("%d s", seconds); } -} \ No newline at end of file +} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemSaver.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemSaver.java similarity index 97% rename from game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemSaver.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemSaver.java index 74cbb11..115d59a 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemSaver.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/ItemSaver.java @@ -1,8 +1,9 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; +package tmb.randy.tmbgriefergames.core.util; import net.labymod.api.Laby; import net.labymod.api.client.world.item.ItemStack; import net.labymod.api.component.data.DataComponentKey; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.input.MouseButtonEvent; import net.labymod.api.event.client.input.MouseButtonEvent.Action; import net.labymod.api.util.I18n; @@ -15,8 +16,11 @@ public class ItemSaver { private static final String NBTTagStringSoS = "[{lvl:-6s,id:18s},{lvl:-6s,id:21s},{lvl:-6s,id:7s}]"; public static final String NBTTagStringBirthBow = "[{lvl:22s,id:48s},{lvl:4s,id:49s},{lvl:1s,id:51s},{lvl:4s,id:19s},{lvl:22s,id:21s}]"; - + @Subscribe public void mouseButtonEvent(MouseButtonEvent event) { + if(!Addon.isGG()) + return; + if(Addon.getSharedInstance().configuration().getItemProtection().get()) { if(Laby.labyAPI().minecraft().getClientPlayer() != null) { if(Laby.labyAPI().minecraft().getClientPlayer().getMainHandItemStack() != null) { @@ -104,3 +108,4 @@ public static int findHotbarSlotforItem() { } } + diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlayerTracer.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlayerTracer.java new file mode 100644 index 0000000..6682b5c --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlayerTracer.java @@ -0,0 +1,122 @@ +package tmb.randy.tmbgriefergames.core.util; + +import net.labymod.api.Laby; +import net.labymod.api.client.gui.screen.key.Key; +import net.labymod.api.client.scoreboard.Scoreboard; +import net.labymod.api.client.scoreboard.ScoreboardTeam; +import net.labymod.api.event.Subscribe; +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import net.labymod.api.event.client.input.KeyEvent; +import net.labymod.api.event.client.input.KeyEvent.State; +import net.labymod.api.util.I18n; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class PlayerTracer { + public static final List CBlist = Arrays.asList(CBs.NONE, CBs.CB1, CBs.CB22, CBs.CB21, CBs.CB20, CBs.CB7, CBs.NATURE, CBs.CB2, CBs.CB3, CBs.CB4, CBs.CB5, CBs.CB6, CBs.CB8, CBs.CB9, CBs.CB10, CBs.CB11, CBs.CB12, CBs.CB13, CBs.CB14, CBs.CB15, CBs.CB16, CBs.CB17, CBs.CB18, CBs.CB19, CBs.EXTREME, CBs.CBE); + private int nextServer = 0; + private String playerName; + private boolean tracerActive; + + @Subscribe + public void onKey(KeyEvent event) { + if(!Addon.isGG()) + return; + + if(tracerActive && event.state() == State.PRESS && (event.key() == Key.W || event.key() == Key.A || event.key() == Key.S || event.key() == Key.D)) { + stopTracer(); + } + } + + @Subscribe + public void messageReceived(ChatReceiveEvent event) { + if(!Addon.isGG()) + return; + + String msg = event.chatMessage().getPlainText(); + if(msg.endsWith("Kicked whilst connecting to connector: Du hast dich zu schnell wieder eingeloggt. Versuche es später erneut.") && tracerActive) { + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); + } + }, + 1000 + ); + event.setCancelled(true); + } else if(tracerActive && ((msg.startsWith("[GrieferGames] Du wurdest automatisch auf ") && msg.endsWith(" verbunden.") || (msg.startsWith("[GrieferGames] Serverwechsel auf ") && msg.endsWith(" wurde gestartet.."))))) { + event.setCancelled(true); + } else if (msg.equals("[Switcher] Daten heruntergeladen!")) { + if(!Addon.isGG() || !tracerActive) return; + + if(CBtracker.isPlotworldCB()) { + if(isPlayerOnCB()) { + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.foundPlayer")); + stopTracer(); + } else if(nextServer < CBlist.size()) { + nextServer++; + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); + } + }, + 6000 + ); + } else { + stopTracer(); + } + } + } + } + + public void startTracer(String name) { + tracerActive = true; + + if(name != null) { + playerName = name.toLowerCase(); + } + nextServer = 1; + Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); + } + + public void stopTracer() { + tracerActive = false; + + playerName = null; + nextServer = 0; + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.tracingEnded")); + } + + private boolean isPlayerOnCB() { + if(playerName == null) { + return false; + } + + Scoreboard scoreboard = Laby.labyAPI().minecraft().getScoreboard(); + + if(scoreboard != null) { + for (ScoreboardTeam team : scoreboard.getTeams()) { + Collection members = team.getEntries(); + + for (String member : members) { + if(member.equalsIgnoreCase(playerName)) { + return true; + } + } + } + } + + return false; + } + + public boolean isTracerActive() { + return tracerActive; + } +} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlotSwitch.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlotSwitch.java similarity index 88% rename from game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlotSwitch.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlotSwitch.java index 4531745..d94d174 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlotSwitch.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/PlotSwitch.java @@ -1,7 +1,8 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; +package tmb.randy.tmbgriefergames.core.util; import net.labymod.api.Laby; import net.labymod.api.event.Phase; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatMessageSendEvent; import net.labymod.api.event.client.chat.ChatReceiveEvent; import net.labymod.api.event.client.input.KeyEvent; @@ -22,19 +23,21 @@ private enum DIRECTION { private String lastPlot = null; - + @Subscribe public void messageSend(ChatMessageSendEvent event) { - if(!Addon.isGG()) { + if(!Addon.isGG()) return; - } if(event.getMessage().toLowerCase().startsWith("/p h")) { lastPlot = event.getMessage(); } } - + @Subscribe public void tick(GameTickEvent event) { + if(!Addon.isGG()) + return; + if(event.phase() == Phase.PRE) { if(COMMAND_COOLDOWN_COUNTER > 0) { COMMAND_COOLDOWN_COUNTER--; @@ -51,8 +54,11 @@ public void tick(GameTickEvent event) { } } - + @Subscribe public void messageReceived(ChatReceiveEvent event) { + if(!Addon.isGG()) + return; + String message = event.chatMessage().getPlainText(); if(message.equals("[GrieferGames] Du wurdest zum Grundstück teleportiert.") && waitingForPlotSwitch) { @@ -60,17 +66,17 @@ public void messageReceived(ChatReceiveEvent event) { } } + @Subscribe public void keyDown(KeyEvent event) { - if(lastPlot == null || nextCommand != null || !Addon.isGG()) { + if(lastPlot == null || nextCommand != null || !Addon.isGG()) return; - } String command = null; if(event.state() == State.PRESS) { - if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getPreviousPlot().get())) { + if(Addon.getSharedInstance().getBridge().allKeysPressed(Addon.getSharedInstance().configuration().getPreviousPlot().get())) { command = getPlotCommand(lastPlot, DIRECTION.PREVIOUS); - } else if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getNextPlot().get())) { + } else if(Addon.getSharedInstance().getBridge().allKeysPressed(Addon.getSharedInstance().configuration().getNextPlot().get())) { command = getPlotCommand(lastPlot, DIRECTION.NEXT); } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/ChatCleaner.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/ChatCleaner.java similarity index 85% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/ChatCleaner.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/ChatCleaner.java index ee7d756..63ddaa0 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/ChatCleaner.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/ChatCleaner.java @@ -1,10 +1,10 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; import java.util.Arrays; import java.util.List; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; import tmb.randy.tmbgriefergames.core.Addon; -import tmb.randy.tmbgriefergames.core.config.Configuration; public class ChatCleaner { @@ -27,24 +27,25 @@ public class ChatCleaner { "Versuche in den Portalraum zu verbinden." ); + @Subscribe public void messageReceived(ChatReceiveEvent event) { - final Configuration configuration = Addon.getSharedInstance().configuration(); String message = event.chatMessage().getPlainText(); - if(message.equals("[Rezepte] Du hast nicht genug Material, um dieses Rezept herzustellen.")) { + // "No friendhip requests" messages is sent before the GrieferGames Server Name is set. So it has to be handles before checking for GG. + if(message.equals("[Freunde] Du hast aktuell keine Freundschaftsanfragen.") && Addon.getSharedInstance().configuration().getChatConfig().getCleanChat().get()) { event.setCancelled(true); } - if(!configuration.getChatConfig().getCleanChat().get()) + if(!Addon.isGG()) return; - - // "No friendhip requests" messages is sent before the GrieferGames Server Name is set. So it has to be handles before checking for GG. - - if(message.equals("[Freunde] Du hast aktuell keine Freundschaftsanfragen.")) { + if(message.equals("[Rezepte] Du hast nicht genug Material, um dieses Rezept herzustellen.")) { event.setCancelled(true); } + if(!Addon.getSharedInstance().configuration().getChatConfig().getCleanChat().get()) + return; + for (String str : cleanupMessages) { if(str.equals(message)) { diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/CooldownNotifier.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/CooldownNotifier.java similarity index 93% rename from game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/CooldownNotifier.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/CooldownNotifier.java index 84a90fb..3e2d74e 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/CooldownNotifier.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/CooldownNotifier.java @@ -1,13 +1,13 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.event.client.chat.ChatMessageSendEvent; -import net.labymod.api.util.I18n; -import tmb.randy.tmbgriefergames.core.Addon; +package tmb.randy.tmbgriefergames.core.util.chat; import java.util.Arrays; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import net.labymod.api.event.Subscribe; +import net.labymod.api.event.client.chat.ChatMessageSendEvent; +import net.labymod.api.util.I18n; +import tmb.randy.tmbgriefergames.core.Addon; public class CooldownNotifier { @@ -20,7 +20,11 @@ public class CooldownNotifier { new Cooldown("/anticopy", 5000, "tmbgriefergames.chat.cooldownAnticopy") ); + @Subscribe public void messageReceived(ChatMessageSendEvent event) { + if(!Addon.isGG()) + return; + if(!Addon.getSharedInstance().configuration().getChatConfig().getCooldownNotifier().get()) return; diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/EmptyLinesRemover.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/EmptyLinesRemover.java similarity index 82% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/EmptyLinesRemover.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/EmptyLinesRemover.java index c5ccd2a..133cb57 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/EmptyLinesRemover.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/EmptyLinesRemover.java @@ -1,17 +1,19 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; import tmb.randy.tmbgriefergames.core.Addon; public class EmptyLinesRemover { + @Subscribe public void messageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getHideEmptyLines().get()) + if(!Addon.getSharedInstance().configuration().getChatConfig().getHideEmptyLines().get() || !Addon.isGG()) return; String message = event.chatMessage().getPlainText(); - if(isStringEmpty(message) || message.equals("»") || message.length() == 0) { + if(isStringEmpty(message) || message.equals("»") || message.isEmpty()) { event.setCancelled(true); } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/MsgTabs.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/MsgTabs.java similarity index 94% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/MsgTabs.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/MsgTabs.java index b1f90d3..40a6a6e 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/MsgTabs.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/MsgTabs.java @@ -1,4 +1,4 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; import net.labymod.api.Laby; import net.labymod.api.client.chat.filter.ChatFilter; @@ -6,34 +6,34 @@ import net.labymod.api.configuration.labymod.chat.ChatWindow; import net.labymod.api.configuration.labymod.chat.config.RootChatTabConfig; import net.labymod.api.configuration.labymod.chat.config.RootChatTabConfig.Type; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatMessageSendEvent; import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiChat; import tmb.randy.tmbgriefergames.core.Addon; -import tmb.randy.tmbgriefergames.v1_8_9.util.VersionisedBridge; public class MsgTabs { private static String currentChatPartner = null; + @Subscribe public void chatMessageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get()) + if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get() || !Addon.isGG()) return; currentChatPartner = getChatPartnerName(event.chatMessage().getPlainText()); if(currentChatPartner != null) { getTabForName(event.chatMessage().getPlainText()); - if(!VersionisedBridge.isChatGuiOpen() && event.chatMessage().getPlainText().contains("[mir -> ")) { + if(!Addon.getSharedInstance().getBridge().isChatGuiOpen() && event.chatMessage().getPlainText().contains("[mir -> ")) { reloadChat(); - Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); + Addon.getSharedInstance().getBridge().openChat(); } } } + @Subscribe public void messageSend(ChatMessageSendEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get() || event.getMessage().startsWith("/msg") || event.getMessage().startsWith("7msg") || event.getMessage().startsWith("(msg")) + if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get() || event.getMessage().startsWith("/msg") || event.getMessage().startsWith("7msg") || event.getMessage().startsWith("(msg") || !Addon.isGG()) return; ChatWindow mainWindow = getChatWindow(); diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/NewsBlocker.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/NewsBlocker.java similarity index 80% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/NewsBlocker.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/NewsBlocker.java index d0ee00c..7c87f9d 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/NewsBlocker.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/NewsBlocker.java @@ -1,13 +1,16 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; import tmb.randy.tmbgriefergames.core.Addon; public class NewsBlocker { private boolean isBlocking = false; + + @Subscribe public void messageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getHideNews().get()) + if(!Addon.getSharedInstance().configuration().getChatConfig().getHideNews().get() || !Addon.isGG()) return; String message = event.chatMessage().getPlainText(); diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/PaymentValidator.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/PaymentValidator.java similarity index 68% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/PaymentValidator.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/PaymentValidator.java index 4faf2ad..8acca4c 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/PaymentValidator.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/PaymentValidator.java @@ -1,31 +1,29 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; import net.labymod.api.client.component.Component; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; import net.labymod.api.util.I18n; import tmb.randy.tmbgriefergames.core.Addon; public class PaymentValidator { - private final static String FAKEMONEY_PREFIX = "§4§l[§c§l✖ " + I18n.translate("autocraft.chat.fakeMoney") + "§4§l]"; - final String VALID_PREFIX = "§2§l[§a§l✔ " + I18n.translate("tmbgriefergames.chat.realMoney") + "§2§l]"; - + @Subscribe public void messageReceived(ChatReceiveEvent event) { - if(!Addon.isGG() || !Addon.getSharedInstance().configuration().getChatConfig().getAntiFakeMoney().get()) { + if(!Addon.isGG() || !Addon.getSharedInstance().configuration().getChatConfig().getAntiFakeMoney().get()) return; - } String message = event.chatMessage().getPlainText(); if(message.contains("hat dir") && message.contains("gegeben")) { if(message.matches(".* hat dir \\$\\d{1,3}(?:,\\d{3})*(\\.\\d{2})? gegeben\\.")) { if(!message.contains("[Greeting]") && !message.contains("»")) { - event.setMessage(event.message().append(Component.text(VALID_PREFIX))); + event.setMessage(event.message().append(Component.text("§2§l[§a§l✔ " + I18n.translate("tmbgriefergames.chat.realMoney") + "§2§l]"))); return; } } - event.setMessage(event.message().append(Component.text(FAKEMONEY_PREFIX))); + event.setMessage(event.message().append(Component.text("§4§l[§c§l✖ " + I18n.translate("tmbgriefergames.chat.fakeMoney") + "§4§l]"))); } } } \ No newline at end of file diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/StreamerMute.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/StreamerMute.java similarity index 51% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/StreamerMute.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/StreamerMute.java index 100bf94..a0c1bed 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/StreamerMute.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/StreamerMute.java @@ -1,14 +1,19 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatReceiveEvent; import tmb.randy.tmbgriefergames.core.Addon; public class StreamerMute { + @Subscribe public void messageReceived(ChatReceiveEvent event) { + if(!Addon.isGG()) + return; + String message = event.chatMessage().getPlainText(); - if(message.contains("[Streamer]") && Addon.getSharedInstance().configuration().getChatConfig().getMuteStreamer().get()) { + if(message.contains("§8[§6Streamer§8]") && Addon.getSharedInstance().configuration().getChatConfig().getMuteStreamer().get()) { event.setCancelled(true); } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/TypeCorrection.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/TypeCorrection.java similarity index 91% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/TypeCorrection.java rename to core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/TypeCorrection.java index 693c5e7..3bb0bac 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/TypeCorrection.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/util/chat/TypeCorrection.java @@ -1,7 +1,8 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; +package tmb.randy.tmbgriefergames.core.util.chat; import java.util.HashMap; import java.util.Map; +import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.chat.ChatMessageSendEvent; import tmb.randy.tmbgriefergames.core.Addon; @@ -87,8 +88,9 @@ public class TypeCorrection { } }; + @Subscribe public void messageSend(ChatMessageSendEvent event) { - if((!Addon.getSharedInstance().configuration().getChatConfig().getTypeCorrection().get() && !Addon.getSharedInstance().configuration().getChatConfig().getMessageSplit().get())) + if(!Addon.isGG() || (!Addon.getSharedInstance().configuration().getChatConfig().getTypeCorrection().get() && !Addon.getSharedInstance().configuration().getChatConfig().getMessageSplit().get())) return; String message = event.getMessage(); diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/FlyTimerWidget.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/FlyTimerWidget.java index 5fa1fca..ed5e292 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/FlyTimerWidget.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/FlyTimerWidget.java @@ -5,6 +5,8 @@ import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidget; import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidgetConfig; import net.labymod.api.client.gui.hud.hudwidget.text.TextLine; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.resources.ResourceLocation; import net.labymod.api.util.I18n; import tmb.randy.tmbgriefergames.core.Addon; @@ -13,10 +15,11 @@ public class FlyTimerWidget extends TextHudWidget { private String name; private TextLine line; - public FlyTimerWidget() { + public FlyTimerWidget(HudWidgetCategory category) { super("flytimer"); this.name = Laby.labyAPI().getName(); - this.bindCategory(HudWidgetCategory.INGAME); + setIcon(Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/fly.png"))); + this.bindCategory(category); } @Override diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/GameInfoWidget.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/GameInfoWidget.java index cf4f3ee..5b1c6b9 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/GameInfoWidget.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/GameInfoWidget.java @@ -6,6 +6,8 @@ import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidget; import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidgetConfig; import net.labymod.api.client.gui.hud.hudwidget.text.TextLine; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.resources.ResourceLocation; import net.labymod.api.client.scoreboard.Scoreboard; import net.labymod.api.client.scoreboard.ScoreboardTeam; import net.labymod.api.util.I18n; @@ -22,9 +24,10 @@ public class GameInfoWidget extends TextHudWidget { private static String playersValue = ""; private static String playtimeValue = ""; - public GameInfoWidget() { + public GameInfoWidget(HudWidgetCategory category) { super("gameinfo"); - this.bindCategory(HudWidgetCategory.INGAME); + setIcon(Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/gameinfo.png"))); + this.bindCategory(category); } public void load(TextHudWidgetConfig config) { diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/HopperModeWidget.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/HopperModeWidget.java new file mode 100644 index 0000000..ffe6393 --- /dev/null +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/HopperModeWidget.java @@ -0,0 +1,65 @@ +package tmb.randy.tmbgriefergames.core.widgets; + +import net.labymod.api.Laby; +import net.labymod.api.client.gui.hud.binding.category.HudWidgetCategory; +import net.labymod.api.client.gui.hud.binding.dropzone.NamedHudWidgetDropzones; +import net.labymod.api.client.gui.hud.hudwidget.HudWidgetConfig; +import net.labymod.api.client.gui.hud.hudwidget.SimpleHudWidget; +import net.labymod.api.client.gui.hud.position.HudSize; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.mouse.MutableMouse; +import net.labymod.api.client.render.matrix.Stack; +import net.labymod.api.client.resources.ResourceLocation; +import net.labymod.api.event.Subscribe; +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.enums.HopperState; +import tmb.randy.tmbgriefergames.core.util.HopperTracker; + +public class HopperModeWidget extends SimpleHudWidget { + private static final Icon HOPPER_CONNECT_ICON = Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/hopper_connect.png")); + private static final Icon HOPPER_MULTI_CONNECT_ICON = Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/hopper_multi.png")); + + public HopperModeWidget(HudWidgetCategory category) { + super("hopper_mode", HudWidgetConfig.class); + bindDropzones(NamedHudWidgetDropzones.ACTION_BAR); + this.bindCategory(category); + this.setIcon(HOPPER_CONNECT_ICON); + } + + public void render(Stack stack, MutableMouse mouse, float partialTicks, boolean isEditorContext, HudSize size) { + if (stack != null) { + if(HopperTracker.getCurrentHopperState() == HopperState.CONNECT || isEditorContext) { + HOPPER_CONNECT_ICON.render(stack, 0, 0, 32); + Laby.references().renderPipeline().resourceRenderer().render(stack); + size.setHeight((float)32); + size.setWidth((float)32); + } else if (HopperTracker.getCurrentHopperState() == HopperState.MULTI_CONNECT) { + HOPPER_MULTI_CONNECT_ICON.render(stack, 0, 0, 32); + Laby.references().renderPipeline().resourceRenderer().render(stack); + size.setHeight((float)32); + size.setWidth((float) 32); + } + } + } + + @Subscribe + public void messageReceived(ChatReceiveEvent event) { + if(this.isEnabled()) { + String message = event.chatMessage().getPlainText(); + if (message.equals("[Trichter] Das Multi-Verbinden wurde aktiviert. Klicke mit dem gewünschten Item auf den gewünschten Endpunkt.") || + message.equals("[Trichter] Das Verbinden wurde aktiviert. Klicke auf den gewünschten Endpunkt.") || + message.equals("[Trichter] Der Trichter wurde erfolgreich verbunden.") || + message.equals("[Trichter] Der Verbindungsmodus wurde beendet.") || + message.equals("[Trichter] Der Startpunkt ist zu weit entfernt. Bitte starte erneut.")) { + event.setCancelled(true); + } + } + } + + @Override + public boolean isVisibleInGame() { + return HopperTracker.getCurrentHopperState() != HopperState.NONE; + } + +} \ No newline at end of file diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/ItemClearWidget.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/ItemClearWidget.java index 350a3ce..510d7fb 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/ItemClearWidget.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/ItemClearWidget.java @@ -5,17 +5,21 @@ import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidget; import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidgetConfig; import net.labymod.api.client.gui.hud.hudwidget.text.TextLine; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.resources.ResourceLocation; import net.labymod.api.util.I18n; import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.util.ItemClearTimerListener; public class ItemClearWidget extends TextHudWidget { private String name; private TextLine line; - public ItemClearWidget() { + public ItemClearWidget(HudWidgetCategory category) { super("itemclear"); this.name = Laby.labyAPI().getName(); - this.bindCategory(HudWidgetCategory.INGAME); + setIcon(Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/itemremover.png"))); + this.bindCategory(category); } @Override @@ -26,12 +30,12 @@ public void load(TextHudWidgetConfig config) { @Override public void onTick(boolean isEditorContext) { - name = Addon.getSharedInstance().getBridge().getItemRemoverValue(); + name = ItemClearTimerListener.getDisplayValue(); this.line.updateAndFlush(name); } @Override public boolean isVisibleInGame() { - return Addon.getSharedInstance().getBridge().getItemRemoverValue().length() > 1 && Addon.isGG(); + return ItemClearTimerListener.getDisplayValue().length() > 1 && Addon.isGG(); } } diff --git a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/NearbyWidget.java b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/NearbyWidget.java index a94e2ce..d001d8c 100644 --- a/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/NearbyWidget.java +++ b/core/src/main/java/tmb/randy/tmbgriefergames/core/widgets/NearbyWidget.java @@ -1,17 +1,27 @@ package tmb.randy.tmbgriefergames.core.widgets; import net.labymod.api.Laby; +import net.labymod.api.client.entity.Entity; +import net.labymod.api.client.entity.Mob; import net.labymod.api.client.entity.player.Player; import net.labymod.api.client.gui.hud.binding.category.HudWidgetCategory; import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidget; import net.labymod.api.client.gui.hud.hudwidget.text.TextHudWidgetConfig; import net.labymod.api.client.gui.hud.hudwidget.text.TextLine; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting; +import net.labymod.api.client.resources.ResourceLocation; +import net.labymod.api.configuration.loader.property.ConfigProperty; import net.labymod.api.util.I18n; import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.widgets.NearbyWidget.NearbyWidgetConfig; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; -public class NearbyWidget extends TextHudWidget { +public class NearbyWidget extends TextHudWidget { private static final List blacklist = Arrays.asList( "Adventurer", @@ -37,21 +47,22 @@ public class NearbyWidget extends TextHudWidget { private String name; private TextLine line; - public NearbyWidget() { - super("nearby"); + public NearbyWidget(HudWidgetCategory category) { + super("nearby", NearbyWidgetConfig.class); this.name = Laby.labyAPI().getName(); - this.bindCategory(HudWidgetCategory.INGAME); + setIcon(Icon.texture(ResourceLocation.create(Addon.getSharedInstance().addonInfo().getNamespace(), "textures/widgets/nearby.png"))); + this.bindCategory(category); } @Override - public void load(TextHudWidgetConfig config) { + public void load(NearbyWidgetConfig config) { super.load(config); this.line = super.createLine(I18n.getTranslation("tmbgriefergames.nearby.nearby"), name); } @Override public void onTick(boolean isEditorContext) { - name = getPlayersList(); + name = getPlayersListAsString(); this.line.updateAndFlush(name); } @@ -60,31 +71,212 @@ public boolean isVisibleInGame() { return Addon.isGG(); } - private String getPlayersList() { + private String getPlayersListAsString() { StringBuilder list = new StringBuilder(); - outerLoop: for (Player player : Laby.labyAPI().minecraft().clientWorld().getPlayers()) { + for (Player player : getPlayersList()) { + int dist = (int)Math.sqrt(player.getDistanceSquared(Laby.labyAPI().minecraft().getClientPlayer())); + list.append("\n").append(player.getName()).append(" (").append(dist).append("m)"); + } - if(Laby.labyAPI().minecraft().getClientPlayer() != null) { - if(player.getName().equals(Laby.labyAPI().minecraft().getClientPlayer().getName())) { - continue; + if(config.getShowMobs().get()) { + MobCounter counter = new MobCounter(); + for (Entity entity : Laby.labyAPI().minecraft().clientWorld().getEntities()) { + if(entity instanceof Mob mob) { + String mobString = mob.toString(); + String mobName = extractMobInfo(mobString); + counter.addMob(mobName); } } - for (String string : blacklist) { - if(player.getName().contains(string)) { - continue outerLoop; + list.append("\n").append(counter.getFormattedMobCounts()); + } + + return list.toString(); + } + + public static List getPlayersList() { + List output = new ArrayList<>(); + + outerLoop: for (Entity entity : Laby.labyAPI().minecraft().clientWorld().getEntities()) { + + if(entity instanceof Player player) { + if(Laby.labyAPI().minecraft().getClientPlayer() != null) { + if(player.getName().equals(Laby.labyAPI().minecraft().getClientPlayer().getName())) { + continue; + } + } + + if(player.getName().startsWith("§6")) + continue; + + for (String string : blacklist) { + if(player.getName().contains(string)) + continue outerLoop; } + + int dist = (int)Math.sqrt(player.getDistanceSquared(Laby.labyAPI().minecraft().getClientPlayer())); + + if(dist > 1000) + continue; + + output.add(player); } + } - int dist = (int)Math.sqrt(player.getDistanceSquared(Laby.labyAPI().minecraft().getClientPlayer())); + return output; + } + + public static String extractMobInfo(String input) { + String cleanInput = input.replaceAll("§[0-9a-fk-or]", ""); + return cleanInput.replaceAll(".*\\['(.*?)'/.*", "$1"); + } + + + public static class MobCounter { + + public enum MobType { + CHICKEN("chicken"), + COW("cow"), + PIG("pig"), + SHEEP("sheep"), + RABBIT("rabbit"), + BAT("bat"), + SQUID("squid"), + MOOSHROOM("mooshroom"), + VILLAGER("villager"), + HORSE("horse"), + DONKEY("donkey"), + MULE("mule"), + OCELOT("ocelot"), + WOLF("wolf"), + + SPIDER("spider"), + CAVE_SPIDER("cave_spider"), + ENDERMAN("enderman"), + PIGMAN("zombie_pigman"), - if(dist > 1000) { - continue; + ZOMBIE("zombie"), + SKELETON("skeleton"), + CREEPER("creeper"), + SPIDER_JOCKEY("spider_jockey"), + SLIME("slime"), + GHAST("ghast"), + ZOMBIE_VILLAGER("zombie_villager"), + BLAZE("blaze"), + WITCH("witch"), + ENDERMITE("endermite"), + SILVERFISH("silverfish"), + GUARDIAN("guardian"), + ELDER_GUARDIAN("elder_guardian"), + WITHER_SKELETON("wither_skeleton"), + WITHER("wither"), + ENDER_DRAGON("ender_dragon"), + MAGMA_CUBE("magma_cube"), + IRON_GOLEM("iron_golem"), + SNOW_GOLEM("snow_golem"); + + private final String name; + + MobType(String name) { + this.name = name; } - list.append("\n").append(player.getName()).append(" (").append(dist).append("m)"); + @Override + public String toString() { + return name; + } + + public static MobType fromString(String mobName) { + return switch (mobName.toLowerCase()) { + case "huhn", "chicken" -> CHICKEN; + case "kuh", "cow" -> COW; + case "schwein", "pig" -> PIG; + case "schaf", "sheep" -> SHEEP; + case "kaninchen", "rabbit" -> RABBIT; + case "fledermaus", "bat" -> BAT; + case "tintenfisch", "squid" -> SQUID; + case "mooshroom", "pilzkuh" -> MOOSHROOM; + case "dorfbewohner", "villager" -> VILLAGER; + case "pferd", "horse" -> HORSE; + case "esel", "donkey" -> DONKEY; + case "mule" -> MULE; + case "ocelot" -> OCELOT; + case "wolf" -> WOLF; + case "spinne", "spider" -> SPIDER; + case "höhlenspinne", "cave spider" -> CAVE_SPIDER; + case "enderman" -> ENDERMAN; + case "zombie" -> ZOMBIE; + case "skelett", "skeleton" -> SKELETON; + case "creeper" -> CREEPER; + case "spider jockey" -> SPIDER_JOCKEY; + case "schleim", "slime" -> SLIME; + case "ghast" -> GHAST; + case "zombie-dorfbewohner", "zombie villager" -> ZOMBIE_VILLAGER; + case "blaze" -> BLAZE; + case "hexe", "witch" -> WITCH; + case "endermite" -> ENDERMITE; + case "silberfischchen", "silberfisch", "silverfish" -> SILVERFISH; + case "wächter", "guardian" -> GUARDIAN; + case "älterer wächter", "elder guardian" -> ELDER_GUARDIAN; + case "wither" -> WITHER; + case "wither_skeleton" -> WITHER_SKELETON; + case "enderdrache", "ender dragon" -> ENDER_DRAGON; + case "magmawürfel", "magma cube" -> MAGMA_CUBE; + case "eisengolem", "iron golem" -> IRON_GOLEM; + case "zombie pigman", "pigman", "pig zombie", "schweinezombie" -> PIGMAN; + case "snowman", "snow golem" -> SNOW_GOLEM; + default -> null; + }; + } } - return list.toString(); + + private final Map mobCountMap = new HashMap<>(); + + public void addMob(String mobName) { + int quantity = 1; + MobType mobType; + + if (mobName.matches("\\d+x\\s+.+")) { + int splitIndex = mobName.indexOf('x') + 1; + quantity = Integer.parseInt(mobName.substring(0, splitIndex - 1).trim()); + mobName = mobName.substring(splitIndex).trim(); + } + + mobType = MobType.fromString(mobName); + + if (mobType != null) { + mobCountMap.put(mobType, mobCountMap.getOrDefault(mobType, 0) + quantity); + } else { + Addon.getSharedInstance().logger().warn("Unknown mob type: " + mobName); + } + } + + public int getMobCount(MobType mobType) { + return mobCountMap.getOrDefault(mobType, 0); + } + + public String getFormattedMobCounts() { + StringBuilder result = new StringBuilder(); + for (Map.Entry entry : mobCountMap.entrySet()) { + int count = entry.getValue(); + if (count > 0 && entry.getKey() != null) { + String translationKey = "tmbgriefergames.mobs." + entry.getKey().name().toLowerCase(); + String mobName = I18n.getTranslation(translationKey); + + result.append("\n§d").append(count).append("x §6").append(mobName); + } + } + return result.toString().trim(); + } + } + + public static class NearbyWidgetConfig extends TextHudWidgetConfig { + + @SwitchSetting + private final ConfigProperty showMobs = new ConfigProperty<>(true); + + public ConfigProperty getShowMobs() {return showMobs;} + } } diff --git a/core/src/main/resources/assets/tmbgriefergames/i18n/de_de.json b/core/src/main/resources/assets/tmbgriefergames/i18n/de_de.json index f97b704..5c43b9d 100644 --- a/core/src/main/resources/assets/tmbgriefergames/i18n/de_de.json +++ b/core/src/main/resources/assets/tmbgriefergames/i18n/de_de.json @@ -61,6 +61,24 @@ }, "autoSneak": { "name": "Automatisch sneaken bei Rechtsklick" + }, + "showRadius": { + "name": "Verbindungsgrenze darstellen" + }, + "showLines": { + "name": "Verbindungslinien darstellen" + }, + "header": { + "auto": { + "name": "Automatische Trichtereinstellungen" + }, + "visual": { + "name": "Visuelle Darstellungen" + } + }, + "resetLines": { + "name": "Linien", + "text": "zurücksetzen" } }, "swordsSubConfig": { @@ -206,101 +224,162 @@ "name": "Autokomprimierer" } } + }, + "autoLoot": { + "name": "Auto Loot", + "description": "Holt automatisch deine /freekiste und deinen /grieferboost ab." } }, - "chat": { - "realMoney": "VERIFIZIERT", - "fakeMoney": "FAKE MONEY", - "cooldownWand": "Der Cooldown für /wand ist abgelaufen.", - "cooldownRand": "Der Cooldown für /rand ist abgelaufen.", - "cooldownBoden": "Der Cooldown für /boden ist abgelaufen.", - "cooldownSign": "Der Cooldown für /sign ist abgelaufen.", - "cooldownAnticopy": "Der Cooldown für /anticopy ist abgelaufen.", - "cooldownAushöhlen": "Der Cooldown für /aushöhlen ist abgelaufen." - }, - "itemSaver": { - "item_saver_message_sword": "Dieses Schwert ist zu wertvoll, um es zu benutzen!", - "item_saver_message_sos": "Diesen Kürbis zu setzen wäre ein gruselig teurer Spaß!", - "item_saver_message_birth_bow": "Manche Bögen sind zum Schießen da. Dieser hier eher nicht!" - }, - "tooltip": { - "compressedTooltip": "§6%s §eDKs §6%s §e Stacks §6%s §eItems", - "adventurerTooltip": "§6 %s%% §f| §eRest: §6 %s §eDKs §6 %s §eStacks §6 %s §eItems" - }, - "payAll": { - "amountTooLow": "Der abgerundete Betrag pro Spieler liegt bei 0$!", - "response": "%s Spieler * %s$ = %s$." - }, - "playerTracer": { - "startedHopping": "CB Hopping gestartet", - "lookingForPlayer": "Fahndung nach Spieler %s läuft...", - "tooManyArguments": "Zu viele Argumente!", - "foundPlayer": "Spieler gefunden!", - "tracingEnded": "Fahndung beendet." + "chat": { + "realMoney": "VERIFIZIERT", + "fakeMoney": "FAKE MONEY", + "cooldownWand": "Der Cooldown für /wand ist abgelaufen.", + "cooldownRand": "Der Cooldown für /rand ist abgelaufen.", + "cooldownBoden": "Der Cooldown für /boden ist abgelaufen.", + "cooldownSign": "Der Cooldown für /sign ist abgelaufen.", + "cooldownAnticopy": "Der Cooldown für /anticopy ist abgelaufen.", + "cooldownAushöhlen": "Der Cooldown für /aushöhlen ist abgelaufen." + }, + "itemSaver": { + "item_saver_message_sword": "Dieses Schwert ist zu wertvoll, um es zu benutzen!", + "item_saver_message_sos": "Diesen Kürbis zu setzen wäre ein gruselig teurer Spaß!", + "item_saver_message_birth_bow": "Manche Bögen sind zum Schießen da. Dieser hier eher nicht!" + }, + "tooltip": { + "compressedTooltip": "§6%s §eDKs §6%s §e Stacks §6%s §eItems", + "adventurerTooltip": "§6 %s%% §f| §eRest: §6 %s §eDKs §6 %s §eStacks §6 %s §eItems" + }, + "payAll": { + "amountTooLow": "Der abgerundete Betrag pro Spieler liegt bei 0$!", + "response": "%s Spieler * %s$ = %s$." + }, + "playerTracer": { + "startedHopping": "CB Hopping gestartet", + "lookingForPlayer": "Fahndung nach Spieler %s läuft...", + "tooManyArguments": "Zu viele Argumente!", + "foundPlayer": "Spieler gefunden!", + "tracingEnded": "Fahndung beendet." + }, + "flyTimer": { + "flyPotion": "Flugtrank", + "flyPotionUsed": "Flugtrank benutzt.", + "flyPotionExpired": "Flugtrank abgelaufen." + }, + "itemRemover": { + "itemRemover": "Item remover" + }, + "nearby": { + "nearby": "In der Nähe" + }, + "gameInfo": { + "cb": "CB", + "money": "Geld", + "playtime": "Spielzeit", + "players": "Spieler" + }, + "natureBorders": { + "plotBordersVisible": "Plotgrenzen §a§lSICHTBAR", + "plotBordersInvisible": "Plotgrenzen §c§lUNSICHTBAR" + }, + "hudWidget": { + "flytimer": { + "name": "Flugtrank Timer" }, - "flyTimer": { - "flyPotion": "Flugtrank", - "flyPotionUsed": "Flugtrank benutzt.", - "flyPotionExpired": "Flugtrank abgelaufen." + "itemclear": { + "name": "Item remover" }, - "itemRemover": { - "itemRemover": "Item remover" + "gameinfo": { + "name": "Spielinfo" }, "nearby": { - "nearby": "In der Nähe" - }, - "gameInfo": { - "cb": "CB", - "money": "Geld", - "playtime": "Spielzeit", - "players": "Spieler" - }, - "natureBorders": { - "plotBordersVisible": "Plotgrenzen §a§lSICHTBAR", - "plotBordersInvisible": "Plotgrenzen §c§lUNSICHTBAR" - }, - "hudWidget": { - "flytimer": { - "name": "Flugtrank Timer" - }, - "itemclear": { - "name": "Item remover" - }, - "gameinfo": { - "name": "Spielinfo" - }, - "nearby": { - "name": "In der Nähe" + "name": "In der Nähe", + "showMobs": { + "name": "Mobs zeigen" } }, - "autoComp": { - "list": "Liste #" - }, - "autoDecomp": { - "started": "Dekomprimiere..." - }, - "autoCrafter": { - "recipeSaved": "Rezept gespeichert", - "active": "Endlosmodus §a§lAKTIV", - "inactive": "Endlosmodus §c§lDEAKTIVIERT", - "recipeSavedV3": "Rezept gespeichert. Öffne jetzt nacheinander alle Kisten für das Quellmaterial!", - "noItemFound": "Lege erst das zu craftende Item in deinen ersten Slot!", - "startedCrafting": "Alle benötigten Materialien wurden erfasst. Crafte...", - "setChestForMaterial": "Quellkiste für %s festgelegt.", - "mixedChest": "Die Kiste enthält verschiedene Items und kann daher nicht als Quellkiste verwendet werden.", - "V3started": "Autocrafter V3 gestartet...", - "V3stopped": "Autocrafter V3 beendet.", - "noSourceFound": "Keine Quellkiste gefunden.", - "chooseVariant": "Es gibt mehrere mögliche Rezepte für dieses Item. Bitte wähle eines aus und halte ENTER gedrückt, bis das Rezept gespeichert wurde." - }, - "eject": { - "enabled": "Auswurf §a§lAKTIVIERT. §fÖffne ein unendliches Lager!", - "disabled": "Auswurf §c§lDEAKTIVIERT" - }, - "autoSword": { - "enabled": "VABK §aAKTIVIERT. §fÖffne den Chat, um automatisch zu schießen.", - "disabled": "VABK §4DEAKTIVIERT" + "hopper_mode": { + "name": "Trichter-Verbindung", + "description": "Zeigt per Icon an, ob du dich im Trichter-Verbindungsmodus befindest. Überflüssige Chatausgaben werden dadurch unterdrückt." + } + }, + "autoComp": { + "list": "Liste #" + }, + "autoDecomp": { + "started": "Dekomprimiere..." + }, + "autoCrafter": { + "recipeSaved": "Rezept gespeichert", + "active": "Endlosmodus §a§lAKTIV", + "inactive": "Endlosmodus §c§lDEAKTIVIERT", + "recipeSavedV3": "Rezept gespeichert. Öffne jetzt nacheinander alle Kisten für das Quellmaterial!", + "noItemFound": "Lege erst das zu craftende Item in deinen ersten Slot!", + "startedCrafting": "Alle benötigten Materialien wurden erfasst. Crafte...", + "setChestForMaterial": "Quellkiste für %s festgelegt.", + "mixedChest": "Die Kiste enthält verschiedene Items und kann daher nicht als Quellkiste verwendet werden.", + "V3started": "Autocrafter V3 gestartet...", + "V3stopped": "Autocrafter V3 beendet.", + "noSourceFound": "Keine Quellkiste gefunden.", + "chooseVariant": "Es gibt mehrere mögliche Rezepte für dieses Item. Bitte wähle eines aus und halte ENTER gedrückt, bis das Rezept gespeichert wurde." + }, + "eject": { + "enabled": "Auswurf §a§lAKTIVIERT. §fÖffne ein unendliches Lager!", + "disabled": "Auswurf §c§lDEAKTIVIERT" + }, + "autoSword": { + "enabled": "VABK §aAKTIVIERT. §fÖffne den Chat, um automatisch zu schießen.", + "disabled": "VABK §4DEAKTIVIERT" + }, + "mobs": { + "chicken": "Huhn", + "cow": "Kuh", + "pig": "Schwein", + "sheep": "Schaf", + "rabbit": "Hase", + "bat": "Fledermaus", + "squid": "Tintenfisch", + "mooshroom": "Pilzkuh", + "villager": "Dorfbewohner", + "horse": "Pferd", + "donkey": "Esel", + "mule": "Maultier", + "ocelot": "Ozelot", + "wolf": "Wolf", + "spider": "Spinne", + "cave_spider": "Höhlenspinne", + "enderman": "Enderman", + "pigman": "Pigman", + "zombie": "Zombie", + "skeleton": "Skelett", + "creeper": "Creeper", + "spider_jockey": "Spinnenreiter", + "slime": "Schleim", + "ghast": "Ghast", + "zombie_villager": "Zombie-Dorfbewohner", + "blaze": "Lohe", + "witch": "Hexe", + "endermite": "Endermilbe", + "silverfish": "Silberfisch", + "guardian": "Wächter", + "elder_guardian": "Großer Wächter", + "wither_skeleton": "Witherskelett", + "wither": "Wither", + "ender_dragon": "Enderdrache", + "magma_cube": "Magmawürfel", + "iron_golem": "Eisengolem", + "snow_golem": "Schneemann" + }, + "autoLoot": { + "skullAvailable": "Du hast wieder /kopf frei!" + } + }, + "labymod": { + "hudWidgetCategory": { + "tmbgriefergames": { + "name": "GrieferGames Addon", + "description": "by §d§l§oT§b§l§oM§d§l§oB" } } + } } diff --git a/core/src/main/resources/assets/tmbgriefergames/i18n/en_us.json b/core/src/main/resources/assets/tmbgriefergames/i18n/en_us.json index 328ff41..21626d2 100644 --- a/core/src/main/resources/assets/tmbgriefergames/i18n/en_us.json +++ b/core/src/main/resources/assets/tmbgriefergames/i18n/en_us.json @@ -61,6 +61,24 @@ }, "autoSneak": { "name": "Auto sneak when right clicking." + }, + "showRadius": { + "name": "Show connection range" + }, + "showLines": { + "name": "Show connection lines" + }, + "header": { + "auto": { + "name": "Automatic settings" + }, + "visual": { + "name": "Visual settings" + } + }, + "resetLines": { + "name": "Linien", + "text": "zurücksetzen" } }, "swordsSubConfig": { @@ -206,6 +224,10 @@ "name": "auto compressor" } } + }, + "autoLoot": { + "name": "Auto Loot", + "description": "Automatically gets your /freekiste and /grieferboost." } }, "chat": { @@ -270,7 +292,10 @@ "name": "Game info" }, "nearby": { - "name": "Nearby" + "name": "Nearby", + "showMobs": { + "name": "Show mobs" + } } }, "autoComp": { @@ -300,6 +325,56 @@ "autoSword": { "enabled": "VABK §a§lENABLED", "disabled": "VABK §4§lDISABLED" + }, + "mobs": { + "chicken": "Chicken", + "cow": "Cow", + "pig": "Pig", + "sheep": "Sheep", + "rabbit": "Rabbit", + "bat": "Bat", + "squid": "Squid", + "mooshroom": "Mooshroom Cow", + "villager": "Villager", + "horse": "Horse", + "donkey": "Donkey", + "mule": "Mule", + "ocelot": "Ocelot", + "wolf": "Wolf", + "spider": "Spider", + "cave_spider": "Cave Spider", + "enderman": "Enderman", + "pigman": "Pigman", + "zombie": "Zombie", + "skeleton": "Skeleton", + "creeper": "Creeper", + "spider_jockey": "Spider Jockey", + "slime": "Slime", + "ghast": "Ghast", + "zombie_villager": "Zombie Villager", + "blaze": "Blaze", + "witch": "Witch", + "endermite": "Endermite", + "silverfish": "Silverfish", + "guardian": "Guardian", + "elder_guardian": "Elder Guardian", + "wither_skeleton": "Wither Skeleton", + "wither": "Wither", + "ender_dragon": "Ender Dragon", + "magma_cube": "Magma Cube", + "iron_golem": "Iron Golem", + "snow_golem": "Snow Golem" + }, + "autoLoot": { + "skullAvailable": "/kopf is available!" + } + }, + "labymod": { + "hudWidgetCategory": { + "tmbgriefergames": { + "name": "GrieferGames Addon", + "description": "by §d§l§oT§b§l§oM§d§l§oB" + } } } } \ No newline at end of file diff --git a/core/src/main/resources/assets/tmbgriefergames/textures/settings.png b/core/src/main/resources/assets/tmbgriefergames/textures/settings.png index 1da5cde19165ca99c7dafc2e2e8a1283c8452113..cb57f36660c05fec8c45048f605b63cc8fffc40c 100644 GIT binary patch delta 15006 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 Q2D%k>6>a5eC99AB3%G?W#&|6W#MJ#=4D}x z{|8O+zYamea6|Fd@WK#5f8n4&Ci{OM7guq2S6&ZGGkXCFR%TZAum8(5esK1%GkI@% z@#k=)K#L5FF#1oyPaIn?!J3+yL^?JuX}m3%1miqdj~QT9?6&R)zLDoIHiSdwAt zX-=#^Xi5o|cAlRZ+)lRx;OWD*2Us#1iH- z1(>iZW0k(Xot9vb-l&!|JpDfGV_%2wtb*CivGOBHH-CUVnQ%-j+O>!=Jkh&0mOB>w zG5)o&vD_+Fpm8N6i{@+TPx?5$6`Yu!V|-VJper10jS_*U#rrM)jjIpiDv?n_48L4+sEzH2`W@kW<2KltSWqO_=)q_s0)4**}X*^_$;||!v--d zWGRs*>bmCHqGspD!yj$)PunZj--%~tn{<}eCkh@En;XuW_SI+g_fOhxwKMAcevB>S z0^F*kO)7LCkZy~WwM~cR3Z7%12`QUGB{S-8=^o0C@c9b^@2TF7w-M449&?wTC+ktB zsZ2dF|8N%XPuOCKd(W(yP1UfDD-P%sYbuL8GOw^f>c*xHZwg<$M?QxAN!w*O$;hvX zgSuWAx=|T~LF513iL(*4pZ#|IW>(fZ0Pwu!sF&0*MpM!ydO}D*usI8uPboR^loX~~ z@-4Hp^hVaHgdfOqu!4JT3PMjD7Muw328xsm2GxyIu&$-MCM*!u072PE9X)M|fdjnVDX)$J9PU0OqF3@+2 z@OIt?A)Y2OCPew(6IXYK2K}@4Zurd-*Fph3ARvH%a3JKsowd4jEQzoE-5iAEc;Mzn zZgEI+9hvJYM}^u%{%Ut&?}|r<{-Q#%nqXn8o2fuhJ9A#=XcEFCgeTyb%W@*G3;)C6 zMrtFOEn!1mke<)q+#n;B!&<`#$hqv{^6lohm@YQjCsf6LK0Q0SbXK3|*nn+upPqT? z1mJJ!ogL)xVdL&QJ6wyY#z&a)dDdU+aOF-sP=L}IF}%7E44Y8WD;hzV+fcep0zncV?_r8Une9K=l#<7>4rUyY_?)j1POGlx6g#NyZi4~++T~M{Rr}_K zT-T(%9jySDW)B6Sv?M~?%kIQFmw%D=Tz?NVCb0fwuxh6=YMLFl^iVgwSOlCBnM!eT zFpCm7j%P!M3vBFR3G`N%hz07=FWeZy^Aux8QMfZ?HH>ccjhNc7qPK?fV-6(BNxl{% zSbQS4Pw`s}qhW%gQ_=$3jZ6!NLfmXL`8dT)6M~z}+)uMCyxbq0@&?K{aI~XjpJ$!rStL?4*#@;N>^D|q48-!(lLobP8Tbx(?iw>840X*647G>u zUU>AS`1a0wAuJL<(;EFmQ)juUVT9I+JNdYULVj{g7Jm8eIvD^=dL~-jIk(@GXvp&K zd$tdK688_m_*|N2_2Yp3K7G0QW^HY6>~5_Rd?oP4BX>B|RGGc*u+*w?uP!ohzG1*@l1r^MNq_!wgdicL`5j>-X0Y+s~; zU<~?kHq5)mj{ejDzPYm0b)N!>VR-HtHpywFElNkar*RK$Pu%7D^aV{rVwOXOzOeMV z1%cxb0tQps5#h-~B0W^rvg~QX;fgO*# zxbm$>8Wkzrj>2ivk=S@=>);tQ=K)8$rFZmJwfc|S=IH~Nzz~lDD+&D_Q?2MbzXrN> z#aUvlEE^z8u$j{kmcr)I2AU_+UOH=^SglP)Ek*{malbqgztuCROeiufbpH~wE1tgLT*Q|hh!+W^64_;lGRPoEMoh18Ee`S)YTQE7(Us+^E^d570<$&4C`Zy zD>44Y9gp3$SE~stxW0Ef%`aj+*V<6&^h?)N4-}&Q7c@@om1uzzE$Ezu`@9tKS>3yx z=Qr?ETZl*NhcmME0$xZNZHt`%OCEngy!G*%cLV}SUuMOsa8;jlJ(8M%?+vxhXffdu!#OKs7} zC$zb8*(Y5)^v-Jtd_NrDaI69n5}aBS;|ox9awaPH@C9k1O?ab`^z;Yo%ZFa@*`X=^ zh*k2+ZZ5dXr=>@^AxLB5u}XNHq}*vvF>0_g>ySF%BI%&k8`cJA zhQ8+|E6w#UE#-n0iu3mJRd$Z2dinuDcw5j~Eo56kmD4y_0~}KLYQE`7UzrAFf-vbK z{Z)mU2dcAyZC^%-(^e5$57$ z1yDQD=D8>CL8g_FSzr;SldeMeND}ywf%P_^xajq8?9FZ-3F(=_jMjEW(e>8B15A)E z;R?2Q2a{o%8UB{AAMvFPkHg_mYc1v;B)=LEir zixu_{ZPN!>H$@blc*o|5qb2X|yxcI^e6T1p=y}eXTkC+dDpF|7`O;<3(1*WEfh-~$3RzMmJj4SGDUP#X*z1$VyBVZ#!o=lXu*5|79m4jN8_gaHOh zg=1J*`LVOQX4$H0v^IwgKy7JFdknSwls+=TRVPe(Lzc%H*da1!r?2=`t@!oKz2#>9 z>gtN7mO|gd=svc~bJLgcP_FqI3nCtrYTnvhU*wGUsgR%s;B2U`IJf$-OMHy8-rZ`Vh^yV{= zP93>+dCz#$Imw#kO8-^w(-z%K=%!zSgq_Z+G*;)>Ct))*C@*CubU%O zjYDb?L7;j2G_QNWP9wU5K1724eDaCQUuiJ;Ay3h5_!R=9dwAl2xP( ze!C6Gmx;sLYO|3f=*HJkwuxu^metGuuzCJj`INTGdtJ5nW`XQoCbP1Pc57n@4_8xo zzf0rE0@ne;qb3ma3_sXLl+p_wR|>a#5rFwQm{^fA{03C_t~YL`*-74m!O^bnnqr~W zW~XU69zMgY8B!=HZR5~Bb(qTzUJxe7rq_w4zO#vwR4wyUsrZ_4ye@jznnZfXFZ{Vh zG||Cb0la@rU^a~W{NnhJFE%K>Q`QAqxKO0pEGAAUtd<Mj|$HA6rQ{rU%f)YhbGDxqD=^*5v>Xp{t)x9s*5Ims2&ZPVp;-=~Y! zM{mTtwzgfy7nq0N(Zkc3vl>K>Eph&-UkU<&k99>O6M<~InVr_3HmPxPToR4F0fY-- zeO}I69c;eq7LS+BEXvo>NM=X&4h9MlUC268Zh<^HdWB>L;w3Hscp$IbG}BK!fYrcx z+*h}$54-z2U>06pZ zg><*B>jsSWW&AUgcIv@T9Ix9MSGP|rDjCcn6IE%@b*YhJ=E{`XM7s?+WByDMdMmojR8%vSyLh~7_m45|9ar9`@pkdYiPJ`lG%-=318oqBG)2+ zn+|3z%s*aQ()0Q`*OIODH`&R*gBVc37d9Ug!twJ)}3{lgV6mV*wq&YU2KLeC&O} z>;sVOUTrX(X~8m56uQ{*P_weEYz~EFw)VEM0m9902(Yz>N%vq7=A*6-0jfCU`a=j& z=Z-zqytL%G=vAc4F#h>T#H!?_W1pnzoit3j0mR~$Z(?&kZ!HawZzsH#1$zJG8r6&U zEd7RdzV2`1|3V-@T4?)&#VdwRkbh z{Tx?rJvDa<6^6y;i6;z@VV>~zS-r^%3I7@;aB;ES@=z~M{Mmk2B^hnqc(b-{&46;E zf(mg=6z=-c#Sj6Ynq z&c^b^a7ZtWHQpfrqL?}oKM7U0obT)A6icWV26GZp1=i@Rs_+1va+X4u+K9l~b3B`7 zEv4tiB(b;MkY#sbHS)^s)}q(@Mk|{Z&#tB@gfCo&&ob&q^@1UYV)>{K#jGYDI!rz^ zthAfB*=ILj=?6l^Ye#XE6Zl(2fVgn-!>@x7cq zdz&0Vg{`A(g@fHY-@7}&dGyS7`RyEuK=28Y6j>#R6ASm_GldOzcncIpmlzE*VkmHp z?vft*faUmAzF|!7>iNBBnLWh@H)x!+pFCGF)zzFJj344xvGllHooXlX5pAH32}^CcxpjS5K~$A7zs|=h1n%qh_;OU~Ka$ zIL?EJk?*5Pm6YIv@LA`eAd+rH%CfoO`RJzxd}GpzmdlLCH1lohGW*vGV7j}FHu@{f z7+s?DsNkC=VSLS3ctUK(4p)J|g5;!!XOb6+VT<&-osfz*$77|hM}o05;-H23<#M8A z8!ov_iXn@x_|?aCEr&E4iwV`^Y=lRzx<{1XF!uTD+~$c?P<)Ije|$+n7u8hb&uv}0 z7A`I$ON(K|T)H)f}z_?zu(J0!&U`AOnF4V-QSbD51T4rb>b?~JL4(#J=XM2CLhGsHgLS_J*!FKKY6^y@RB(%b_QqwGqtZ*45NEwKLlh}Mu*xq3zpg6(2)p8~i- zwD~u@`a zmoG!DkFiT)i(`i>B1kNjET-eNon%uS7h5bWw$QYh2T>veJ;)z~OTNU?w+<~cUIr7W zWe9~xF;ejCe(wJ+jw|d@vX6mLA2CST$uN0gsSpJbKUC)Q9ZM{jvv5Had^vF&``VI} zotS^NuE~@FEb)s{N3{H2g-iNgW3vTI9Hu|D@;eV!imhbWwUp(rj!)^F2bqOhj8VC!&Oq-87n1S^dGKfI34!R(V8 zDd061M*Zx%>Esqbq#_dYsesOFU*T-gdDwm!DX^gV-FK6%OBtp|yQ+tDN%;7P68PIu zk7WVU^{u|=GljDypO+y&Kp6dm3D$ojwCx-px7;O1P!#L!P>O?;AIRK{#2~LvdZ^!S zKNZMNO4P^j?dwgn$-udLzP}wS`5J=*+vS7<-FbLsZ3-A3JwVWneu=*ER~R(E<{!uO z88HF3a2>?4ZC1793W6?n-ImjAiYf$3<3dE+t$$QHRq2hFYqz^nbIP=vhHM_axmMfF zrmH;BgwcsIgX(`gZ%+W_(5>i=$m;X5FIaU5jUO8?G9AFj@pa^*d|wDXNjef&njp6=B&Z&+!j5r7j-B`K>oP+7g;hh&{Olm|Z1`sAo=oRl5T6kp z1#RlS?Ja9l!=uYG3TJ=N?=P1NZ=PfSZn$26vsj`%xMaQSWpHe})0m;_5F6**B6lG> z9gjM3STJ{3CtilfMuIfvred>I2-ZgpynJON519p?e9CV8lY6xObKFR}(w4G4?&=bkf4{W?T;?YJ<Cii8=5DEO9m=u;2Bfoijd24I zN5sQb@~le4ILWWzR=Y8DG}nJraa)Mi44X=VEkApo?ucBliIcAbYi77_n_nB&?-T~^ zDNzD9Kp$~Hu!Yd5TnN#Y=LnvAUxJ+bo|HvuEyQgR%0z9U~n^ddf|>uB(@Vc#t>tP zG_X7!il|r;t%FOyghm?LieQQNs(0q0YKzW;y}-#LC~>(WZOWn%kz$F~a0F`@_?D^+ z+a`673Y<*s#!f|^eGmJ#&!-3tXZPn9_Zxv^o-@L@0WraKqN1gw0I}J?HG3wz*>7!u zEkjJu3n-r?!&C8Vy6qjQB3vKY7P^pYUc|pO2Z3B^4ic_3v0x9|%%e$r?{SjgT_TBe zGY!XWy$7$O?-7wW(#D@I`Sa50XQ@OeWc09NB-OrSMMe!?)LubDD9(|H_ZPp-Zf`Df zX6paAg9B$7c%BG017wJ|Zn`l3EFo81_NLDE<*g`EDskN3{&+wsz+W^G%H5oV*(ib; zk(0kYHJJ!L^>ck+{G|3Um-TZnzk$qHQ^n@8W?vuH5*Xz2+-C8rl;4iAP-X74T&-Sl zmu1q*PiijByy1UpRhpagMxBMlkn;X|^jRX~AEUFgTC30!EfAU$nlHy3+vP2J=1hS> zB|WH;qK{6ZH4OHwmZ52Itx3@Qt##wdYlKgRDF0)d00f#tMSbsz4UZpMB{l28AG<}? z4LnsU(0w~bqMN`NrDqBKPQmE)st|^20Pjx zQgsaH15K)IfK+?J@{XFmC1GxFSvSA3(VTGqB1Y8Mg{{!c-}j{(S51S~wOJo(uM=&%UxD=@4!ep^+W1$XoEQ!o0(9&)B)hLx@ZeO)eSwn^aT}I3(k*Md{c-%)L)u4W* zsZNydDi_YssC09Y+qNh@P>NqAxO~qJUf29|==tnTp2%~5-kgrR5z!qavGm4Lim z)Eb$r-I+=Y7NaMT;eM;0nsI!Iqv&qj++d^QtdAZLO>>qYehp*gxtZXaxjFn$EH{D6 zmF>0yMe>2k%YPF_$blQ4eB@A_cs(IiEF`H*JtzM#uTDAT(Y9k+-&R_`q}bGbJYHx! zan)1ALT5qjzqYs$AYmf0Ac>!z&IZm6hVEGW@q+M#nSVbX*iO=MD`l{(bWF2-!>p>e z!Yd2vs$Mx_soTNFS7qd@kZ(x8IIlI)pf|tEF?yt7i~Jy_irHh#XHx(7nicJf$%lcE zuFwEY4BmTa=l!88qKc6E66V=USw^#+apFtg_h7h|mjZ$CtT|Khh|T`YQULVG=1CuU z2&=LwU)rZ5q0WQpRd|&$ZV&?vt3cHb5-}8hc_%@1;W>dhM;Zdx$zs?_K~ur#B#1)llc0Ij@ut@`m?GLn5FoB^p167V0? zl&qBkl+Nj{XR20Qa>xIj5dit-e1^f+8Iv3!BXVxU=!Q=?pi-8M8hZg98k)mvFPfvu zg2es~&oiBLfNTmL(-D8R$odN)JC@8a@7 z;AHltTzI&Jp<)?rUjVNPk7(bnuxf#g!L4}Z#<8DzVr@_+`^|bBX!Hy#yIbwL)oJe* z@lLhouvjIFrg;?x&f)84akYovptjHVB+|BJu4hp;PWruw14kM(N=i zyb{sDxV7S*t@;oGI!P8vYPM~{to1mc2uDbaeSV5TZv>#-ybL;{{vV60u_3KB+zGK(ZN6)b1-~q z*@V)#0uQe*CX6l~!x_xl{hJO|ogxG4Iy`bkn}9=RX)Gnxz|^X#=eoLQFN>QNuTYx+ zG2d~Ar1c9N{62CxYEo;@BArXb@Tjr$pQJw$-AfB96(U4ts;Y_sGg`lBY-Z2Mxa%_V z|8B?kqA=A0W4RB`EO<(k`?`*s;MsuBpjqk6pUWrEVLfJ!#l&xEhD25J?$^8v8YrqDwo7`&w* z*g+|X^oCJeb+S)laM*nm3Gw{l9&r5&m(gV1E$YW9oXuere-iJQ84KbPH15jgWSf*m zd+=eBw0Al`@0d`Yq{%ngSj03%7brE-!Unn!$rj~ zu#`e&p$Yy81#O5SLTxak>N{zD+RyRJ-!s9w7F%A7Ipf)R7T*rHP>*6$Lo-FHD^$ne z$j_K-2pLU2%r4SUrBEG#`d5Ijc!v0E#_Wq-Owt{w@964TV?+YONw`l!%bftK{*Fk9~|hYNq>Z6~w2Fzfm~RBc2J3hn8Jj4ONuT;8*?**a)hWD z?mOn+wcyoFVaLE=P^DMS_h$={=Qv+dMLBk*HwU)+TXF*``B#B3a5B{Q(!mGPC&jW* z2DQ^_;;|7IL`x~yySQiU@?r3k!zBG5D$ zUh8&^d9Z>LuIxYuMGqTQG~5DQN4Fhy1_dhOLK?R()*Zb%Z-H3(cz$?48{cCW5gg!Yi6?wsEK=d?c9l2b>;6EdQ(eZ_kpKv=7LAQCl_)m6 zLH!A%qnzk?&b!dshBiy@_o)gV9?mJCCLv^GqxHt0&VC|D!`;YaN=jHnBT6Y+x6Lb zRrOCM7+J3tnYNb&6d|)$O|~PH>nEfyjZwd3%4ALQ?#EBrbOA^6pstyzLW!B}P^!S% zW%BAI38Ft+7_=pxIODPA55xOPj7PkZ9OdW(EbWfF2{9t&(n-k?tKm>A*T^Hcha~Ye zO}rIGnbJ{>-MsI+xacTP(9?fX?%>I;#UQ z%#)5ntUtj+cuhslxHsYIu3x*@sY!!pLOJ6O&t|0PudI@dleMNLAC5NMRRmny%IW2B zfznI&@Dq5A8n;7jqd|;xm4s{w;yjma?<@jI@;(F3fQwh#z>T53LYU6^j#sz#^I#^& zF^>64_tPbli!6DqtsyKssGQJHYZEgO12|o+ZhW^jPaQkwxn>Hx{Tu1BrHWC8FVzi2 z&7R^>*OHuY`=QlD;^$VIYQ7q(YJU{38)Y9(YzCr-aL&y(M)nq18h=y^GE{^Nt9p?(C1iZed{mj z%a`r#Z4d(^V|8mQs!$wNWK2v=Wu;Kbtnq5I8z45djn-l_&-e^=griZS*5BWM>(}P8 zKkf&9qVZdE%8^kSamZD!+Q?X>4wMk$6d>?(&`^Ci;u<3-kS z!*xv_(~b}u-36NXHHmU1>&eGYgeFcXoTWA$gOhbvR=B_21~^+aQYF!g{g85@YY$RG zxWVvA_=O$KkL!OAo@l&>$$z7t=}>Ea?|*ooJuQX3js|YHI_u&DbX+D@oS%7g5c-!? zw5P=Y&)d2lt8T3jUx>-o-dJR0B>&ligWpwp)6-eYop+|e+l|3KCF#T9S_QC)>lcv8 z=W%w|+R%1t=W`%R%G+<@1iD*oU`3R<-Wq8^e(BPFnihsOR-8hN&6iqi>eHYEq-+-( z#j&;pLbv*ovH70_{GyQKa1(-8RonK6NfuYXz0$Zl>UfOS`XBorbK2|PJ-aSG_pK;D z#XTJndrxU`^dp!skf5sOca9C-c$Kg&E@FU;ekg7J*D2B$j3|j9Cclda_H?;#uNN^_V-9}tVPQ!6x7Eo` z%XSS;>%Mmv*{{<8?*`-K&G9^pK)HkzIZ$LIS1-+_TA%&QbIfFb!+@N9!7>oKeu|`OLWENA+K+wg<7DlT0 z;4-=>b<*^mtZ?duGPJS^TfdK5-}sb$538Z)HVc(~l{ViR5*!Ry-nfPQ?WRcK;z*+- zO{4uXQP=09ul2-?X*)mNek+LdnM|kN*2vIsKS@Fc5*RC3^fM7-Ef$EpE+0CwSu;i5%N~LemkMaNLq6(0ZDk zk$gOINUq&~NXymGR;Nq(&Uc)5$IHqZFo)xln4h+a zWMf}4JQe%YYBBv`eSpuXDt=lfQNHELYvTrbp1u|Bek$xa<9!=Bia~9>Kmfrt@3Yn` z`LwY;4AN&g2d_^Z_Yoa~Eo(Q7I5;E?w*v)&FILudz!JuLuj}q$=?6YR?nSEw^hT!1 zYya}E?(KlsWP`2^1wjNTTcz`jR9Xp)m7MAERMun=pET@|1An`UK^Y#;mGwG}HoF~vd{~jr z>$Wj?(hdm;x%IYnbo|xTB@7P_@A$+Hz25H2Cn_o`D=S-Rzsjrsv@~Ds`{cgG?YDAu zsgmp0dRD_^VB|;Hv7?fA9P~)NWoT++*vQFRb{Eq3Y~;Y{NvCxrpS@Iz%OM57OQh_psTe<3 zpySQG4_o8>UvhgwjL!~b>*fcCjSmi6404*fEfiWz))bIt70$?tPDfW-l7xM#w_pP%0^Iiq}%{)~TAHS(RKNDK|m zl`o;7!oX9zz78)Cb`&922Q?m-w=|yCFE<_)m)wr*@L)EqdC}jkxJ*EidQW(-)p%fd z_Ca3OAWB#<>r{`o4IM9q>jSY;WB*L^OtPYclyd*Q4!vX#43@zD)~89;j0mSa2G(uY zgPnGT*uihf3pWM8tii{*av8n}$-EN(w1Xc7UL-az^sj1Wi~{d@W1Wu9rq>zn3nqTr zjZrB^u|!y%OwA^~j)oDhidQDJcCblQDn)rc^A?yYvy*-_N`Avu%)~RY<`||l>bBC| z9=9nuim&G2gP+eSNqe}mfEm! zA85YS5*(69K~hbeoWcq|oEq0w_tu|rr}GhB;PDFz#yeo){>)kk^| zd;RRcoOhAD*?(dJf+(21CrHVnEeSiHboOdUQKxh4Xj-2SVt z6g4@Ke^thmc@D($d>?MZl%8$CAKWXVkd^&Pkx0OMi)w02S(Ayp-ln6)H?y6?hGR9i zvFuT9;nnp0h>|t_x6o|eIe2_!N4|N)rBLoX%8kKNc%nXF(wz03PS;KdYJWT`X?iz> z+hxzza8)=kwL~Pygfre+RloHqYh&LVF&tM^RZg=BKwypy9=tUWqr`a78uoGwzYL0Z zW~50~lPtw&K`-Fx$1x<%$E=x=PBAF{SIC>jp~+T=g;}FJ^O!y^yC@t*w5{^*mUZOH z#nJ??tRl}ug7 zn{Z87T9~09hG-$ys&F}s=iD88kF#Aazp=) zr%zQ1`XzpD8|LNKNFcQnY>FSuN}|VO9`ld61}vyKVonczh%chN#W?=?89yrNcXf0v z$#%x1%~#AmmWwpxi%#w8Gt69in`5JUv_KdnD8rlHLZ3lOL6lI89I#;eaZm&^zBh#3TDj0flKf(1 zdDm0S#vBg4YEJ*QGuU&iX02e_HD?l1dy#fXk?a6XK~t*>KSP;QV5znIJNYqi%lnH4 zSPREJ#Lp|ZM}$z`ko;sS2!6CmT*5$sJcd?)h$u zM;ILz#jIZur)s=M<8qd+pTAnl#=#=0J(Q9zN1K!=;>DfX14{qNNOcRqDIA||b_ahy zv+rBsQ|k(Qh{j!OFtKJ-h4~QZ`vX*oh5;YIHiBs!6TP@g6_c2VIv$w9PJiV;{CG8L zzZPr14uNa1yP_p3^pAC%Gi=jFeS%4P1;Wd8k_6aB*1Ac$cz)7%g7bcbLIfISxxv{J@U*kpkBL<)*;@7N7H$lNutpqOi(<00<}+42vp} z5I@|#ofZ5m6Uv53TH=ZIwDr!4On_tQjdC+}iqdZgHm42N`5yVN?ImCYf?Ge#%vZz` zEJ`h)Re%Xw5R4A`Xl~Y7kmf@zv4-#j_!l6t5@79t1nYCzT)S5fc{U2f5=zRnh*tf9!g& zMg6yQ0t>b);0MT&8M+r^mTeveUa9e=UVJ4^`D}Uia4q`Q#`F5<<$NGDHC5jsjDeEWk)`E0&xatIbA!B;;ltrY7dP1sx+Z8z#@?>hO!q&XN48NOrWK0|L3f(rSPZy z-jECV#41jo58BSR;M92E5Mf6;WT*|K&?Jq#YSvwoTtS-}E_^ATN8v|W)jRagV`t@~vOasnPtHXXM_`>y$yeU{|YNJ9p=tFVF1kKEE@+J-cUj{U5_fG@_QVnth%=kP{Iqp9C-{R%1;_EHr=VUzC-rSwQ$<)wtEw1kA9n2;z4#FONcG^(le;$c*GrAT0b zZXB)9)5^DzG-~fZrq({^Ks>65x3K(>INGJEyio97_kPn>)3@$|<`+AUcw!%!b_hA^ zd&(LSaUS1u7?saVGtuaddu=r)yBfBPYmgDqQ~LfE3M>X{>aiN{Xu%h>bU)%)cFuZhWC>bvJ+}dAIoM0>A%6@d-{Zj zqKH-ip&$np;o@gp3*x_Qc*tdxWMWSc|8~lbM~r7X%Rom%D<&^B$-Z|NhlFi^pG)u!n&q{-AGw5E#m>!G&Q=t=`qu);1kKA%RR;`uQ86(Qof>u z_}HX&6E(+zzkmCDSjitpH0d@p_N>grxIP;2@1d_TZvI>uk{Qy5&I=kxpI}xOlU$ut z83n~n{T10LFWI+Pm%I`kHZamC%uTQ&8!&F%l*%oc==n{-liL6UYIRzwj^8WvxPkXi zgbFg-S<}OFtE0QJHwg~f><*FG#122!hPJ;qKJid}HpbpC=Q}|UXb`#kNu;Gwan$g2 z-|+i!N!v5*rX&oFd_CvqxQN0Q*L)&pr?|;@Xk|mkHH`z2Dud~tnrqJtqHYp7U9Umm5@Yi2ijiU%Bi-CY9{P)OkLr_ zjqBe`t~0`Fzo8$vYUM~%fyz5#-0fv~f!BH9Y2?;E#0#}y$e*2+<*ZvHiB3<|&K5Lv zQq99G%j1oK>v~Gl)>Za$z#3h7$xRgwS$bLwV_I~GhO?!=^@hiZ#Mzm)Y7{K@ufF(< z=ijT({Y)tv8f|aH&oF$K(}d`2Mv>{{(1^6HgO14g57Mc1UiwJ{kjI-*v6FCZj!HLx zdKx)qqrD}i7Z;NMQgUDU3t@_DduG!+g&YgPMLXnP5Vx^^wTG}&lPlN-w z0*jZ`oSy1uIko%6KY9;*NvPxDlwjwQDnYwS1ZdeKz}h&&e4@U9u$6S6ul{s{W| zr&b8u9Y6Mn?PKr|W$vD>3ZIjhBiD_U*90|d@~Rg44@1Z#{j|&WneOZTT{2Bt*Iv8t z)I5H~KX_RQHQ0CGx4Y49ZtdHRZHH=Gc72rd^QC-U?_(2t1g@i)(i5U}S;`&TIj~1< z44%XOOu^j70fmsqzcoZVX7%__3LA_(=2za7uT!tC+CF6(E3EXg{W!2DH07JN@ZE5r zdW(29h5VS_q`f$!BxK3k*O0Vl$R^GZF+}OuB;D~q0<_rZW<)rnmzp6}u-l8sg1`6( z+CRU3x(WeK-iAYh(f#2Kbj8xcT*R95I;^=~a-uoWfP`Cca8TB9h3J*(il*qm-WXVe z-zBM3&<47&beY}(Q8yEWG@VzG6NbN`o_E0)EZuo+S~b(yq4;l~j2e#>le?5zHjEm3 zKc2N@C?pXw_YP?y-A6TqMsVI~L<*aLxx)9#J``R2ljtzh>a_9Z(I{;>hAy6TO%HrsT6sJsHf5+i@A|okQA?6Z>!3A%nGDt zQ(kNL0O1MQ_hF`0N_SLhVg>kVe>TW*zh6HAvR=!59Zbxg*()c=CsH71u8pyOa>qbZ z0rk$tJIE>hq)zU51pQ7-3c2$hFZ3Hx>S{kvX+e4fJelj^QZvOkZ}nE|eCyGX>&?~R zfvd#L(tc=K2XbnkKRB+#l7yZ=Q-+ag9nH^RjamfmU(!slUV!=}HTcwH>N`uZ$-t?1%HO~0k&$I; z2>RXf`tpvEsl0I;-1Gg^`8b;~!=pA+lj65)5v*dG+Yx4j%gEO|zU1Z&zAGtk=aoH7 zcW7-rm3ZNTqBt5k>bXpWaDdO^KlLo*^eL;q^Bw%E(C(+b>Tl@qrq+P;OTaMvUzYYA zCP{^55DbYuJ3t3rDy+b~CPI3+A6W9f^ zO}dy04Ay(0kTA5N@Sy}NFjPwE>K8!05P#Ws_)}SDI43WU!c@IZxZfkoBu+JbY9#JQ zVpkJ&NE5X~Zr#Vpy26S-&E~78m5co&C`nOq=k*aU{ttn5ao;wBCi@zQ1Lg~VTi`U3 z;S3e&;`Lsh2NQn$UK#;pyr}QStRF#3jon6*Ed{_KnbdS(J5J3q7-R701%d92> zHsW!RMHg;|gr7;2Qx!v}J`9jvSe{6&%fq`pH)m5++QY|CLYUTa6Fp5}Do$nx!+;{( zD-p>!+sR+_Kc92xt}-a^9FT`i$}7k`dv>{=l$4}W6>Y?3eyjxvI1LXd@u-*(T?N~7 znrzs;-WcD>Ck61OhQq8+co8`d?Z1uEa4(qJ(T};HAhngwEZu*QZQhzkC6>%!)$g=$ z_KJMQ7mwnPZgNYeaO8*0!!ZLjTCbnEq&a8y*oU0@`hAYD0gc<()e|X~CBtLw4)X{hLIQ9dK4;`(ZKMQOkeb%TGPAI_C{5sSMgk= zc5NvtgA4L?MX%~RzkSOtWq6SCy0kRgF2FSmSb_>C9pfl`L%3D`t5(XlxaFPE2OL?a zH|`Imp#*;H6cuqd{2CvQBVGnw2NIhXsRZ;Fb%d=t+`VAzf0k+87Q{Q5^CU4oP%p68A#&RG@7dvAv=_d07XPLyA%OWAJ!J@L4Raqxu&p1Z4H5T+-{ zjZ6^D%Wk>urbzq^c%bq~4F&c#pwsEp0L%6kfX%9@7unIXo+v(?@7?n5?7ck zP6D@LSSGI(pTtzLF;=j7hU^xT{ujemZyDB&cdfJX?i`~hr95|Mks)US2(ajFzmT7S zQC{%66RD_&ZBK?`Rb~iPd5N*zf#f?0tqcQ4%>gGHpO&tI?&!Re&Fo&&*(J6F3y(a& zm6){fGeq>*@NMd5xBt7p_SK*I3xuOHEq=;GySc3^+&`g3C~EE8c?zA+dfAZs>KZ3N zFaPRf%m$n)yP$(V_JI2iV0_A{O?a8z4K$L+V6nl?swYZ5I{ zxo6!cD=6{N3GHu;*6Mnqr@DSym#hVAT%#16ceqrY;^{uEQ3Ov7jj#t4i0^c|4SV~9 z_OGDsbA~q3q$6ShdHmLtlF-HQ=NJa;H^@g=yPGZ91&04m-X&$vNX@w%HhaVS%B4z9 zEWP=g>1@Yk!|cKvJ3I!JWdH)96qXBmwsq*7wjFSSEoN8FbpzG-1|!%`@1w>u;GPzQN4dEN_Dhx<+uh27@Ak!lm!LtL05 zksBd}=jA60P& zpHy3WSq^|v!L2^R!w0u-{sWz*m7sMMjr8exwe#T8a;D+>U9Gv0pkYglL!uW(zB`+auGLPbya4+vKvaDS(g3#sDEtQb<% zd6wRirX_kCwI2X0I_J!1-X>@lq=HRTHQtK7gyv`2+k5nlgq*N50Sh;|xB^?qv3NY- zldrHbXN$xfowIc1{*9B3+@Z9l6-#uuC%|jOeuw&r#&U8xeuWUiqkU+^* z{nyUFsU50JlpLDg^pjMLfIxJ|>dG$+cD>QF%NNE%60amo?W&-I67gD6Sn@@;hzk-w z#m?1l;u!5)UH5~5@26=FKJrQ)H9o+c>tF=Oo!vVFY$_-+AZTKI6=`Cw?fla3{zSW@ zyIDmMmcB<;bOw|wx5K*3x5t}xdC$LYXumEY08BiVQ)I`gVeO}uVm6wJbuD;$2&YtN zzxi^n&fLg?jywnF{z)E;dK=p*hTkJWQR&ZJEwRM02O~c)d29G~qdoX>@)! zCUy(edZnd1eR9e4$iRP@f05qkZiajfwq@~osV5(Hi^)MCv|EnzQisQOM~z&C3yC`~ zi2|wI11Ng&IM>`V*m3li2Y|fuxGZwd@AZKApT4~+>=dWfD)^qw?ozWoSj7z;jDf5_ zcP067d86En=q*y`x$!A^huL}2eHe3qJxWZROWFG+3HiEnh6Bq*tVMw(VkhJ0JQMyo z!4Y>#RPNz}$pz#bX%)y9mG`qFA)SsrsIS}cm2V+-3loZEI8A*gAkZ%l*-a^IyX+rt!h3SH{oOZvh0Qz1?qk|K_cC)w zJ31_6O&~Xc;-g3lA?{P}Ki>>TuU9E0>TDg8m#g{cV0JXBK=Gu&@g*l#C1=9d&tSiO z55tt`tcSDGjsewn-vXMwtu1pO4Lf+2o1KwVD4}D&PRqwAQerFeF0$c4$MSmvq9=AV zYQ)f=EjTi($pJx1fbCAplPY&y?AIPazok|ukC_JS3YFOsTTt>F|GbWTlIzY)^WDQY z;U#eEG;Tl<{GwpV9C1V{Ah)rP4!eOv2LN|IdRh649&1>>wksCy-gfD^${*N}s?V-|FXuXh)(24V1RdL?h!4)S-R=iLx z1Y1jSy?CHRY7jjO1~;x~T^3aHE(kofgjFeG09KFUIbFC*%{0r`?N0k01kH^qxBxnU z6A8OLbGr8}9r$5GqQ1)j>4yYQo#mnQE1{ql-Z&z^?!Kb@or{8(_A@i_s?I&W>FG~& zo@oA9qV4rlzaD;*2Nf~Q4nB?i`+z@uFGXkGDGf|iNxSGwRnc~t9F`yHB{Rh$8^qH{zjfwnTd3w;qu&oOz9yO)y>(ZHwk+knz{CiG5Wn;y{!zqnGvf?@H zD8<>z42xuKpjeC+ZM9uV=X%WlWOIr6-h{v?BYS*P-?T1Y(x=qVpMFh)>g4NIzqED8 zDkn}BWd`t=ES_Lc`6AOY9RGJA(~$k3<7;Fq-yzgK4z-}TIqUSg9uGQr7oqbQ;Nbos zZKf3Z?oZbbV52eL??a*2qxghG$OVEn6GGK`+`nw_W%=%Np$ zXjDjlflIYHR4iEkr_MzbN^}9|R=~B@bfR+)WZcpo(j|yvW)GxF2j!?Tf4|cKvA|_{ z_xW^uX<~Q$xm8lW#H?aG5-cu(COY4YhTzxuYqGU8W%-5@WsVW9;*b5w8{qp@W-(O{ znq{h^nO}Jkh4JkvbfBtDdM{BqnpK_`lz4t}?urXhk>64^DmV8^Dhy={DceFZzKgll zrt#D1g4yWqQCqu-3n|;_X;4j3YjuhO$iOzZDs6Y?KEh@#9Kc#C9UKEMg3h}_-E@2W zkxa;;gt3LhS|BAlXM|!ZIDrwKyr0L(c#UTfcz&Xu9PxDYi?;qhYj1KH+T{D+($VMt zzIkj51e&>%fz!Wy;xetROr7Sl-?J1vE>;=kSRo`M6#tmZmm$nC_~RYk$`|9wKZE7x zEEw+w_44o0MfPC<0(owLP2Oq%3_=9&k(b+nX9{Tq;Wng#?Wm;n#xjY#1tRWCIgBy- z-lL?`!5e#$=4s+r81+4PCQCPHc_qHJ3qLBO^P1+S23T0A+Kky=gq=7|Eis9Z2^?&0 zoH^u@_y@I8_T49i71UWMYb%j4f;5ER7mve(FUlNQ<`;g|wGzzO%>BT&Q=hP)Y=%%IyD$r1dqZkb_u#zK`#eE;?u2 z7&=&%P|e!ln?Pv=ZkF64AzN#%xoi#+y^z&CrA92(W_G{fm#3O@>B$Enpjem!ak_x@ z;Gsy7zW%9?FJO~JEb}cvGgOE-D!3$xP?%fY0iEnz%VCir>#SuL?;F`YnPzZjuj4xQ z)svP3{6`*MiMLT|612;vs9?m&!Cgpn`+$|t&8;+T&XKpZz3m=coIVXPH;?n!PBEko zrull!8CBAwaXoWzlh<|emM(MEm43OGo2|3LSTp9Z1E71SVN^osR*4%Ad57V55hYvc zqi?X(l6;R-$Gkrye8dqXr~$geUfbTC@8G*<=NO!m^qu#(SDo}d+ro%gBsVwZ&SLyi z`N~xtW@0cNXT*7BC>OP0a+JgRNh9~Q!*K|{6}wfB2!889HaRs_K)TB9Yba!C>7J0; zz~&m46Odl#aDC{&nQ)5CwZngo@XQJOyQbbJ0*xSqpIf$j2#lwOxDR?Px-S+*hEiqr z77~SV5strWi;b7{6{-5PV&Zf2gMXO@5lRl-&s*N^sP3qi{hsOpEo+Ce$pRkU_W72ri zCaXAieUGx*vfB|Qcb8Tm$Dv0ke{S~d2bple{IoiBU{yz9C^Ck9F}JuOP6KxrL=7DT z+}Y-a=qK;R?P>t+d)baKOJxdcJ%TX25|w2FT@BhZ>cm`v`eKfaW!B%E{y{%TqQMlA zfONHorSirO7YmCHRZZZFDf6w+T%wNwwc@uOn7O7rH<0sh?NFI#8p+Sx3-ah^=JXz7 zD*t>(o^XQjdx{2qlp**Dm*G5jqle^pK+HN$Mrj(y_FnCaxpdvfKMqTg!Q50|G{hCo zX3K*600+n8ozg{O!)@;!|5yaNAW6G4&pLyj~BfVK+dez z2b))6&rTjX@cru-e_kpFP)P^h1)Vrp@ZuzkuIFzo-D~{&SG%?UCcK2Hw;e;iN9+(7 zKNgimrLb)cX^^@NL~f;;v0iiMM1P`Qf5y-ADGVi@4e5;e9>v>bi16%~No4Jd-Tn!5B_ZgjeMP#fSCaZKoqNtKx^ zlA*DYpJVU~KAb9+cpdhbUe#NYQQyeV@+vliPPm?Zsr5{AOI)@S^W&rf@P2}$C}Q$U zxA6X3vMx@158qAO#g)3H^QM|~9s5{it4MWZf8qwxnf3xAZQlCGwKiN>hoe>WPVSFzbQUq#P@&nx=A6Z=D1FWdR0$8n;AiTd~UY#6)0#C z1t&DZMfEmB#%^=zEH$>6Lt1V;ub?At$gb5THE4hhOS+(liT`)Lj9-EDP??;fqQ5#d znmfwGy(Oe_Fk2q7$V5S@o><*W)1^tWb$&tnp&NTva{|E7U6f%JHL$E~2rSbK(v?OT zdKi8?S4j~tZ$FhD>|SL#SebmqCchFAy3-OGml%3l6ok7jmF$YCGHYRVUwroGUGFP} z<0RW)ng;)WF_|xBHEP;w_kXfhcFD8YS>Z_vThF{V^mdDBqBck_^oWyYR~6wl72xwX zP1<{~SPK}c>dlVH2fAcAH0uane~KBJDCDF7+1lDJ`Yyar)p+a%y9Bp`osKT*5<{TX z)k3g~e&MO5rLi$dB%-DJ<~=b9N!xDysQ+OPNx;7t?u$JncF!b;u*S6MZWw02Bk^{$ z7E2kj`I3a$@8;|e+ty=datP>mref;@gvg2SU7(vrAM?eAO`DPD2jHno(ROhd+9*szB{ zRN^UhLf!eBDh72O%3M@;w4*97sTOvc@~dI*SX}}|xgwh5Bh%xkuR0+#{4;*?H(RB^ zP|=c!7NsbIXAK+Dg*r)pj*2MkKN$Py11|nXZSC(X{7dP+*@K`2ApvB6ECKmj>P-af ziRWM5V_{)=b-f%1LC!00?v(7H0L#125nihM0ry8asEn`Ly7ItdJ-9fX)WhwYUa>qlQau+M%?|gp0C9ykZjv-<74;y3+a-I3J zjKiW2%n9?3qJWDiyE(7XWy_$wrdK!83CiNogKyeV8MdG8UuRz(=_u&bN-{oo;7;qI zX(bx+%*t+|I{r5hI;aEdYwo^UIQOjmbFy)&()yd_Q1?xFSu`M!)q59|sBpz|5ONR{ zu=zF0xGV5XFaH{gIY31+xqUfndYvsXIX8Ei)7^1PIZCO00=5gd9+1H4`KMHByfpJu z+)vCrnRqA9hAL|uqJVx_UJ2TFjwRC34{jF~pI9}qV3^1YQ2n0AQNMYMvh#8bvQa-O zB)hhRduwD4^b6yTg(m_R>0pOMN<3oV<)Z{Y_w_WR@hjG*dD!+y{w2cUV*U?IV#fn{ zIqsLRU~|O4FZ+OC`^?a>J+s4_P{|v?x$L%rkJ*0J!L%>#LOAJ8sjj1=6eiayF7}oR)~&aX&sf$$clZAOzH~!)y09e-jh2^}CjnmLa&FN{qds~801i(!j;>c2=4z$# zCLUnw9Ks5}_3iq>*N=ae_w?`ASE^y>k;nwT2%95G@85UQ-pD@kPy1R|GYhZZY|S{F zka+c^yK$3_lS45@JJ$23k!8rU+kJL~rJs1)lw}QhWGqsks9t5r=eBIy8_h|6kK42W zFsKkYxp!ZKG&T7=+kY5gp`%AR?y;{R^oQft%sIr3KdOJ;EU2iBuHq;f6Nf#10k8^5%iGA3|Ck58rMCbjxz7yIf9H&o4*d0{QLv1c|YM;=710PfMkJ zZJvOJfbT6zBo8q}^Aq^=32#S&DqaHjPfnaCEKk4!EBmjfHgd(a9rCe|guc=>myXFJ2m8uWLFwf{9cLK}%wKz=yh z4n^Qoq$kFAk4|6bg22tsOpnE^ym6Eq9G(J>cQ-{^Uy6{i8;fuvv@X8Tpn(%&LgDg2 zLw?#1j_e+aLxdAvFi^U2hesVJtz{d}m% zFkHoMk_WUq2(?%_EqrwVyB(MRN}JUpc2La(o37!th0DIwadUE0SRt2uAN%@CRalaT zD#St1jM_o)rY6~)qaOYcMDZ&RfBqnH$$=5xV(Dh&%R>z0SLv?mw| zcveEhshYpEEr|#be_v51BqhrB!_1LOvtmBdnEho+9D~(Fo~kV+?)cFwM-DY*S|~pJ z#TUB%1y}G0w=obj1BQrw_Bsu3Bo3gG7NW>>T6Qg2J6h9HL!9J*vsjlEj~#A)sDBJc zSxFZt<#Kp#OU*tABRF3z%ikE(QS36#cVHje(Ux73Uc{RBA%^@CAL<`dENjKkf_=kc zqH}(21mb@qK!)jqsp?fcM({HKM2{JdagVDuGEj6S;sYIrf%uUv@~X?zZC1 z;#G#-G#F^}@zye3XvXfyd^=nmYrP)=QQhd#kcp1Yaix$h4*5^R!ZVp93=KOmAG>5- z^w`hLz|Ua)CxYHwjW3hDAu{cwq57W%_@7n&pKAR7_8FYt5=u#XkFz Q2D%k>6>a5eC99AB3%G?W#&|6W#MJ#=4D}x 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 Q2D%k>6>a5eC99AB3%G? toSend; + private final LinkedList toSend; private Simulator simulator; private boolean endlessModeToggle = false; @@ -61,20 +60,19 @@ public void onKeyEvent(KeyEvent event) { } public void onTickEvent(GameTickEvent event) { - if(endlessModeToggle && ClickManager.getSharedInstance().isClickQueueEmpty(getCraftingSpeed())) { + if(endlessModeToggle && ClickManager.getSharedInstance().isClickQueueEmpty(getCraftingSpeed())) craft(); - } } public void storeCrafting() { this.inv = (ContainerWorkbench)Minecraft.getMinecraft().player.openContainer; - if (!(this.inv.inventorySlots.get(0)).getHasStack()) + if (!(this.inv.inventorySlots.getFirst()).getHasStack()) { return; } - ItemStack result = (this.inv.inventorySlots.get(0)).getStack(); + ItemStack result = (this.inv.inventorySlots.getFirst()).getStack(); for (int i = 0; i < 9; i++) { if (this.inv.inventorySlots.get(i+1) != null) @@ -145,7 +143,7 @@ else if (stored[i] == 0) ItemStack curr = this.simulator.stackAt(j); String name = curr.getDisplayName(); boolean isFullStack = curr.getCount() == curr.getMaxStackSize() || !Addon.getSharedInstance().configuration().getAutoCrafterConfig().getOnlyFullStacks().get(); - if (curr != null && Item.getIdFromItem(curr.getItem()) == stored[i] && curr.getItemDamage() == meta[i] && name.equals(names[i]) && isFullStack) { + if (Item.getIdFromItem(curr.getItem()) == stored[i] && curr.getItemDamage() == meta[i] && name.equals(names[i]) && isFullStack) { this.click(j); this.click(i+1); found = true; diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/AutoCrafterV3.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/AutoCrafterV3.java index 834a341..1324eb0 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/AutoCrafterV3.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/AutoCrafterV3.java @@ -43,7 +43,7 @@ enum COMP_STATE { private static final int[] RECIPE_SLOTS = {10, 11, 12, 19, 20, 21, 28, 29, 30}; - private boolean active; + private boolean active = false; private ItemStack craftItem; private Map recipe = new HashMap<>(); private Map sourceChests = new HashMap<>(); @@ -164,14 +164,18 @@ public void onTick(GameTickEvent event) { } public void start() { - active = true; - resetVars(); - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3started")); + if(!active) { + active = true; + resetVars(); + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3started")); + } } public void stop() { - active = false; - resetVars(); - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3stopped")); + if(active) { + active = false; + resetVars(); + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3stopped")); + } } public void toggle() { if(active) @@ -614,9 +618,7 @@ else if (step < 6) else if(step > 6) decreaseStep(); } - case FINISHED -> { - closeChest(); - } + case FINISHED -> closeChest(); } } } diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/Simulator.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/Simulator.java similarity index 93% rename from game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/Simulator.java rename to game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/Simulator.java index 762374d..fff1bc7 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/Simulator.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoCrafter/Simulator.java @@ -1,4 +1,4 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; +package tmb.randy.tmbgriefergames.v1_12_2.util.AutoCrafter; import java.util.List; @@ -7,8 +7,8 @@ public class Simulator { - private int size; - private ItemStack[] slots; + private final int size; + private final ItemStack[] slots; private ItemStack held; public Simulator(List inventorySlots, int size) diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoDecomp.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoDecomp.java index 2db0ba0..0f0d05d 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoDecomp.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoDecomp.java @@ -27,7 +27,7 @@ public class AutoDecomp { public void onKeyEvent(KeyEvent event) { if(Key.ESCAPE.isPressed() && autoDecompActive) { stopDecomp(); - } else if (VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoDecompHotkey().get())) { + } else if (VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoDecompHotkey().get())) { startDecomp(); Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoDecomp.started")); } @@ -52,9 +52,9 @@ private void decomp() { if (ClickManager.getSharedInstance().isClickQueueEmpty(QueueType.MEDIUM)) { if (compItem == null) { - if (!Minecraft.getMinecraft().player.inventory.mainInventory.get(0).isEmpty()) { - compItem = Minecraft.getMinecraft().player.inventory.mainInventory.get(0).getItem(); - compSubID = Minecraft.getMinecraft().player.inventory.mainInventory.get(0).getMetadata(); + if (!Minecraft.getMinecraft().player.inventory.mainInventory.getFirst().isEmpty()) { + compItem = Minecraft.getMinecraft().player.inventory.mainInventory.getFirst().getItem(); + compSubID = Minecraft.getMinecraft().player.inventory.mainInventory.getFirst().getMetadata(); } } else { //Do Decomp @@ -231,23 +231,15 @@ private int getBestSlotForCompStep(int step) { } private String getRomanianNumberForInt(int number) { - switch (number) { - case 1: - return "I"; - case 2: - return "II"; - case 3: - return "III"; - case 4: - return "IV"; - case 5: - return "V"; - case 6: - return "VI"; - case 7: - return "VII"; - default: - return ""; - } + return switch (number) { + case 1 -> "I"; + case 2 -> "II"; + case 3 -> "III"; + case 4 -> "IV"; + case 5 -> "V"; + case 6 -> "VI"; + case 7 -> "VII"; + default -> ""; + }; } } \ No newline at end of file diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoLoot.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoLoot.java new file mode 100644 index 0000000..0724b29 --- /dev/null +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/AutoLoot.java @@ -0,0 +1,150 @@ +package tmb.randy.tmbgriefergames.v1_12_2.util; + +import net.labymod.api.Laby; +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import net.labymod.api.util.I18n; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.util.text.ITextComponent; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; +import tmb.randy.tmbgriefergames.core.FileManager; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class AutoLoot { + + public void chatMessageReceived(ChatReceiveEvent event) { + String message = event.chatMessage().getPlainText(); + + if(Addon.getSharedInstance().configuration().getAutoLoot().get()) { + if(CBtracker.getCurrentCB() != CBs.NONE && message.equals("[Switcher] Daten heruntergeladen!") && !Addon.getSharedInstance().getPlayerTracer().isTracerActive()) { + + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodSkull = getTimePeriodForFreeSkull(rank); + int periodChest = getTimePeriodForFreeChest(rank); + + if(periodChest == -1 && periodSkull == -1) + return; + + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + if(!Addon.isGG()) + return; + + if(CBtracker.isPlotworldCB() && Minecraft.getMinecraft().player != null && Minecraft.getMinecraft().world != null) { + + Object freeBooster = FileManager.getValue("freeBooster"); + String freeBoosterString = freeBooster instanceof String ? (String) freeBooster : ""; + + Object freeChest = FileManager.getValue("freeChest"); + String freeChestString = freeChest instanceof String ? (String) freeChest : ""; + + Object freeSkull = FileManager.getValue("freeSkull"); + String freeSkullString = freeSkull instanceof String ? (String) freeSkull : ""; + + if(periodChest > -1) { + if(!freeBoosterString.isEmpty()) { + LocalDateTime freeBoosterDate = LocalDateTime.parse(freeBoosterString); + + if(freeBoosterDate.isBefore(LocalDateTime.now())) { + Minecraft.getMinecraft().player.sendChatMessage("/grieferboost"); + } + } else { + Minecraft.getMinecraft().player.sendChatMessage("/grieferboost"); + } + + if(!freeChestString.isEmpty()) { + LocalDateTime freeChestDate = LocalDateTime.parse(freeChestString); + + if(freeChestDate.isBefore(LocalDateTime.now())) { + Minecraft.getMinecraft().player.sendChatMessage("/freekiste"); + } + } else { + Minecraft.getMinecraft().player.sendChatMessage("/freekiste"); + } + } + + + if(!freeSkullString.isEmpty() && periodSkull > -1) { + LocalDateTime freeSkullDate = LocalDateTime.parse(freeSkullString); + + if(freeSkullDate.isBefore(LocalDateTime.now())) { + Addon.getSharedInstance().displayNotification(I18n.translate("tmbgriefergames.autoLoot.skullAvailable")); + } + } + } + } + }, 5000 + ); + } + + if(message.startsWith("[CaseOpening] Du kannst erst am ") && message.endsWith(" wieder Free-Kisten abholen.")) { + event.setCancelled(true); + String isolatedDate = message.replace("[CaseOpening] Du kannst erst am ", "").replace(" wieder Free-Kisten abholen.", ""); + FileManager.setValue("freeChest", stringToDate(isolatedDate).toString()); + } else if(message.startsWith("Du kannst erst am ") && message.endsWith(" wieder einen Free-Booster abholen.")) { + event.setCancelled(true); + String isolatedDate = message.replace("Du kannst erst am ", "").replace(" wieder einen Free-Booster abholen.", ""); + FileManager.setValue("freeBooster", stringToDate(isolatedDate).toString()); + } else if(message.equals("[CaseOpening] Du hast 2 Kisten erhalten.")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodChest = getTimePeriodForFreeChest(rank); + if(periodChest > -1) + FileManager.setValue("freeChest", LocalDateTime.now().plusDays(periodChest).toString()); + } else if(message.startsWith("Du hast 1 ") && message.endsWith("-Booster erhalten. Danke für deine Unterstützung von GrieferGames!")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodChest = getTimePeriodForFreeChest(rank); + if(periodChest > -1) + FileManager.setValue("freeBooster", LocalDateTime.now().plusDays(periodChest).toString()); + } else if(message.startsWith("[Kopf] Du hast einen ") && message.endsWith("-Kopf erhalten!")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodSkull = getTimePeriodForFreeSkull(rank); + if(periodSkull > -1) + FileManager.setValue("freeSkull", LocalDateTime.now().plusDays(periodSkull).toString()); + } + } + } + + public static String getPlayerRank(String name) { + if (Minecraft.getMinecraft().getConnection() == null) + return ""; + + NetworkPlayerInfo info = Minecraft.getMinecraft().getConnection().getPlayerInfo(name); + + if (info == null) + return ""; + + ITextComponent component = info.getDisplayName(); + if (component != null) { + String[] parts = component.getUnformattedText().split("┃"); + if (parts.length > 1) { + return parts[0].trim(); + } + } + return ""; + } + + private LocalDateTime stringToDate(String string) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy 'um' HH:mm:ss"); + return LocalDateTime.parse(string, formatter); + } + + private int getTimePeriodForFreeSkull(String rank) { + return switch (rank) { + case "Spieler", "Premium", "Ultra", "Legende" -> -1; + case "Titan" -> 14; + default -> 7; + }; + } + + private int getTimePeriodForFreeChest(String rank) { + return switch (rank) { + case "Spieler", "Premium", "Ultra", "Legende", "Titan" -> -1; + default -> 14; + }; + } +} \ No newline at end of file diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/CBTracker.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/CBTracker.java deleted file mode 100644 index ce37622..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/CBTracker.java +++ /dev/null @@ -1,74 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; - -import net.labymod.api.Laby; -import net.labymod.api.client.component.TextComponent; -import net.labymod.api.client.scoreboard.Scoreboard; -import net.labymod.api.client.scoreboard.ScoreboardTeam; -import net.labymod.api.event.client.world.WorldLoadEvent; -import tmb.randy.tmbgriefergames.core.Addon; -import java.util.Arrays; -import java.util.List; - -public class CBTracker { - - public static final List CBs = Arrays.asList( - "Lobby", - "Portal", - "Extreme", - "CBE", - "Nature", - "CB1", - "CB2", - "CB3", - "CB4", - "CB5", - "CB6", - "CB7", - "CB8", - "CB9", - "CB10", - "CB11", - "CB12", - "CB13", - "CB14", - "CB15", - "CB16", - "CB17", - "CB18", - "CB19", - "CB20", - "CB21", - "CB22", - "Lava", - "Wasser", - "Event" - ); - - public static String currentCB = ""; - - public void worldLoadEvent(WorldLoadEvent event) { - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Scoreboard scoreboard = Laby.labyAPI().minecraft().getScoreboard(); - for (ScoreboardTeam team : scoreboard.getTeams()) { - if(team.getTeamName().equals("server_value")) { - String CBString = ((TextComponent)team.getPrefix()).getText(); - if(!CBString.equals(currentCB) && CBs.contains(CBString)) { - - ItemClearTimerListener.resetItemRemover(); - currentCB = CBString; - Addon.getSharedInstance().getBridge().cbChanged(); - - if(currentCB.equals("Lobby") && Addon.getSharedInstance().configuration().getSkipHub().get()) { - VersionisedBridge.sendCommand("/portal"); - } - } - } - } - } - }, 600 - ); - } -} \ No newline at end of file diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HABK.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HABK.java index b5ac3aa..684db3e 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HABK.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HABK.java @@ -9,8 +9,8 @@ import net.minecraft.item.ItemSword; import tmb.randy.tmbgriefergames.core.Addon; -import static tmb.randy.tmbgriefergames.v1_12_2.util.ItemSaver.NBTTagStringBirthBow; -import static tmb.randy.tmbgriefergames.v1_12_2.util.ItemSaver.findHotbarSlotforItem; +import static tmb.randy.tmbgriefergames.core.util.ItemSaver.NBTTagStringBirthBow; +import static tmb.randy.tmbgriefergames.core.util.ItemSaver.findHotbarSlotforItem; public class HABK { diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HopperConnections.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HopperConnections.java new file mode 100644 index 0000000..ae8ee20 --- /dev/null +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/HopperConnections.java @@ -0,0 +1,362 @@ +package tmb.randy.tmbgriefergames.v1_12_2.util; + +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import net.labymod.api.event.client.render.world.RenderWorldEvent; +import net.labymod.api.nbt.NBTTagType; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.RayTraceResult.Type; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL11; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import tmb.randy.tmbgriefergames.core.enums.HopperState; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import tmb.randy.tmbgriefergames.core.events.HopperStateChangedEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class HopperConnections { + + private Map conntections = new HashMap<>(); + private BlockPos currentConnectingHopper; + + private record HopperConnection(BlockPos pos1, BlockPos pos2, @Nullable ItemStack stack, CBs cb) { + public String toString() { + if(stack != null) { + return cb.getName() + "." + stack.getItem().toString() + ":" + stack.getMetadata() + "." + pos1; + } + + return cb.getName() + "." + pos1; + } + } + + public void hopperStateChanged(HopperStateChangedEvent event) { + if(event.getNewState() == HopperState.NONE) { + currentConnectingHopper = null; + } + } + + public void onGuiOpenEvent() { + + if(Minecraft.getMinecraft().player.openContainer instanceof ContainerChest chestContainer) { + String invName = chestContainer.getLowerChestInventory().getName(); + if(invName.equals("§6Trichter-Mehrfach-Verbindungen")) { + for (int i = 0; i < 44; i++) { + ItemStack stack = chestContainer.getLowerChestInventory().getStackInSlot(i); + if(stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { + String firstLine = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", NBTTagType.STRING.getId()).get(0).toString(); + if(firstLine.contains("Verbunden mit:")) { + String coordinateString = firstLine.replace("§7Verbunden mit: §e", "").replace("\"", "").replace(".0", ""); + String[] coodStrings = coordinateString.split(";"); + if(coodStrings.length == 3) { + int x = Integer.parseInt(coodStrings[0]); + int y = Integer.parseInt(coodStrings[1]); + int z = Integer.parseInt(coodStrings[2]); + + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == Type.BLOCK) { + HopperConnection newConn = new HopperConnection(mop.getBlockPos(), new BlockPos(x, y, z), stack, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + + } + } + } + } + } else if(invName.equals("§6Trichter-Einstellungen")) { + ItemStack stack = chestContainer.getLowerChestInventory().getStackInSlot(16); + if(stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { + String firstLine = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", NBTTagType.STRING.getId()).get(0).toString(); + if(firstLine.contains("Weiterleiten an ")) { + String coordinateString = firstLine.replace("Weiterleiten an ", "").replace("\"", "").replace(".0", "").replace("§7", "").replace("§e", "").trim(); + String[] coodStrings = coordinateString.split(";"); + if(coodStrings.length == 3) { + int x = Integer.parseInt(coodStrings[0]); + int y = Integer.parseInt(coodStrings[1]); + int z = Integer.parseInt(coodStrings[2]); + + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == Type.BLOCK) { + + HopperConnection newConn = new HopperConnection(mop.getBlockPos(), new BlockPos(x, y, z), null, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + } + } + } + } + } + + public void messageReceived(ChatReceiveEvent event) { + String message = event.chatMessage().getPlainText(); + switch (message) { + case "[Trichter] Das Verbinden wurde aktiviert. Klicke auf den gewünschten Endpunkt.", + "[Trichter] Das Multi-Verbinden wurde aktiviert. Klicke mit dem gewünschten Item auf den gewünschten Endpunkt." -> { + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == Type.BLOCK) { + BlockPos blockPos = mop.getBlockPos(); + IBlockState state = Minecraft.getMinecraft().world.getBlockState(blockPos); + + if (state.getBlock() == Blocks.HOPPER) { + currentConnectingHopper = blockPos; + } + } + } + case "[Trichter] Der Trichter wurde erfolgreich verbunden.", + "[Trichter] Der Verbindungsmodus wurde beendet.", + "[Trichter] Der Startpunkt ist zu weit entfernt. Bitte starte erneut." -> { + if (message.equals("[Trichter] Der Trichter wurde erfolgreich verbunden.")) { + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == Type.BLOCK) { + + HopperConnection newConn = new HopperConnection(currentConnectingHopper, mop.getBlockPos(), null, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + + currentConnectingHopper = null; + } + case "[Trichter] Die Multi-Verbindung wurde hinzugefügt." -> { + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == Type.BLOCK) { + ItemStack stack = Minecraft.getMinecraft().player.inventory.getCurrentItem(); + HopperConnection newConn = new HopperConnection(currentConnectingHopper, mop.getBlockPos(), stack, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + case "[Trichter] Die Mehrfach-Verbindungen wurden aufgehoben." -> { + ArrayList removeKeys = new ArrayList<>(); + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if(mop != null && mop.typeOfHit == Type.BLOCK) { + for (String key : conntections.keySet()) { + HopperConnection connection = conntections.get(key); + if(connection.stack != null) { + if(connection.pos1.equals(mop.getBlockPos())) { + removeKeys.add(key); + } + } + } + + for (String removeKey : removeKeys) { + conntections.remove(removeKey); + } + } + } + case "[Trichter] Die Verbindung wurde aufgehoben." -> { + String removeKey = null; + RayTraceResult mop = Minecraft.getMinecraft().player.rayTrace(5, 1.0F); + if(mop != null && mop.typeOfHit == Type.BLOCK) { + for (String key : conntections.keySet()) { + HopperConnection connection = conntections.get(key); + if(connection.stack == null) { + if(connection.pos1.equals(mop.getBlockPos())) { + removeKey = key; + break; + } + } + } + + if(removeKey != null) { + conntections.remove(removeKey); + } + } + } + } + } + + public void cbChanged(CbChangedEvent event) { + currentConnectingHopper = null; + } + + public void renderWorld(RenderWorldEvent event) { + Iterator> iterator = conntections.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + HopperConnection conntection = entry.getValue(); + + double distance = conntection.pos1.distanceSq(Minecraft.getMinecraft().player.posX, Minecraft.getMinecraft().player.posY, Minecraft.getMinecraft().player.posZ); + double actualDistance = Math.sqrt(distance); + + if(actualDistance > 30) + continue; + + if (conntection.cb == CBtracker.getCurrentCB()) { + if (Minecraft.getMinecraft().world.getBlockState(conntection.pos1()).getBlock() == Blocks.HOPPER) { + drawLineBetween(conntection); + } else { + iterator.remove(); + } + } + } + + + if(currentConnectingHopper != null) { + drawSphere(currentConnectingHopper, 30.0d, event.getPartialTicks()); + } + } + + private void drawLineBetween(HopperConnection connection) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowLines().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + double x1 = connection.pos1.getX() - mc.getRenderManager().viewerPosX + 0.5; + double y1 = connection.pos1.getY() - mc.getRenderManager().viewerPosY + 0.5; + double z1 = connection.pos1.getZ() - mc.getRenderManager().viewerPosZ + 0.5; + + double x2 = connection.pos2.getX() - mc.getRenderManager().viewerPosX + 0.5; + double y2 = connection.pos2.getY() - mc.getRenderManager().viewerPosY + 0.5; + double z2 = connection.pos2.getZ() - mc.getRenderManager().viewerPosZ + 0.5; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + GlStateManager.disableBlend(); + + GL11.glLineWidth(64.0F); + GL11.glBegin(GL11.GL_LINES); + + if (connection.stack == null) { + GL11.glColor3f(0.333f, 1.0f, 1.0f); + GL11.glVertex3d(x1, y1, z1); + + GL11.glColor3f(0.0f, 0.0f, 0.667f); + GL11.glVertex3d(x2, y2, z2); + } else { + GL11.glColor3f(1.0f, 0.667f, 0.0f); + GL11.glVertex3d(x1, y1, z1); + + GL11.glColor3f(0.667f, 0.0f, 0.0f); + GL11.glVertex3d(x2, y2, z2); + } + + GL11.glEnd(); + + GlStateManager.enableDepth(); + GlStateManager.enableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + + if (connection.stack != null) { + long time = mc.world.getTotalWorldTime(); + double animationDuration = 100.0; + + double progress = (time % (int) animationDuration) / animationDuration; + + double animX = x1 + (x2 - x1) * progress; + double animY = y1 + (y2 - y1) * progress; + double animZ = z1 + (z2 - z1) * progress; + + renderItemStackAt(connection.stack, animX, animY, animZ); + } + } + + private void renderItemStackAt(ItemStack stack, double x, double y, double z) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowLines().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + GlStateManager.pushMatrix(); + + GlStateManager.translate(x, y, z); + + GlStateManager.rotate(-mc.getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(mc.getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); + + GlStateManager.disableLighting(); + + GlStateManager.scale(0.5F, 0.5F, 0.5F); + + mc.getRenderItem().renderItem(stack, TransformType.FIXED); + + GlStateManager.enableLighting(); + + GlStateManager.popMatrix(); + } + + private void drawSphere(BlockPos center, double radius, float partialTicks) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowRadius().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + double cx = center.getX() - mc.getRenderManager().viewerPosX; + double cy = center.getY() - mc.getRenderManager().viewerPosY; + double cz = center.getZ() - mc.getRenderManager().viewerPosZ; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + + GL11.glLineWidth(1.5F); + GlStateManager.color(1.0f, 0.0f, 0.0f, 1.0f); + + GL11.glTranslated(cx, cy, cz); + + GL11.glBegin(GL11.GL_LINES); + + int segments = 60; + double step = Math.PI * 2 / segments; + + for (double theta = 0; theta < Math.PI * 2; theta += step) { + for (double phi = 0; phi < Math.PI; phi += step) { + double x1 = radius * Math.sin(phi) * Math.cos(theta); + double z1 = radius * Math.sin(phi) * Math.sin(theta); + double y1 = radius * Math.cos(phi); + + double x2 = radius * Math.sin(phi + step) * Math.cos(theta); + double z2 = radius * Math.sin(phi + step) * Math.sin(theta); + double y2 = radius * Math.cos(phi + step); + + GL11.glVertex3d(x1, y1, z1); + GL11.glVertex3d(x2, y2, z2); + } + } + + for (double theta = 0; theta < Math.PI * 2; theta += step) { + for (double phi = 0; phi < Math.PI; phi += step) { + double y1 = radius * Math.sin(phi) * Math.cos(theta); + double z1 = radius * Math.sin(phi) * Math.sin(theta); + double x1 = radius * Math.cos(phi); + + double y2 = radius * Math.sin(phi + step) * Math.cos(theta); + double z2 = radius * Math.sin(phi + step) * Math.sin(theta); + double x2 = radius * Math.cos(phi + step); + + GL11.glVertex3d(x1, y1, z1); + GL11.glVertex3d(x2, y2, z2); + } + } + + GL11.glEnd(); + + GlStateManager.enableDepth(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + } + + + public void resetConnections() { + conntections = new HashMap<>(); + } +} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemClearTimerListener.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemClearTimerListener.java deleted file mode 100644 index f897027..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/ItemClearTimerListener.java +++ /dev/null @@ -1,56 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; - -import net.labymod.api.event.client.network.server.NetworkPayloadEvent; -import net.labymod.api.event.client.network.server.NetworkPayloadEvent.Side; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.TimeUnit; - -public class ItemClearTimerListener { - private static int itemRemover = -1; - private static long endTime = -1L; - - public void networkPayloadEvent(NetworkPayloadEvent event) { - if(event.side() == Side.RECEIVE) { - byte[] packetBuffer = event.getPayload().clone(); - String payloadString = new String(packetBuffer, StandardCharsets.UTF_8); - - if(payloadString.contains("countdown_create")) { - itemRemover = extractUntilValue(payloadString); - TimeUnit timeUnit = TimeUnit.SECONDS; - if(itemRemover != -1) { - endTime = System.currentTimeMillis() + timeUnit.toMillis(itemRemover); - } - } - } - } - - public static int getItemRemover() {return itemRemover;} - public static void resetItemRemover() {itemRemover = -1;} - - private int extractUntilValue(String input) { - String pattern = "until\":(\\d+)"; - - java.util.regex.Pattern regex = java.util.regex.Pattern.compile(pattern); - java.util.regex.Matcher matcher = regex.matcher(input); - - if (matcher.find()) { - String untilValueStr = matcher.group(1); - return Integer.parseInt(untilValueStr); - } - - return -1; - } - - public static String getDisplayValue() { - long remainingTime = endTime - System.currentTimeMillis(); - - if (remainingTime < 0) { - return ""; - } - - long minutes = remainingTime / (60 * 1000); - long seconds = (remainingTime % (60 * 1000)) / 1000; - - return (minutes > 0) ? String.format("%02d:%02d", minutes, seconds) : String.format("%d s", seconds); - } -} \ No newline at end of file diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/NatureBordersRenderer.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/NatureBordersRenderer.java index 9b24de1..80a897c 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/NatureBordersRenderer.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/NatureBordersRenderer.java @@ -19,12 +19,10 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.util.vector.Vector3f; import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; public class NatureBordersRenderer { - private final int offsetX = 1; - private final int offsetZ = 0; - public static double getDistanceSq(double x1, double z1, double x2, double z2) { double xs = x1 - x2; @@ -37,7 +35,7 @@ public static double getDistanceSq(double x1, double z1, double x2, double z2) private float lineBlue = 0.0F; public void onKey(KeyEvent event) { - if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getNatureSubConfig().getHotkey().get())) { + if(VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getNatureSubConfig().getHotkey().get()) && !Addon.isChatGuiOpen() && CBtracker.isNatureWorldCB()) { Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().set(!Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get()); String activeString = Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() ? I18n.getTranslation("tmbgriefergames.natureBorders.plotBordersVisible") : I18n.getTranslation("tmbgriefergames.natureBorders.plotBordersInvisible"); @@ -138,7 +136,7 @@ public boolean isPosInRenderableArea(EntityPlayerSP player, int posX, int posZ) public void onRender(RenderWorldEvent event) { - if (Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() && (CBTracker.currentCB.equals("Nature") || CBTracker.currentCB.equals("Extreme"))) + if (Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() && CBtracker.isNatureWorldCB()) { EntityPlayerSP player = Minecraft.getMinecraft().player; WorldClient world = Minecraft.getMinecraft().world; @@ -198,7 +196,7 @@ public void onRender(RenderWorldEvent event) int additionalOffsetZ = (pos.getZ() < 0 ? -1 : 0); - if ((pos.getZ() + offsetZ + additionalOffsetZ) % 42 == 0) + if ((pos.getZ() + additionalOffsetZ) % 42 == 0) { if (!Addon.getSharedInstance().configuration().getNatureSubConfig().getBorderMaxHeight().get()) { @@ -214,7 +212,7 @@ public void onRender(RenderWorldEvent event) int additionalOffsetX = (pos.getX() < 0 ? -1 : 0); - if ((pos.getX() + offsetX + additionalOffsetX) % 42 == 0) + if ((pos.getX() + 1 + additionalOffsetX) % 42 == 0) { if (!Addon.getSharedInstance().configuration().getNatureSubConfig().getBorderMaxHeight().get()) { diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlayerTracer.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlayerTracer.java deleted file mode 100644 index 11d5672..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/PlayerTracer.java +++ /dev/null @@ -1,99 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util; - -import net.labymod.api.Laby; -import net.labymod.api.client.gui.screen.key.Key; -import net.labymod.api.client.scoreboard.ScoreboardTeam; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.labymod.api.event.client.input.KeyEvent; -import net.labymod.api.event.client.input.KeyEvent.State; -import net.labymod.api.util.I18n; -import tmb.randy.tmbgriefergames.core.Addon; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -public class PlayerTracer { - public static final List CBlist = Arrays.asList("None", "CB1", "CB22", "CB21", "CB20", "CB7", "Nature", "CB2", "CB3", "CB4", "CB5", "CB6", "CB8", "CB9", "CB10", "CB11", "CB12", "CB13", "CB14", "CB15", "CB16", "CB17", "CB18", "CB19", "Extreme", "CBEvil"); - private int nextServer = 0; - private String playerName; - - public void onKey(KeyEvent event) { - if(isTracerActive() && event.state() == State.PRESS && (event.key() == Key.W || event.key() == Key.A || event.key() == Key.S || event.key() == Key.D)) { - stopTracer(); - } - } - - public void messageReceived(ChatReceiveEvent event) { - String msg = event.chatMessage().getPlainText(); - if(msg.endsWith("Kicked whilst connecting to connector: Du hast dich zu schnell wieder eingeloggt. Versuche es später erneut.") && isTracerActive()) { - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - }, - 1000 - ); - event.setCancelled(true); - } else if(isTracerActive() && ((msg.startsWith("[GrieferGames] Du wurdest automatisch auf ") && msg.endsWith(" verbunden.") || (msg.startsWith("[GrieferGames] Serverwechsel auf ") && msg.endsWith(" wurde gestartet.."))))) { - event.setCancelled(true); - } - } - public void cbChanged() { - if(CBTracker.currentCB != null && !CBTracker.currentCB.equals("Portal") && !CBTracker.currentCB.equals("Lobby") && isTracerActive()) { - if(isPlayerOnCB()) { - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.foundPlayer")); - stopTracer(); - } else if(nextServer < CBlist.size()) { - nextServer++; - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - }, - 4500 - ); - } else { - stopTracer(); - } - } - } - - public void startTracer(String name) { - if(name != null) { - playerName = name.toLowerCase(); - } - nextServer = 1; - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - - public void stopTracer() { - playerName = null; - nextServer = 0; - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.tracingEnded")); - } - - private boolean isPlayerOnCB() { - if(playerName == null) { - return false; - } - - for (ScoreboardTeam team : Laby.labyAPI().minecraft().getScoreboard().getTeams()) { - Collection members = team.getEntries(); - for (String member : members) { - if(member.equalsIgnoreCase(playerName)) { - return true; - } - } - } - - return false; - } - - public boolean isTracerActive() { - return (nextServer != 0); - } -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VABK.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VABK.java index 124c5af..90bc749 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VABK.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VABK.java @@ -37,7 +37,7 @@ public void onTickEvent(GameTickEvent event) { } public void onKeyEvent(KeyEvent event) { - if(event.state() == State.PRESS && VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getSwordsSubConfig().getVABKhotkey().get()) && !VersionisedBridge.isChatGuiOpen()) { + if(event.state() == State.PRESS && VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getSwordsSubConfig().getVABKhotkey().get()) && !VersionisedBridge.getSharedInstance().isChatGuiOpen()) { toggleActive(); } } diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VersionisedBridge.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VersionisedBridge.java index 7ded56c..565392a 100644 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VersionisedBridge.java +++ b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/VersionisedBridge.java @@ -6,19 +6,17 @@ import net.labymod.api.event.Phase; import net.labymod.api.event.Priority; import net.labymod.api.event.Subscribe; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; import net.labymod.api.event.client.chat.ChatReceiveEvent; import net.labymod.api.event.client.input.KeyEvent; import net.labymod.api.event.client.input.MouseButtonEvent; import net.labymod.api.event.client.lifecycle.GameTickEvent; -import net.labymod.api.event.client.network.server.NetworkPayloadEvent; import net.labymod.api.event.client.render.overlay.IngameOverlayElementRenderEvent; import net.labymod.api.event.client.render.overlay.IngameOverlayElementRenderEvent.OverlayElementType; import net.labymod.api.event.client.render.world.RenderWorldEvent; import net.labymod.api.event.client.world.ItemStackTooltipEvent; -import net.labymod.api.event.client.world.WorldLoadEvent; import net.labymod.api.models.Implements; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiCrafting; @@ -26,42 +24,25 @@ import org.lwjgl.input.Keyboard; import tmb.randy.tmbgriefergames.core.Addon; import tmb.randy.tmbgriefergames.core.IBridge; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import tmb.randy.tmbgriefergames.core.events.HopperStateChangedEvent; import tmb.randy.tmbgriefergames.v1_12_2.util.AutoCrafter.AutoCrafterV1; import tmb.randy.tmbgriefergames.v1_12_2.util.AutoCrafter.AutoCrafterV2; import tmb.randy.tmbgriefergames.v1_12_2.util.AutoCrafter.AutoCrafterV3; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.ChatCleaner; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.CooldownNotifier; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.EmptyLinesRemover; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.MsgTabs; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.NewsBlocker; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.PaymentValidator; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.StreamerMute; -import tmb.randy.tmbgriefergames.v1_12_2.util.chat.TypeCorrection; import tmb.randy.tmbgriefergames.v1_12_2.util.click.ClickManager; import javax.inject.Singleton; @Singleton @Implements(IBridge.class) public class VersionisedBridge implements IBridge { - private final ChatCleaner chatCleaner = new ChatCleaner(); - private final CooldownNotifier cooldownNotifier = new CooldownNotifier(); - private final EmptyLinesRemover emptyLinesRemover = new EmptyLinesRemover(); - private final NewsBlocker newsBlocker = new NewsBlocker(); - private final MsgTabs msgTabs = new MsgTabs(); - private final PaymentValidator paymentValidator = new PaymentValidator(); - private final StreamerMute streamerMute = new StreamerMute(); - private final TypeCorrection typeCorrection = new TypeCorrection(); - private final PlotSwitch plotSwitch = new PlotSwitch(); - private final ItemSaver itemSaver = new ItemSaver(); + private static VersionisedBridge sharedInstance; + private final TooltipExtension tooltipExtension = new TooltipExtension(); - private final PlayerTracer playerTracer = new PlayerTracer(); - private final CBTracker cbTracker = new CBTracker(); - private final ItemClearTimerListener itemClearTimerListener = new ItemClearTimerListener(); private final AutoHopper autoHopper = new AutoHopper(); private final FlyTimer flyTimer = new FlyTimer(); private final ItemShifter itemShifter = new ItemShifter(); private final NatureBordersRenderer natureBordersRenderer = new NatureBordersRenderer(); - private final AccountUnity accountUnity = new AccountUnity(); private final AutoComp autoComp = new AutoComp(); private final AutoCrafterV1 autoCrafterV1 = new AutoCrafterV1(); private final AutoCrafterV2 autoCrafterV2 = new AutoCrafterV2(); @@ -70,44 +51,39 @@ public class VersionisedBridge implements IBridge { private final Auswurf auswurf = new Auswurf(); private final HABK habk = new HABK(); private final VABK vabk = new VABK(); + private final HopperConnections hopperConnections = new HopperConnections(); + private final AutoLoot autoLoot = new AutoLoot(); + private GuiScreen lastGui; private static final int commandCountdownLimit = 80; private static int commandCountdown = 0; - @Subscribe - public void worldLoadEvent(WorldLoadEvent event) { - // No checking for isGG as the function to auto skip the lobby/hub wouldn't work as the server adress is set too late. - cbTracker.worldLoadEvent(event); + public VersionisedBridge() { + sharedInstance = this; } @Subscribe - public void messageReceived(ChatReceiveEvent event) { - if(!Addon.isGG()) - return; + public void cbChanged(CbChangedEvent event) { + autoComp.stopComp(); + autoCrafterV2.stopCrafter(); + autoCrafterV3.stop(); + hopperConnections.cbChanged(event); - chatCleaner.messageReceived(event); - emptyLinesRemover.messageReceived(event); - newsBlocker.messageReceived(event); - paymentValidator.messageReceived(event); - streamerMute.messageReceived(event); - plotSwitch.messageReceived(event); - playerTracer.messageReceived(event); - autoHopper.messageReceived(event); - accountUnity.messageReceived(event); - msgTabs.chatMessageReceived(event); - autoCrafterV3.chatMessageReceived(event); + if(event.CB() == CBs.LOBBY && Addon.getSharedInstance().configuration().getSkipHub().get()) { + VersionisedBridge.sendCommand("/portal"); + } } @Subscribe - public void messageSend(ChatMessageSendEvent event) { + public void messageReceived(ChatReceiveEvent event) { if(!Addon.isGG()) return; - msgTabs.messageSend(event); - cooldownNotifier.messageReceived(event); - typeCorrection.messageSend(event); - plotSwitch.messageSend(event); + autoHopper.messageReceived(event); + autoCrafterV3.chatMessageReceived(event); + hopperConnections.messageReceived(event); + autoLoot.chatMessageReceived(event); } @Subscribe (Priority.FIRST) @@ -115,7 +91,6 @@ public void mouseInput(MouseButtonEvent event) { if(!Addon.isGG()) return; - itemSaver.mouseButtonEvent(event); autoHopper.mouseInput(event); flyTimer.onMouseButtonEvent(event); habk.onMouseButtonEvent(event); @@ -156,7 +131,6 @@ public void tick(GameTickEvent event) { autoCrafterV1.onTickEvent(event); autoHopper.tick(event); itemShifter.tick(event); - plotSwitch.tick(event); autoCrafterV2.onTickEvent(event); autoDecomp.onTickEvent(event); auswurf.onTickEvent(event); @@ -166,13 +140,16 @@ public void tick(GameTickEvent event) { commandCountdown(); } + @Subscribe + public void hopperStateChanged(HopperStateChangedEvent event) { + hopperConnections.hopperStateChanged(event); + } + @Subscribe public void keyDown(KeyEvent event) { if(!Addon.isGG()) return; - plotSwitch.keyDown(event); - playerTracer.onKey(event); itemShifter.onKey(event); natureBordersRenderer.onKey(event); autoComp.onKeyEvent(event); @@ -190,6 +167,7 @@ public void onRenderEvent(RenderWorldEvent event) { return; natureBordersRenderer.onRender(event); + hopperConnections.renderWorld(event); } @Subscribe @@ -201,35 +179,13 @@ public void renderTooltip(ItemStackTooltipEvent event) { flyTimer.onTooltipEvent(event); } - @Override - public void startPlayerTracer(String name) { - if(!Addon.isGG()) - return; - - playerTracer.startTracer(name); - } - public void onGuiOpenEvent(GuiScreen screen) { ClickManager.getSharedInstance().clearAllQueues(); if(screen == null) { autoComp.stopComp(); itemShifter.stopShifting(); } - } - - @Subscribe - public void networkPayloadEvent(NetworkPayloadEvent event) { - if(!Addon.isGG()) - return; - - itemClearTimerListener.networkPayloadEvent(event); - } - - @Override - public void cbChanged() { - playerTracer.cbChanged(); - autoComp.stopComp(); - autoCrafterV2.stopCrafter(); + hopperConnections.onGuiOpenEvent(); } @Override @@ -242,10 +198,6 @@ public String getWidgetString() { return flyTimer.getWidgetString(); } - @Override - public String getItemRemoverValue() { - return ItemClearTimerListener.getDisplayValue(); - } @Override public void startNewAutocrafter() { @@ -274,14 +226,15 @@ private static void commandCountdown() { public static boolean canSendCommand() { return commandCountdown <= 0; } public static boolean sendCommand(String command) { if(canSendCommand()) { - Minecraft.getMinecraft().player.sendChatMessage(command); + Laby.references().chatExecutor().chat(command); commandCountdown = commandCountdownLimit; return true; } return false; } - public static boolean isChatGuiOpen() { + @Override + public boolean isChatGuiOpen() { for (IngameOverlayActivity activity : Laby.labyAPI().ingameOverlay().getActivities()) { if(activity.isAcceptingInput()) { return true; @@ -297,7 +250,8 @@ public static boolean isGUIOpen() { return currentScreen instanceof GuiChest || currentScreen instanceof GuiInventory || currentScreen instanceof GuiCrafting; } - public static boolean allKeysPressed(Key[] keys) { + @Override + public boolean allKeysPressed(Key[] keys) { if(keys.length == 0) return false; @@ -315,4 +269,16 @@ public static boolean allKeysPressed(Key[] keys) { public void startAuswurf() { auswurf.startAuswurf(); } + + @Override + public void openChat() { + Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); + } + + public static VersionisedBridge getSharedInstance() {return sharedInstance;} + + @Override + public void resetLines() { + hopperConnections.resetConnections(); + } } diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/ChatCleaner.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/ChatCleaner.java deleted file mode 100644 index 8c47478..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/ChatCleaner.java +++ /dev/null @@ -1,57 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import java.util.Arrays; -import java.util.List; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import tmb.randy.tmbgriefergames.core.Addon; -import tmb.randy.tmbgriefergames.core.config.Configuration; - -public class ChatCleaner { - - private final List cleanupMessages = Arrays.asList( - "[GrieferGames] Download: https://mysterymod.net/download/", - "[GrieferGames] Wir sind optimiert für MysteryMod. Lade Dir gerne die Mod runter!", - "[GrieferGames] Du bist im Portalraum. Wähle deinen Citybuild aus.", - "[Switcher] Lade Daten herunter!", - "[Switcher] Daten heruntergeladen!", - "[GrieferGames] Deine Daten wurden vollständig heruntergeladen.", - "[GrieferGames] Bitte warte 12 Sekunden zwischen jedem Teleport.", - "[GGAuth] Du wurdest erfolgreich verifiziert.", - "Already connecting to this server!", - "[GrieferGames] Du wurdest zum Grundstück teleportiert.", - "[GrieferGames] Deine Tageszeit wurde vom Grundstück aktualisiert.", - "[GrieferGames] Deine Tageszeit wurde wiederhergestellt.", - "[GrieferGames] Bitte warte 15 Sekunden zwischen jedem Join-Versuch.", - "------------ [ Server-Status ] ------------", - "Ergriffene Maßnahmen:", - "Versuche in den Portalraum zu verbinden." - ); - - public void messageReceived(ChatReceiveEvent event) { - final Configuration configuration = Addon.getSharedInstance().configuration(); - String message = event.chatMessage().getPlainText(); - - if(message.equals("[Rezepte] Du hast nicht genug Material, um dieses Rezept herzustellen.")) { - event.setCancelled(true); - } - - - if(!configuration.getChatConfig().getCleanChat().get()) - return; - - - // "No friendhip requests" messages is sent before the GrieferGames Server Name is set. So it has to be handles before checking for GG. - if(message.equals("[Freunde] Du hast aktuell keine Freundschaftsanfragen.")) { - event.setCancelled(true); - } - - - for (String str : cleanupMessages) { - if(str.equals(message)) { - event.setCancelled(true); - break; - } - } - - } -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/EmptyLinesRemover.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/EmptyLinesRemover.java deleted file mode 100644 index 102a8ee..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/EmptyLinesRemover.java +++ /dev/null @@ -1,33 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class EmptyLinesRemover { - - public void messageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getHideEmptyLines().get()) - return; - - String message = event.chatMessage().getPlainText(); - - if(isStringEmpty(message) || message.equals("»") || message.length() == 0) { - event.setCancelled(true); - } - } - - - public static boolean isStringEmpty(String text) { - if (text == null || text.isEmpty()) { - return false; - } - - for (int i = 0; i < text.length(); i++) { - if (!Character.isWhitespace(text.charAt(i))) { - return false; - } - } - - return true; - } -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/MsgTabs.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/MsgTabs.java deleted file mode 100644 index b86b204..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/MsgTabs.java +++ /dev/null @@ -1,177 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.Laby; -import net.labymod.api.client.chat.filter.ChatFilter; -import net.labymod.api.configuration.labymod.chat.ChatTab; -import net.labymod.api.configuration.labymod.chat.ChatWindow; -import net.labymod.api.configuration.labymod.chat.config.RootChatTabConfig; -import net.labymod.api.configuration.labymod.chat.config.RootChatTabConfig.Type; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiChat; -import tmb.randy.tmbgriefergames.core.Addon; -import tmb.randy.tmbgriefergames.v1_12_2.util.VersionisedBridge; - -public class MsgTabs { - - private static String currentChatPartner = null; - - public void chatMessageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get()) - return; - - currentChatPartner = getChatPartnerName(event.chatMessage().getPlainText()); - if(currentChatPartner != null) { - getTabForName(event.chatMessage().getPlainText()); - - if(!VersionisedBridge.isChatGuiOpen() && event.chatMessage().getPlainText().contains("[mir -> ")) { - reloadChat(); - Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); - } - } - } - - public void messageSend(ChatMessageSendEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get() || event.getMessage().startsWith("/msg") || event.getMessage().startsWith("7msg") || event.getMessage().startsWith("(msg")) - return; - - ChatWindow mainWindow = getChatWindow(); - if(mainWindow != null) { - if(mainWindow.getActiveTab().getName().startsWith("➥ ")) { - String currentReciever = mainWindow.getActiveTab().getName().replace("➥ ", ""); - if(currentReciever.length() >= 3) { - String[] messageSplit = event.getMessage().split(" "); - if(messageSplit[0].startsWith("/") && !messageSplit[0].equalsIgnoreCase("/msg") && !messageSplit[0].equalsIgnoreCase("7msg") && !messageSplit[0].equalsIgnoreCase("(msg") - && !messageSplit[0].equalsIgnoreCase("/r") && !messageSplit[0].equalsIgnoreCase("7r") && !messageSplit[0].equalsIgnoreCase("(r")) { - return; - } - if(messageSplit[0].equalsIgnoreCase("/r") || messageSplit[0].equalsIgnoreCase("7r") || messageSplit[0].equalsIgnoreCase("(r")) { - int firstSpaceIndex = event.getMessage().indexOf(" "); - if (firstSpaceIndex != -1) { - if(currentReciever.equals(currentChatPartner)) { - event.changeMessage("/r " + event.getMessage().substring(firstSpaceIndex + 1)); - } else { - event.changeMessage(mainWindow.getActiveTab().getName().replace("➥", "/msg") + " " + event.getMessage().substring(firstSpaceIndex + 1)); - } - } - } else if(!(messageSplit[0].equalsIgnoreCase("/msg") || messageSplit[0].equalsIgnoreCase("7msg") || messageSplit[0].equalsIgnoreCase("(msg"))) { - if(currentReciever.equals(currentChatPartner)) { - event.changeMessage("/r " + event.getMessage()); - } else { - event.changeMessage(mainWindow.getActiveTab().getName().replace("➥", "/msg") + " " + event.getMessage()); - } - } - } - } - } - } - - public ChatTab createTabForPlayer(String message) { - ChatWindow mainWindow = getChatWindow(); - if(mainWindow != null) { - - String name = getChatPartnerName(message); - String rank = getChatPartnerRank(message); - - String incomingFilter = "[" + rank + " ┃ " + name + " -> mir]"; - String outgoingFilter = "[mir -> " + rank + " ┃ " + name + "]"; - - RootChatTabConfig tabConfig = new RootChatTabConfig(Type.CUSTOM, "➥ " + name); - ChatTab tab = mainWindow.initializeTab(tabConfig); - - ChatFilter filterOutgoingMsg = new ChatFilter(); - filterOutgoingMsg.name().set("outgoing /msg"); - filterOutgoingMsg.getIncludedTags().add(outgoingFilter); - filterOutgoingMsg.shouldPlaySound().set(false); - filterOutgoingMsg.caseSensitive().set(true); - - ChatFilter filterIncomingMsg = new ChatFilter(); - filterIncomingMsg.name().set("incoming /msg"); - filterIncomingMsg.getIncludedTags().add(incomingFilter); - filterIncomingMsg.shouldPlaySound().set(true); - filterIncomingMsg.caseSensitive().set(true); - - tab.config().filters().get().add(filterOutgoingMsg); - tab.config().filters().get().add(filterIncomingMsg); - - return tab; - } - return null; - } - - private ChatTab getTabForName(String message) { - String chatPartner = getChatPartnerName(message); - ChatTab output = null; - - ChatWindow mainWindow = getChatWindow(); - if(mainWindow != null) { - for (ChatTab tab : mainWindow.getTabs()) { - if(tab.getName().equals("➥ " + chatPartner)) { - output = tab; - break; - } - } - - if(output == null) { - output = createTabForPlayer(message); - } - } - - return output; - } - - private ChatWindow getChatWindow() { - if(Addon.getSharedInstance().configuration().getChatConfig().getMsgTabMode().get()) { - for (ChatWindow window : Laby.references().advancedChatController().getWindows()) { - - if (window.isMainWindow()) { - return window; - } - } - } - return null; - } - - private String getChatPartnerName(String message) { - if(message.contains("[mir ->") || message.contains("-> mir]")) { - String[] split = message.split(" "); - if(split.length >= 5) { - boolean returnNext = false; - for (String string : split) { - if(returnNext) - return string.replace("[", "").replace("]", ""); - else if(string.equals("┃")) - returnNext = true; - } - } - } - - return null; - } - - private String getChatPartnerRank(String message) { - if(message.contains("[mir ->") || message.contains("-> mir]")) { - String[] split = message.split(" "); - String previous = ""; - - for (String string : split) { - if(string.equals("┃")) { - return previous.replace("[", "").replace("]", ""); - } else { - previous = string; - } - } - } - - return null; - } - - public static void resetCurrentChatPartner() { - currentChatPartner = null; - } - - private void reloadChat() { - Laby.references().chatAccessor().reload(); - } -} \ No newline at end of file diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/NewsBlocker.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/NewsBlocker.java deleted file mode 100644 index b2ff319..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/NewsBlocker.java +++ /dev/null @@ -1,28 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class NewsBlocker { - - private boolean isBlocking = false; - public void messageReceived(ChatReceiveEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getHideNews().get()) - return; - - String message = event.chatMessage().getPlainText(); - - if(isBlocking) { - event.setCancelled(true); - } - - if(message.equals("------------ [ News ] ------------")) { - isBlocking = !isBlocking; - } - - if(isBlocking) { - event.setCancelled(true); - } - } - -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/PaymentValidator.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/PaymentValidator.java deleted file mode 100644 index 3429f8e..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/PaymentValidator.java +++ /dev/null @@ -1,31 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.client.component.Component; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.labymod.api.util.I18n; -import tmb.randy.tmbgriefergames.core.Addon; - -public class PaymentValidator { - - private final static String FAKEMONEY_PREFIX = "§4§l[§c§l✖ " + I18n.translate("autocraft.chat.fakeMoney") + "§4§l]"; - final String VALID_PREFIX = "§2§l[§a§l✔ " + I18n.translate("tmbgriefergames.chat.realMoney") + "§2§l]"; - - public void messageReceived(ChatReceiveEvent event) { - if(!Addon.isGG() || !Addon.getSharedInstance().configuration().getChatConfig().getAntiFakeMoney().get()) { - return; - } - - String message = event.chatMessage().getPlainText(); - - if(message.contains("hat dir") && message.contains("gegeben")) { - if(message.matches(".* hat dir \\$\\d{1,3}(?:,\\d{3})*(\\.\\d{2})? gegeben\\.")) { - if(!message.contains("[Greeting]") && !message.contains("»")) { - event.setMessage(event.message().append(Component.text(VALID_PREFIX))); - return; - } - } - - event.setMessage(event.message().append(Component.text(FAKEMONEY_PREFIX))); - } - } -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/StreamerMute.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/StreamerMute.java deleted file mode 100644 index 18d645f..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/StreamerMute.java +++ /dev/null @@ -1,15 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class StreamerMute { - - public void messageReceived(ChatReceiveEvent event) { - String message = event.chatMessage().getPlainText(); - - if(message.startsWith("[Streamer]") && Addon.getSharedInstance().configuration().getChatConfig().getMuteStreamer().get()) { - event.setCancelled(true); - } - } -} diff --git a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/TypeCorrection.java b/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/TypeCorrection.java deleted file mode 100644 index 1a55745..0000000 --- a/game-runner/src/v1_12_2/java/tmb/randy/tmbgriefergames/v1_12_2/util/chat/TypeCorrection.java +++ /dev/null @@ -1,125 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_12_2.util.chat; - -import java.util.HashMap; -import java.util.Map; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class TypeCorrection { - - private final Map replacements = new HashMap<>() { - { - put("7r", "/r"); - put("(r", "/r"); - put("t/r", "/r"); - - put("7ec", "/ec"); - put("(ec", "/ec"); - put("t/ec", "/ec"); - - put("7msg", "/msg"); - put("(msg", "/msg"); - put("t/msg", "/msg"); - - put("7pay", "/pay"); - put("(pay", "/pay"); - put("t/pay", "/pay"); - - put("7bank", "/bank"); - put("(bank", "/bank"); - put("t/bank", "/bank"); - - put("7craft", "/craft"); - put("(craft", "/craft"); - put("t/craft", "/craft"); - - put("7invsee", "/invsee"); - put("(invsee", "/invsee"); - put("t/invsee", "/invsee"); - - put("7booster", "/booster"); - put("(booster", "/booster"); - put("t/booster", "/booster"); - - put("7cooldowns", "/cooldowns"); - put("(cooldowns", "/cooldowns"); - put("t/cooldowns", "/cooldowns"); - - put("7p h ", "/p h "); - put("(p h ", "/p h "); - put("t/p h ", "/p h "); - - - put("7tpahere", "/tpahere"); - put("(tpahere", "/tpahere"); - put("t/tpahere", "/tpahere"); - - put("/p t ", "/p trust "); - - put("/cb1", "/switch cb1"); - put("/cb2", "/switch cb2"); - put("/cb3", "/switch cb3"); - put("/cb4", "/switch cb4"); - put("/cb5", "/switch cb5"); - put("/cb6", "/switch cb6"); - put("/cb7", "/switch cb7"); - put("/cb8", "/switch cb8"); - put("/cb9", "/switch cb9"); - put("/cb10", "/switch cb10"); - put("/cb11", "/switch cb11"); - put("/cb12", "/switch cb12"); - put("/cb13", "/switch cb13"); - put("/cb14", "/switch cb14"); - put("/cb15", "/switch cb15"); - put("/cb16", "/switch cb16"); - put("/cb17", "/switch cb17"); - put("/cb18", "/switch cb18"); - put("/cb19", "/switch cb19"); - put("/cb20", "/switch cb20"); - put("/cb21", "/switch cb21"); - put("/cb22", "/switch cb22"); - put("/nature", "/switch nature"); - put("/evil", "/switch cbevil"); - put("/extreme", "/switch extreme"); - } - }; - - public void messageSend(ChatMessageSendEvent event) { - if((!Addon.getSharedInstance().configuration().getChatConfig().getTypeCorrection().get() && !Addon.getSharedInstance().configuration().getChatConfig().getMessageSplit().get())) - return; - - String message = event.getMessage(); - - // Type correction - if(Addon.getSharedInstance().configuration().getChatConfig().getTypeCorrection().get()) { - for (Map.Entry entry : replacements.entrySet()) { - message = message.replace(entry.getKey(), entry.getValue()); - } - } - - // Message split - if(message.length() > 100 && (message.toLowerCase().startsWith("/msg ") || message.toLowerCase().startsWith("/r ")) && Addon.getSharedInstance().configuration().getChatConfig().getMessageSplit().get()) { - String[] messageArray; - - messageArray = message.split("(?<=\\G.{" + 97 + "})"); - - for (int i = 1; i < messageArray.length; i++) { - messageArray[i] = "/r " + messageArray[i]; - } - - for (String s : messageArray) { - Addon.getSharedInstance().sendMessage(s); - } - - message = ""; - event.setCancelled(true); - } - - if(!event.isCancelled()) { - event.changeMessage(message); - } else { - event.changeMessage(""); - } - } - -} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AccountUnity.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AccountUnity.java deleted file mode 100644 index 73c9d09..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AccountUnity.java +++ /dev/null @@ -1,18 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; - -import net.labymod.api.Laby; -import net.labymod.api.account.Account; -import net.labymod.api.event.client.chat.ChatReceiveEvent; - -public class AccountUnity { - - public void messageReceived(ChatReceiveEvent event) { - for (Account account : Laby.references().accountService().getAccounts()) { - String name = account.getUsername(); - if(event.chatMessage().getPlainText().endsWith(name + " möchte sich zu dir teleportieren.") || event.chatMessage().getPlainText().endsWith(name + " möchte, dass du dich zu der Person teleportierst.")) { - VersionisedBridge.sendCommand("/tpaccept"); - - } - } - } -} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoComp.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoComp.java index e4efc54..e936c94 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoComp.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoComp.java @@ -6,10 +6,6 @@ import net.labymod.api.event.client.lifecycle.GameTickEvent; import net.labymod.api.util.I18n; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.inventory.GuiChest; -import net.minecraft.client.gui.inventory.GuiCrafting; -import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.inventory.Container; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; @@ -53,7 +49,7 @@ public void onKeyEvent(KeyEvent event) { } } } else { - if (VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoCompHotkey().get())) { + if (VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoCompHotkey().get())) { startComp(); } } @@ -235,14 +231,6 @@ private void click(int slot) { this.toSend.clear(); } - private boolean isGUIOpen() { - GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen; - - // Check if a GUI is open and if it is a chest GUI - return currentScreen instanceof GuiChest || currentScreen instanceof GuiInventory - || currentScreen instanceof GuiCrafting; - } - public boolean isCompActive() { return compActive; } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV1.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV1.java index 6acd948..3c5f563 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV1.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV1.java @@ -14,7 +14,6 @@ import org.apache.commons.lang3.ArrayUtils; import tmb.randy.tmbgriefergames.core.Addon; import tmb.randy.tmbgriefergames.core.enums.QueueType; -import tmb.randy.tmbgriefergames.v1_8_9.util.Simulator; import tmb.randy.tmbgriefergames.v1_8_9.util.click.Click; import tmb.randy.tmbgriefergames.v1_8_9.util.click.ClickManager; import java.util.HashMap; @@ -23,12 +22,12 @@ public class AutoCrafterV1 { private ContainerWorkbench inv; - private int[] stored; - private int[] meta; - private String[] names; + private final int[] stored; + private final int[] meta; + private final String[] names; private String output; private Item outputItem; - private LinkedList toSend; + private final LinkedList toSend; private Simulator simulator; private boolean endlessModeToggle = false; @@ -73,7 +72,7 @@ public void storeCrafting() { return; } - ItemStack result = (this.inv.inventorySlots.get(0)).getStack(); + ItemStack result = (this.inv.inventorySlots.getFirst()).getStack(); for (int i = 0; i < 9; i++) { if (this.inv.inventorySlots.get(i+1) != null) @@ -197,7 +196,7 @@ else if (stored[i] == 0) private void depositHeld() { for (int i = 10; i < 46; i++) { - if (!((Slot)this.inv.inventorySlots.get(i)).getHasStack()) + if (!(this.inv.inventorySlots.get(i)).getHasStack()) { Minecraft.getMinecraft().playerController.windowClick(this.inv.windowId, i, 0, 0, Minecraft.getMinecraft().thePlayer); return; @@ -206,7 +205,7 @@ private void depositHeld() { for (int i = 1; i < 10; i++) { - if (!((Slot)this.inv.inventorySlots.get(i)).getHasStack()) + if (!(this.inv.inventorySlots.get(i)).getHasStack()) { Minecraft.getMinecraft().playerController.windowClick(this.inv.windowId, i, 0, 0, Minecraft.getMinecraft().thePlayer); @@ -229,15 +228,11 @@ private void depositHeld() { private boolean checkMaterials() { - HashMap needed = new HashMap(); + HashMap needed = new HashMap<>(); for (int i = 0; i < 9; i++) { - if (this.stored[i] != 0) { - Integer count = needed.get(stored[i] + ":" + meta[i]); - if (count == null) - needed.put(stored[i] + ":" + meta[i], 1); - else - needed.put(stored[i] + ":" + meta[i], count + 1); - } + if (this.stored[i] != 0) + needed.merge(stored[i] + ":" + meta[i], 1, Integer::sum); + } for (int i = 1; i <= 45; i++) { this.inv = (ContainerWorkbench)Minecraft.getMinecraft().thePlayer.openContainer; @@ -257,11 +252,11 @@ private boolean checkMaterials() else needed.put(item, count - stack.stackSize); } - if (needed.size() == 0) + if (needed.isEmpty()) break; } - if (needed.size() > 0) { + if (!needed.isEmpty()) { String item = needed.keySet().iterator().next(); ItemStack displayStack = new ItemStack(Item.getItemById(Integer.parseInt(item.split(":")[0]))); displayStack.setItemDamage(Integer.parseInt(item.split(":")[1])); diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV3.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV3.java index c652741..f956d2e 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV3.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/AutoCrafterV3.java @@ -164,14 +164,18 @@ public void onTick(GameTickEvent event) { } public void start() { - active = true; - resetVars(); - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3started")); + if(!active) { + active = true; + resetVars(); + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3started")); + } } public void stop() { - active = false; - resetVars(); - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3stopped")); + if(active) { + active = false; + resetVars(); + Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoCrafter.V3stopped")); + } } public void toggle() { if(active) @@ -619,9 +623,7 @@ else if (step < 6) else if(step > 6) decreaseStep(); } - case FINISHED -> { - closeChest(); - } + case FINISHED -> closeChest(); } } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/Simulator.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/Simulator.java similarity index 93% rename from game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/Simulator.java rename to game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/Simulator.java index e6dfbd3..508a659 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/Simulator.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoCrafter/Simulator.java @@ -1,4 +1,4 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; +package tmb.randy.tmbgriefergames.v1_8_9.util.AutoCrafter; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; @@ -6,8 +6,8 @@ public class Simulator { - private int size; - private ItemStack[] slots; + private final int size; + private final ItemStack[] slots; private ItemStack held; public Simulator(List inventorySlots, int size) diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoDecomp.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoDecomp.java index 6e7299e..b49fb04 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoDecomp.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoDecomp.java @@ -26,7 +26,7 @@ public class AutoDecomp { public void onKeyEvent(KeyEvent event) { if(Key.ESCAPE.isPressed() && autoDecompActive) { stopDecomp(); - } else if (VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoDecompHotkey().get())) { + } else if (VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getAutoCrafterConfig().getAutoDecompHotkey().get())) { startDecomp(); Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.autoDecomp.started")); } @@ -230,23 +230,15 @@ private int getBestSlotForCompStep(int step) { } private String getRomanianNumberForInt(int number) { - switch (number) { - case 1: - return "I"; - case 2: - return "II"; - case 3: - return "III"; - case 4: - return "IV"; - case 5: - return "V"; - case 6: - return "VI"; - case 7: - return "VII"; - default: - return ""; - } + return switch (number) { + case 1 -> "I"; + case 2 -> "II"; + case 3 -> "III"; + case 4 -> "IV"; + case 5 -> "V"; + case 6 -> "VI"; + case 7 -> "VII"; + default -> ""; + }; } } \ No newline at end of file diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoHopper.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoHopper.java index bb2ebd8..7982dfc 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoHopper.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoHopper.java @@ -1,6 +1,5 @@ package tmb.randy.tmbgriefergames.v1_8_9.util; -import net.labymod.api.Laby; import net.labymod.api.event.client.chat.ChatReceiveEvent; import net.labymod.api.event.client.input.MouseButtonEvent; import net.labymod.api.event.client.input.MouseButtonEvent.Action; @@ -13,9 +12,7 @@ import net.minecraft.inventory.Container; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.Slot; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraft.util.BlockPos; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition.MovingObjectType; @@ -178,17 +175,5 @@ private boolean isLookingAtHopper() { } return false; } - - private Item getItemForSlot72(ContainerChest chest) { - if(chest.getSlot(72) == null) { - return Item.getItemFromBlock(Block.getBlockById(166)); - } else if(chest.getSlot(72).getStack() == null) { - return Item.getItemFromBlock(Block.getBlockById(166)); - } else if(chest.getSlot(72).getStack().getItem() == null) { - return Item.getItemFromBlock(Block.getBlockById(166)); - } - - return chest.getSlot(72).getStack().getItem(); - } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoLoot.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoLoot.java new file mode 100644 index 0000000..cc728eb --- /dev/null +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/AutoLoot.java @@ -0,0 +1,150 @@ +package tmb.randy.tmbgriefergames.v1_8_9.util; + +import net.labymod.api.Laby; +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import net.labymod.api.util.I18n; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.util.IChatComponent; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; +import tmb.randy.tmbgriefergames.core.FileManager; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class AutoLoot { + + public void chatMessageReceived(ChatReceiveEvent event) { + String message = event.chatMessage().getPlainText(); + + if(Addon.getSharedInstance().configuration().getAutoLoot().get()) { + if(CBtracker.getCurrentCB() != CBs.NONE && message.equals("[Switcher] Daten heruntergeladen!") && !Addon.getSharedInstance().getPlayerTracer().isTracerActive()) { + + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodSkull = getTimePeriodForFreeSkull(rank); + int periodChest = getTimePeriodForFreeChest(rank); + + if(periodChest == -1 && periodSkull == -1) + return; + + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + if(!Addon.isGG()) + return; + + if(CBtracker.isPlotworldCB() && Minecraft.getMinecraft().thePlayer != null && Minecraft.getMinecraft().theWorld != null) { + + Object freeBooster = FileManager.getValue("freeBooster"); + String freeBoosterString = freeBooster instanceof String ? (String) freeBooster : ""; + + Object freeChest = FileManager.getValue("freeChest"); + String freeChestString = freeChest instanceof String ? (String) freeChest : ""; + + Object freeSkull = FileManager.getValue("freeSkull"); + String freeSkullString = freeSkull instanceof String ? (String) freeSkull : ""; + + if(periodChest > -1) { + if(!freeBoosterString.isEmpty()) { + LocalDateTime freeBoosterDate = LocalDateTime.parse(freeBoosterString); + + if(freeBoosterDate.isBefore(LocalDateTime.now())) { + Minecraft.getMinecraft().thePlayer.sendChatMessage("/grieferboost"); + } + } else { + Minecraft.getMinecraft().thePlayer.sendChatMessage("/grieferboost"); + } + + if(!freeChestString.isEmpty()) { + LocalDateTime freeChestDate = LocalDateTime.parse(freeChestString); + + if(freeChestDate.isBefore(LocalDateTime.now())) { + Minecraft.getMinecraft().thePlayer.sendChatMessage("/freekiste"); + } + } else { + Minecraft.getMinecraft().thePlayer.sendChatMessage("/freekiste"); + } + } + + + if(!freeSkullString.isEmpty() && periodSkull > -1) { + LocalDateTime freeSkullDate = LocalDateTime.parse(freeSkullString); + + if(freeSkullDate.isBefore(LocalDateTime.now())) { + Addon.getSharedInstance().displayNotification(I18n.translate("tmbgriefergames.autoLoot.skullAvailable")); + } + } + } + } + }, 5000 + ); + } + + if(message.startsWith("[CaseOpening] Du kannst erst am ") && message.endsWith(" wieder Free-Kisten abholen.")) { + event.setCancelled(true); + String isolatedDate = message.replace("[CaseOpening] Du kannst erst am ", "").replace(" wieder Free-Kisten abholen.", ""); + FileManager.setValue("freeChest", stringToDate(isolatedDate).toString()); + } else if(message.startsWith("Du kannst erst am ") && message.endsWith(" wieder einen Free-Booster abholen.")) { + event.setCancelled(true); + String isolatedDate = message.replace("Du kannst erst am ", "").replace(" wieder einen Free-Booster abholen.", ""); + FileManager.setValue("freeBooster", stringToDate(isolatedDate).toString()); + } else if(message.equals("[CaseOpening] Du hast 2 Kisten erhalten.")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodChest = getTimePeriodForFreeChest(rank); + if(periodChest > -1) + FileManager.setValue("freeChest", LocalDateTime.now().plusDays(periodChest).toString()); + } else if(message.startsWith("Du hast 1 ") && message.endsWith("-Booster erhalten. Danke für deine Unterstützung von GrieferGames!")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodChest = getTimePeriodForFreeChest(rank); + if(periodChest > -1) + FileManager.setValue("freeBooster", LocalDateTime.now().plusDays(periodChest).toString()); + } else if(message.startsWith("[Kopf] Du hast einen ") && message.endsWith("-Kopf erhalten!")) { + String rank = getPlayerRank(Laby.labyAPI().getName()); + int periodSkull = getTimePeriodForFreeSkull(rank); + if(periodSkull > -1) + FileManager.setValue("freeSkull", LocalDateTime.now().plusDays(periodSkull).toString()); + } + } + } + + public static String getPlayerRank(String name) { + if (Minecraft.getMinecraft().getNetHandler() == null) + return ""; + + NetworkPlayerInfo info = Minecraft.getMinecraft().getNetHandler().getPlayerInfo(name); + + if (info == null) + return ""; + + IChatComponent component = info.getDisplayName(); + if (component != null) { + String[] parts = component.getUnformattedText().split("┃"); + if (parts.length > 1) { + return parts[0].trim(); + } + } + return ""; + } + + private LocalDateTime stringToDate(String string) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy 'um' HH:mm:ss"); + return LocalDateTime.parse(string, formatter); + } + + private int getTimePeriodForFreeSkull(String rank) { + return switch (rank) { + case "Spieler", "Premium", "Ultra", "Legende" -> -1; + case "Titan" -> 14; + default -> 7; + }; + } + + private int getTimePeriodForFreeChest(String rank) { + return switch (rank) { + case "Spieler", "Premium", "Ultra", "Legende", "Titan" -> -1; + default -> 14; + }; + } +} \ No newline at end of file diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/CBTracker.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/CBTracker.java deleted file mode 100644 index 2a7f506..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/CBTracker.java +++ /dev/null @@ -1,73 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; - -import java.util.Arrays; -import java.util.List; -import net.labymod.api.Laby; -import net.labymod.api.client.component.TextComponent; -import net.labymod.api.client.scoreboard.Scoreboard; -import net.labymod.api.client.scoreboard.ScoreboardTeam; -import net.labymod.api.event.client.world.WorldLoadEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class CBTracker { - - public static final List CBs = Arrays.asList( - "Lobby", - "Portal", - "Extreme", - "CBE", - "Nature", - "CB1", - "CB2", - "CB3", - "CB4", - "CB5", - "CB6", - "CB7", - "CB8", - "CB9", - "CB10", - "CB11", - "CB12", - "CB13", - "CB14", - "CB15", - "CB16", - "CB17", - "CB18", - "CB19", - "CB20", - "CB21", - "CB22", - "Lava", - "Wasser", - "Event" - ); - - public static String currentCB = ""; - - public void worldLoadEvent(WorldLoadEvent event) { - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Scoreboard scoreboard = Laby.labyAPI().minecraft().getScoreboard(); - for (ScoreboardTeam team : scoreboard.getTeams()) { - if(team.getTeamName().equals("server_value")) { - String CBString = ((TextComponent)team.getPrefix()).getText(); - if(!CBString.equals(currentCB) && CBs.contains(CBString)) { - ItemClearTimerListener.resetItemRemover(); - currentCB = CBString; - Addon.getSharedInstance().getBridge().cbChanged(); - - if(currentCB.equals("Lobby") && Addon.getSharedInstance().configuration().getSkipHub().get()) { - VersionisedBridge.sendCommand("/portal"); - } - } - } - } - } - }, 600 - ); - } -} \ No newline at end of file diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HABK.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HABK.java index 57016bf..0c0dbf9 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HABK.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HABK.java @@ -9,8 +9,8 @@ import net.minecraft.item.ItemSword; import tmb.randy.tmbgriefergames.core.Addon; -import static tmb.randy.tmbgriefergames.v1_8_9.util.ItemSaver.NBTTagStringBirthBow; -import static tmb.randy.tmbgriefergames.v1_8_9.util.ItemSaver.findHotbarSlotforItem; +import static tmb.randy.tmbgriefergames.core.util.ItemSaver.NBTTagStringBirthBow; +import static tmb.randy.tmbgriefergames.core.util.ItemSaver.findHotbarSlotforItem; public class HABK { diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HopperConnections.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HopperConnections.java new file mode 100644 index 0000000..147ad0b --- /dev/null +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/HopperConnections.java @@ -0,0 +1,362 @@ +package tmb.randy.tmbgriefergames.v1_8_9.util; + +import net.labymod.api.event.client.chat.ChatReceiveEvent; +import net.labymod.api.event.client.render.world.RenderWorldEvent; +import net.labymod.api.nbt.NBTTagType; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockPos; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL11; +import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import tmb.randy.tmbgriefergames.core.enums.HopperState; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import tmb.randy.tmbgriefergames.core.events.HopperStateChangedEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class HopperConnections { + + private Map conntections = new HashMap<>(); + private BlockPos currentConnectingHopper; + + private record HopperConnection(BlockPos pos1, BlockPos pos2, @Nullable ItemStack stack, CBs cb) { + public String toString() { + if(stack != null) { + return cb.getName() + "." + stack.getItem().toString() + ":" + stack.getMetadata() + "." + pos1; + } + + return cb.getName() + "." + pos1; + } + } + + public void hopperStateChanged(HopperStateChangedEvent event) { + if(event.getNewState() == HopperState.NONE) { + currentConnectingHopper = null; + } + } + + public void onGuiOpenEvent() { + + if(Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest chestContainer) { + String invName = chestContainer.getLowerChestInventory().getName(); + if(invName.equals("§6Trichter-Mehrfach-Verbindungen")) { + for (int i = 0; i < 44; i++) { + ItemStack stack = chestContainer.getLowerChestInventory().getStackInSlot(i); + if(stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { + String firstLine = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", NBTTagType.STRING.getId()).get(0).toString(); + if(firstLine.contains("Verbunden mit:")) { + String coordinateString = firstLine.replace("§7Verbunden mit: §e", "").replace("\"", "").replace(".0", ""); + String[] coodStrings = coordinateString.split(";"); + if(coodStrings.length == 3) { + int x = Integer.parseInt(coodStrings[0]); + int y = Integer.parseInt(coodStrings[1]); + int z = Integer.parseInt(coodStrings[2]); + + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + HopperConnection newConn = new HopperConnection(mop.getBlockPos(), new BlockPos(x, y, z), stack, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + + } + } + } + } + } else if(invName.equals("§6Trichter-Einstellungen")) { + ItemStack stack = chestContainer.getLowerChestInventory().getStackInSlot(16); + if(stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { + String firstLine = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", NBTTagType.STRING.getId()).get(0).toString(); + if(firstLine.contains("Weiterleiten an ")) { + String coordinateString = firstLine.replace("Weiterleiten an ", "").replace("\"", "").replace(".0", "").replace("§7", "").replace("§e", "").trim(); + String[] coodStrings = coordinateString.split(";"); + if(coodStrings.length == 3) { + int x = Integer.parseInt(coodStrings[0]); + int y = Integer.parseInt(coodStrings[1]); + int z = Integer.parseInt(coodStrings[2]); + + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + + HopperConnection newConn = new HopperConnection(mop.getBlockPos(), new BlockPos(x, y, z), null, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + } + } + } + } + } + + public void messageReceived(ChatReceiveEvent event) { + String message = event.chatMessage().getPlainText(); + switch (message) { + case "[Trichter] Das Verbinden wurde aktiviert. Klicke auf den gewünschten Endpunkt.", + "[Trichter] Das Multi-Verbinden wurde aktiviert. Klicke mit dem gewünschten Item auf den gewünschten Endpunkt." -> { + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + BlockPos blockPos = mop.getBlockPos(); + IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(blockPos); + + if (state.getBlock() == Blocks.hopper) { + currentConnectingHopper = blockPos; + } + } + } + case "[Trichter] Der Trichter wurde erfolgreich verbunden.", + "[Trichter] Der Verbindungsmodus wurde beendet.", + "[Trichter] Der Startpunkt ist zu weit entfernt. Bitte starte erneut." -> { + if (message.equals("[Trichter] Der Trichter wurde erfolgreich verbunden.")) { + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + + HopperConnection newConn = new HopperConnection(currentConnectingHopper, mop.getBlockPos(), null, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + + currentConnectingHopper = null; + } + case "[Trichter] Die Multi-Verbindung wurde hinzugefügt." -> { + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + ItemStack stack = Minecraft.getMinecraft().thePlayer.inventory.getCurrentItem(); + HopperConnection newConn = new HopperConnection(currentConnectingHopper, mop.getBlockPos(), stack, CBtracker.getCurrentCB()); + conntections.put(newConn.toString(), newConn); + } + } + case "[Trichter] Die Mehrfach-Verbindungen wurden aufgehoben." -> { + ArrayList removeKeys = new ArrayList<>(); + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + for (String key : conntections.keySet()) { + HopperConnection connection = conntections.get(key); + if(connection.stack != null) { + if(connection.pos1.equals(mop.getBlockPos())) { + removeKeys.add(key); + } + } + } + + for (String removeKey : removeKeys) { + conntections.remove(removeKey); + } + } + } + case "[Trichter] Die Verbindung wurde aufgehoben." -> { + String removeKey = null; + MovingObjectPosition mop = Minecraft.getMinecraft().thePlayer.rayTrace(5, 1.0F); + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + for (String key : conntections.keySet()) { + HopperConnection connection = conntections.get(key); + if(connection.stack == null) { + if(connection.pos1.equals(mop.getBlockPos())) { + removeKey = key; + break; + } + } + } + + if(removeKey != null) { + conntections.remove(removeKey); + } + } + } + } + } + + public void cbChanged(CbChangedEvent event) { + currentConnectingHopper = null; + } + + public void renderWorld(RenderWorldEvent event) { + Iterator> iterator = conntections.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + HopperConnection conntection = entry.getValue(); + + double distance = conntection.pos1.distanceSq(Minecraft.getMinecraft().thePlayer.posX, Minecraft.getMinecraft().thePlayer.posY, Minecraft.getMinecraft().thePlayer.posZ); + double actualDistance = Math.sqrt(distance); + + if(actualDistance > 30) + continue; + + if (conntection.cb == CBtracker.getCurrentCB()) { + if (Minecraft.getMinecraft().theWorld.getBlockState(conntection.pos1()).getBlock() == Blocks.hopper) { + drawLineBetween(conntection); + } else { + iterator.remove(); + } + } + } + + + if(currentConnectingHopper != null) { + drawSphere(currentConnectingHopper, 30.0d, event.getPartialTicks()); + } + } + + private void drawLineBetween(HopperConnection connection) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowLines().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + double x1 = connection.pos1.getX() - mc.getRenderManager().viewerPosX + 0.5; + double y1 = connection.pos1.getY() - mc.getRenderManager().viewerPosY + 0.5; + double z1 = connection.pos1.getZ() - mc.getRenderManager().viewerPosZ + 0.5; + + double x2 = connection.pos2.getX() - mc.getRenderManager().viewerPosX + 0.5; + double y2 = connection.pos2.getY() - mc.getRenderManager().viewerPosY + 0.5; + double z2 = connection.pos2.getZ() - mc.getRenderManager().viewerPosZ + 0.5; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + GlStateManager.disableBlend(); + + GL11.glLineWidth(64.0F); + GL11.glBegin(GL11.GL_LINES); + + if (connection.stack == null) { + GL11.glColor3f(0.333f, 1.0f, 1.0f); + GL11.glVertex3d(x1, y1, z1); + + GL11.glColor3f(0.0f, 0.0f, 0.667f); + GL11.glVertex3d(x2, y2, z2); + } else { + GL11.glColor3f(1.0f, 0.667f, 0.0f); + GL11.glVertex3d(x1, y1, z1); + + GL11.glColor3f(0.667f, 0.0f, 0.0f); + GL11.glVertex3d(x2, y2, z2); + } + + GL11.glEnd(); + + GlStateManager.enableDepth(); + GlStateManager.enableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + + if (connection.stack != null) { + long time = mc.theWorld.getTotalWorldTime(); + double animationDuration = 100.0; + + double progress = (time % (int) animationDuration) / animationDuration; + + double animX = x1 + (x2 - x1) * progress; + double animY = y1 + (y2 - y1) * progress; + double animZ = z1 + (z2 - z1) * progress; + + renderItemStackAt(connection.stack, animX, animY, animZ); + } + } + + private void renderItemStackAt(ItemStack stack, double x, double y, double z) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowLines().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + GlStateManager.pushMatrix(); + + GlStateManager.translate(x, y, z); + + GlStateManager.rotate(-mc.getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(mc.getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); + + GlStateManager.disableLighting(); + + GlStateManager.scale(0.5F, 0.5F, 0.5F); + + mc.getRenderItem().renderItem(stack, TransformType.FIXED); + + GlStateManager.enableLighting(); + + GlStateManager.popMatrix(); + } + + private void drawSphere(BlockPos center, double radius, float partialTicks) { + if(!Addon.getSharedInstance().configuration().getHopperSubConfig().getShowRadius().get()) + return; + + Minecraft mc = Minecraft.getMinecraft(); + + double cx = center.getX() - mc.getRenderManager().viewerPosX; + double cy = center.getY() - mc.getRenderManager().viewerPosY; + double cz = center.getZ() - mc.getRenderManager().viewerPosZ; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + + GL11.glLineWidth(1.5F); + GlStateManager.color(1.0f, 0.0f, 0.0f, 1.0f); + + GL11.glTranslated(cx, cy, cz); + + GL11.glBegin(GL11.GL_LINES); + + int segments = 60; + double step = Math.PI * 2 / segments; + + for (double theta = 0; theta < Math.PI * 2; theta += step) { + for (double phi = 0; phi < Math.PI; phi += step) { + double x1 = radius * Math.sin(phi) * Math.cos(theta); + double z1 = radius * Math.sin(phi) * Math.sin(theta); + double y1 = radius * Math.cos(phi); + + double x2 = radius * Math.sin(phi + step) * Math.cos(theta); + double z2 = radius * Math.sin(phi + step) * Math.sin(theta); + double y2 = radius * Math.cos(phi + step); + + GL11.glVertex3d(x1, y1, z1); + GL11.glVertex3d(x2, y2, z2); + } + } + + for (double theta = 0; theta < Math.PI * 2; theta += step) { + for (double phi = 0; phi < Math.PI; phi += step) { + double y1 = radius * Math.sin(phi) * Math.cos(theta); + double z1 = radius * Math.sin(phi) * Math.sin(theta); + double x1 = radius * Math.cos(phi); + + double y2 = radius * Math.sin(phi + step) * Math.cos(theta); + double z2 = radius * Math.sin(phi + step) * Math.sin(theta); + double x2 = radius * Math.cos(phi + step); + + GL11.glVertex3d(x1, y1, z1); + GL11.glVertex3d(x2, y2, z2); + } + } + + GL11.glEnd(); + + GlStateManager.enableDepth(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + } + + + public void resetConnections() { + conntections = new HashMap<>(); + } +} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemSaver.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemSaver.java deleted file mode 100644 index a52fdab..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/ItemSaver.java +++ /dev/null @@ -1,107 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; - -import net.labymod.api.Laby; -import net.labymod.api.client.world.item.ItemStack; -import net.labymod.api.component.data.DataComponentKey; -import net.labymod.api.event.client.input.MouseButtonEvent; -import net.labymod.api.event.client.input.MouseButtonEvent.Action; -import net.labymod.api.util.I18n; -import net.minecraft.client.Minecraft; -import tmb.randy.tmbgriefergames.core.Addon; - -public class ItemSaver { - - private static final String NBTTagStringBonze = "[0:{lvl:21s,id:16s},1:{lvl:3s,id:34s},2:{lvl:2s,id:20s},3:{lvl:5s,id:61s},4:{lvl:21s,id:21s}]"; - private static final String NBTTagStringBirthSword = "[0:{lvl:21s,id:16s},1:{lvl:2s,id:20s},2:{lvl:5s,id:61s},3:{lvl:21s,id:21s}]"; - private static final String NBTTagStringSoS = "[0:{lvl:-6s,id:18s},1:{lvl:-6s,id:21s},2:{lvl:-6s,id:7s}]"; - public static final String NBTTagStringBirthBow = "[0:{lvl:22s,id:48s},1:{lvl:4s,id:49s},2:{lvl:1s,id:51s},3:{lvl:4s,id:19s},4:{lvl:22s,id:21s}]"; - - - public void mouseButtonEvent(MouseButtonEvent event) { - if(Addon.getSharedInstance().configuration().getItemProtection().get()) { - if(Laby.labyAPI().minecraft().getClientPlayer() != null) { - if(Laby.labyAPI().minecraft().getClientPlayer().getMainHandItemStack() != null) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().getMainHandItemStack(); - if(stack.hasDataComponentContainer()) { - if(stack.getDataComponentContainer().has(DataComponentKey.simple("ench"))) { - String enchantments = stack.getDataComponentContainer().get(DataComponentKey.simple("ench")).toString(); - - if(event.action() == Action.CLICK) { - if((enchantments.equals(NBTTagStringBonze) || enchantments.equals(NBTTagStringBirthSword)) && event.button().isLeft()) { - Addon.getSharedInstance().displayNotification("§4§l" + I18n.translate("tmbgriefergames.itemSaver.item_saver_message_sword")); - Addon.getSharedInstance().getBridge().changeSlot(findHotbarSlotforItem()); - event.setCancelled(true); - } else if(enchantments.equals(NBTTagStringSoS) && event.button().isRight()) { - Addon.getSharedInstance().displayNotification("§4§l" + I18n.translate("tmbgriefergames.itemSaver.item_saver_message_sos")); - Addon.getSharedInstance().getBridge().changeSlot(findHotbarSlotforBlock()); - event.setCancelled(true); - } else if(enchantments.equals(NBTTagStringBirthBow) && event.button().isRight()) { - Addon.getSharedInstance().displayNotification("§4§l" + I18n.translate("tmbgriefergames.itemSaver.item_saver_message_birth_bow")); - Addon.getSharedInstance().getBridge().changeSlot(findHotbarSlotforItem()); - event.setCancelled(true); - } - } - } - } - } - } - } - } - - public static int findHotbarSlotforBlock() { - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if (stack.isAir()) { - return i; - } - } - - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if(stack.isItem()) { - return i; - } - } - - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if(stack.isBlock() && !stack.hasDataComponentContainer()) { - return i; - } - } - - return Laby.labyAPI().minecraft().getClientPlayer().inventory().getSelectedIndex() == 8 ? 0 : Laby.labyAPI().minecraft().getClientPlayer().inventory().getSelectedIndex() + 1; - } - - public static int findHotbarSlotforItem() { - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if (stack.isAir()) { - return i; - } - } - - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if(stack.isBlock()) { - return i; - } - } - - for (int i = 0; i < 9; i++) { - ItemStack stack = Laby.labyAPI().minecraft().getClientPlayer().inventory().itemStackAt(i); - - if(stack.isItem() && !stack.hasDataComponentContainer()) { - return i; - } - } - - return Laby.labyAPI().minecraft().getClientPlayer().inventory().getSelectedIndex() == 8 ? 0 : Laby.labyAPI().minecraft().getClientPlayer().inventory().getSelectedIndex() + 1; - } - -} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/NatureBordersRenderer.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/NatureBordersRenderer.java index 604f4bb..74af761 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/NatureBordersRenderer.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/NatureBordersRenderer.java @@ -19,12 +19,10 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.util.vector.Vector3f; import tmb.randy.tmbgriefergames.core.Addon; +import tmb.randy.tmbgriefergames.core.CBtracker; public class NatureBordersRenderer { - private final int offsetX = 1; - private final int offsetZ = 0; - public static double getDistanceSq(double x1, double z1, double x2, double z2) { double xs = x1 - x2; @@ -37,7 +35,7 @@ public static double getDistanceSq(double x1, double z1, double x2, double z2) private float lineBlue = 0.0F; public void onKey(KeyEvent event) { - if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getNatureSubConfig().getHotkey().get())) { + if(VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getNatureSubConfig().getHotkey().get()) && !VersionisedBridge.getSharedInstance().isChatGuiOpen() && CBtracker.isNatureWorldCB()) { Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().set(!Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get()); String activeString = Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() ? I18n.getTranslation("tmbgriefergames.natureBorders.plotBordersVisible") : I18n.getTranslation("tmbgriefergames.natureBorders.plotBordersInvisible"); @@ -134,7 +132,7 @@ public boolean isPosInRenderableArea(EntityPlayerSP player, int posX, int posZ) } public void onRender(RenderWorldEvent event) { - if (Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() && (CBTracker.currentCB.equals("Nature") || CBTracker.currentCB.equals("Extreme"))) + if (Addon.getSharedInstance().configuration().getNatureSubConfig().getShowBorders().get() && CBtracker.isNatureWorldCB()) { EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; WorldClient world = Minecraft.getMinecraft().theWorld; @@ -194,7 +192,7 @@ public void onRender(RenderWorldEvent event) { int additionalOffsetZ = (pos.getZ() < 0 ? -1 : 0); - if ((pos.getZ() + offsetZ + additionalOffsetZ) % 42 == 0) + if ((pos.getZ() + additionalOffsetZ) % 42 == 0) { if (!Addon.getSharedInstance().configuration().getNatureSubConfig().getBorderMaxHeight().get()) { @@ -210,7 +208,7 @@ public void onRender(RenderWorldEvent event) { int additionalOffsetX = (pos.getX() < 0 ? -1 : 0); - if ((pos.getX() + offsetX + additionalOffsetX) % 42 == 0) + if ((pos.getX() + 1 + additionalOffsetX) % 42 == 0) { if (!Addon.getSharedInstance().configuration().getNatureSubConfig().getBorderMaxHeight().get()) { diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlayerTracer.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlayerTracer.java deleted file mode 100644 index d171442..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlayerTracer.java +++ /dev/null @@ -1,99 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import net.labymod.api.Laby; -import net.labymod.api.client.gui.screen.key.Key; -import net.labymod.api.client.scoreboard.ScoreboardTeam; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.labymod.api.event.client.input.KeyEvent; -import net.labymod.api.event.client.input.KeyEvent.State; -import net.labymod.api.util.I18n; -import tmb.randy.tmbgriefergames.core.Addon; - -public class PlayerTracer { - public static final List CBlist = Arrays.asList("None", "CB1", "CB22", "CB21", "CB20", "CB7", "Nature", "CB2", "CB3", "CB4", "CB5", "CB6", "CB8", "CB9", "CB10", "CB11", "CB12", "CB13", "CB14", "CB15", "CB16", "CB17", "CB18", "CB19", "Extreme", "CBEvil"); - private int nextServer = 0; - private String playerName; - - public void onKey(KeyEvent event) { - if(isTracerActive() && event.state() == State.PRESS && (event.key() == Key.W || event.key() == Key.A || event.key() == Key.S || event.key() == Key.D)) { - stopTracer(); - } - } - - public void messageReceived(ChatReceiveEvent event) { - String msg = event.chatMessage().getPlainText(); - if(msg.endsWith("Kicked whilst connecting to connector: Du hast dich zu schnell wieder eingeloggt. Versuche es später erneut.") && isTracerActive()) { - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - }, - 1000 - ); - event.setCancelled(true); - } else if(isTracerActive() && ((msg.startsWith("[GrieferGames] Du wurdest automatisch auf ") && msg.endsWith(" verbunden.") || (msg.startsWith("[GrieferGames] Serverwechsel auf ") && msg.endsWith(" wurde gestartet.."))))) { - event.setCancelled(true); - } - } - public void cbChanged() { - if(CBTracker.currentCB != null && !CBTracker.currentCB.equals("Portal") && !CBTracker.currentCB.equals("Lobby") && isTracerActive()) { - if(isPlayerOnCB()) { - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.foundPlayer")); - stopTracer(); - } else if(nextServer < CBlist.size()) { - nextServer++; - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - }, - 4500 - ); - } else { - stopTracer(); - } - } - } - - public void startTracer(String name) { - if(name != null) { - playerName = name.toLowerCase(); - } - nextServer = 1; - Laby.labyAPI().minecraft().chatExecutor().chat("/switch " + CBlist.get(nextServer)); - } - - public void stopTracer() { - playerName = null; - nextServer = 0; - Addon.getSharedInstance().displayNotification(I18n.getTranslation("tmbgriefergames.playerTracer.tracingEnded")); - } - - private boolean isPlayerOnCB() { - if(playerName == null) { - return false; - } - - for (ScoreboardTeam team : Laby.labyAPI().minecraft().getScoreboard().getTeams()) { - Collection members = team.getEntries(); - for (String member : members) { - if(member.equalsIgnoreCase(playerName)) { - return true; - } - } - } - - return false; - } - - public boolean isTracerActive() { - return (nextServer != 0); - } -} diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlotSwitch.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlotSwitch.java deleted file mode 100644 index 629ac83..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/PlotSwitch.java +++ /dev/null @@ -1,148 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util; - -import net.labymod.api.Laby; -import net.labymod.api.event.Phase; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; -import net.labymod.api.event.client.chat.ChatReceiveEvent; -import net.labymod.api.event.client.input.KeyEvent; -import net.labymod.api.event.client.input.KeyEvent.State; -import net.labymod.api.event.client.lifecycle.GameTickEvent; -import tmb.randy.tmbgriefergames.core.Addon; - -public class PlotSwitch { - - private static final int COMMAND_COOLDOWN = 25; - private static int COMMAND_COOLDOWN_COUNTER = 0; - private String nextCommand = null; - - private boolean waitingForPlotSwitch = false; - private enum DIRECTION { - PREVIOUS, NEXT - } - - private String lastPlot = null; - - - public void messageSend(ChatMessageSendEvent event) { - if(!Addon.isGG()) { - return; - } - - if(event.getMessage().toLowerCase().startsWith("/p h")) { - lastPlot = event.getMessage(); - } - } - - - public void tick(GameTickEvent event) { - if(event.phase() == Phase.PRE) { - if(COMMAND_COOLDOWN_COUNTER > 0) { - COMMAND_COOLDOWN_COUNTER--; - Addon.getSharedInstance().logger().info("Counting: " + COMMAND_COOLDOWN_COUNTER); - return; - } - - if(nextCommand != null && Laby.labyAPI().minecraft().getClientPlayer() != null) { - COMMAND_COOLDOWN_COUNTER = COMMAND_COOLDOWN; - waitingForPlotSwitch = true; - Laby.labyAPI().minecraft().chatExecutor().chat(nextCommand); - nextCommand = null; - } - } - } - - - public void messageReceived(ChatReceiveEvent event) { - String message = event.chatMessage().getPlainText(); - - if(message.equals("[GrieferGames] Du wurdest zum Grundstück teleportiert.") && waitingForPlotSwitch) { - waitingForPlotSwitch = false; - } - } - - public void keyDown(KeyEvent event) { - if(lastPlot == null || nextCommand != null || !Addon.isGG()) { - return; - } - - String command = null; - - if(event.state() == State.PRESS) { - if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getPreviousPlot().get())) { - command = getPlotCommand(lastPlot, DIRECTION.PREVIOUS); - } else if(VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getNextPlot().get())) { - command = getPlotCommand(lastPlot, DIRECTION.NEXT); - } - - if(command != null) { - nextCommand = command; - } - } - } - - private String getPlotCommand(String command, DIRECTION direction) { - String[] args = command.split(" "); - - if(args.length == 2) { - if(!(args[0].equalsIgnoreCase("/p") && args[1].equalsIgnoreCase("h"))) { - return null; - } - - if(direction == DIRECTION.PREVIOUS) { - return null; - } else { - return command + " 2"; - } - } else if(args.length == 3) { - if(!(args[0].equalsIgnoreCase("/p") && args[1].equalsIgnoreCase("h"))) { - return null; - } - - if(isInteger(args[2])) { - int currentPlot = Integer.parseInt(args[2]); - if(direction == DIRECTION.PREVIOUS) { - return args[0] + " " + args[1] + " " + (currentPlot - 1); - } else { - return args[0] + " " + args[1] + " " + (currentPlot + 1); - } - } else { - if(direction == DIRECTION.PREVIOUS) { - return null; - } else { - return command + " 2"; - } - } - } else if(args.length == 4) { - if(!(args[0].equalsIgnoreCase("/p") && args[1].equalsIgnoreCase("h"))) { - return null; - } - - if(!isInteger(args[3])) { - return null; - } else { - int nextPlot = Integer.parseInt(args[3]); - if(direction == DIRECTION.NEXT) { - nextPlot++; - } else { - nextPlot--; - } - - if(nextPlot < 1) { - return null; - } - - return args[0] + " " + args[1] + " " + args[2] + " " + nextPlot; - } - } - return null; - } - - private boolean isInteger(String input) { - try { - Integer.parseInt(input); - return true; - } catch (NumberFormatException e) { - return false; - } - } -} \ No newline at end of file diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/TooltipExtension.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/TooltipExtension.java index d7d6ae3..a037b9f 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/TooltipExtension.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/TooltipExtension.java @@ -22,7 +22,7 @@ public void renderTooltip(ItemStackTooltipEvent event) { if(Addon.getSharedInstance().configuration().getTooltipConfig().getShowCompTooltip().get() && (stack.getDataComponentContainer().has( DataComponentKey.simple("currentAmount")) || stack.getDataComponentContainer().has(DataComponentKey.simple("stackSize")))) { - // Show com item size + int currentAmount; if(stack.getDataComponentContainer().has(DataComponentKey.simple("currentAmount"))) { @@ -42,7 +42,7 @@ public void renderTooltip(ItemStackTooltipEvent event) { event.getTooltipLines().add(Component.translatable("tmbgriefergames.tooltip.compressedTooltip", Component.text(DKs), Component.text(stacks), Component.text(items))); } else if(Addon.getSharedInstance().configuration().getTooltipConfig().getShowAdventurerTooltip().get() && stack.getDataComponentContainer().has(DataComponentKey.simple("adventure"))) { - // Show extended adventurer tool data + int amount = ((NBTTagCompound)stack.getDataComponentContainer().get(DataComponentKey.simple("adventure"))).getInteger("adventure.amount"); int total = ((NBTTagCompound)stack.getDataComponentContainer().get(DataComponentKey.simple("adventure"))).getInteger("adventure.req_amount"); diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VABK.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VABK.java index 69c2ecc..d2ae370 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VABK.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VABK.java @@ -33,7 +33,7 @@ public void onTickEvent(GameTickEvent event) { } public void onKeyEvent(KeyEvent event) { - if(event.state() == State.PRESS && VersionisedBridge.allKeysPressed(Addon.getSharedInstance().configuration().getSwordsSubConfig().getVABKhotkey().get()) && !VersionisedBridge.isChatGuiOpen()) { + if(event.state() == State.PRESS && VersionisedBridge.getSharedInstance().allKeysPressed(Addon.getSharedInstance().configuration().getSwordsSubConfig().getVABKhotkey().get()) && !VersionisedBridge.getSharedInstance().isChatGuiOpen()) { toggleActive(); } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VersionisedBridge.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VersionisedBridge.java index 2fde906..1d0f25f 100644 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VersionisedBridge.java +++ b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/VersionisedBridge.java @@ -6,17 +6,14 @@ import net.labymod.api.event.Phase; import net.labymod.api.event.Priority; import net.labymod.api.event.Subscribe; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; import net.labymod.api.event.client.chat.ChatReceiveEvent; import net.labymod.api.event.client.input.KeyEvent; import net.labymod.api.event.client.input.MouseButtonEvent; import net.labymod.api.event.client.lifecycle.GameTickEvent; -import net.labymod.api.event.client.network.server.NetworkPayloadEvent; import net.labymod.api.event.client.render.overlay.IngameOverlayElementRenderEvent; import net.labymod.api.event.client.render.overlay.IngameOverlayElementRenderEvent.OverlayElementType; import net.labymod.api.event.client.render.world.RenderWorldEvent; import net.labymod.api.event.client.world.ItemStackTooltipEvent; -import net.labymod.api.event.client.world.WorldLoadEvent; import net.labymod.api.models.Implements; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -26,42 +23,24 @@ import org.lwjgl.input.Keyboard; import tmb.randy.tmbgriefergames.core.Addon; import tmb.randy.tmbgriefergames.core.IBridge; +import tmb.randy.tmbgriefergames.core.enums.CBs; +import tmb.randy.tmbgriefergames.core.events.CbChangedEvent; +import tmb.randy.tmbgriefergames.core.events.HopperStateChangedEvent; import tmb.randy.tmbgriefergames.v1_8_9.util.AutoCrafter.AutoCrafterV1; import tmb.randy.tmbgriefergames.v1_8_9.util.AutoCrafter.AutoCrafterV2; import tmb.randy.tmbgriefergames.v1_8_9.util.AutoCrafter.AutoCrafterV3; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.ChatCleaner; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.CooldownNotifier; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.EmptyLinesRemover; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.MsgTabs; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.NewsBlocker; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.PaymentValidator; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.StreamerMute; -import tmb.randy.tmbgriefergames.v1_8_9.util.chat.TypeCorrection; import tmb.randy.tmbgriefergames.v1_8_9.util.click.ClickManager; import javax.inject.Singleton; @Singleton @Implements(IBridge.class) public class VersionisedBridge implements IBridge { - private final ChatCleaner chatCleaner = new ChatCleaner(); - private final CooldownNotifier cooldownNotifier = new CooldownNotifier(); - private final EmptyLinesRemover emptyLinesRemover = new EmptyLinesRemover(); - private final NewsBlocker newsBlocker = new NewsBlocker(); - private final MsgTabs msgTabs = new MsgTabs(); - private final PaymentValidator paymentValidator = new PaymentValidator(); - private final StreamerMute streamerMute = new StreamerMute(); - private final TypeCorrection typeCorrection = new TypeCorrection(); - private final PlotSwitch plotSwitch = new PlotSwitch(); - private final ItemSaver itemSaver = new ItemSaver(); + private static VersionisedBridge sharedInstance; private final TooltipExtension tooltipExtension = new TooltipExtension(); - private final PlayerTracer playerTracer = new PlayerTracer(); - private final CBTracker cbTracker = new CBTracker(); - private final ItemClearTimerListener itemClearTimerListener = new ItemClearTimerListener(); private final AutoHopper autoHopper = new AutoHopper(); private final FlyTimer flyTimer = new FlyTimer(); private final ItemShifter itemShifter = new ItemShifter(); private final NatureBordersRenderer natureBordersRenderer = new NatureBordersRenderer(); - private final AccountUnity accountUnity = new AccountUnity(); private final AutoCrafterV1 autoCrafterV1 = new AutoCrafterV1(); private final AutoCrafterV2 autoCrafterV2 = new AutoCrafterV2(); private final AutoCrafterV3 autoCrafterV3 = new AutoCrafterV3(); @@ -70,45 +49,39 @@ public class VersionisedBridge implements IBridge { private final Auswurf auswurf = new Auswurf(); private final HABK habk = new HABK(); private final VABK vabk = new VABK(); + private final HopperConnections hopperConnections = new HopperConnections(); + private final AutoLoot autoLoot = new AutoLoot(); private GuiScreen lastGui; private static final int commandCountdownLimit = 80; private static int commandCountdown = 0; - @Subscribe - public void worldLoadEvent(WorldLoadEvent event) { - // No checking for isGG as the function to auto skip the lobby/hub wouldn't work as the server adress is set too late. - cbTracker.worldLoadEvent(event); + public VersionisedBridge() { + sharedInstance = this; } @Subscribe - public void messageReceived(ChatReceiveEvent event) { - if(!Addon.isGG()) - return; + public void cbChanged(CbChangedEvent event) { + autoComp.stopComp(); + autoCrafterV2.stopCrafter(); + autoCrafterV3.stop(); + hopperConnections.cbChanged(event); - chatCleaner.messageReceived(event); - emptyLinesRemover.messageReceived(event); - newsBlocker.messageReceived(event); - paymentValidator.messageReceived(event); - streamerMute.messageReceived(event); - plotSwitch.messageReceived(event); - playerTracer.messageReceived(event); - autoHopper.messageReceived(event); - accountUnity.messageReceived(event); - msgTabs.chatMessageReceived(event); - autoCrafterV3.chatMessageReceived(event); + if(event.CB() == CBs.LOBBY && Addon.getSharedInstance().configuration().getSkipHub().get()) { + VersionisedBridge.sendCommand("/portal"); + } } @Subscribe - public void messageSend(ChatMessageSendEvent event) { + public void messageReceived(ChatReceiveEvent event) { if(!Addon.isGG()) return; - msgTabs.messageSend(event); - cooldownNotifier.messageReceived(event); - typeCorrection.messageSend(event); - plotSwitch.messageSend(event); + autoHopper.messageReceived(event); + autoCrafterV3.chatMessageReceived(event); + hopperConnections.messageReceived(event); + autoLoot.chatMessageReceived(event); } @Subscribe (Priority.FIRST) @@ -116,7 +89,6 @@ public void mouseInput(MouseButtonEvent event) { if(!Addon.isGG()) return; - itemSaver.mouseButtonEvent(event); autoHopper.mouseInput(event); flyTimer.onMouseButtonEvent(event); habk.onMouseButtonEvent(event); @@ -157,7 +129,6 @@ public void tick(GameTickEvent event) { autoCrafterV1.onTickEvent(event); autoHopper.tick(event); itemShifter.tick(event); - plotSwitch.tick(event); autoCrafterV2.onTickEvent(event); autoDecomp.onTickEvent(event); auswurf.onTickEvent(event); @@ -167,13 +138,16 @@ public void tick(GameTickEvent event) { commandCountdown(); } + @Subscribe + public void hopperStateChanged(HopperStateChangedEvent event) { + hopperConnections.hopperStateChanged(event); + } + @Subscribe public void keyDown(KeyEvent event) { if(!Addon.isGG()) return; - plotSwitch.keyDown(event); - playerTracer.onKey(event); itemShifter.onKey(event); natureBordersRenderer.onKey(event); autoComp.onKeyEvent(event); @@ -191,6 +165,7 @@ public void onRenderEvent(RenderWorldEvent event) { return; natureBordersRenderer.onRender(event); + hopperConnections.renderWorld(event); } @Subscribe @@ -202,37 +177,17 @@ public void renderTooltip(ItemStackTooltipEvent event) { flyTimer.onTooltipEvent(event); } - @Override - public void startPlayerTracer(String name) { - if(!Addon.isGG()) - return; - - playerTracer.startTracer(name); - } public void onGuiOpenEvent(GuiScreen screen) { ClickManager.getSharedInstance().clearAllQueues(); if(screen == null) { autoComp.stopComp(); itemShifter.stopShifting(); + } else { + hopperConnections.onGuiOpenEvent(); } } - @Subscribe - public void networkPayloadEvent(NetworkPayloadEvent event) { - if(!Addon.isGG()) - return; - - itemClearTimerListener.networkPayloadEvent(event); - } - - @Override - public void cbChanged() { - playerTracer.cbChanged(); - autoComp.stopComp(); - autoCrafterV2.stopCrafter(); - } - @Override public boolean isFlyCountdownActive() { return flyTimer.isTotalCountdownActive(); @@ -243,11 +198,6 @@ public String getWidgetString() { return flyTimer.getWidgetString(); } - @Override - public String getItemRemoverValue() { - return ItemClearTimerListener.getDisplayValue(); - } - @Override public void startNewAutocrafter() { autoCrafterV2.startCrafter(); @@ -275,14 +225,15 @@ private static void commandCountdown() { public static boolean canSendCommand() { return commandCountdown <= 0; } public static boolean sendCommand(String command) { if(canSendCommand()) { - Minecraft.getMinecraft().thePlayer.sendChatMessage(command); + Laby.references().chatExecutor().chat(command); commandCountdown = commandCountdownLimit; return true; } return false; } - public static boolean isChatGuiOpen() { + @Override + public boolean isChatGuiOpen() { for (IngameOverlayActivity activity : Laby.labyAPI().ingameOverlay().getActivities()) { if(activity.isAcceptingInput()) { return true; @@ -298,7 +249,8 @@ public static boolean isGUIOpen() { return currentScreen instanceof GuiChest || currentScreen instanceof GuiInventory || currentScreen instanceof GuiCrafting; } - public static boolean allKeysPressed(Key[] keys) { + @Override + public boolean allKeysPressed(Key[] keys) { if(keys.length == 0) return false; @@ -317,5 +269,15 @@ public void startAuswurf() { auswurf.startAuswurf(); } + @Override + public void openChat() { + + } + + public static VersionisedBridge getSharedInstance() {return sharedInstance;} + @Override + public void resetLines() { + hopperConnections.resetConnections(); + } } diff --git a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/CooldownNotifier.java b/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/CooldownNotifier.java deleted file mode 100644 index 0de21e1..0000000 --- a/game-runner/src/v1_8_9/java/tmb/randy/tmbgriefergames/v1_8_9/util/chat/CooldownNotifier.java +++ /dev/null @@ -1,59 +0,0 @@ -package tmb.randy.tmbgriefergames.v1_8_9.util.chat; - -import java.util.Arrays; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import net.labymod.api.event.client.chat.ChatMessageSendEvent; -import net.labymod.api.util.I18n; -import tmb.randy.tmbgriefergames.core.Addon; - - -public class CooldownNotifier { - - private final List cooldowns = Arrays.asList( - new Cooldown("/wand", 30000, "tmbgriefergames.chat.cooldownWand"), - new Cooldown("/rand", 30000, "tmbgriefergames.chat.cooldownRand"), - new Cooldown("/boden", 30000, "tmbgriefergames.chat.cooldownBoden"), - new Cooldown("^/sign.*", 3000, "tmbgriefergames.chat.cooldownSign"), - new Cooldown("/anticopy", 5000, "tmbgriefergames.chat.cooldownAnticopy") - ); - - public void messageReceived(ChatMessageSendEvent event) { - if(!Addon.getSharedInstance().configuration().getChatConfig().getCooldownNotifier().get()) - return; - - String str = event.getMessage().toLowerCase(); - - for (Cooldown cooldown : cooldowns) { - if(str.matches(cooldown.getCommand())) { - new Timer().schedule(new TimerTask() { - @Override - public void run() { - try { - Addon.getSharedInstance().displayNotification("§f" + I18n.translate(cooldown.getNotificationKey())); - } catch (Exception e) { - e.printStackTrace(); - } - - } - }, cooldown.getCooldown()); - } - } - } - - private static class Cooldown { - private final String command; - private final long cooldown; - private final String notificationKey; - Cooldown(String command, long cooldown, String notificationKey) { - this.command = command; - this.cooldown = cooldown; - this.notificationKey = notificationKey; - } - - public String getCommand() {return command;} - public long getCooldown() {return cooldown;} - public String getNotificationKey() {return notificationKey;} - } -} diff --git a/gradle.properties b/gradle.properties index 609a9ce..c50beeb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ -org.gradle.jvmargs=-Xmx4096m \ No newline at end of file +org.gradle.jvmargs=-Xmx4096m +net.labymod.minecraft-versions=1.8.9;1.12.2 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 48c0a02..b1e749b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 7483ebb..f81c526 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,25 +1,23 @@ rootProject.name = "griefergames-addon-by-tmb" pluginManagement { - val labyGradlePluginVersion = "0.3.48" - plugins { - id("net.labymod.gradle") version (labyGradlePluginVersion) - } - + val labyGradlePluginVersion = "0.5.4" buildscript { repositories { maven("https://dist.labymod.net/api/v1/maven/release/") - maven("https://repo.spongepowered.org/repository/maven-public") + maven("https://maven.neoforged.net/releases/") + maven("https://maven.fabricmc.net/") + gradlePluginPortal() mavenCentral() } dependencies { - classpath("net.labymod.gradle", "addon", labyGradlePluginVersion) + classpath("net.labymod.gradle", "common", labyGradlePluginVersion) } } } -plugins.apply("net.labymod.gradle") +plugins.apply("net.labymod.labygradle.settings") include(":api") -include(":core") +include(":core") \ No newline at end of file