diff options
| author | syeyoung <cyoung06@naver.com> | 2023-01-24 15:14:10 +0900 |
|---|---|---|
| committer | syeyoung <cyoung06@naver.com> | 2023-01-24 15:14:10 +0900 |
| commit | 7b54bf2ff34b8119451b59da79776d33c29061c8 (patch) | |
| tree | b06c0c1f5605e457af666c24e04188448b629618 /mod/src/main/java | |
| parent | 13bb84c42b2aebd2c0b33739620177d5ac2c2d9a (diff) | |
| download | Skyblock-Dungeons-Guide-7b54bf2ff34b8119451b59da79776d33c29061c8.tar.gz Skyblock-Dungeons-Guide-7b54bf2ff34b8119451b59da79776d33c29061c8.tar.bz2 Skyblock-Dungeons-Guide-7b54bf2ff34b8119451b59da79776d33c29061c8.zip | |
- Fix #261
Signed-off-by: syeyoung <cyoung06@naver.com>
Diffstat (limited to 'mod/src/main/java')
16 files changed, 843 insertions, 709 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java index 6482e5d5..707a4a20 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java @@ -19,7 +19,9 @@ package kr.syeyoung.dungeonsguide.mod.cosmetics; -import kr.syeyoung.dungeonsguide.mod.cosmetics.chatreplacers.*; +import kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors.*; +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.SurgicalReplacer; import kr.syeyoung.dungeonsguide.mod.events.impl.PlayerListItemPacketEvent; import kr.syeyoung.dungeonsguide.mod.events.impl.StompConnectedEvent; import kr.syeyoung.dungeonsguide.mod.stomp.StompHeader; @@ -32,6 +34,8 @@ import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.play.server.S38PacketPlayerListItem; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.IChatComponent; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -224,26 +228,134 @@ public class CosmeticsManager { requestPerms(); } @Getter @Setter - private static List<IChatReplacer> iChatReplacers = new ArrayList<>(); + private static List<IChatDetector> iChatDetectors = new ArrayList<>(); static { - iChatReplacers.add(new ChatReplacerViewProfile()); - iChatReplacers.add(new ChatReplacerPV()); - iChatReplacers.add(new ChatReplacerSocialOptions()); - iChatReplacers.add(new ChatReplacerCoop()); - iChatReplacers.add(new ChatReplacerMessage()); - iChatReplacers.add(new ChatReplacerChatByMe()); + iChatDetectors.add(new ChatDetectorProbablyUniversal()); + iChatDetectors.add(new ChatDetectorFriendList()); + iChatDetectors.add(new ChatDetectorGuildPartyList()); + iChatDetectors.add(new ChatDetectorPartyMessages()); + iChatDetectors.add(new ChatDetectorJoinLeave()); } - @SubscribeEvent(priority = EventPriority.LOWEST) + private final ThreadLocal<List<ReplacementContext>> contextThreadLocal = new ThreadLocal<>(); + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onChatDetect(ClientChatReceivedEvent clientChatReceivedEvent) { + try { + if (clientChatReceivedEvent.type == 2) return; + List<ReplacementContext> total = new ArrayList<>(); + for (IChatDetector iChatReplacer : iChatDetectors) { + List<ReplacementContext> replacementContext = iChatReplacer.getReplacementContext(clientChatReceivedEvent.message); + if (replacementContext != null) { + total.addAll(replacementContext); + } + } + contextThreadLocal.set(total); + } catch (Throwable t) { + System.out.println(clientChatReceivedEvent.message); + t.printStackTrace(); + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST, receiveCanceled = true) public void onChat(ClientChatReceivedEvent clientChatReceivedEvent) { try { if (clientChatReceivedEvent.type == 2) return; - for (IChatReplacer iChatReplacer : iChatReplacers) { - if (iChatReplacer.isAcceptable(clientChatReceivedEvent)) { - iChatReplacer.translate(clientChatReceivedEvent, this); + if (clientChatReceivedEvent.isCanceled()) { + contextThreadLocal.set(null); + return; + } + + List<ReplacementContext> replacementContexts = contextThreadLocal.get(); + contextThreadLocal.set(null); + + LinkedList<IChatComponent> chatComponents = SurgicalReplacer.linearifyMoveColorCharToStyle(clientChatReceivedEvent.message); + for (ReplacementContext replacementContext : replacementContexts) { + if (replacementContext.getUsername().isEmpty()) continue; + List<ActiveCosmetic> activeCosmetics = getActiveCosmeticByPlayerNameLowerCase() + .get(replacementContext.getUsername().toLowerCase()); + String color=null, prefix="[coolprefix]"; + if (activeCosmetics != null) { + for (ActiveCosmetic activeCosmetic : activeCosmetics) { + CosmeticData cosmeticData = getCosmeticDataMap().get(activeCosmetic.getCosmeticData()); + if (cosmeticData != null && cosmeticData.getCosmeticType().equals("color")) { + color = cosmeticData.getData().replace("&", "§"); + } else if (cosmeticData != null && cosmeticData.getCosmeticType().equals("prefix")) { + prefix = cosmeticData.getData().replace("&", "§"); + } + } + } + + if (color == null && prefix == null) continue; + + + StringBuilder sb = new StringBuilder(); + for (IChatComponent chatComponent : chatComponents) { + String str = chatComponent.getUnformattedText(); + sb.append(str); + } + + List<Integer> allIdxes = new ArrayList<>(); + int lastIdx = -1; + String theThing = sb.toString(); + do { + lastIdx = theThing.indexOf(replacementContext.getUsername(), lastIdx+1); + if (lastIdx != -1) + allIdxes.add(lastIdx); + } while (lastIdx != -1); + + int idx = allIdxes.stream() + .min(Comparator.comparingInt(a -> Math.abs(a - replacementContext.getNearIdx()))).orElse(-1); + + System.out.println("Was expecting to find " +replacementContext.getUsername()); + if (idx == -1) { + System.out.println("WTF?"); + + List<IChatComponent> components = SurgicalReplacer.inject(chatComponents, + SurgicalReplacer.linearifyMoveColorCharToStyle( + new ChatComponentText(prefix+" ") + .setChatStyle(SurgicalReplacer.getChatStyleAt(chatComponents, 0)) + ), + 0, 0); + clientChatReceivedEvent.message = SurgicalReplacer.combine(components); + // since we couldn't find username anywhere, just do this. return; } + + int stIdx = theThing.lastIndexOf('\n', idx) + 1; + String beforeUsername = theThing.substring(theThing.lastIndexOf('\n', idx) + 1, idx); + int startingSearch = beforeUsername.length(); + while (true) { + startingSearch = beforeUsername.lastIndexOf(' ', startingSearch-1); + if (startingSearch == -1) break; + if (startingSearch-1 >= 0) { + char c = beforeUsername.charAt(startingSearch-1); + if (c == ' ') continue; + if (c == ']') continue; + startingSearch ++; + break; + } + } + + if (startingSearch == -1) startingSearch = 0; + startingSearch += stIdx; + + if (color != null) + chatComponents = SurgicalReplacer.inject(chatComponents, + SurgicalReplacer.linearifyMoveColorCharToStyle( + new ChatComponentText(color+replacementContext.getUsername()) + .setChatStyle(SurgicalReplacer.getChatStyleAt(chatComponents, idx)) + ), + idx, replacementContext.getUsername().length()); + + if (prefix != null) + chatComponents = SurgicalReplacer.inject(chatComponents, + SurgicalReplacer.linearifyMoveColorCharToStyle( + new ChatComponentText(prefix+" ") + .setChatStyle(SurgicalReplacer.getChatStyleAt(chatComponents, 0)) + ), + startingSearch, 0); } + clientChatReceivedEvent.message = SurgicalReplacer.combine(chatComponents); } catch (Throwable t) { System.out.println(clientChatReceivedEvent.message); t.printStackTrace(); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/README.md b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/README.md new file mode 100644 index 00000000..98d13246 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/README.md @@ -0,0 +1,5 @@ +2 Phase Cosmetic Injection +1. Gather data + - and instruct the thing to replace what near what pos +2. Actually replace + - aghhhhhh diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorFriendList.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorFriendList.java new file mode 100644 index 00000000..62eb16a7 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorFriendList.java @@ -0,0 +1,62 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors; + +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.util.IChatComponent; + +import java.util.ArrayList; +import java.util.List; + +public class ChatDetectorFriendList implements IChatDetector { + @Override + public List<ReplacementContext> getReplacementContext(IChatComponent chatComponent) { + boolean friend = false; + int idx = 0; + for (IChatComponent iChatComponent : chatComponent) { + idx++; + if (iChatComponent.getUnformattedText().startsWith(" §6Friends ")) { + friend = true; + } + if (idx > 5 && !friend) return null; + } + + if (!friend) return null; + + String formatted = chatComponent.getFormattedText(); + String strip = TextUtils.stripColor(formatted); + int len = 0; + List<ReplacementContext> replacementContexts = new ArrayList<>(); + for (String s : strip.split("\n")) { + if (s.charAt(0) == '-' || s.charAt(0) == ' ') { + len += s.length()+1; + continue; + } + String username = s.split(" ")[0]; + System.out.println(username); + replacementContexts.add(new ReplacementContext( + len, username, null + )); + len += s.length()+1; + } + + return replacementContexts; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorGuildPartyList.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorGuildPartyList.java new file mode 100644 index 00000000..7df0b62f --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorGuildPartyList.java @@ -0,0 +1,55 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors; + +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.util.IChatComponent; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ChatDetectorGuildPartyList implements IChatDetector { + @Override + public List<ReplacementContext> getReplacementContext(IChatComponent chatComponent) { + String formatted = chatComponent.getFormattedText(); + if (!(formatted.contains("§c ● ") || formatted.contains("§a ● ") || + formatted.contains("§c●") || formatted.contains("§a●"))) { + return null; + } +// + String strip = TextUtils.stripColor(formatted); +// String last = strip.split(": "); + + List<String> players = new ArrayList<>(); + for (String s : strip.split(" ")) { + if (s.contains("●")) continue; + if (s.startsWith("[")) continue; + if (s.endsWith(":")) continue; + + if (!(formatted.contains(s+"§r") || formatted.contains(s+" §r") )) continue; + players.add(s); + } + + return players.stream().map(a -> new ReplacementContext( + strip.indexOf(a), a, null + )).collect(Collectors.toList()); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorJoinLeave.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorJoinLeave.java new file mode 100644 index 00000000..9de4be0a --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorJoinLeave.java @@ -0,0 +1,79 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors; + +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.util.IChatComponent; + +import java.util.Collections; +import java.util.List; + +public class ChatDetectorJoinLeave implements IChatDetector { + @Override + public List<ReplacementContext> getReplacementContext(IChatComponent chatComponent) { + String formatted = chatComponent.getFormattedText(); + if (formatted.startsWith("§aFriend > §r")) { + if (formatted.endsWith("§r§eleft.§r") || formatted.endsWith("§r§ejoined.§r")) { + String strip = TextUtils.stripColor(formatted); + String username = strip.substring(9, strip.indexOf(' ', 9)); + return Collections.singletonList(new ReplacementContext( + 9, username, null + )); + } + } else if (formatted.endsWith("§6joined the lobby!§r")) { + String[] messageSplit = TextUtils.stripColor(formatted).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + if (oldLeader != null) + return Collections.singletonList(new ReplacementContext( + TextUtils.stripColor(formatted).indexOf(oldLeader), oldLeader, null + )); + } else if (formatted.endsWith("§6joined the lobby!§r §a<§c<§b<§r")) { + String[] messageSplit = TextUtils.stripColor(formatted.substring(15)).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + if (oldLeader != null) + return Collections.singletonList(new ReplacementContext( + TextUtils.stripColor(formatted).indexOf(oldLeader), oldLeader, null + )); + } else if (formatted.startsWith("§b✦ ") && formatted.contains("§r§7found a ") && formatted.endsWith("§r§bMystery Box§r§7!§r")) { + String[] messageSplit = TextUtils.stripColor(formatted.substring(4)).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + if (oldLeader != null) + return Collections.singletonList(new ReplacementContext( + TextUtils.stripColor(formatted).indexOf(oldLeader), oldLeader, null + )); + } + return null; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorPartyMessages.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorPartyMessages.java new file mode 100644 index 00000000..6637b7a9 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorPartyMessages.java @@ -0,0 +1,192 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors; + +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.party.PartyManager; +import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.util.IChatComponent; + +import java.util.ArrayList; +import java.util.List; + +public class ChatDetectorPartyMessages implements IChatDetector { + @Override + public List<ReplacementContext> getReplacementContext(IChatComponent chatComponent) { + String str = chatComponent.getFormattedText(); + String strip = TextUtils.stripColor(str); + + List<ReplacementContext> detectors = new ArrayList<>(); + if (str.endsWith("§aenabled All Invite§r") || str.endsWith("§cdisabled All Invite§r") || str.endsWith("§ejoined the party.§r") || str.endsWith("§ehas been removed from the party.§r") || str.endsWith("§ehas left the party.§r")) { + String username = null; + for (String s : TextUtils.stripColor(str).split(" ")) { + if (s.startsWith("[")) continue; + username = s; + break; + } + if (username != null) + detectors.add(new ReplacementContext( + strip.indexOf(username), username, null + )); + } else if (str.endsWith(" They have §r§c60 §r§eseconds to accept.§r")) { + String username = null; + for (String s : TextUtils.stripColor(str).split(" ")) { + if (s.startsWith("[")) continue; + username = s; + break; + } + if (username != null) + detectors.add(new ReplacementContext( + strip.indexOf(username), username, null + )); + username = null; + for (String s : TextUtils.stripColor(str.substring(str.indexOf("§r§einvited ")+12)).split(" ")) { + if (s.startsWith("[")) continue; + username = s; + break; + } + if (username != null) + detectors.add(new ReplacementContext( + strip.indexOf(username), username, null + )); + } else if (str.startsWith("§eThe party was transferred to ")) { + String[] messageSplit = TextUtils.stripColor(str.substring(31)).split(" "); + String newLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + newLeader = s; + break; + } + String oldLeader; + if (str.endsWith("§r§eleft§r")) { + oldLeader = messageSplit[messageSplit.length - 2]; + } else { + oldLeader = messageSplit[messageSplit.length - 1]; + } + + if (oldLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(oldLeader), oldLeader, null + )); + if (newLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(newLeader), newLeader, null + )); + } else if (str.endsWith("§eto Party Leader§r")) { + String[] messageSplit = TextUtils.stripColor(str).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + messageSplit = TextUtils.stripColor(str.substring(str.indexOf("has promoted") + 13)).split(" "); + String newLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + newLeader = s; + break; + } + if (oldLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(oldLeader), oldLeader, null + )); + if (newLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(newLeader), newLeader, null + )); + } else if (str.endsWith("§r§eto Party Moderator§r")) { + String[] messageSplit = TextUtils.stripColor(str).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + messageSplit = TextUtils.stripColor(str.substring(str.indexOf("has promoted") + 13)).split(" "); + String newModerator = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + newModerator = s; + break; + } + if (oldLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(oldLeader), oldLeader, null + )); + if (newModerator != null) + detectors.add(new ReplacementContext( + strip.indexOf(newModerator), newModerator, null + )); + + } else if (str.endsWith("§r§eto Party Member§r")) { + String[] messageSplit = TextUtils.stripColor(str).split(" "); + String oldLeader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + oldLeader = s; + break; + } + messageSplit = TextUtils.stripColor(str.substring(str.indexOf("has demoted") + 12)).split(" "); + String newMember = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + newMember = s; + break; + } + if (oldLeader != null) + detectors.add(new ReplacementContext( + strip.indexOf(oldLeader), oldLeader, null + )); + if (newMember != null) + detectors.add(new ReplacementContext( + strip.indexOf(newMember), newMember, null + )); + + } else if (str.startsWith("§eYou have joined ")) { + String[] messageSplit = strip.split(" "); + String leader = null; + for (String s : messageSplit) { + if (s.startsWith("[")) continue; + leader = s; + break; + } + if (leader == null) return null; + String username = leader.substring(0, leader.length()-2); + detectors.add(new ReplacementContext( + strip.indexOf(username), username, null + )); + } else if (str.startsWith("§eYou'll be partying with: ")) { + String[] players = strip.split(" "); + for (String player : players) { + if (player.startsWith("[")) continue; + // player + detectors.add(new ReplacementContext( + strip.indexOf(player), player, null + )); + } + } else if (str.contains("§r§ejoined the dungeon group! (§r§b")) { + String username = TextUtils.stripColor(str).split(" ")[3]; + detectors.add(new ReplacementContext( + strip.indexOf(username), username, null + )); + } + return detectors; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorProbablyUniversal.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorProbablyUniversal.java new file mode 100644 index 00000000..fc3188be --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/ChatDetectorProbablyUniversal.java @@ -0,0 +1,76 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.cosmetics.chatdetectors; + +import kr.syeyoung.dungeonsguide.mod.cosmetics.surgical.ReplacementContext; +import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.event.ClickEvent; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.IChatComponent; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ChatDetectorProbablyUniversal implements IChatDetector { + @Override + public List<ReplacementContext> getReplacementContext(IChatComponent chatComponent) { + String formatted = chatComponent.getFormattedText(); + if (!formatted.contains(": ")) return null; + + + boolean correspondingEvFound = false; + for (IChatComponent iChatComponent : chatComponent) { + ClickEvent ev = iChatComponent.getChatStyle().getChatClickEvent(); + if (ev != null) { + if (ev.getValue().startsWith("/msg")) correspondingEvFound = true; + if (ev.getValue().startsWith("/socialoptions")) correspondingEvFound = true; + if (ev.getValue().startsWith("/viewprofile")) correspondingEvFound = true; + } + } + + formatted = formatted.substring(0, formatted.indexOf(": ")); + String name = TextUtils.stripColor(formatted); + + String[] splited = name.split(" "); + int backLen = 0; + label: for (int i = splited.length - 1; i >= 0; i--) { + String potentialName = splited[i]; + backLen += potentialName.length() + 1; + for (char c : potentialName.toCharArray()) { + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '_' || c == '-')) { + continue; + } + continue label; + } + if (potentialName.equalsIgnoreCase(Minecraft.getMinecraft().thePlayer.getName())) + return Collections.singletonList(new ReplacementContext( + name.length() - backLen, potentialName, null + )); + else if (correspondingEvFound) + return Collections.singletonList(new ReplacementContext( + name.length() - backLen, potentialName, null + )); + else return null; + } + return null; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/IChatDetector.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/chatdetectors/IChatDetector.java new file mode 100644 index 00000000..2b1d47b5 --- /dev/null +++ b/mod/src/main/java/kr/ |
