aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung/dungeonsguide/cosmetics
diff options
context:
space:
mode:
authorsyeyoung <cyong06@naver.com>2021-05-08 17:23:08 +0900
committersyeyoung <cyong06@naver.com>2021-05-08 17:23:08 +0900
commitb34b217f44c0c5ae7e69a4d7b830a8607f5fc13a (patch)
tree6467fd8dbec016cc63b27dad05c4060e59f70d2b /src/main/java/kr/syeyoung/dungeonsguide/cosmetics
parent5f5e168df2abd0f168ae780d1ffeb4b7dab6c0a8 (diff)
downloadSkyblock-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')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/cosmetics/ActiveCosmetic.java12
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticData.java14
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/cosmetics/CosmeticsManager.java288
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);
+ }
+}