aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java
diff options
context:
space:
mode:
authorCow <cow@volloeko.de>2021-07-06 20:24:21 +0200
committerCow <cow@volloeko.de>2021-07-06 20:24:21 +0200
commit65e5ee4b431cc7513e53d61827249148b06de79a (patch)
treec55e9c7ebd0c7e37a7a81de0df10b79f67e39930 /src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java
parentc0c7011643a6ffa7c549ad4eff662309644b244c (diff)
downloadCowlection-65e5ee4b431cc7513e53d61827249148b06de79a.tar.gz
Cowlection-65e5ee4b431cc7513e53d61827249148b06de79a.tar.bz2
Cowlection-65e5ee4b431cc7513e53d61827249148b06de79a.zip
Added 'lowest BINs' support to Chest Tracker & Analyzer
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java')
-rw-r--r--src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java118
1 files changed, 110 insertions, 8 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java b/src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java
index 64e4067..4ff6fe2 100644
--- a/src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java
+++ b/src/main/java/de/cowtipper/cowlection/chesttracker/ChestTracker.java
@@ -1,29 +1,39 @@
package de.cowtipper.cowlection.chesttracker;
import de.cowtipper.cowlection.Cowlection;
+import de.cowtipper.cowlection.data.DataHelper;
+import de.cowtipper.cowlection.data.HySkyBlockStats;
import de.cowtipper.cowlection.util.ApiUtils;
+import de.cowtipper.cowlection.util.GsonUtils;
import de.cowtipper.cowlection.util.MooChatComponent;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.nbt.NBTTagString;
import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.Constants;
import java.util.*;
public class ChestTracker {
+ public static long lastBazaarUpdate;
+ public static long lastLowestBinsUpdate;
private final Map<BlockPos, List<ItemStack>> chestCache = new HashMap<>();
private final Map<BlockPos, EnumFacing> doubleChestCache = new HashMap<>();
private Map<String, ItemData> analysisResult = new HashMap<>();
private ChestInteractionListener chestInteractionListener;
private HyBazaarData bazaarCache;
- private long lastBazaarUpdate;
+ private LowestBinsCache lowestBinsCache;
private final Cowlection main;
public ChestTracker(Cowlection main) {
this.main = main;
- refreshBazaarCache();
+ refreshPriceCache();
chestInteractionListener = new ChestInteractionListener(main);
MinecraftForge.EVENT_BUS.register(chestInteractionListener);
}
@@ -34,12 +44,30 @@ public class ChestTracker {
for (ItemStack item : chestContents) {
String key = item.hasDisplayName() ? item.getDisplayName() : item.getUnlocalizedName();
+ boolean isAmbiguousItem = false;
if (item.hasTagCompound()) {
key = item.getTagCompound().getCompoundTag("ExtraAttributes").getString("id");
}
+ if ("PET".equals(key)) {
+ HySkyBlockStats.Profile.Pet petInfo = GsonUtils.fromJson(item.getTagCompound().getCompoundTag("ExtraAttributes").getString("petInfo"), HySkyBlockStats.Profile.Pet.class);
+ key = petInfo.getType() + ";" + petInfo.getRarity().ordinal();
+ // remove pet lvl from name, as lowest BINs also disregard it
+ String petName = item.getDisplayName();
+ int endOfPetLevel = petName.indexOf(']');
+ if (petName.startsWith(EnumChatFormatting.GRAY + "[Lvl ") && endOfPetLevel > 0) {
+ item.setStackDisplayName(EnumChatFormatting.GRAY + "[Lvl " + EnumChatFormatting.DARK_GRAY + "?" + EnumChatFormatting.GRAY + petName.substring(endOfPetLevel));
+ }
+ } else if (DataHelper.AMBIGUOUS_ITEM_IDS.contains(key)) {
+ isAmbiguousItem = true;
+ key += "_ambiguous";
+ }
ItemData itemData = itemCounts.get(key);
if (itemData == null) {
+ // item hasn't been cached yet
+ if (isAmbiguousItem) {
+ convertToDummyItem(item, key);
+ }
itemData = new ItemData(key, item.copy());
}
itemCounts.put(key, itemData.addAmount(item.stackSize));
@@ -48,6 +76,46 @@ public class ChestTracker {
this.analysisResult = itemCounts;
}
+ private void convertToDummyItem(ItemStack item, String key) {
+ NBTTagCompound itemNbtDisplay = item.getSubCompound("display", true);
+ NBTTagList loreList = new NBTTagList();
+ loreList.appendTag(new NBTTagString("" + EnumChatFormatting.RED + EnumChatFormatting.ITALIC + "This ambiguous item type"));
+ loreList.appendTag(new NBTTagString("" + EnumChatFormatting.RED + EnumChatFormatting.ITALIC + "is not listed separately."));
+ itemNbtDisplay.setTag("Lore", loreList);
+ String itemName = null;
+ switch (key) {
+ case "ENCHANTED_BOOK_ambiguous":
+ itemName = "Enchanted Book";
+ break;
+ case "POTION_ambiguous":
+ itemName = "Potion";
+ break;
+ case "RUNE_ambiguous":
+ itemName = "Rune";
+ NBTTagCompound skullNbtTextureData = item.getSubCompound("SkullOwner", false);
+ if (skullNbtTextureData != null) {
+ skullNbtTextureData.setString("Id", UUID.randomUUID().toString());
+ NBTTagCompound nbtSkin = new NBTTagCompound();
+ // set texture to Empty Rune
+ nbtSkin.setString("Value", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODJiODIwN2E1ZmUxOTJjZDQ3N2U5MjE0NjYxOTdjOGFmNzQ5YWYxOGRkMWVmMzg5ZTI3MzNhMmY3NGQwOTI4YiJ9fX0=");
+ skullNbtTextureData.getCompoundTag("Properties").getTagList("textures", Constants.NBT.TAG_COMPOUND).set(0, nbtSkin);
+ }
+ break;
+ case "NEW_YEAR_CAKE_ambiguous":
+ itemName = "New Year Cake";
+ break;
+ case "SPOOKY_PIE_ambiguous":
+ itemName = "Spooky Pie";
+ break;
+ case "CAKE_SOUL_ambiguous":
+ itemName = "Cake Soul";
+ break;
+ }
+ if (itemName != null) {
+ item.setStackDisplayName(EnumChatFormatting.GRAY + itemName);
+ }
+ }
+
/**
* Returns ordered analysis result with prices
*/
@@ -55,6 +123,7 @@ public class ChestTracker {
List<ItemData> orderedAnalysisResult = new ArrayList<>();
// sort by bazaar value (most value first)
for (Map.Entry<String, ItemData> itemEntry : analysisResult.entrySet()) {
+ boolean foundPriceForItem = false;
if (bazaarCache != null && bazaarCache.isSuccess()) {
String productKey = itemEntry.getKey();
HyBazaarData.Product product = bazaarCache.getProduct(productKey);
@@ -62,6 +131,15 @@ public class ChestTracker {
// item is sold on bazaar!
itemEntry.getValue().setBazaarInstantSellPrice(product.getInstantSellPrice());
itemEntry.getValue().setBazaarSellOfferPrice(product.getSellOfferPrice());
+ foundPriceForItem = true;
+ }
+ }
+ if (!foundPriceForItem && lowestBinsCache != null && lowestBinsCache.size() > 0) {
+ String productKey = itemEntry.getKey().replace(':', '-');
+ Integer lowestBin = lowestBinsCache.get(productKey);
+ if (lowestBin != null) {
+ // item is sold via BIN
+ itemEntry.getValue().setLowestBin(lowestBin);
}
}
orderedAnalysisResult.add(itemEntry.getValue());
@@ -75,10 +153,10 @@ public class ChestTracker {
comparator = Comparator.comparing(ItemData::getAmount);
break;
case PRICE_EACH:
- comparator = useInstantSellPrices ? Comparator.comparing(ItemData::getBazaarInstantSellPrice) : Comparator.comparing(ItemData::getBazaarSellOfferPrice);
+ comparator = Comparator.comparing(itemData -> itemData.getPrice(useInstantSellPrices));
break;
default: // case PRICE_SUM:
- comparator = useInstantSellPrices ? Comparator.comparing(ItemData::getBazaarInstantSellValue) : Comparator.comparing(ItemData::getBazaarSellOfferValue);
+ comparator = Comparator.comparing(itemData -> itemData.getPriceSum(useInstantSellPrices));
break;
}
orderedAnalysisResult.sort((orderDesc ? comparator.reversed() : comparator).thenComparing(ItemData::getName));
@@ -93,6 +171,7 @@ public class ChestTracker {
MinecraftForge.EVENT_BUS.unregister(chestInteractionListener);
chestInteractionListener = null;
bazaarCache = null;
+ lowestBinsCache = null;
chestCache.clear();
doubleChestCache.clear();
analysisResult.clear();
@@ -148,23 +227,46 @@ public class ChestTracker {
return doubleChestCache.getOrDefault(pos, EnumFacing.UP);
}
- public void refreshBazaarCache() {
+ public EnumSet<Updating> refreshPriceCache() {
+ EnumSet<Updating> updating = EnumSet.of(Updating.UNDEFINED);
if (allowUpdateBazaar()) {
+ updating.add(Updating.BAZAAR);
ApiUtils.fetchBazaarData(bazaarData -> {
if (bazaarData == null || !bazaarData.isSuccess()) {
main.getChatHelper().sendMessage(new MooChatComponent("Error: Couldn't get Bazaar data from Hypixel API! API might be down: check status.hypixel.net").red().setUrl("https://status.hypixel.net/"));
}
this.bazaarCache = bazaarData;
- this.lastBazaarUpdate = System.currentTimeMillis();
+ lastBazaarUpdate = System.currentTimeMillis();
+ });
+ }
+ if (allowUpdateLowestBins()) {
+ updating.add(Updating.LOWEST_BINS);
+ ApiUtils.fetchLowestBins(lowestBins -> {
+ if (!lowestBins.hasData()) {
+ main.getChatHelper().sendMessage(new MooChatComponent("Error: Couldn't get lowest BINs from Moulberry's API! API might be down: check if " + ApiUtils.LOWEST_BINS + " is reachable.").red().setUrl(ApiUtils.LOWEST_BINS));
+ }
+ this.lowestBinsCache = lowestBins;
+ lastLowestBinsUpdate = System.currentTimeMillis();
});
}
+ return updating;
}
+ /**
+ * Allow bazaar update once per minute
+ */
public boolean allowUpdateBazaar() {
return bazaarCache == null || bazaarCache.allowRefreshData();
}
- public long getLastBazaarUpdate() {
- return this.lastBazaarUpdate;
+ /**
+ * Allow lowest bins update once every 5 minutes
+ */
+ public boolean allowUpdateLowestBins() {
+ return lowestBinsCache == null || (System.currentTimeMillis() - lastLowestBinsUpdate) > 300000;
+ }
+
+ public enum Updating {
+ UNDEFINED, BAZAAR, LOWEST_BINS
}
}