1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
package de.cowtipper.cowlection.chesttracker;
import de.cowtipper.cowlection.Cowlection;
import de.cowtipper.cowlection.util.ApiUtils;
import de.cowtipper.cowlection.util.MooChatComponent;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.MinecraftForge;
import java.util.*;
public class ChestTracker {
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 final Cowlection main;
public ChestTracker(Cowlection main) {
this.main = main;
refreshBazaarCache();
chestInteractionListener = new ChestInteractionListener(main);
MinecraftForge.EVENT_BUS.register(chestInteractionListener);
}
public void analyzeResults() {
Map<String, ItemData> itemCounts = new HashMap<>();
for (List<ItemStack> chestContents : chestCache.values()) {
for (ItemStack item : chestContents) {
String key = item.hasDisplayName() ? item.getDisplayName() : item.getUnlocalizedName();
if (item.hasTagCompound()) {
key = item.getTagCompound().getCompoundTag("ExtraAttributes").getString("id");
}
ItemData itemData = itemCounts.get(key);
if (itemData == null) {
itemData = new ItemData(key, item.copy());
}
itemCounts.put(key, itemData.addAmount(item.stackSize));
}
}
this.analysisResult = itemCounts;
}
/**
* Returns ordered analysis result with prices
*/
public List<ItemData> getAnalysisResult(ChestOverviewGui.Column orderBy, boolean orderDesc, boolean useInstantSellPrices) {
List<ItemData> orderedAnalysisResult = new ArrayList<>();
// sort by bazaar value (most value first)
for (Map.Entry<String, ItemData> itemEntry : analysisResult.entrySet()) {
if (bazaarCache != null && bazaarCache.isSuccess()) {
String productKey = itemEntry.getKey();
HyBazaarData.Product product = bazaarCache.getProduct(productKey);
if (product != null) {
// item is sold on bazaar!
itemEntry.getValue().setBazaarInstantSellPrice(product.getInstantSellPrice());
itemEntry.getValue().setBazaarSellOfferPrice(product.getSellOfferPrice());
}
}
orderedAnalysisResult.add(itemEntry.getValue());
}
Comparator<ItemData> comparator;
switch (orderBy) {
case ITEM_NAME:
comparator = Comparator.comparing(ItemData::getName);
break;
case ITEM_AMOUNT:
comparator = Comparator.comparing(ItemData::getAmount);
break;
case PRICE_EACH:
comparator = useInstantSellPrices ? Comparator.comparing(ItemData::getBazaarInstantSellPrice) : Comparator.comparing(ItemData::getBazaarSellOfferPrice);
break;
default: // case PRICE_SUM:
comparator = useInstantSellPrices ? Comparator.comparing(ItemData::getBazaarInstantSellValue) : Comparator.comparing(ItemData::getBazaarSellOfferValue);
break;
}
orderedAnalysisResult.sort((orderDesc ? comparator.reversed() : comparator).thenComparing(ItemData::getName));
return orderedAnalysisResult;
}
public Set<BlockPos> getCachedPositions() {
return chestCache.keySet();
}
public void clear() {
MinecraftForge.EVENT_BUS.unregister(chestInteractionListener);
chestInteractionListener = null;
bazaarCache = null;
chestCache.clear();
doubleChestCache.clear();
analysisResult.clear();
}
public void addChest(BlockPos chestPos, List<ItemStack> chestContents, EnumFacing otherChestFacing) {
if (chestContents.size() > 0) { // check if the chest is a chest we want to cache/analyze
ItemStack firstItem = chestContents.get(0);
if (firstItem != null && firstItem.hasDisplayName() && firstItem.getDisplayName().equals(" ") && firstItem.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) {
// item in first slot of chest is a glass pane with the display name " ", indicating e.g. a minion chest which we don't want to track
return;
}
}
BlockPos mainChestPos = chestPos;
if (otherChestFacing != EnumFacing.UP) { // we have a double chest!
if (isOtherChestCached(chestPos, otherChestFacing)) { // other chest is cached already, update that one instead
mainChestPos = chestPos.offset(otherChestFacing);
}
if (chestPos.equals(mainChestPos)) {
doubleChestCache.put(chestPos, otherChestFacing);
} else {
doubleChestCache.put(mainChestPos, otherChestFacing.getOpposite());
}
}
chestCache.put(mainChestPos, chestContents);
}
public void removeChest(BlockPos chestPos, EnumFacing otherChestFacing) {
BlockPos mainChestPos = chestPos;
if (otherChestFacing != EnumFacing.UP) { // we have a double chest!
if (isOtherChestCached(chestPos, otherChestFacing)) { // other chest is cached already, update that one instead
mainChestPos = chestPos.offset(otherChestFacing);
}
if (chestPos.equals(mainChestPos)) {
doubleChestCache.remove(chestPos);
} else {
doubleChestCache.remove(mainChestPos);
}
}
chestCache.remove(mainChestPos);
}
private boolean isOtherChestCached(BlockPos chestPos, EnumFacing otherChestFacing) {
BlockPos otherChestPos = chestPos.offset(otherChestFacing);
return chestCache.containsKey(otherChestPos);
}
public EnumFacing getOtherChestFacing(BlockPos pos) {
return doubleChestCache.getOrDefault(pos, EnumFacing.UP);
}
public void refreshBazaarCache() {
if (allowUpdateBazaar()) {
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();
});
}
}
public boolean allowUpdateBazaar() {
return bazaarCache == null || bazaarCache.allowRefreshData();
}
public long getLastBazaarUpdate() {
return this.lastBazaarUpdate;
}
}
|