aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/eu/olli/cowmoonication/command
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/olli/cowmoonication/command')
-rw-r--r--src/main/java/eu/olli/cowmoonication/command/MooCommand.java98
1 files changed, 91 insertions, 7 deletions
diff --git a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
index b4d357d..7a468de 100644
--- a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
+++ b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
@@ -7,22 +7,29 @@ import eu.olli.cowmoonication.command.exception.InvalidPlayerNameException;
import eu.olli.cowmoonication.command.exception.MooCommandException;
import eu.olli.cowmoonication.config.MooConfig;
import eu.olli.cowmoonication.config.MooGuiConfig;
+import eu.olli.cowmoonication.data.DataHelper;
import eu.olli.cowmoonication.data.Friend;
import eu.olli.cowmoonication.data.HySkyBlockStats;
import eu.olli.cowmoonication.data.HyStalkingData;
import eu.olli.cowmoonication.search.GuiSearch;
-import eu.olli.cowmoonication.util.ApiUtils;
-import eu.olli.cowmoonication.util.MooChatComponent;
-import eu.olli.cowmoonication.util.TickDelay;
-import eu.olli.cowmoonication.util.Utils;
+import eu.olli.cowmoonication.util.*;
import net.minecraft.client.Minecraft;
import net.minecraft.command.*;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
+import net.minecraft.item.ItemSkull;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.*;
+import net.minecraftforge.common.util.Constants;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
import java.awt.*;
import java.io.IOException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -58,6 +65,80 @@ public class MooCommand extends CommandBase {
} else {
handleStalkingSkyBlock(args[1]);
}
+ } else if (args[0].equalsIgnoreCase("analyzeIsland")) {
+ Map<String, String> minions = DataHelper.getMinions();
+
+ Map<String, Integer> detectedMinions = new HashMap<>();
+ Map<Integer, Integer> detectedMinionsWithSkin = new HashMap<>();
+ int detectedMinionCount = 0;
+ int minionsWithSkinCount = 0;
+ entityLoop:
+ for (Entity entity : sender.getEntityWorld().loadedEntityList) {
+ if (entity instanceof EntityArmorStand) {
+ EntityArmorStand minion = (EntityArmorStand) entity;
+
+ if (minion.isInvisible() || !minion.isSmall() || minion.getHeldItem() == null) {
+ // not a minion: invisible, or not small armor stand, or no item in hand (= minion in a minion chair)
+ continue;
+ }
+ for (int slot = 0; slot < 4; slot++) {
+ if (minion.getCurrentArmor(slot) == null) {
+ // not a minion: missing equipment
+ continue entityLoop;
+ }
+ }
+ ItemStack skullItem = minion.getCurrentArmor(3); // head slot
+ if (skullItem.getItem() instanceof ItemSkull && skullItem.getMetadata() == 3 && skullItem.hasTagCompound()) {
+ // is a player head!
+ if (skullItem.getTagCompound().hasKey("SkullOwner", Constants.NBT.TAG_COMPOUND)) {
+ NBTTagCompound skullOwner = skullItem.getTagCompound().getCompoundTag("SkullOwner");
+ String skullDataBase64 = skullOwner.getCompoundTag("Properties").getTagList("textures", Constants.NBT.TAG_COMPOUND).getCompoundTagAt(0).getString("Value");
+ String skullData = new String(Base64.decodeBase64(skullDataBase64));
+ String minionSkinId = StringUtils.substringBetween(skullData, "http://textures.minecraft.net/texture/", "\"");
+ String detectedMinion = minions.get(minionSkinId);
+ if (detectedMinion != null) {
+ // minion head matches one know minion tier
+ detectedMinions.put(detectedMinion, detectedMinions.getOrDefault(detectedMinion, 0) + 1);
+ detectedMinionCount++;
+ } else {
+ int minionTier = ImageUtils.getTierFromTexture(minionSkinId);
+ if (minionTier > 0) {
+ detectedMinionsWithSkin.put(minionTier, detectedMinionsWithSkin.getOrDefault(minionTier, 0) + 1);
+ minionsWithSkinCount++;
+ } else {
+ // looked like a minion but has no matching tier badge
+ main.getLogger().info("[/moo analyzeIsland] Found an armor stand that could be a minion but it is missing a tier badge: " + minionSkinId + "\t\t\t" + minion.serializeNBT());
+ }
+ }
+ }
+ }
+ }
+ }
+ main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW,
+ "Found " + EnumChatFormatting.GOLD + detectedMinionCount + EnumChatFormatting.YELLOW + " minions" +
+ (minionsWithSkinCount > 0 ? (" + " + EnumChatFormatting.GOLD + minionsWithSkinCount + EnumChatFormatting.YELLOW + " unknown minions with skins") : "") +
+ " on this island");
+ detectedMinions.entrySet().stream()
+ .sorted(Map.Entry.comparingByKey()) // sort alphabetically by minion name and tier
+ .forEach(minion -> {
+ String minionWithTier = minion.getKey();
+ int lastSpace = minionWithTier.lastIndexOf(' ');
+
+ String tierRoman = minionWithTier.substring(lastSpace + 1);
+
+ int tierArabic = Utils.convertRomanToArabic(tierRoman);
+ EnumChatFormatting tierColor = Utils.getMinionTierColor(tierArabic);
+
+ minionWithTier = minionWithTier.substring(0, lastSpace) + " " + tierColor + (MooConfig.useRomanNumerals() ? tierRoman : tierArabic);
+ main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, " " + minion.getValue() + (minion.getValue() > 1 ? "✕ " : "⨉ ") + EnumChatFormatting.YELLOW + minionWithTier);
+ });
+ detectedMinionsWithSkin.entrySet().stream()
+ .sorted(Map.Entry.comparingByKey()) // sort by tier
+ .forEach(minionWithSkin -> {
+ EnumChatFormatting tierColor = Utils.getMinionTierColor(minionWithSkin.getKey());
+ String minionTier = MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(minionWithSkin.getKey()) : String.valueOf(minionWithSkin.getKey());
+ main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, " " + minionWithSkin.getValue() + (minionWithSkin.getValue() > 1 ? "✕ " : "⨉ ") + EnumChatFormatting.RED + "Unknown minion " + EnumChatFormatting.YELLOW + "(new or with minion skin) " + tierColor + minionTier);
+ });
} else if (args.length == 2 && args[0].equalsIgnoreCase("add")) {
handleBestFriendAdd(args[1]);
} else if (args.length == 2 && args[0].equalsIgnoreCase("remove")) {
@@ -269,7 +350,8 @@ public class MooCommand extends CommandBase {
String skill = Utils.fancyCase(entry.getKey().name());
int level = entry.getKey().getLevel(entry.getValue());
if (level > 0) {
- skillLevels.appendFreshSibling(new MooChatComponent.KeyValueTooltipComponent(skill, String.valueOf(level)));
+ String skillLevel = MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(level) : String.valueOf(level);
+ skillLevels.appendFreshSibling(new MooChatComponent.KeyValueTooltipComponent(skill, skillLevel));
}
if (level > highestLevel) {
@@ -297,7 +379,8 @@ public class MooCommand extends CommandBase {
if (highestLevel == 0) {
sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Highest Skill", "All skills level 0"));
} else {
- sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Highest Skill", highestSkill + " " + highestLevel).setHover(skillLevels));
+ String highestSkillLevel = MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(highestLevel) : String.valueOf(highestLevel);
+ sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Highest Skill", highestSkill + " " + highestSkillLevel).setHover(skillLevels));
}
} else {
sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Highest Skill", "API access disabled"));
@@ -375,6 +458,7 @@ public class MooCommand extends CommandBase {
.appendSibling(createCmdHelpSection(1, "Friends"))
.appendSibling(createCmdHelpEntry("stalk", "Get info of player's status"))
.appendSibling(createCmdHelpEntry("stalkskyblock", "Get info of player's SkyBlock stats"))
+ .appendSibling(createCmdHelpEntry("analyzeIsland", "Analyze a SkyBlock private island"))
.appendSibling(createCmdHelpEntry("add", "Add best friends"))
.appendSibling(createCmdHelpEntry("remove", "Remove best friends"))
.appendSibling(createCmdHelpEntry("list", "View list of best friends"))
@@ -413,7 +497,7 @@ public class MooCommand extends CommandBase {
public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) {
if (args.length == 1) {
return getListOfStringsMatchingLastWord(args,
- /* friends */ "stalk", "stalkskyblock", "skyblockstalk", "add", "remove", "list", "nameChangeCheck", "toggle",
+ /* friends */ "stalk", "stalkskyblock", "skyblockstalk", "analyzeIsland", "add", "remove", "list", "nameChangeCheck", "toggle",
/* miscellaneous */ "config", "search", "guiscale", "shrug", "apikey",
/* update mod */ "update", "updateHelp", "version", "directory",
/* help */ "help");