diff options
author | syeyoung <cyong06@naver.com> | 2021-05-08 17:23:08 +0900 |
---|---|---|
committer | syeyoung <cyong06@naver.com> | 2021-05-08 17:23:08 +0900 |
commit | b34b217f44c0c5ae7e69a4d7b830a8607f5fc13a (patch) | |
tree | 6467fd8dbec016cc63b27dad05c4060e59f70d2b /src/main/java/kr/syeyoung/dungeonsguide/cosmetics | |
parent | 5f5e168df2abd0f168ae780d1ffeb4b7dab6c0a8 (diff) | |
download | Skyblock-Dungeons-Guide-b34b217f44c0c5ae7e69a4d7b830a8607f5fc13a.tar.gz Skyblock-Dungeons-Guide-b34b217f44c0c5ae7e69a4d7b830a8607f5fc13a.tar.bz2 Skyblock-Dungeons-Guide-b34b217f44c0c5ae7e69a4d7b830a8607f5fc13a.zip |
cosmetics.
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/cosmetics')
3 files changed, 314 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/ActiveCosmetic.java b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/ActiveCosmetic.java new file mode 100644 index 00000000..f00ecf06 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/ActiveCosmetic.java @@ -0,0 +1,12 @@ +package kr.syeyoung.dungeonsguide.cosmetics; + +import lombok.Data; +import java.util.UUID; + +@Data +public class ActiveCosmetic { + private UUID activityUID; + private UUID playerUID; + private UUID cosmeticData; + private String username; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticData.java b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticData.java new file mode 100644 index 00000000..24842a8e --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticData.java @@ -0,0 +1,14 @@ +package kr.syeyoung.dungeonsguide.cosmetics; + + +import lombok.Data; + +import java.util.UUID; + +@Data +public class CosmeticData { + private UUID id; + private String cosmeticType; + private String reqPerm; + private String data; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticsManager.java b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticsManager.java new file mode 100644 index 00000000..d7c8114f --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticsManager.java @@ -0,0 +1,288 @@ +/* + * 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.cosmetics; + +import com.google.gson.JsonPrimitive; +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.events.StompConnectedEvent; +import kr.syeyoung.dungeonsguide.stomp.*; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import lombok.Getter; +import net.minecraft.client.Minecraft; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CosmeticsManager implements StompMessageHandler { + @Getter + private Map<UUID, CosmeticData> cosmeticDataMap = new HashMap<>(); + @Getter + private Map<UUID, ActiveCosmetic> activeCosmeticMap = new HashMap<>(); + @Getter + private Map<String, List<ActiveCosmetic>> activeCosmeticByType = new HashMap<>(); + @Getter + private Map<UUID, List<ActiveCosmetic>> activeCosmeticByPlayer = new HashMap<>(); + @Getter + private Map<String, List<ActiveCosmetic>> activeCosmeticByPlayerNameLowerCase = new HashMap<>(); + @Getter + private Set<String> perms = new HashSet<>(); + + public void requestActiveCosmetics() { + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload() + .method(StompHeader.SEND) + .header("destination", "/app/cosmetic.activelist") + ); + } + public void requestCosmeticsList() { + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload() + .method(StompHeader.SEND) + .header("destination", "/app/cosmetic.list") + ); + } + public void requestPerms() { + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload() + .method(StompHeader.SEND) + .header("destination", "/app/user.perms") + ); + } + public void setCosmetic(CosmeticData cosmetic) { + if (!perms.contains(cosmetic.getReqPerm())) return; + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload() + .method(StompHeader.SEND) + .header("destination", "/app/cosmetic.set") + .payload(cosmetic.getId().toString()) + ); + } + public void removeCosmetic(ActiveCosmetic activeCosmetic) { + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload() + .method(StompHeader.SEND) + .header("destination", "/app/cosmetic.remove") + .payload(activeCosmetic.getActivityUID().toString()) + ); + } + + @Override + public void handle(StompInterface stompInterface, StompPayload stompPayload) { + String destination = stompPayload.headers().get("destination"); + if (destination.equals("/topic/cosmetic.set")) { + JSONObject jsonObject = new JSONObject(stompPayload.payload()); + ActiveCosmetic activeCosmetic = new ActiveCosmetic(); + activeCosmetic.setActivityUID(UUID.fromString(jsonObject.getString("activityUID"))); + activeCosmetic.setPlayerUID(UUID.fromString(jsonObject.getString("playerUID"))); + activeCosmetic.setCosmeticData(UUID.fromString(jsonObject.getString("cosmeticUID"))); + activeCosmetic.setUsername(jsonObject.getString("username")); + + ActiveCosmetic previousThing = activeCosmeticMap.get(activeCosmetic.getActivityUID()); + activeCosmeticMap.put(activeCosmetic.getActivityUID(), activeCosmetic); + + CosmeticData cosmeticData = cosmeticDataMap.get(activeCosmetic.getCosmeticData()); + if (cosmeticData != null) { + List<ActiveCosmetic> cosmeticsByTypeList = activeCosmeticByType.computeIfAbsent(cosmeticData.getCosmeticType(), a-> new ArrayList<>()); + cosmeticsByTypeList.add(activeCosmetic); + cosmeticsByTypeList.remove(previousThing); + } + List<ActiveCosmetic> activeCosmetics = activeCosmeticByPlayer.computeIfAbsent(activeCosmetic.getPlayerUID(), a-> new ArrayList<>()); + activeCosmetics.add(activeCosmetic); + activeCosmetics.remove(previousThing); + + activeCosmetics = activeCosmeticByPlayerNameLowerCase.computeIfAbsent(activeCosmetic.getUsername().toLowerCase(), a-> new ArrayList<>()); + activeCosmetics.add(activeCosmetic); + activeCosmetics.remove(previousThing); + + + } else if (destination.equals("/user/queue/reply/user.perms")) { + JSONArray object = new JSONArray(stompPayload.payload()); + Set<String> cache = new HashSet<>(); + for (Object o : object) { + cache.add((String) o); + } + this.perms = cache; + } else if (destination.equals("/user/queue/reply/cosmetic.activelist")) { + Map<UUID, ActiveCosmetic> activeCosmeticMap = new HashMap<>(); + JSONArray object = new JSONArray(stompPayload.payload()); + for (Object o : object) { + JSONObject jsonObject = (JSONObject) o; + ActiveCosmetic cosmeticData = new ActiveCosmetic(); + cosmeticData.setActivityUID(UUID.fromString(jsonObject.getString("activityUID"))); + cosmeticData.setPlayerUID(UUID.fromString(jsonObject.getString("playerUID"))); + cosmeticData.setCosmeticData(UUID.fromString(jsonObject.getString("cosmeticUID"))); + cosmeticData.setUsername(jsonObject.getString("username")); + + activeCosmeticMap.put(cosmeticData.getActivityUID(), cosmeticData); + } + this.activeCosmeticMap = activeCosmeticMap; + rebuildCaches(); + } else if (destination.equals("/user/queue/reply/cosmetic.list")) { + JSONArray object = new JSONArray(stompPayload.payload()); + Map<UUID, CosmeticData> newCosmeticList = new HashMap<>(); + for (Object o : object) { + JSONObject jsonObject = (JSONObject) o; + CosmeticData cosmeticData = new CosmeticData(); + cosmeticData.setCosmeticType(jsonObject.getString("cosmeticType")); + cosmeticData.setReqPerm(jsonObject.getString("reqPerm")); + cosmeticData.setData(jsonObject.getString("data")); + cosmeticData.setId(UUID.fromString(jsonObject.getString("id"))); + + newCosmeticList.put(cosmeticData.getId(), cosmeticData); + } + + cosmeticDataMap = newCosmeticList; + rebuildCaches(); + } + } + + private void rebuildCaches() { + Map<String, List<ActiveCosmetic>> activeCosmeticByType = new HashMap<>(); + Map<UUID, List<ActiveCosmetic>> activeCosmeticByPlayer = new HashMap<>(); + Map<String, List<ActiveCosmetic>> activeCosmeticByPlayerName = new HashMap<>(); + for (ActiveCosmetic value : activeCosmeticMap.values()) { + CosmeticData cosmeticData = cosmeticDataMap.get(value.getCosmeticData()); + if (cosmeticData != null) { + List<ActiveCosmetic> cosmeticsByTypeList = activeCosmeticByType.computeIfAbsent(cosmeticData.getCosmeticType(), a-> new ArrayList<>()); + cosmeticsByTypeList.add(value); + } + List<ActiveCosmetic> activeCosmetics = activeCosmeticByPlayer.computeIfAbsent(value.getPlayerUID(), a-> new ArrayList<>()); + activeCosmetics.add(value); + activeCosmetics = activeCosmeticByPlayerName.computeIfAbsent(value.getUsername().toLowerCase(), a-> new ArrayList<>()); + activeCosmetics.add(value); + } + + this.activeCosmeticByPlayerNameLowerCase = activeCosmeticByPlayerName; + this.activeCosmeticByPlayer = activeCosmeticByPlayer; + this.activeCosmeticByType = activeCosmeticByType; + } + + @SubscribeEvent + public void stompConnect(StompConnectedEvent stompConnectedEvent) { + stompConnectedEvent.getStompInterface().subscribe(StompSubscription.builder() + .stompMessageHandler(this).ackMode(StompSubscription.AckMode.AUTO).destination("/topic/cosmetic.set").build()); + stompConnectedEvent.getStompInterface().subscribe(StompSubscription.builder() + .stompMessageHandler(this).ackMode(StompSubscription.AckMode.AUTO).destination("/user/queue/reply/user.perms").build()); + stompConnectedEvent.getStompInterface().subscribe(StompSubscription.builder() + .stompMessageHandler(this).ackMode(StompSubscription.AckMode.AUTO).destination("/user/queue/reply/cosmetic.activelist").build()); + stompConnectedEvent.getStompInterface().subscribe(StompSubscription.builder() + .stompMessageHandler(this).ackMode(StompSubscription.AckMode.AUTO).destination("/user/queue/reply/cosmetic.list").build()); + + requestCosmeticsList(); + requestActiveCosmetics(); + requestPerms(); + } + + // §9Party §8> §a[VIP§6+§a] syeyoung§f: ty + // §2Guild > §a[VIP§6+§a] syeyoung §3[Vet]§f + // §dTo §r§a[VIP§r§6+§r§a] SlashSlayer§r§7: §r§7what§r + // §dFrom §r§a[VIP§r§6+§r§a] SlashSlayer§r§7: §r§7?§r + // §7Rock_Bird§7§r§7: SELLING 30 DIAMOD BLOCK /p me§r + // §b[MVP§c+§b] Probutnoobgamer§f: quitting skyblock! highe + // §r§bCo-op > §a[VIP§6+§a] syeyoung§f: §rwhat§r + + public static String substitute(String str) { + str = str.replace("{HYPIXEL_RANKED_NAME}", "§.(?:\\[[a-zA-Z\\+§0-9]+\\] )?{MC_NAME}"); + str = str.replace("{HYPIXEL_RANKED_NAME_PAT}", "(§.(?:\\[[a-zA-Z\\+§0-9]+\\] )?)({MC_NAME})"); + str = str.replace("{MC_NAME}", "[a-zA-Z0-9_]+"); + str = str.replace("{ANY_COLOR}", "(?:§[a-zA-Z0-9])+"); + return str; + } + + private static final Pattern PARTY_MSG = Pattern.compile(substitute("§r§9Party §8> {HYPIXEL_RANKED_NAME_PAT}({ANY_COLOR}): (.+)")); + private static final Pattern GUILD_MSG = Pattern.compile(substitute("§r§2Guild > {HYPIXEL_RANKED_NAME_PAT} ({ANY_COLOR}\\[.+\\]{ANY_COLOR}): (.+)")); + private static final Pattern CHAT_MSG = Pattern.compile(substitute("(?:§r)?{HYPIXEL_RANKED_NAME_PAT}({ANY_COLOR}): (.+)")); + private static final Pattern COOP_MSG = Pattern.compile(substitute("§r§bCo-op > {HYPIXEL_RANKED_NAME_PAT}({ANY_COLOR}): (.+)")); + private static final Pattern DM_TO = Pattern.compile(substitute("§dTo §r{HYPIXEL_RANKED_NAME_PAT}§r§7: (.+)")); + private static final Pattern DM_FROM = Pattern.compile(substitute("§dFrom §r{HYPIXEL_RANKED_NAME_PAT}§r§7: (.+)")); + + + @SubscribeEvent(receiveCanceled = false, priority = EventPriority.HIGHEST) + public void onChat(ClientChatReceivedEvent clientChatReceivedEvent) { + Matcher m; + String msg = clientChatReceivedEvent.message.getFormattedText(); + boolean match = false; + String preRank = ""; + String rank = ""; + String last = ""; + String nickname = ""; + if ((m = PARTY_MSG.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = "§r§9Party §8> "; + rank = m.group(1); + last = m.group(2)+m.group(3)+": "+m.group(4); + } else if ((m = GUILD_MSG.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = "§r§2Guild > "; + rank = m.group(1); + last = m.group(2)+" "+m.group(3)+": "+m.group(4); + } else if ((m = CHAT_MSG.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = ""; + rank = m.group(1); + last = m.group(2)+m.group(3)+": "+m.group(4); + } else if ((m = COOP_MSG.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = "§r§bCo-op > "; + rank = m.group(1); + last = m.group(2)+m.group(3)+": "+m.group(4); + } else if ((m = DM_TO.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = "§dTo §r"; + rank = m.group(1); + last = m.group(2)+"§r§7: "+m.group(3); + } else if ((m = DM_FROM.matcher(msg)).matches()) { + match = true; + nickname = m.group(2); + preRank = "§dFrom §r"; + rank = m.group(1); + last = m.group(2)+"§r§7: "+m.group(3); + } + + if (!match) return; + + List<ActiveCosmetic> activeCosmetics = activeCosmeticByPlayerNameLowerCase.get(nickname.toLowerCase()); + if (activeCosmetics != null) { + CosmeticData prefix = null, color =null; + for (ActiveCosmetic activeCosmetic : activeCosmetics) { + CosmeticData cosmeticData = cosmeticDataMap.get(activeCosmetic.getCosmeticData()); + if (cosmeticData == null) continue; + if (cosmeticData.getCosmeticType().equals("prefix")) prefix = cosmeticData; + if (cosmeticData.getCosmeticType().equals("color")) color = cosmeticData; + } + + if (prefix != null) { + preRank += prefix.getData()+" "; + } + if (color != null) { + last = color.getData() + last; + } + } + + clientChatReceivedEvent.message = new ChatComponentText(preRank + rank + last); + } +} |