diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..e075f0b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,14 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: udu3324 +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +polar: # Replace with a single Polar username +buy_me_a_coffee: # Replace with a single Buy Me a Coffee username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e2fa68a..15ae91e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: matrix: # Use these Java versions java: [ - 17, # Current Java LTS & minimum supported by Minecraft + 21, # Current Java LTS & minimum supported by Minecraft ] # and run on both Linux and Windows os: [ubuntu-22.04, windows-2022] @@ -33,7 +33,7 @@ jobs: - name: build run: ./gradlew build - name: capture build artifacts - if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS + if: ${{ runner.os == 'Linux' && matrix.java == '21' }} # Only upload artifacts built from latest java on one OS uses: actions/upload-artifact@v3 with: name: Artifacts diff --git a/README.md b/README.md index bb28726..bb58ebe 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,44 @@ ![Mod Banner](https://github.com/udu3324/Poinpow/blob/master/src/main/resources/assets/poinpow/banner.png?raw=true) -![License](https://img.shields.io/github/license/udu3324/poinpow) -![Latest Releases](https://img.shields.io/github/v/release/udu3324/Poinpow) -![Github Downloads](https://img.shields.io/github/downloads/udu3324/poinpow/total) -![Modrinth Downloads](https://img.shields.io/badge/dynamic/json?color=1bd96a&label=modrinth&query=downloads&suffix=%20downloads&url=https%3A%2F%2Fapi.modrinth.com%2Fv2%2Fproject%2Fpoinpow) -![Mod loader: Fabric](https://img.shields.io/badge/modloader-Fabric-decea6?style=round) -![Requires](https://img.shields.io/badge/requires-Fabric%20API-dece5a?style=round) +![License](https://img.shields.io/github/license/udu3324/poinpow) +![Latest Releases](https://img.shields.io/github/v/release/udu3324/Poinpow) +![Github Downloads](https://img.shields.io/github/downloads/udu3324/poinpow/total) +![Modrinth Downloads](https://img.shields.io/badge/dynamic/json?color=1bd96a&label=modrinth&query=downloads&suffix=%20downloads&url=https%3A%2F%2Fapi.modrinth.com%2Fv2%2Fproject%2Fpoinpow) +![Mod loader: Fabric](https://img.shields.io/badge/modloader-Fabric-decea6?style=round) +![Requires](https://img.shields.io/badge/requires-Fabric%20API-dece5a?style=round) [![Discord Server](https://img.shields.io/badge/Official%20Discord%20Server-7289DA?style=round&logo=discord&logoColor=white)](https://discord.gg/NXm9tJvyBT) # ๐Ÿ“˜ Features -Poinpow adds **utilities/features** that **make the player experience 102% better**. If you catch a bug, create an issue in the repo or send it to me in this [discord server](https://discord.gg/NXm9tJvyBT). - -- **AutoSkipBarrier** - Automatically skip the ads when joining minehut or free servers. -- **HubCommandBack** - Adds back the hub command. -- **BlockMinehutAds** - Blocks ads from minehut that are sent in free servers `Example: [Minehut] boost your server speed!!!` -- **ChatPhraseFilter** - Filters and blocks messages in chat based on a regex list. -- **BlockLobbyAds** - Blocks player made ads in the lobby. `Example: [Ad] NintendoOS: /join fishwind join my server for op yes` -- **BlockFreeCredits** - Blocks the vote messages encouraging to vote for free credits. -- **BlockLobbyWelcome** - Blocks the lobby join message that sometimes has an ad in it. -- **BlockLobbyMapAds** - Removes the humungous map art that advertises things in lobby. -- **BlockRaids** - Blocks the raid messages in hub. -- **ToggleSpecificAds** - Extends BlockLobbyAds to toggle which ranks can advertise. -- **BlockChestAds** - Removes the ads inside the compass server listing in hub. -- **ServerLookup** - A command to see details about a minehut server. (by [BuggyAl](https://github.com/BuggyAl)) - -![](https://cdn.modrinth.com/data/zmUzIoT1/images/aaa8cda2723de8979014cde22db46d34c8160553.png) -Skipping ads **automatically** with AutoSkipBarrier **(extremely fast)** - -![](https://cdn.modrinth.com/data/zmUzIoT1/images/c49843c5f4e7412df0c53670e94f3434eb4c4238.png) +Poinpow is a fabric mod that adds **amazing features** and **makes the player experience 103% better**. (QoL) Features that Minehut locks behind a paywall (ex: removing ads, muting chat, etc.) are in Poinpow. + +| Features | Command | +|:------------------|:-------------------------------------------------------------------------------------------------------| +| AutoSkipBarrier | Automatically skips the transition ads when joining minehut/free servers. | +| BlockLobbyAds | Blocks player made ads in the lobby. | +| ToggleSpecificAds | Extends the functionality of BlockLobbyAds to block certain ads based on ranks. | +| ChatPhraseFilter | Filters and blocks messages in chat based on a regex list. | +| ServerLookup | A command to see details about a minehut server. Contributed by [BuggyAl](https://github.com/BuggyAl). | +| MuteLobbyChat | A command that mutes Minehut's lobby, only allowing `/msg`, joins, and some other stuff. | +| HubCommandBack | Adds back the `/hub` command. It redirects the command `/hub` to `/mh` when necessary. | +| BlockChestAds | Removes the ads inside the compass server listing in hub. | +| BlockLobbyMapAds | Removes the humungous map art that advertises things in lobby. | +| BlockLobbyWelcome | Blocks the lobby join message that sometimes has an ad in it. | +| BlockRaids | Blocks the raid messages in hub. | +| BlockFreeCredits | Blocks the vote messages encouraging to vote for free credits. | +| BlockMinehutAds | Blocks ads from Minehut that are sent in free servers. | + + +![screenshot of me using AutoSkipBarrier](https://cdn.modrinth.com/data/zmUzIoT1/images/aaa8cda2723de8979014cde22db46d34c8160553.png) +Skipping ads **automatically** with AutoSkipBarrier **(extremely fast)** +![screenshot of me using BlockLobbyAds and BlockLobbyMapAds](https://cdn.modrinth.com/data/zmUzIoT1/images/c49843c5f4e7412df0c53670e94f3434eb4c4238.png) Example of **BlockLobbyAds** (blocks ads made by player) and **BlockLobbyMapAds**. It clears up chat a lot and blocks those awful map ads. -![](https://cdn.modrinth.com/data/zmUzIoT1/images/75745e7d81968d0ad369493ab3174f0d2a605517.png) -/poinpow - An **intractable/clickable** help command that easily allows the toggling of features. -## ๐Ÿ’พ How to Install +![commands of poinpow](https://cdn.modrinth.com/data/zmUzIoT1/images/75745e7d81968d0ad369493ab3174f0d2a605517.png) +/poinpow - An **intractable/clickable** help command that easily allows the toggling of features. (image may be outdated) + +## ๐Ÿ’พ How to Install the Mod 1. Make sure you have **[Fabric](https://fabricmc.net/use/installer/)** installed in your mc launcher 2. Download the latest release of **Poinpow** [here](https://github.com/udu3324/poinpow/releases) 3. Download the latest release of **Fabric API** [here](https://modrinth.com/mod/fabric-api/versions) @@ -50,7 +54,7 @@ If you want to **contribute to the code** or **make the jar yourself**, you can 3. Open a terminal and cd to the folder 4. Run `gradlew build` or `.\gradlew build` depending on your system os 5. Done! The jar should be in `/build/libs` -6. (optional) Open up the folder in your IDE (intellij recommended) to look at the code and contribute to it if you want :> +6. (optional) Open up the folder in your IDE (intellij recommended) to look at the code and contribute to it if you want to. Run `.\gradlew runClient` to run the mod directly in your IDE. ## ๐Ÿงพ Is it Against the Rules? **No.** I read the rules, and it doesn't break any. Unless..... "Minehut reserves the right to suspend or refuse service for users and servers at any time at their discretion." bruh diff --git a/gradle.properties b/gradle.properties index 7c311a1..ac7848e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.parallel=true loader_version=0.15.11 # Mod Properties - mod_version = 1.7 + mod_version = 1.7.1 maven_group = com.udu3324 archives_base_name = poinpow diff --git a/src/main/java/com/udu3324/poinpow/Config.java b/src/main/java/com/udu3324/poinpow/Config.java index 656765a..4fcd274 100644 --- a/src/main/java/com/udu3324/poinpow/Config.java +++ b/src/main/java/com/udu3324/poinpow/Config.java @@ -239,6 +239,8 @@ public static void create() { BlockRaids.toggled.set(Boolean.parseBoolean(getValueFromConfig(HubCommandBack.name))); BlockChestAds.toggled.set(Boolean.parseBoolean(getValueFromConfig(BlockChestAds.name))); + MuteLobbyChat.toggled = Boolean.parseBoolean(getValueFromConfig(MuteLobbyChat.name)); + defaultRank = Boolean.parseBoolean(getValueFromConfig(name + "_default")); vip = Boolean.parseBoolean(getValueFromConfig(name + "_vip")); vipPlus = Boolean.parseBoolean(getValueFromConfig(name + "_vipPlus")); @@ -268,6 +270,7 @@ private static void writeDefaultConfig() throws IOException { w.write(HubCommandBack.name + ": true" + System.lineSeparator()); w.write(BlockRaids.name + ": true" + System.lineSeparator()); w.write(BlockChestAds.name + ": true" + System.lineSeparator()); + w.write(MuteLobbyChat.name + ": false" + System.lineSeparator()); w.write(name + "_default: false" + System.lineSeparator()); w.write(name + "_vip: false" + System.lineSeparator()); diff --git a/src/main/java/com/udu3324/poinpow/api/Minecraft.java b/src/main/java/com/udu3324/poinpow/api/Minecraft.java new file mode 100644 index 0000000..5a9e96b --- /dev/null +++ b/src/main/java/com/udu3324/poinpow/api/Minecraft.java @@ -0,0 +1,67 @@ +package com.udu3324.poinpow.api; + +import com.udu3324.poinpow.Poinpow; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +public class Minecraft { + public static Map uuidOfPlayers = new HashMap<>(); + + //this gets a player's uuid from their ign + public static String getUUID(String ign) { + try { + //check if player's uuid has already been cached + if (uuidOfPlayers.containsKey(ign)) { + //Poinpow.log.info("ign {} cached with uuid {}", uuid, playerRank.get(ign)); + return uuidOfPlayers.get(ign); + } + + URL apiURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + ign); + HttpURLConnection connection = (HttpURLConnection) apiURL.openConnection(); + connection.setRequestMethod("GET"); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + Poinpow.log.error("Player ({}) not found! ({})", ign, connection.getResponseCode()); + return null; + } + + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + + String json = response.toString().replaceAll(" ", ""); + + connection.disconnect(); + + //parse uuid + int start = json.indexOf("id\":\"") + 5; + int end = json.indexOf("\",\"", start); + + json = json.substring(start, end); + + uuidOfPlayers.put(ign, json); + + return json; + } catch (Exception e) { + Poinpow.log.error("Response to minecraft api was unsuccessful. Player ign: {} - {}", ign, e); + return null; + } + } + + public static String insertUUIDDashes(String uuid) { + StringBuilder sb = new StringBuilder(uuid); + sb.insert(8, "-"); + sb.insert(13, "-"); + sb.insert(18, "-"); + sb.insert(23, "-"); + return sb.toString(); + } +} diff --git a/src/main/java/com/udu3324/poinpow/api/Minehut.java b/src/main/java/com/udu3324/poinpow/api/Minehut.java index 92a9333..e481e8f 100644 --- a/src/main/java/com/udu3324/poinpow/api/Minehut.java +++ b/src/main/java/com/udu3324/poinpow/api/Minehut.java @@ -3,15 +3,37 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.udu3324.poinpow.Poinpow; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.scoreboard.Scoreboard; +import net.minecraft.scoreboard.ScoreboardObjective; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; public class Minehut { + public static Map playerRank = new HashMap<>(); + + public static Boolean inLobby() { + if (MinecraftClient.getInstance().player == null) return null; + + // check for scoreboard + Scoreboard scoreboard = MinecraftClient.getInstance().player.getScoreboard(); + ArrayList scores = new ArrayList<>(); + for (ScoreboardObjective objective : scoreboard.getObjectives()) { + scores.add(objective.getDisplayName().toString()); + } + + return scores.toString().toLowerCase().contains("minehut"); + } + //(BuggyAl) this gets information about a server in json public static JsonObject getServer(ClientPlayerEntity player, String serverName) { try { @@ -19,10 +41,14 @@ public static JsonObject getServer(ClientPlayerEntity player, String serverName) HttpURLConnection connection = (HttpURLConnection) apiURL.openConnection(); connection.setRequestMethod("GET"); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + if (connection.getResponseCode() == 500) { player.sendMessage(Text.literal("Server not found! (" + connection.getResponseCode() + ")").styled(style -> style .withColor(Formatting.RED))); return null; + } else if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { // bruh + player.sendMessage(Text.literal("Server not found! API may be down. (" + connection.getResponseCode() + ")").styled(style -> style + .withColor(Formatting.RED))); + return null; } JsonObject obj = JsonParser.parseReader(new InputStreamReader(connection.getInputStream())).getAsJsonObject().get("server").getAsJsonObject(); @@ -36,4 +62,45 @@ public static JsonObject getServer(ClientPlayerEntity player, String serverName) return null; } } + + //this gets a player's mh rank through their uuid, has to have dashes in + public static String getRank(String uuid) { + try { + //check if rank of player already has been cached + if (playerRank.containsKey(uuid)) { + //Poinpow.log.info("uuid {} cached with rank {}", uuid, playerRank.get(uuid)); + return playerRank.get(uuid); + } + + URL apiURL = new URL("https://api.minehut.com/cosmetics/profile/" + uuid); + HttpURLConnection connection = (HttpURLConnection) apiURL.openConnection(); + connection.setRequestMethod("GET"); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + Poinpow.log.error("Player ({}) not found! ({})", uuid, connection.getResponseCode()); + return null; + } + + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + String json; + json = in.readLine(); + + in.close(); + + connection.disconnect(); + + //parse rank + int start = json.indexOf("rank\":\"") + 7; + int end = json.indexOf("\",\"", start); + + String rank = json.substring(start, end); + playerRank.put(uuid, rank); + + return rank; + } catch (Exception e) { + Poinpow.log.error("Response to minehut api was unsuccessful. Player uuid: {} {}", uuid, e); + return null; + } + } } diff --git a/src/main/java/com/udu3324/poinpow/commands/Commands.java b/src/main/java/com/udu3324/poinpow/commands/Commands.java index 0dc9f6d..3dbd061 100644 --- a/src/main/java/com/udu3324/poinpow/commands/Commands.java +++ b/src/main/java/com/udu3324/poinpow/commands/Commands.java @@ -23,6 +23,7 @@ public class Commands { //register poinpow commands in the mc brigadier public static void register(CommandDispatcher dispatcher) { ServerLookup.registerCommand(dispatcher); + MuteLobbyChat.registerCommand(dispatcher); dispatcher.register(literal("poinpow") .executes(ctx -> help(ctx.getSource())) @@ -193,6 +194,13 @@ private static int help(FabricClientCommandSource source) { .withColor(Formatting.DARK_GRAY) )); + //toggle lobby chat + source.sendFeedback(Text.literal("[" + MuteLobbyChat.toggled + "] " + MuteLobbyChat.name).styled(style -> style + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal(MuteLobbyChat.description + "\n\nClick to Toggle"))) + .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + MuteLobbyChat.name)) + .withColor(Formatting.DARK_GRAY) + )); + //chat phrase filter source.sendFeedback(Text.literal("/poinpow " + ChatPhraseFilter.name + " ").styled(style -> style .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal(ChatPhraseFilter.description + "\n\nClick to change"))) diff --git a/src/main/java/com/udu3324/poinpow/mixin/ChatMixin.java b/src/main/java/com/udu3324/poinpow/mixin/ChatMixin.java index 4a9f05e..a9f5e13 100644 --- a/src/main/java/com/udu3324/poinpow/mixin/ChatMixin.java +++ b/src/main/java/com/udu3324/poinpow/mixin/ChatMixin.java @@ -1,7 +1,9 @@ package com.udu3324.poinpow.mixin; +import com.udu3324.poinpow.api.Minehut; import com.udu3324.poinpow.commands.Commands; import com.udu3324.poinpow.utils.*; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.MessageIndicator; import net.minecraft.network.message.MessageSignatureData; @@ -13,13 +15,23 @@ @Mixin(ChatHud.class) public class ChatMixin { - @Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true) + @Inject(method = "Lnet/minecraft/client/gui/hud/ChatHud;addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true) private void onMessage(Text message, MessageSignatureData signature, MessageIndicator indicator, CallbackInfo ci) { String chat = message.getString(); //don't allow blockers to run while help command is running if (Commands.running) return; + //if lobby chat is toggled, don't run checks + if (MuteLobbyChat.toggled) { + // if they're in lobby & the message isn't allowed, cancel. + Boolean inLobby = Minehut.inLobby(); + if (inLobby != null && inLobby && !MuteLobbyChat.isAllowed(chat)) { + ci.cancel(); + return; + } + } + if (BlockLobbyWelcome.check(chat, ci)) return; if (BlockLobbyAds.check(chat, ci)) return; @@ -32,4 +44,9 @@ private void onMessage(Text message, MessageSignatureData signature, MessageIndi ChatPhraseFilter.check(chat, ci); } + + @Inject(method = "Lnet/minecraft/client/gui/hud/ChatHud;render(Lnet/minecraft/client/gui/DrawContext;IIIZ)V", at = @At("RETURN"), cancellable = true) + private void onRender(DrawContext context, int currentTick, int mouseX, int mouseY, boolean focused, CallbackInfo ci) { + MuteLobbyChat.check(); + } } diff --git a/src/main/java/com/udu3324/poinpow/mixin/WorldLoadedMixin.java b/src/main/java/com/udu3324/poinpow/mixin/WorldLoadedMixin.java index eea1532..a3f3f1c 100644 --- a/src/main/java/com/udu3324/poinpow/mixin/WorldLoadedMixin.java +++ b/src/main/java/com/udu3324/poinpow/mixin/WorldLoadedMixin.java @@ -3,6 +3,7 @@ import com.udu3324.poinpow.Poinpow; import com.udu3324.poinpow.api.GitHubVersion; import com.udu3324.poinpow.utils.AutoSkipBarrier; +import com.udu3324.poinpow.utils.MuteLobbyChat; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.minecraft.client.MinecraftClient; @@ -28,5 +29,8 @@ private static void onLoad(ClientPlayConnectionEvents.Join[] callbacks, ClientPl if (Poinpow.onMinehut) GitHubVersion.check(); AutoSkipBarrier.check(); + + //allow to send a check only once cause chat gets rendered per tick + MuteLobbyChat.canSendCheck = true; } } diff --git a/src/main/java/com/udu3324/poinpow/utils/BlockLobbyAds.java b/src/main/java/com/udu3324/poinpow/utils/BlockLobbyAds.java index cae9d9f..08ace90 100644 --- a/src/main/java/com/udu3324/poinpow/utils/BlockLobbyAds.java +++ b/src/main/java/com/udu3324/poinpow/utils/BlockLobbyAds.java @@ -23,11 +23,12 @@ public static Boolean check(String chat, CallbackInfo ci) { //if it's not a suspected ad, return if (!(pattern.matcher(chat).find() || chat.contains(": /join"))) return false; - //since it's an ad, check the rank if its allowed - boolean yeah = ToggleSpecificAds.checkRank(chat); + //confirmed an ad - if (yeah) return false; + //check if the rank is allowed to send it, return to allow sending + if (ToggleSpecificAds.checkRank(chat)) return false; + Poinpow.log.info("Blocked: {}", chat.replace("\n", "")); ci.cancel(); return true; diff --git a/src/main/java/com/udu3324/poinpow/utils/BlockLobbyMapAds.java b/src/main/java/com/udu3324/poinpow/utils/BlockLobbyMapAds.java index 317876e..3f80281 100644 --- a/src/main/java/com/udu3324/poinpow/utils/BlockLobbyMapAds.java +++ b/src/main/java/com/udu3324/poinpow/utils/BlockLobbyMapAds.java @@ -1,19 +1,16 @@ package com.udu3324.poinpow.utils; import com.udu3324.poinpow.Poinpow; -import net.minecraft.client.MinecraftClient; +import com.udu3324.poinpow.api.Minehut; import net.minecraft.client.gui.hud.ClientBossBar; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.scoreboard.ScoreboardObjective; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.ArrayList; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -31,16 +28,8 @@ public static void block(Entity entity) { // return if not on minehut if (!Poinpow.onMinehut) return; - if (MinecraftClient.getInstance().player == null) return; - - // check for scoreboard - Scoreboard scoreboard = MinecraftClient.getInstance().player.getScoreboard(); - ArrayList scores = new ArrayList<>(); - for (ScoreboardObjective objective : scoreboard.getObjectives()) { - scores.add(objective.getDisplayName().toString()); - } - - if (!scores.toString().toLowerCase().contains("minehut")) return; + Boolean inLobby = Minehut.inLobby(); + if (inLobby == null || !inLobby) return; // remove if item frame has a map in it ItemFrameEntity itemFrame = (ItemFrameEntity) entity; diff --git a/src/main/java/com/udu3324/poinpow/utils/MuteLobbyChat.java b/src/main/java/com/udu3324/poinpow/utils/MuteLobbyChat.java new file mode 100644 index 0000000..a33435b --- /dev/null +++ b/src/main/java/com/udu3324/poinpow/utils/MuteLobbyChat.java @@ -0,0 +1,83 @@ +package com.udu3324.poinpow.utils; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.udu3324.poinpow.Config; +import com.udu3324.poinpow.api.Minehut; +import com.udu3324.poinpow.commands.Commands; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.MinecraftClient; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class MuteLobbyChat { + public static String name = "muteLobbyChat"; + public static String description = "This mutes the lobby chat if you don't want to see it."; + + public static boolean toggled = false; + public static boolean canSendCheck = false; + + public static void registerCommand(CommandDispatcher dispatcher) { + dispatcher.register(ClientCommandManager.literal(name).executes(ctx -> toggle(ctx.getSource()))); + } + + private static int toggle(FabricClientCommandSource source) { + Commands.running = true; + + //don't allow check as they already know + canSendCheck = false; + + if (toggled) { + source.sendFeedback(Text.literal("Lobby chat has been unmuted.").styled(style -> style + .withColor(Formatting.RED))); + + toggled = false; + } else { + source.sendFeedback(Text.literal("Lobby chat has been muted.").styled(style -> style + .withColor(Formatting.GREEN))); + + toggled = true; + } + + Config.setValueFromConfig(name, String.valueOf(toggled)); + + Commands.running = false; + return Command.SINGLE_SUCCESS; + } + + public static boolean isAllowed(String chat) { + if (MinecraftClient.getInstance().player == null || MinecraftClient.getInstance().player.getName().getLiteralString() == null) return false; + + //it is a /msg from someone + if (chat.startsWith("To") || chat.startsWith("From")) { + //it is a /msg from someone + return true; + } else if (!chat.contains(":")) { + //misc message should be allowed + return true; + } else if (chat.toLowerCase().contains(MinecraftClient.getInstance().player.getName().getLiteralString().toLowerCase())) { + //messages with the player's ign + return true; + } else { + return false; + } + } + + //this is run when joining back into the lobby while it is muted. + public static void check() { + if (!canSendCheck) return; + + if (!toggled) return; + + Boolean inLobby = Minehut.inLobby(); + if (inLobby != null && inLobby) { + MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(Text.literal("Lobby is currently muted by you. (click)").styled(style -> style + .withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + MuteLobbyChat.name)) + .withColor(Formatting.DARK_GRAY))); + } + + canSendCheck = false; + } +} diff --git a/src/main/java/com/udu3324/poinpow/utils/ServerLookup.java b/src/main/java/com/udu3324/poinpow/utils/ServerLookup.java index 59594f4..c8a8629 100644 --- a/src/main/java/com/udu3324/poinpow/utils/ServerLookup.java +++ b/src/main/java/com/udu3324/poinpow/utils/ServerLookup.java @@ -8,6 +8,7 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.udu3324.poinpow.Poinpow; import com.udu3324.poinpow.api.Minehut; +import com.udu3324.poinpow.commands.Commands; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; @@ -56,6 +57,8 @@ private static int lookup(String serverName) { status = Formatting.GREEN + "Online"; } + Commands.running = true; + player.sendMessage(Text.literal("")); player.sendMessage(Text.literal(serverName + " is ").styled(style -> style .withColor(Formatting.GOLD)) @@ -104,6 +107,8 @@ private static int lookup(String serverName) { } player.sendMessage(Text.literal("")); + + Commands.running = false; }).start(); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/com/udu3324/poinpow/utils/ToggleSpecificAds.java b/src/main/java/com/udu3324/poinpow/utils/ToggleSpecificAds.java index 88e42bb..53bbc03 100644 --- a/src/main/java/com/udu3324/poinpow/utils/ToggleSpecificAds.java +++ b/src/main/java/com/udu3324/poinpow/utils/ToggleSpecificAds.java @@ -1,6 +1,8 @@ package com.udu3324.poinpow.utils; import com.udu3324.poinpow.Config; +import com.udu3324.poinpow.api.Minecraft; +import com.udu3324.poinpow.api.Minehut; import com.udu3324.poinpow.commands.Commands; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import com.mojang.brigadier.Command; @@ -21,13 +23,53 @@ public class ToggleSpecificAds { //return true if a rank that is toggled is matched public static boolean checkRank(String chat) { - String rank = chat.substring(0, chat.indexOf(":")); - - //return true if none are activated + //return if none are activated if (!(defaultRank || vip || vipPlus || pro || legend || patron)) return false; - //check for if the rank portion contains it + //get ign from chat, then the uuid, then get their rank + String ign = chat.substring(0, chat.indexOf(":")); + ign = ign.substring(ign.lastIndexOf(" ") + 1); + + String uuid = Minecraft.getUUID(ign); + + //wi-fi errors, fake username, etc. + if (uuid == null) { + return false; + } + + //reformat the uuid because minehut is stupid + uuid = Minecraft.insertUUIDDashes(uuid); + + //use mh api to get their rank instead of parsing untrusted chat + String rank = Minehut.getRank(uuid); + + //wi-fi errors, etc. no clue why this scenario would ever happen... :) + if (rank == null) { + return fallback(chat); + } + + //System.out.println("rank: " + rank); + + //check if their rank is toggled or not + if (rank.equals("VIP") && vip) { + return true; + } else if (rank.equals("VIP_PLUS") && vipPlus) { + return true; + } else if (rank.equals("PRO") && pro) { + return true; + } else if (rank.equals("LEGEND") && legend) { + return true; + } else if (rank.equals("PATRON") && patron) { + return true; + } else return rank.equals("DEFAULT") && defaultRank; + } + + // fallback in case if mh api does not work (minehut sucks, and their staff are probably underpaid to do stuff) + private static boolean fallback(String chat) { + String rank = chat.substring(0, chat.indexOf(":")); + + //check if the rank portion in chat contains it if (rank.contains("[VIP]") && vip) { return true; } else if (rank.contains("[VIP+]") && vipPlus) { @@ -38,7 +80,7 @@ public static boolean checkRank(String chat) { return true; } else if (rank.contains("[PATRON]") && patron) { return true; - } else return !(rank.contains("VIP") || rank.contains("PRO") || rank.contains("LEGEND") || rank.contains("PATRON")) && defaultRank; + } else return !(rank.contains("[PATRON]") || rank.contains("[LEGEND]") || rank.contains("[PRO]") || rank.contains("[VIP+]") || rank.contains("[VIP]")) && defaultRank; } public static int toggle(FabricClientCommandSource source, String rank) { diff --git a/src/main/resources/assets/poinpow/image.jpg b/src/main/resources/assets/poinpow/image.jpg new file mode 100644 index 0000000..9a9efbd Binary files /dev/null and b/src/main/resources/assets/poinpow/image.jpg differ