diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..3ae61f0
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,37 @@
+plugins {
+ id 'net.fabricmc.fabric-loom' version "${loom_version}"
+}
+
+version = project.mod_version
+group = project.maven_group
+
+base {
+ archivesName = 'autogg'
+}
+
+repositories {
+}
+
+dependencies {
+ minecraft "com.mojang:minecraft:${project.minecraft_version}"
+ // No mappings line — MC 26.x ships unobfuscated
+ implementation "net.fabricmc:fabric-loader:${project.loader_version}"
+ implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
+}
+
+processResources {
+ inputs.property "version", project.version
+ filesMatching("fabric.mod.json") {
+ expand "version": project.version
+ }
+}
+
+tasks.withType(JavaCompile).configureEach {
+ it.options.release = 25
+ it.options.encoding = 'UTF-8'
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_25
+ targetCompatibility = JavaVersion.VERSION_25
+}
diff --git a/build.gradle.kts b/build.gradle.kts
deleted file mode 100644
index 7513919..0000000
--- a/build.gradle.kts
+++ /dev/null
@@ -1,49 +0,0 @@
-import gg.essential.gradle.util.noServerRunConfigs
-
-plugins {
- kotlin("jvm")
- id("gg.essential.multi-version")
- id("gg.essential.defaults")
-}
-
-val modGroup: String by project
-val modBaseName: String by project
-group = modGroup
-base.archivesName.set("$modBaseName-${platform.mcVersionStr}")
-
-repositories {
- maven("https://repo.spongepowered.org/repository/maven-public/")
- maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
-}
-
-loom {
- noServerRunConfigs()
- runConfigs {
- getByName("client") {
- programArgs("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
- }
- }
-}
-
-val embed by configurations.creating
-configurations.implementation.get().extendsFrom(embed)
-
-dependencies {
- embed("org.spongepowered:mixin:0.7-SNAPSHOT")
- embed("gg.essential:vigilance:306")
- embed(modImplementation("gg.essential:universalcraft-1.8.9-forge:369")!!)
- modRuntimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.2.1")
-}
-
-tasks.jar {
- from(embed.files.map { zipTree(it) })
-
- manifest.attributes(
- mapOf(
- "ModSide" to "CLIENT",
- "FMLCorePluginContainsFMLMod" to "Yes, yes it does",
- "TweakClass" to "org.spongepowered.asm.launch.MixinTweaker",
- "TweakOrder" to "0"
- )
- )
-}
\ No newline at end of file
diff --git a/deploy.jar b/deploy.jar
deleted file mode 100644
index 758228f..0000000
Binary files a/deploy.jar and /dev/null differ
diff --git a/gradle.properties b/gradle.properties
index d92949a..4f17003 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,13 @@
-essential.defaults.loom=0
-loom.platform=forge
-modGroup=club.sk1er
-modBaseName=AutoGG
-
org.gradle.jvmargs=-Xmx2G
+org.gradle.parallel=true
+org.gradle.configuration-cache=false
+
+# Fabric — check https://fabricmc.net/develop for updates
+minecraft_version=26.2
+loader_version=0.19.3
+loom_version=1.17-SNAPSHOT
+fabric_api_version=0.153.0+26.2
+
+# Mod
+mod_version=4.2.0
+maven_group=club.sk1er
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 17655d0..5dd3c01 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/root.gradle.kts b/root.gradle.kts
deleted file mode 100644
index bb0ed09..0000000
--- a/root.gradle.kts
+++ /dev/null
@@ -1,12 +0,0 @@
-import gg.essential.gradle.util.versionFromBuildIdAndBranch
-
-plugins {
- kotlin("jvm") version "1.9.0" apply false
- id("gg.essential.multi-version.root")
-}
-
-version = versionFromBuildIdAndBranch()
-
-preprocess {
- "1.8.9"(10809, "srg")
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e298b43
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,12 @@
+pluginManagement {
+ repositories {
+ maven {
+ name = 'Fabric'
+ url = 'https://maven.fabricmc.net/'
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+rootProject.name = 'autogg'
diff --git a/settings.gradle.kts b/settings.gradle.kts
deleted file mode 100644
index ad92d72..0000000
--- a/settings.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-pluginManagement {
- repositories {
- gradlePluginPortal()
- mavenCentral()
- maven("https://maven.fabricmc.net")
- maven("https://maven.architectury.dev/")
- maven("https://maven.minecraftforge.net")
- maven("https://repo.essential.gg/repository/maven-public")
- }
- plugins {
- val egtVersion = "0.6.0"
- id("gg.essential.multi-version.root") version egtVersion
- }
-}
-
-rootProject.buildFileName = "root.gradle.kts"
-
-listOf(
- "1.8.9"
-).forEach { version ->
- include(":$version")
- project(":$version").apply {
- projectDir = file("versions/$version")
- buildFileName = "../../build.gradle.kts"
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/club/sk1er/mods/autogg/AutoGG.java b/src/main/java/club/sk1er/mods/autogg/AutoGG.java
index 4579cfc..b5cfa44 100644
--- a/src/main/java/club/sk1er/mods/autogg/AutoGG.java
+++ b/src/main/java/club/sk1er/mods/autogg/AutoGG.java
@@ -1,21 +1,3 @@
-/*
- * AutoGG - Automatically say a selectable phrase at the end of a game on supported servers.
- * Copyright (C) 2020 Sk1er LLC
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
package club.sk1er.mods.autogg;
import club.sk1er.mods.autogg.command.AutoGGCommand;
@@ -24,85 +6,73 @@
import club.sk1er.mods.autogg.handlers.patterns.PlaceholderAPI;
import club.sk1er.mods.autogg.handlers.web.WebHandler;
import club.sk1er.mods.autogg.tasks.RetrieveTriggersTask;
+import club.sk1er.mods.autogg.tasks.data.Server;
import club.sk1er.mods.autogg.tasks.data.TriggersSchema;
import club.sk1er.mods.autogg.util.JsonUtil;
import com.google.gson.JsonObject;
+import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.Minecraft;
-import net.minecraftforge.client.ClientCommandHandler;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.common.event.FMLInitializationEvent;
-import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-/**
- * Contains the main class for AutoGG which handles trigger schema setting/getting and the main initialization code.
- *
- * @author ChachyDev
- */
-@Mod(modid = "autogg", name = "AutoGG", version = "4.1.3")
-public class AutoGG {
-
- @Mod.Instance
+public class AutoGG implements ClientModInitializer {
+ public static final String MODID = "autogg";
+ public static final Logger LOGGER = LoggerFactory.getLogger(MODID);
public static AutoGG INSTANCE;
private final String[] primaryGGStrings = {"gg", "GG", "gf", "Good Game", "Good Fight", "Good Round! :D"};
private final String[] secondaryGGStrings = {"Have a good day!", "<3", "AutoGG By Sk1er!", "gf", "Good Fight", "Good Round", ":D", "Well played!", "wp"};
- private TriggersSchema triggers;
- private AutoGGConfig autoGGConfig;
-
- public boolean usingEnglish;
+ private volatile TriggersSchema triggers;
+ public volatile boolean usingEnglish = true;
public static final ScheduledExecutorService POOL = Executors.newScheduledThreadPool(5);
- @Mod.EventHandler
- public void onFMLPreInitialization(FMLPreInitializationEvent event) {
- POOL.submit(this::checkUserLanguage);
- }
+ @Override
+ public void onInitializeClient() {
+ INSTANCE = this;
- @Mod.EventHandler
- public void onFMLInitialization(FMLInitializationEvent event) {
- autoGGConfig = new AutoGGConfig();
- autoGGConfig.preload();
+ AutoGGConfig.load();
Set joined = new HashSet<>();
joined.addAll(Arrays.asList(primaryGGStrings));
joined.addAll(Arrays.asList(secondaryGGStrings));
-
PlaceholderAPI.INSTANCE.registerPlaceHolder("antigg_strings", String.join("|", joined));
- POOL.submit(new RetrieveTriggersTask());
- MinecraftForge.EVENT_BUS.register(new AutoGGHandler());
- ClientCommandHandler.instance.registerCommand(new AutoGGCommand());
+ new AutoGGHandler().register();
+ AutoGGCommand.register();
- // fix settings that were moved to seconds instead of ms
- // so users aren't waiting 5000 seconds to send GG
- if (autoGGConfig.getAutoGGDelay() > 5) autoGGConfig.setAutoGGDelay(1);
- if (autoGGConfig.getSecondaryDelay() > 5) autoGGConfig.setSecondaryDelay(1);
+ POOL.submit(new RetrieveTriggersTask());
+ POOL.submit(this::checkUserLanguage);
}
private void checkUserLanguage() {
- final String username = Minecraft.getMinecraft().getSession().getUsername();
- final JsonObject json = WebHandler.fetchJson("https://api.sk1er.club/language/" + username);
- final String language = JsonUtil.getOrDefaultString(json,"language", "ENGLISH");
- this.usingEnglish = "ENGLISH".equals(language);
+ try {
+ Thread.sleep(5000);
+ Minecraft mc = Minecraft.getInstance();
+ if (mc.getUser() == null) return;
+ final String username = mc.getUser().getName();
+ final JsonObject json = WebHandler.fetchJson("https://api.sk1er.club/language/" + username);
+ final String language = JsonUtil.getOrDefaultString(json, "language", "ENGLISH");
+ this.usingEnglish = "ENGLISH".equals(language);
+ } catch (Exception e) {
+ LOGGER.error("Failed to check user language", e);
+ }
}
public TriggersSchema getTriggers() {
- return triggers;
+ return triggers != null ? triggers : new TriggersSchema(new Server[0]);
}
public void setTriggers(TriggersSchema triggers) {
this.triggers = triggers;
}
- public AutoGGConfig getAutoGGConfig() {
- return autoGGConfig;
- }
-
public String[] getPrimaryGGStrings() {
return primaryGGStrings;
}
diff --git a/src/main/java/club/sk1er/mods/autogg/command/AutoGGCommand.java b/src/main/java/club/sk1er/mods/autogg/command/AutoGGCommand.java
index abf9827..922ceea 100644
--- a/src/main/java/club/sk1er/mods/autogg/command/AutoGGCommand.java
+++ b/src/main/java/club/sk1er/mods/autogg/command/AutoGGCommand.java
@@ -1,40 +1,42 @@
package club.sk1er.mods.autogg.command;
import club.sk1er.mods.autogg.AutoGG;
-import club.sk1er.mods.autogg.handlers.gg.AutoGGHandler;
import club.sk1er.mods.autogg.tasks.RetrieveTriggersTask;
-import gg.essential.universal.ChatColor;
-import gg.essential.universal.wrappers.message.UTextComponent;
-import net.minecraft.command.CommandBase;
-import net.minecraft.command.CommandException;
-import net.minecraft.command.ICommandSender;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.chat.Component;
-import static club.sk1er.mods.autogg.AutoGG.POOL;
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommands.literal;
-public class AutoGGCommand extends CommandBase {
-
- @Override
- public String getCommandName() {
- return "autogg";
- }
-
- @Override
- public String getCommandUsage(ICommandSender sender) {
- return "autogg";
+public class AutoGGCommand {
+ public static void register() {
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) ->
+ dispatcher.register(
+ literal("autogg")
+ .executes(ctx -> {
+ sendMessage(ctx.getSource(),
+ ChatFormatting.GOLD + "[AutoGG] " + ChatFormatting.GRAY +
+ "Edit §econfig/autogg.json §7to change settings. " +
+ "Use §e/autogg refresh §7to reload triggers.");
+ return 1;
+ })
+ .then(literal("refresh")
+ .executes(ctx -> {
+ AutoGG.POOL.submit(new RetrieveTriggersTask());
+ sendMessage(ctx.getSource(),
+ ChatFormatting.GOLD + "[AutoGG] " + ChatFormatting.GREEN + "Refreshed triggers!");
+ return 1;
+ }))
+ )
+ );
}
- @Override
- public void processCommand(ICommandSender sender, String[] args) throws CommandException {
- if (args.length == 1 && args[0].equalsIgnoreCase("refresh")) {
- POOL.submit(new RetrieveTriggersTask());
- (new UTextComponent(ChatColor.GREEN + "Refreshed triggers!")).chat();
- return;
+ private static void sendMessage(FabricClientCommandSource source, String text) {
+ Minecraft mc = Minecraft.getInstance();
+ if (mc.player != null) {
+ mc.player.sendSystemMessage(Component.literal(text));
}
- AutoGGHandler.displayScreen = AutoGG.INSTANCE.getAutoGGConfig().gui();
- }
-
- @Override
- public int getRequiredPermissionLevel() {
- return 0;
}
}
diff --git a/src/main/java/club/sk1er/mods/autogg/config/AutoGGConfig.java b/src/main/java/club/sk1er/mods/autogg/config/AutoGGConfig.java
index 8418393..e407a4a 100644
--- a/src/main/java/club/sk1er/mods/autogg/config/AutoGGConfig.java
+++ b/src/main/java/club/sk1er/mods/autogg/config/AutoGGConfig.java
@@ -1,126 +1,68 @@
package club.sk1er.mods.autogg.config;
-import gg.essential.vigilance.Vigilant;
-import gg.essential.vigilance.data.Property;
-import gg.essential.vigilance.data.PropertyType;
-
-import java.io.File;
-
-@SuppressWarnings("FieldMayBeFinal")
-public class AutoGGConfig extends Vigilant {
- @Property(
- type = PropertyType.SWITCH, name = "AutoGG",
- description = "Entirely toggles AutoGG",
- category = "General", subcategory = "General"
- )
- private boolean autoGGEnabled = true;
-
- @Property(
- type = PropertyType.SWITCH, name = "Casual AutoGG",
- description = "Enable AutoGG for things that don't give Karma such as Skyblock Events.",
- category = "General", subcategory = "General"
- )
- private boolean casualAutoGGEnabled;
-
- @Property(
- type = PropertyType.SWITCH, name = "Anti GG",
- description = "Remove GG messages from chat.",
- category = "General", subcategory = "Miscellaneous"
- )
- private boolean antiGGEnabled;
-
- @Property(
- type = PropertyType.SWITCH, name = "Anti Karma",
- description = "Remove Karma messages from chat.",
- category = "General", subcategory = "Miscellaneous"
- )
- private boolean antiKarmaEnabled;
-
- @Property(
- type = PropertyType.SLIDER, name = "Delay",
- description = "Delay after the game ends to say the message.\n§eMeasured in seconds.",
- category = "General", subcategory = "General",
- max = 5
- )
+import club.sk1er.mods.autogg.AutoGG;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import net.fabricmc.loader.api.FabricLoader;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class AutoGGConfig {
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+ private static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("autogg.json");
+
+ private static AutoGGConfig instance = new AutoGGConfig();
+
+ // General
+ private boolean modEnabled = true;
+ private boolean casualAutoGGEnabled = false;
private int autoGGDelay = 1;
-
- @Property(
- type = PropertyType.SELECTOR, name = "Phrase",
- description = "Choose what message is said on game completion.",
- category = "General", subcategory = "General",
- options = {"gg", "GG", "gf", "Good Game", "Good Fight", "Good Round! :D"}
- )
private int autoGGPhrase = 0;
- @Property(
- type = PropertyType.SWITCH, name = "Second Message",
- description = "Enable a secondary message to send after your first GG.",
- category = "General", subcategory = "Secondary Message"
- )
- private boolean secondaryEnabled;
+ // Misc
+ private boolean antiGGEnabled = false;
+ private boolean antiKarmaEnabled = false;
- @Property(
- type = PropertyType.SELECTOR, name = "Phrase",
- description = "Send a secondary message sent after the first GG message.",
- category = "General", subcategory = "Secondary Message",
- options = {"Have a good day!", "<3", "AutoGG By Sk1er!", "gf", "Good Fight", "Good Round", ":D", "Well played!", "wp"}
- )
+ // Secondary
+ private boolean secondaryEnabled = false;
private int autoGGPhrase2 = 0;
-
- @Property(
- type = PropertyType.SLIDER, name = "Second Message Delay",
- description = "Delay between the first & second end of game messages.\n§eMeasured in seconds.",
- category = "General", subcategory = "Secondary Message",
- max = 5
- )
private int secondaryDelay = 1;
- public AutoGGConfig() {
- super(new File("./config/autogg.toml"));
- initialize();
- }
-
- public boolean isModEnabled() {
- return autoGGEnabled;
+ public static AutoGGConfig get() {
+ return instance;
}
- public boolean isCasualAutoGGEnabled() {
- return casualAutoGGEnabled;
+ public static void load() {
+ if (Files.exists(CONFIG_PATH)) {
+ try (Reader reader = Files.newBufferedReader(CONFIG_PATH)) {
+ AutoGGConfig loaded = GSON.fromJson(reader, AutoGGConfig.class);
+ if (loaded != null) instance = loaded;
+ } catch (IOException e) {
+ AutoGG.LOGGER.error("Failed to load AutoGG config", e);
+ }
+ }
+ save();
}
- public boolean isAntiGGEnabled() {
- return antiGGEnabled;
+ public static void save() {
+ try (Writer writer = Files.newBufferedWriter(CONFIG_PATH)) {
+ GSON.toJson(instance, writer);
+ } catch (IOException e) {
+ AutoGG.LOGGER.error("Failed to save AutoGG config", e);
+ }
}
- public boolean isAntiKarmaEnabled() {
- return antiKarmaEnabled;
- }
-
- public int getAutoGGDelay() {
- return autoGGDelay;
- }
-
- public int getAutoGGPhrase() {
- return autoGGPhrase;
- }
-
- public boolean isSecondaryEnabled() {
- return secondaryEnabled;
- }
-
- public int getAutoGGPhrase2() {
- return autoGGPhrase2;
- }
-
- public int getSecondaryDelay() {
- return secondaryDelay;
- }
-
- public void setAutoGGDelay(int autoGGDelay) {
- this.autoGGDelay = autoGGDelay;
- }
-
- public void setSecondaryDelay(int secondaryDelay) {
- this.secondaryDelay = secondaryDelay;
- }
+ public boolean isModEnabled() { return modEnabled; }
+ public boolean isCasualAutoGGEnabled() { return casualAutoGGEnabled; }
+ public int getAutoGGDelay() { return Math.max(0, Math.min(5, autoGGDelay)); }
+ public int getAutoGGPhrase() { return Math.max(0, Math.min(5, autoGGPhrase)); }
+ public boolean isAntiGGEnabled() { return antiGGEnabled; }
+ public boolean isAntiKarmaEnabled() { return antiKarmaEnabled; }
+ public boolean isSecondaryEnabled() { return secondaryEnabled; }
+ public int getAutoGGPhrase2() { return Math.max(0, Math.min(8, autoGGPhrase2)); }
+ public int getSecondaryDelay() { return Math.max(0, Math.min(5, secondaryDelay)); }
}
diff --git a/src/main/java/club/sk1er/mods/autogg/detectors/branding/ServerBrandingDetector.java b/src/main/java/club/sk1er/mods/autogg/detectors/branding/ServerBrandingDetector.java
index b444ec2..9ad3f82 100644
--- a/src/main/java/club/sk1er/mods/autogg/detectors/branding/ServerBrandingDetector.java
+++ b/src/main/java/club/sk1er/mods/autogg/detectors/branding/ServerBrandingDetector.java
@@ -3,10 +3,16 @@
import club.sk1er.mods.autogg.detectors.IDetector;
import club.sk1er.mods.autogg.handlers.patterns.PatternHandler;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
public class ServerBrandingDetector implements IDetector {
@Override
public boolean detect(String data) {
- return Minecraft.getMinecraft().thePlayer != null && PatternHandler.INSTANCE.getOrRegisterPattern(data).matcher(Minecraft.getMinecraft().thePlayer.getClientBrand()).matches();
+ Minecraft mc = Minecraft.getInstance();
+ if (mc.player == null || mc.getConnection() == null) return false;
+ ClientCommonPacketListenerImpl connection = (ClientCommonPacketListenerImpl) mc.getConnection();
+ String brand = connection.serverBrand();
+ if (brand == null) return false;
+ return PatternHandler.INSTANCE.getOrRegisterPattern(data).matcher(brand).matches();
}
}
diff --git a/src/main/java/club/sk1er/mods/autogg/detectors/ip/ServerIPDetector.java b/src/main/java/club/sk1er/mods/autogg/detectors/ip/ServerIPDetector.java
index 352be60..f3055f4 100644
--- a/src/main/java/club/sk1er/mods/autogg/detectors/ip/ServerIPDetector.java
+++ b/src/main/java/club/sk1er/mods/autogg/detectors/ip/ServerIPDetector.java
@@ -3,10 +3,15 @@
import club.sk1er.mods.autogg.detectors.IDetector;
import club.sk1er.mods.autogg.handlers.patterns.PatternHandler;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.ServerData;
public class ServerIPDetector implements IDetector {
@Override
public boolean detect(String data) {
- return Minecraft.getMinecraft().thePlayer != null && PatternHandler.INSTANCE.getOrRegisterPattern(data).matcher(Minecraft.getMinecraft().getCurrentServerData().serverIP).matches();
+ Minecraft mc = Minecraft.getInstance();
+ if (mc.player == null) return false;
+ ServerData serverData = mc.getCurrentServer();
+ if (serverData == null) return false;
+ return PatternHandler.INSTANCE.getOrRegisterPattern(data).matcher(serverData.ip).matches();
}
}
diff --git a/src/main/java/club/sk1er/mods/autogg/handlers/gg/AutoGGHandler.java b/src/main/java/club/sk1er/mods/autogg/handlers/gg/AutoGGHandler.java
index c6d40e2..f18f0fe 100644
--- a/src/main/java/club/sk1er/mods/autogg/handlers/gg/AutoGGHandler.java
+++ b/src/main/java/club/sk1er/mods/autogg/handlers/gg/AutoGGHandler.java
@@ -1,35 +1,29 @@
package club.sk1er.mods.autogg.handlers.gg;
import club.sk1er.mods.autogg.AutoGG;
+import club.sk1er.mods.autogg.config.AutoGGConfig;
import club.sk1er.mods.autogg.handlers.patterns.PatternHandler;
import club.sk1er.mods.autogg.tasks.data.Server;
import club.sk1er.mods.autogg.tasks.data.Trigger;
-import gg.essential.universal.wrappers.message.UMessage;
+import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
+import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
+import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.util.EnumChatFormatting;
-import net.minecraftforge.client.event.ClientChatReceivedEvent;
-import net.minecraftforge.event.entity.EntityJoinWorldEvent;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.fml.common.gameevent.TickEvent;
+import net.minecraft.network.chat.Component;
import java.util.concurrent.TimeUnit;
import static club.sk1er.mods.autogg.AutoGG.POOL;
-/**
- * Where the magic happens...
- * We handle which server's triggers should be used
- * and how to detect which server the player is currently
- * on.
- */
public class AutoGGHandler {
private volatile Server server;
private long lastGG = 0;
- @SubscribeEvent
- public void onEntityJoinWorld(EntityJoinWorldEvent event) {
- if (event.entity == Minecraft.getMinecraft().thePlayer && AutoGG.INSTANCE.getAutoGGConfig().isModEnabled()) {
+ public void register() {
+ ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
+ server = null;
+ if (!AutoGGConfig.get().isModEnabled()) return;
+
POOL.submit(() -> {
for (Server s : AutoGG.INSTANCE.getTriggers().getServers()) {
try {
@@ -37,106 +31,106 @@ public void onEntityJoinWorld(EntityJoinWorldEvent event) {
server = s;
return;
}
- } catch (Throwable e) {
- // Stop log spam
+ } catch (Throwable ignored) {
}
}
-
- // In case if it's not null and we couldn't find the triggers for the current server.
- server = null;
});
- if (!AutoGG.INSTANCE.usingEnglish) {
- new UMessage("AutoGG").chat();
- new UMessage("We've detected your Hypixel language isn't set to English! AutoGG will not work on other languages.\n" +
- "If this is a mistake, feel free to ignore it.").chat();
+
+ if (!AutoGG.INSTANCE.usingEnglish && client.player != null) {
+ client.player.sendSystemMessage(Component.literal(
+ ChatFormatting.GOLD + "[AutoGG] " + ChatFormatting.RED +
+ "We've detected your Hypixel language isn't set to English! " +
+ "AutoGG will not work on other languages."
+ ));
}
- }
+ });
+
+ ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> server = null);
+
+ ClientReceiveMessageEvents.ALLOW_CHAT.register((message, signedMessage, sender, params, receptionTimestamp) ->
+ handleIncoming(message.getString())
+ );
+
+ ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> {
+ if (overlay) return true;
+ return handleIncoming(message.getString());
+ });
}
- @SubscribeEvent
- public void onClientChatReceived(ClientChatReceivedEvent event) {
- if (event.type == 2) return;
- String stripped = EnumChatFormatting.getTextWithoutFormattingCodes(event.message.getUnformattedText());
+ // Returns false to cancel the message, true to allow it
+ private boolean handleIncoming(String rawMessage) {
+ if (!AutoGGConfig.get().isModEnabled() || server == null) return true;
- if (AutoGG.INSTANCE.getAutoGGConfig().isModEnabled() && server != null) {
+ String stripped = ChatFormatting.stripFormatting(rawMessage);
+
+ for (Trigger trigger : server.getTriggers()) {
+ switch (trigger.getType()) {
+ case ANTI_GG:
+ if (AutoGGConfig.get().isAntiGGEnabled() &&
+ PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
+ return false;
+ }
+ break;
+ case ANTI_KARMA:
+ if (AutoGGConfig.get().isAntiKarmaEnabled() &&
+ PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ POOL.submit(() -> {
for (Trigger trigger : server.getTriggers()) {
switch (trigger.getType()) {
- case ANTI_GG:
- if (AutoGG.INSTANCE.getAutoGGConfig().isAntiGGEnabled()) {
- if (PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
- event.setCanceled(true);
- return;
- }
+ case NORMAL:
+ if (PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
+ invokeGG();
+ return;
}
break;
- case ANTI_KARMA:
- if (AutoGG.INSTANCE.getAutoGGConfig().isAntiKarmaEnabled()) {
- if (PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
- event.setCanceled(true);
- return;
- }
+ case CASUAL:
+ if (AutoGGConfig.get().isCasualAutoGGEnabled() &&
+ PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
+ invokeGG();
+ return;
}
break;
+ default:
+ break;
}
}
+ });
- POOL.submit(() -> {
- // Casual GG feature
- for (Trigger trigger : server.getTriggers()) {
- switch (trigger.getType()) {
- case NORMAL:
- if (PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
- invokeGG();
- return;
- }
- break;
-
- case CASUAL:
- if (AutoGG.INSTANCE.getAutoGGConfig().isCasualAutoGGEnabled()) {
- if (PatternHandler.INSTANCE.getOrRegisterPattern(trigger.getPattern()).matcher(stripped).matches()) {
- invokeGG();
- return;
- }
- }
- break;
- }
- }
- });
- }
+ return true;
}
private void invokeGG() {
- // Better safe than sorry
- if (server != null) {
- String prefix = server.getMessagePrefix();
-
- if (System.currentTimeMillis() - lastGG < 10_000) return;
- lastGG = System.currentTimeMillis();
-
- String ggMessage = AutoGG.INSTANCE.getPrimaryGGStrings()[AutoGG.INSTANCE.getAutoGGConfig().getAutoGGPhrase()];
- int delay = AutoGG.INSTANCE.getAutoGGConfig().getAutoGGDelay();
-
- POOL.schedule(() -> Minecraft.getMinecraft().thePlayer.sendChatMessage(prefix.isEmpty() ? ggMessage : prefix + " " + ggMessage), delay, TimeUnit.SECONDS);
-
- if (AutoGG.INSTANCE.getAutoGGConfig().isSecondaryEnabled()) {
- String secondGGMessage = AutoGG.INSTANCE.getSecondaryGGStrings()[AutoGG.INSTANCE.getAutoGGConfig().getAutoGGPhrase2()];
- int secondaryDelay = AutoGG.INSTANCE.getAutoGGConfig().getSecondaryDelay() + AutoGG.INSTANCE.getAutoGGConfig().getAutoGGDelay();
-
- POOL.schedule(() -> Minecraft.getMinecraft().thePlayer.sendChatMessage(prefix.isEmpty() ? ggMessage : prefix + " " + secondGGMessage), secondaryDelay, TimeUnit.SECONDS);
- }
+ if (server == null) return;
+ if (System.currentTimeMillis() - lastGG < 10_000) return;
+ lastGG = System.currentTimeMillis();
+
+ String prefix = server.getMessagePrefix();
+ String ggMessage = AutoGG.INSTANCE.getPrimaryGGStrings()[AutoGGConfig.get().getAutoGGPhrase()];
+ int delay = AutoGGConfig.get().getAutoGGDelay();
+
+ String firstMsg = prefix.isEmpty() ? ggMessage : prefix + " " + ggMessage;
+ POOL.schedule(() -> sendChat(firstMsg), delay, TimeUnit.SECONDS);
+
+ if (AutoGGConfig.get().isSecondaryEnabled()) {
+ String secondMsg = AutoGG.INSTANCE.getSecondaryGGStrings()[AutoGGConfig.get().getAutoGGPhrase2()];
+ String secondFull = prefix.isEmpty() ? secondMsg : prefix + " " + secondMsg;
+ int secondaryDelay = delay + AutoGGConfig.get().getSecondaryDelay();
+ POOL.schedule(() -> sendChat(secondFull), secondaryDelay, TimeUnit.SECONDS);
}
}
- /**
- * Gui Handling
- */
- public static GuiScreen displayScreen = null;
-
- @SubscribeEvent
- public void onTick(TickEvent.ClientTickEvent event) {
- if (event.phase != TickEvent.Phase.END) return;
- if (displayScreen == null) return;
- Minecraft.getMinecraft().displayGuiScreen(displayScreen);
- displayScreen = null;
+ private static void sendChat(String message) {
+ Minecraft mc = Minecraft.getInstance();
+ if (mc.player != null && mc.getConnection() != null) {
+ mc.getConnection().sendChat(message);
+ }
}
}
diff --git a/src/main/java/club/sk1er/mods/autogg/handlers/patterns/PatternHandler.java b/src/main/java/club/sk1er/mods/autogg/handlers/patterns/PatternHandler.java
index de5800c..9bfca2b 100644
--- a/src/main/java/club/sk1er/mods/autogg/handlers/patterns/PatternHandler.java
+++ b/src/main/java/club/sk1er/mods/autogg/handlers/patterns/PatternHandler.java
@@ -1,30 +1,17 @@
package club.sk1er.mods.autogg.handlers.patterns;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
-/**
- * Helper for compiling Regular Expressions on startup to prevent them being compiled on each chat message.
- *
- * @author ChachyDev
- */
public class PatternHandler {
public static PatternHandler INSTANCE = new PatternHandler();
private final Map patternCache = new HashMap<>();
public Pattern getOrRegisterPattern(String pattern) {
- String processedPattern = PlaceholderAPI.INSTANCE.process(pattern);
-
- Pattern p = patternCache.get(processedPattern);
- if (p == null) {
- p = patternCache.put(processedPattern, Pattern.compile(processedPattern));
- }
-
- return p;
+ String processed = PlaceholderAPI.INSTANCE.process(pattern);
+ return patternCache.computeIfAbsent(processed, Pattern::compile);
}
public void clearPatterns() {
diff --git a/src/main/java/club/sk1er/mods/autogg/handlers/web/WebHandler.java b/src/main/java/club/sk1er/mods/autogg/handlers/web/WebHandler.java
index 0350a85..dce83d0 100644
--- a/src/main/java/club/sk1er/mods/autogg/handlers/web/WebHandler.java
+++ b/src/main/java/club/sk1er/mods/autogg/handlers/web/WebHandler.java
@@ -2,12 +2,13 @@
import com.google.gson.Gson;
import com.google.gson.JsonObject;
-import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
public class WebHandler {
private static final Gson gson = new Gson();
@@ -19,7 +20,7 @@ public static JsonObject fetchJson(String url) {
public static String fetchString(String url) {
try {
- return fetchString(new URL(url));
+ return fetchString(URI.create(url).toURL());
} catch (Exception e) {
return "malformed url";
}
@@ -29,9 +30,8 @@ public static String fetchString(URL url) {
try {
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", "AutoGG");
-
try (InputStream in = connection.getInputStream()) {
- return IOUtils.toString(in, "UTF-8");
+ return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
} catch (IOException ex) {
ex.printStackTrace();
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
new file mode 100644
index 0000000..2de5781
--- /dev/null
+++ b/src/main/resources/fabric.mod.json
@@ -0,0 +1,18 @@
+{
+ "schemaVersion": 1,
+ "id": "autogg",
+ "version": "${version}",
+ "name": "AutoGG",
+ "description": "AutoGG automatically says a selectable phrase after a game has ended on supported servers.",
+ "authors": ["2Pi", "Sk1er LLC", "SirNapkin1334"],
+ "license": "LGPL-3.0",
+ "environment": "client",
+ "entrypoints": {
+ "client": ["club.sk1er.mods.autogg.AutoGG"]
+ },
+ "depends": {
+ "fabricloader": ">=0.19.0",
+ "fabric-api": "*",
+ "minecraft": "26.2"
+ }
+}
diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info
deleted file mode 100644
index 39792eb..0000000
--- a/src/main/resources/mcmod.info
+++ /dev/null
@@ -1,20 +0,0 @@
-[
- {
- "modid": "autogg",
- "name": "AutoGG",
- "description": "AutoGG automatically says a selectable phrase after a game has ended on supported servers.",
- "version": "${version}",
- "mcversion": "${mcVersionStr}",
- "url": "https://sk1er.club/",
- "updateUrl": "",
- "authorList": [
- "2Pi",
- "Sk1er LLC",
- "SirNapkin1334"
- ],
- "credits": "Created by 2PI, maintained and updated by Sk1er LLC. Regex update created by SirNapkin1334.",
- "logoFile": "",
- "screenshots": [],
- "dependencies": []
- }
-]