aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/io')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java60
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java472
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java129
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/questing/requirements/RequirementApi.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java35
8 files changed, 413 insertions, 320 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java
index b9f086a4..f272ee29 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java
@@ -63,6 +63,19 @@ public class NEUIO {
}
}
+ public String getLatestCommit() {
+ try {
+ GitHub github = new GitHubBuilder().withOAuthToken(accessToken).build();
+ GHRepository repo = github.getRepositoryById("247692460");
+ for(GHCommit commit : repo.listCommits()) {
+ return commit.getSHA1();
+ }
+ } catch(IOException e) {
+ return null;
+ }
+ return "";
+ }
+
/**
* @param oldShas Map from filename (eg. BOW.json) to the sha in the local repository
* @return Map from filename to the new shas
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 14dc61fb..30dc12c4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -10,6 +10,7 @@ import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.init.Blocks;
+import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.*;
@@ -115,12 +116,10 @@ public class NEUManager {
public void setCurrentProfile(String currentProfile) {
this.currentProfile = currentProfile;
- this.auctionManager.incPlayerInfoVersion();
}
public void setCurrentProfileBackup(String currentProfile) {
this.currentProfileBackup = currentProfile;
- this.auctionManager.incPlayerInfoVersion();
}
public String getCurrentProfile() {
@@ -378,6 +377,21 @@ public class NEUManager {
if (Display.isActive()) dialog.toFront();
+ String latestCommit = neuio.getLatestCommit();
+ if(latestCommit == null || latestCommit.isEmpty()) return;
+
+ JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json"));
+ if(currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestCommit)) {
+ JsonObject newCurrentCommitJSON = new JsonObject();
+ newCurrentCommitJSON.addProperty("sha", latestCommit);
+ try {
+ writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json"));
+ } catch (IOException e) {
+ }
+ } else {
+ return;
+ }
+
HashMap<String, String> oldShas = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : itemShaConfig.entrySet()) {
if (new File(repoLocation, entry.getKey() + ".json").exists()) {
@@ -386,8 +400,6 @@ public class NEUManager {
}
Map<String, String> changedFiles = neuio.getChangedItems(oldShas);
-
-
if (Display.isActive()) dialog.toFront();
if (changedFiles != null && changedFiles.size() <= 20) {
@@ -447,7 +459,11 @@ public class NEUManager {
} catch (IOException e) {
return;
}
- try (BufferedInputStream inStream = new BufferedInputStream(new URL(dlUrl).openStream());
+ URL url = new URL(dlUrl);
+ URLConnection urlConnection = url.openConnection();
+ urlConnection.setConnectTimeout(3000);
+ urlConnection.setReadTimeout(3000);
+ try (BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream());
FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)) {
byte dataBuffer[] = new byte[1024];
int bytesRead;
@@ -481,24 +497,30 @@ public class NEUManager {
}
} catch(Exception e) {}
- Set<String> currentlyInstalledItems = new HashSet<>();
- for(File f : new File(repoLocation, "items").listFiles()) {
- currentlyInstalledItems.add(f.getName().substring(0, f.getName().length()-5));
+ File items = new File(repoLocation, "items");
+ if(items.exists()) {
+ File[] itemFiles = new File(repoLocation, "items").listFiles();
+ if(itemFiles != null) {
+ for(File f : itemFiles) {
+ String internalname = f.getName().substring(0, f.getName().length()-5);
+ if(!getItemInformation().keySet().contains(internalname)) {
+ loadItem(internalname);
+ }
+ }
+ }
}
+ });
- Set<String> removedItems;
- if(config.autoupdate.value) {
- removedItems = neuio.getRemovedItems(currentlyInstalledItems);
- } else {
- removedItems = new HashSet<>();
- }
- for(File f : new File(repoLocation, "items").listFiles()) {
- String internalname = f.getName().substring(0, f.getName().length()-5);
- if(!removedItems.contains(internalname)) {
+ File items = new File(repoLocation, "items");
+ if(items.exists()) {
+ File[] itemFiles = new File(repoLocation, "items").listFiles();
+ if(itemFiles != null) {
+ for(File f : itemFiles) {
+ String internalname = f.getName().substring(0, f.getName().length()-5);
loadItem(internalname);
}
}
- });
+ }
thread.start();
}
@@ -1510,6 +1532,8 @@ public class NEUManager {
}
public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements) {
+ if(json == null) return new ItemStack(Items.painting, 1, 10);
+
if(useCache && itemstackCache.containsKey(json.get("internalname").getAsString())) {
return itemstackCache.get(json.get("internalname").getAsString()).copy();
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 9e4e851a..0e21067b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -77,7 +77,7 @@ import static io.github.moulberry.notenoughupdates.GuiTextures.*;
@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION)
public class NotEnoughUpdates {
public static final String MODID = "notenoughupdates";
- public static final String VERSION = "REL-1.0.0";
+ public static final String VERSION = "REL-1.0.1";
public static NotEnoughUpdates INSTANCE = null;
@@ -366,7 +366,7 @@ public class NotEnoughUpdates {
Minecraft.getMinecraft().thePlayer.addChatMessage(links);
}
- private boolean displayUpdateMessageIfOutOfDate() {
+ private void displayUpdateMessageIfOutOfDate() {
File repo = manager.repoLocation;
if(repo.exists()) {
File updateJson = new File(repo, "update.json");
@@ -408,12 +408,8 @@ public class NotEnoughUpdates {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
}
-
- return true;
} catch(Exception ignored) {}
- return true;
}
- return false;
}
/**
@@ -425,6 +421,8 @@ public class NotEnoughUpdates {
private long lastLongUpdate = 0;
@SubscribeEvent
public void onTick(TickEvent.ClientTickEvent event) {
+ if(event.phase != TickEvent.Phase.START) return;
+
boolean longUpdate = false;
long currentTime = System.currentTimeMillis();
if(currentTime - lastLongUpdate > 1000) {
@@ -440,9 +438,8 @@ public class NotEnoughUpdates {
if(hasSkyblockScoreboard()) {
manager.auctionManager.tick();
if(!joinedSB && manager.config.showUpdateMsg.value) {
- if(displayUpdateMessageIfOutOfDate()) {
- joinedSB = false;
- }
+ joinedSB = true;
+ displayUpdateMessageIfOutOfDate();
}
SBScoreboardData.getInstance().tick();
//GuiQuestLine.questLine.tick();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
index ea6d2f9f..0fe0cc67 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -1,6 +1,7 @@
package io.github.moulberry.notenoughupdates.auction;
import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -29,8 +30,6 @@ public class APIManager {
public final CustomAH customAH;
private int totalPages = 0;
- private int lastApiUpdate;
- private LinkedList<Integer> needUpdate = new LinkedList<>();
private TreeMap<String, Auction> auctionMap = new TreeMap<>();
public HashMap<String, HashSet<String>> internalnameToAucIdMap = new HashMap<>();
@@ -42,12 +41,10 @@ public class APIManager {
private JsonArray playerInformation = null;
- public HashMap<Integer, Integer> aucUpdates = new HashMap<>();
-
public TreeMap<String, HashMap<Integer, HashSet<String>>> extrasToAucIdMap = new TreeMap<>();
- private long lastPageUpdate = 0;
- private long lastProfileUpdate = 0;
+ private boolean fullDownload = false;
+ private long lastAuctionUpdate = 0;
private long lastCustomAHSearch = 0;
private long lastCleanup = 0;
@@ -58,38 +55,11 @@ public class APIManager {
public int taggedAuctions = 0;
public int processMillis = 0;
- private boolean doFullUpdate = false;
-
public APIManager(NEUManager manager) {
this.manager = manager;
customAH = new CustomAH(manager);
}
- private AtomicInteger playerInfoVersion = new AtomicInteger(0);
-
- public JsonObject getPlayerInformation() {
- if(playerInformation == null) return null;
- for(int i=0; i<playerInformation.size(); i++) {
- JsonObject profile = playerInformation.get(i).getAsJsonObject();
- if(profile.get("cute_name").getAsString().equalsIgnoreCase(manager.getCurrentProfile())) {
- if(!profile.has("members")) return null;
- JsonObject members = profile.get("members").getAsJsonObject();
- String uuid = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "");
- if(!members.has(uuid)) return null;
- return members.get(uuid).getAsJsonObject();
- }
- }
- return null;
- }
-
- public int getPlayerInfoVersion() {
- return playerInfoVersion.get();
- }
-
- public void incPlayerInfoVersion() {
- playerInfoVersion.incrementAndGet();
- }
-
public TreeMap<String, Auction> getAuctionItems() {
return auctionMap;
}
@@ -148,8 +118,8 @@ public class APIManager {
customAH.tick();
long currentTime = System.currentTimeMillis();
- if(currentTime - lastPageUpdate > 5*1000) {
- lastPageUpdate = currentTime;
+ if(currentTime - lastAuctionUpdate > 60*1000) {
+ lastAuctionUpdate = currentTime;
updatePageTick();
ahNotification();
}
@@ -170,44 +140,6 @@ public class APIManager {
}
}
- public void updateProfiles(String uuid) {
- HashMap<String, String> args = new HashMap<>();
- args.put("uuid", ""+uuid);
- manager.hypixelApi.getHypixelApiAsync(manager.config.apiKey.value, "skyblock/profiles",
- args, jsonObject -> {
- if(jsonObject == null) return;
-
- if(jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) {
- incPlayerInfoVersion();
- playerInformation = jsonObject.get("profiles").getAsJsonArray();
- if(playerInformation == null) return;
- String backup = null;
- long backupLastSave = 0;
- for(int i=0; i<playerInformation.size(); i++) {
- JsonObject profile = playerInformation.get(i).getAsJsonObject();
- String cute_name = profile.get("cute_name").getAsString();
-
- if(backup == null) backup = cute_name;
-
- if(!profile.has("members")) continue;
- JsonObject members = profile.get("members").getAsJsonObject();
-
- if(members.has(uuid)) {
- JsonObject member = members.get(uuid).getAsJsonObject();
- long last_save = member.get("last_save").getAsLong();
- if(last_save > backupLastSave) {
- backupLastSave = last_save;
- backup = cute_name;
- }
- }
- }
-
- manager.setCurrentProfileBackup(backup);
- }
- }
- );
- }
-
private String niceAucId(String aucId) {
if(aucId.length()!=32) return aucId;
@@ -277,50 +209,77 @@ public class APIManager {
long timeToEnd = entry.getValue().end - currTime;
if(timeToEnd < -60) {
toRemove.add(entry.getKey());
- } else if(currTime - entry.getValue().lastUpdate > 5*60*1000) {
- toRemove.add(entry.getKey());
}
}
toRemove.removeAll(playerBids);
- for(String aucid : toRemove) {
- auctionMap.remove(aucid);
- }
- for(HashMap<Integer, HashSet<String>> extrasMap : extrasToAucIdMap.values()) {
- for(HashSet<String> aucids : extrasMap.values()) {
- for(String aucid : toRemove) {
- aucids.remove(aucid);
- }
- }
- }
- for(HashSet<String> aucids : internalnameToAucIdMap.values()) {
- aucids.removeAll(toRemove);
- }
- for(TreeMap<Integer, String> lowestBINs : internalnameToLowestBIN.values()) {
- lowestBINs.values().removeAll(toRemove);
- }
+ remove(toRemove);
} catch(ConcurrentModificationException e) {
lastCleanup = System.currentTimeMillis() - 110*1000;
}
});
}
+ private void remove(Set<String> toRemove) {
+ for(String aucid : toRemove) {
+ auctionMap.remove(aucid);
+ }
+ for(HashMap<Integer, HashSet<String>> extrasMap : extrasToAucIdMap.values()) {
+ for(HashSet<String> aucids : extrasMap.values()) {
+ for(String aucid : toRemove) {
+ aucids.remove(aucid);
+ }
+ }
+ }
+ for(HashSet<String> aucids : internalnameToAucIdMap.values()) {
+ aucids.removeAll(toRemove);
+ }
+ for(TreeMap<Integer, String> lowestBINs : internalnameToLowestBIN.values()) {
+ lowestBINs.values().removeAll(toRemove);
+ }
+ }
+
private void updatePageTick() {
- if(totalPages == 0) {
+ JsonObject disable = Utils.getConstant("disable");
+ if(!fullDownload && (disable == null || !disable.get("auctions").getAsBoolean())) {
+ fullDownload = true;
getPageFromAPI(0);
- } else if(doFullUpdate) {
- doFullUpdate = false;
- for(int i=0; i<totalPages; i++) {
+ for(int i=1; i<totalPages; i++) {
getPageFromAPI(i);
}
} else {
- if(needUpdate.isEmpty()) resetNeedUpdate();
-
- int pageToUpdate = needUpdate.pop();
- while (pageToUpdate >= totalPages && !needUpdate.isEmpty()) {
- pageToUpdate = needUpdate.pop();
- }
-
- getPageFromAPI(pageToUpdate);
+ manager.hypixelApi.getApiGZIPAsync("http://51.89.22.3/auction.json.gz", jsonObject -> {
+ if(jsonObject.get("success").getAsBoolean()) {
+ JsonArray new_auctions = jsonObject.get("new_auctions").getAsJsonArray();
+ for(JsonElement auctionElement : new_auctions) {
+ JsonObject auction = auctionElement.getAsJsonObject();
+ processAuction(auction);
+ }
+ JsonArray new_bids = jsonObject.get("new_bids").getAsJsonArray();
+ for(JsonElement newBidElement : new_bids) {
+ JsonObject newBid = newBidElement.getAsJsonObject();
+ String newBidUUID = newBid.get("uuid").getAsString();
+ int newBidAmount = newBid.get("highest_bid_amount").getAsInt();
+ int end = newBid.get("end").getAsInt();
+ int bid_count = newBid.get("bid_count").getAsInt();
+
+ Auction auc = auctionMap.get(newBidUUID);
+ if(auc != null) {
+ auc.highest_bid_amount = newBidAmount;
+ auc.end = end;
+ auc.bid_count = bid_count;
+ }
+ }
+ Set<String> toRemove = new HashSet<>();
+ JsonArray removed_auctions = jsonObject.get("removed_auctions").getAsJsonArray();
+ for(JsonElement removedAuctionsElement : removed_auctions) {
+ String removed = removedAuctionsElement.getAsString();
+ toRemove.add(removed);
+ }
+ remove(toRemove);
+ }
+ }, () -> {
+ System.out.println("error");
+ });
}
}
@@ -375,6 +334,147 @@ public class APIManager {
private String[] romans = new String[]{"I","II","III","IV","V","VI","VII","VIII","IX","X","XI",
"XII","XIII","XIV","XV","XVI","XVII","XIX","XX"};
+
+ String[] categoryItemType = new String[]{"sword","fishingrod","pickaxe","axe",
+ "shovel","petitem","travelscroll","reforgestone","bow"};
+ String playerUUID = null;
+ private void processAuction(JsonObject auction) {
+ if(playerUUID == null) playerUUID = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replaceAll("-","");
+
+ String auctionUuid = auction.get("uuid").getAsString();
+ String auctioneerUuid = auction.get("auctioneer").getAsString();
+ long end = auction.get("end").getAsLong();
+ int starting_bid = auction.get("starting_bid").getAsInt();
+ int highest_bid_amount = auction.get("highest_bid_amount").getAsInt();
+ int bid_count = auction.get("bids").getAsJsonArray().size();
+ boolean bin = false;
+ if(auction.has("bin")) {
+ bin = auction.get("bin").getAsBoolean();
+ }
+ String sbCategory = auction.get("category").getAsString();
+ String extras = auction.get("extra").getAsString().toLowerCase();
+ String item_name = auction.get("item_name").getAsString();
+ String item_lore = Utils.fixBrokenAPIColour(auction.get("item_lore").getAsString());
+ String item_bytes = auction.get("item_bytes").getAsString();
+ String rarity = auction.get("tier").getAsString();
+ JsonArray bids = auction.get("bids").getAsJsonArray();
+
+ try {
+ NBTTagCompound item_tag;
+ try {
+ item_tag = CompressedStreamTools.readCompressed(
+ new ByteArrayInputStream(Base64.getDecoder().decode(item_bytes)));
+ } catch(IOException e) { return; }
+
+ NBTTagCompound tag = item_tag.getTagList("i", 10).getCompoundTagAt(0).getCompoundTag("tag");
+ String internalname = manager.getInternalnameFromNBT(tag);
+ String displayNormal = "";
+ if(manager.getItemInformation().containsKey(internalname)) {
+ displayNormal = Utils.cleanColour(manager.getItemInformation().get(internalname).get("displayname").getAsString());
+ } else {
+
+ }
+
+ String[] lore = new String[0];
+ NBTTagCompound display = tag.getCompoundTag("display");
+ if(display.hasKey("Lore", 9)) {
+ NBTTagList loreList = new NBTTagList();
+ for(String line : item_lore.split("\n")) {
+ loreList.appendTag(new NBTTagString(line));
+ }
+ display.setTag("Lore", loreList);
+ }
+ tag.setTag("display", display);
+ item_tag.getTagList("i", 10).getCompoundTagAt(0).setTag("tag", tag);
+
+ if(tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+
+ if(ea.hasKey("enchantments", 10)) {
+ NBTTagCompound enchantments = ea.getCompoundTag("enchantments");
+ for(String key : enchantments.getKeySet()) {
+ String enchantname = key.toLowerCase().replace("_", " ");
+ int enchantlevel = enchantments.getInteger(key);
+ String enchantLevelStr;
+ if(enchantlevel >= 1 && enchantlevel <= 20) {
+ enchantLevelStr = romans[enchantlevel-1];
+ } else {
+ enchantLevelStr = String.valueOf(enchantlevel);
+ }
+ extras = extras.replace(enchantname, enchantname + " " + enchantLevelStr);
+ }
+ }
+ }
+
+ int index=0;
+ for(String str : extras.split(" ")) {
+ str = Utils.cleanColour(str).toLowerCase();
+ if(str.length() > 0) {
+ HashMap<Integer, HashSet<String>> extrasMap = extrasToAucIdMap.computeIfAbsent(str, k -> new HashMap<>());
+ HashSet<String> aucids = extrasMap.computeIfAbsent(index, k -> new HashSet<>());
+ aucids.add(auctionUuid);
+ }
+ index++;
+ }
+
+ if(bin) {
+ TreeMap<Integer, String> lowestBINs = internalnameToLowestBIN.computeIfAbsent(internalname, k -> new TreeMap<>());
+ int count = item_tag.getInteger("Count");
+ lowestBINs.put(starting_bid/(count>0?count:1), auctionUuid);
+ if(lowestBINs.size() > 5) {
+ lowestBINs.keySet().remove(lowestBINs.lastKey());
+ }
+ }
+
+ for(int j=0; j<bids.size(); j++) {
+ JsonObject bid = bids.get(j).getAsJsonObject();
+ if(bid.get("bidder").getAsString().equalsIgnoreCase(playerUUID)) {
+ playerBids.add(auctionUuid);
+ }
+ }
+
+ if(checkItemType(item_lore, true, "DUNGEON") >= 0) {
+ HashMap<Integer, HashSet<String>> extrasMap = extrasToAucIdMap.computeIfAbsent("dungeon", k -> new HashMap<>());
+ HashSet<String> aucids = extrasMap.computeIfAbsent(0, k -> new HashSet<>());
+ aucids.add(auctionUuid);
+ }
+
+ //Categories
+ String category = sbCategory;
+ int itemType = checkItemType(item_lore, true,"SWORD", "FISHING ROD", "PICKAXE",
+ "AXE", "SHOVEL", "PET ITEM", "TRAVEL SCROLL", "REFORGE STONE", "BOW");
+ if(itemType >= 0 && itemType < categoryItemType.length) {
+ category = categoryItemType[itemType];
+ }
+ if(internalname.contains("ENCHANTED_BOOK")) category = "ebook";
+ if(extras.endsWith("Potion")) category = "potion";
+ if(extras.contains("Rune")) category = "rune";
+ if(item_lore.split("\n")[0].endsWith("Furniture")) category = "furniture";
+ if(item_lore.split("\n")[0].endsWith("Pet") ||
+ item_lore.split("\n")[0].endsWith("Mount")) category = "pet";
+
+ Auction auction1 = new Auction(auctioneerUuid, end, starting_bid, highest_bid_amount,
+ bid_count, bin, category, rarity, item_tag);
+
+ if(tag.hasKey("ench")) {
+ auction1.enchLevel = 1;
+ if(tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+
+ int hotpotatocount = ea.getInteger("hot_potato_count");
+ if(hotpotatocount == 10) {
+ auction1.enchLevel = 2;
+ }
+ }
+ }
+
+ auction1.lastUpdate = System.currentTimeMillis();
+
+ auctionMap.put(auctionUuid, auction1);
+ internalnameToAucIdMap.computeIfAbsent(internalname, k -> new HashSet<>()).add(auctionUuid);
+ } catch(Exception e) {e.printStackTrace();}
+ }
+
private void getPageFromAPI(int page) {
//System.out.println("Trying to update page: " + page);
HashMap<String, String> args = new HashMap<>();
@@ -387,168 +487,12 @@ public class APIManager {
totalPages = jsonObject.get("totalPages").getAsInt();
activeAuctions = jsonObject.get("totalAuctions").getAsInt();
- int lastUpdated = jsonObject.get("lastUpdated").getAsInt();
-
- if(lastApiUpdate != lastUpdated) {
- if(manager.config.quickAHUpdate.value &&
- (Minecraft.getMinecraft().currentScreen instanceof CustomAHGui || customAH.isRenderOverAuctionView())) {
- doFullUpdate = true;
- }
- resetNeedUpdate();
- }
-
- lastApiUpdate = lastUpdated;
-
- String[] lvl4Maxes = {"Experience", "Life Steal", "Scavenger", "Looting"};
-
- String[] categoryItemType = new String[]{"sword","fishingrod","pickaxe","axe",
- "shovel","petitem","travelscroll","reforgestone","bow"};
- String playerUUID = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replaceAll("-","");
-
long startProcess = System.currentTimeMillis();
JsonArray auctions = jsonObject.get("auctions").getAsJsonArray();
for (int i = 0; i < auctions.size(); i++) {
JsonObject auction = auctions.get(i).getAsJsonObject();
- String auctionUuid = auction.get("uuid").getAsString();
- String auctioneerUuid = auction.get("auctioneer").getAsString();
- long end = auction.get("end").getAsLong();
- int starting_bid = auction.get("starting_bid").getAsInt();
- int highest_bid_amount = auction.get("highest_bid_amount").getAsInt();
- int bid_count = auction.get("bids").getAsJsonArray().size();
- boolean bin = false;
- if(auction.has("bin")) {
- bin = auction.get("bin").getAsBoolean();
- }
- String sbCategory = auction.get("category").getAsString();
- String extras = auction.get("extra").getAsString().toLowerCase();
- String item_name = auction.get("item_name").getAsString();
- String item_lore = Utils.fixBrokenAPIColour(auction.get("item_lore").getAsString());
- String item_bytes = auction.get("item_bytes").getAsString();
- String rarity = auction.get("tier").getAsString();
- JsonArray bids = auction.get("bids").getAsJsonArray();
-
- {
- Auction old = auctionMap.get(auctionUuid);
- if(old != null && old.highest_bid_amount != highest_bid_amount) {
- aucUpdates.put(page, aucUpdates.computeIfAbsent(page, k->0)+1);
- }
- }
-
- try {
- NBTTagCompound item_tag;
- try {
- item_tag = CompressedStreamTools.readCompressed(
- new ByteArrayInputStream(Base64.getDecoder().decode(item_bytes)));
- } catch(IOException e) { continue; }
-
- NBTTagCompound tag = item_tag.getTagList("i", 10).getCompoundTagAt(0).getCompoundTag("tag");
- String internalname = manager.getInternalnameFromNBT(tag);
- String displayNormal = "";
- if(manager.getItemInformation().containsKey(internalname)) {
- displayNormal = Utils.cleanColour(manager.getItemInformation().get(internalname).get("displayname").getAsString());
- } else {
-
- }
-
- String[] lore = new String[0];
- NBTTagCompound display = tag.getCompoundTag("display");
- if(display.hasKey("Lore", 9)) {
- NBTTagList loreList = new NBTTagList();
- for(String line : item_lore.split("\n")) {
- loreList.appendTag(new NBTTagString(line));
- }
- display.setTag("Lore", loreList);
- }
- tag.setTag("display", display);
- item_tag.getTagList("i", 10).getCompoundTagAt(0).setTag("tag", tag);
-
- if(tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if(ea.hasKey("enchantments", 10)) {
- NBTTagCompound enchantments = ea.getCompoundTag("enchantments");
- for(String key : enchantments.getKeySet()) {
- String enchantname = key.toLowerCase().replace("_", " ");
- int enchantlevel = enchantments.getInteger(key);
- String enchantLevelStr;
- if(enchantlevel >= 1 && enchantlevel <= 20) {
- enchantLevelStr = romans[enchantlevel-1];
- } else {
- enchantLevelStr = String.valueOf(enchantlevel);
- }
- extras = extras.replace(enchantname, enchantname + " " + enchantLevelStr);
- }
- }
- }
-
- int index=0;
- for(String str : extras.split(" ")) {
- str = Utils.cleanColour(str).toLowerCase();
- if(str.length() > 0) {
- HashMap<Integer, HashSet<String>> extrasMap = extrasToAucIdMap.computeIfAbsent(str, k -> new HashMap<>());
- HashSet<String> aucids = extrasMap.computeIfAbsent(index, k -> new HashSet<>());
- aucids.add(auctionUuid);
- }
- index++;
- }
-
- if(bin) {
- TreeMap<Integer, String> lowestBINs = internalnameToLowestBIN.computeIfAbsent(internalname, k -> new TreeMap<>());
- int count = item_tag.getInteger("Count");
- lowestBINs.put(starting_bid/(count>0?count:1), auctionUuid);
- if(lowestBINs.size() > 5) {
- lowestBINs.keySet().remove(lowestBINs.lastKey());
- }
- }
-
- for(int j=0; j<bids.size(); j++) {
- JsonObject bid = bids.get(j).getAsJsonObject();
- if(bid.get("bidder").getAsString().equalsIgnoreCase(playerUUID)) {
- playerBids.add(auctionUuid);
- }
- }
-
- if(checkItemType(item_lore, true, "DUNGEON") >= 0) {
- HashMap<Integer, HashSet<String>> extrasMap = extrasToAucIdMap.computeIfAbsent("dungeon", k -> new HashMap<>());
- HashSet<String> aucids = extrasMap.computeIfAbsent(0, k -> new HashSet<>());
- aucids.add(auctionUuid);
- }
-
- //Categories
- String category = sbCategory;
- int itemType = checkItemType(item_lore, true,"SWORD", "FISHING ROD", "PICKAXE",
- "AXE", "SHOVEL", "PET ITEM", "TRAVEL SCROLL", "REFORGE STONE", "BOW");
- if(itemType >= 0 && itemType < categoryItemType.length) {
- category = categoryItemType[itemType];
- }
- if(internalname.contains("ENCHANTED_BOOK")) category = "ebook";
- if(extras.endsWith("Potion")) category = "potion";
- if(extras.contains("Rune")) category = "rune";
- if(item_lore.split("\n")[0].endsWith("Furniture")) category = "furniture";
- if(item_lore.split("\n")[0].endsWith("Pet") ||
- item_lore.split("\n")[0].endsWith("Mount")) category = "pet";
-
- Auction auction1 = new Auction(auctioneerUuid, end, starting_bid, highest_bid_amount,
- bid_count, bin, category, rarity, item_tag);
-
- if(tag.hasKey("ench")) {
- auction1.enchLevel = 1;
- if(tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- int hotpotatocount = ea.getInteger("hot_potato_count");
- if(hotpotatocount == 10) {
- auction1.enchLevel = 2;
- }
- }
- }
-
- auction1.lastUpdate = System.currentTimeMillis();
-
- auctionMap.put(auctionUuid, auction1);
- internalnameToAucIdMap.computeIfAbsent(internalname, k -> new HashSet<>()).add(auctionUuid);
- } catch(Exception e) {e.printStackTrace();}
+ processAuction(auction);
}
processMillis = (int)(System.currentTimeMillis() - startProcess);
}
@@ -556,14 +500,6 @@ public class APIManager {
);
}
- private void resetNeedUpdate() {
- for(Integer page=0; page<totalPages; page++) {
- if(!needUpdate.contains(page)) {
- needUpdate.addLast(page);
- }
- }
- }
-
/*ScheduledExecutorService auctionUpdateSES = Executors.newSingleThreadScheduledExecutor();
private AtomicInteger auctionUpdateId = new AtomicInteger(0);
public void updateAuctions() {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
index f7409c97..a1ad89a1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
@@ -881,11 +881,6 @@ public class CustomAH extends Gui {
lore.add("ID Tagged Auctions: " + manager.auctionManager.internalnameTaggedAuctions);
lore.add("Total Tags: " + manager.auctionManager.totalTags);
lore.add("Tagged Auctions: " + manager.auctionManager.taggedAuctions);
- lore.add("AucUpdates(0): " + manager.auctionManager.aucUpdates.computeIfAbsent(0, k->0));
- lore.add("AucUpdates(1): " + manager.auctionManager.aucUpdates.computeIfAbsent(1, k->0));
- lore.add("AucUpdates(20): " + manager.auctionManager.aucUpdates.computeIfAbsent(20, k->0));
- lore.add("AucUpdates(Last-1): " + manager.auctionManager.aucUpdates.computeIfAbsent(manager.auctionManager.aucUpdates.size()-2, k->0));
- lore.add("AucUpdates(Last): " + manager.auctionManager.aucUpdates.computeIfAbsent(manager.auctionManager.aucUpdates.size()-1, k->0));
lore.add("");
lore.add(EnumChatFormatting.AQUA + "Right-Click to copy current aucid to clipboard!");
lore.add(EnumChatFormatting.YELLOW + "Click to refresh!");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index 8224bb6d..95fca402 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -588,6 +588,7 @@ public class GuiProfileViewer extends GuiScreen {
private class Level {
float level;
float currentLevelRequirement;
+ float maxXP;
}
public Level getLevel(JsonArray levels, int offset, float exp) {
@@ -596,15 +597,19 @@ public class GuiProfileViewer extends GuiScreen {
float currentLevelRequirement = 0;
float remainingToNextLevel = 0;
+ boolean addLevel = true;
+
for(int i=offset; i<offset+99; i++) {
currentLevelRequirement = levels.get(i).getAsFloat();
xpTotal += currentLevelRequirement;
- if(xpTotal > exp) {
- remainingToNextLevel = (xpTotal-currentLevelRequirement+exp)/currentLevelRequirement;
- break;
- } else {
- level += 1;
+ if(addLevel) {
+ if(xpTotal > exp) {
+ remainingToNextLevel = (exp-(xpTotal-currentLevelRequirement))/currentLevelRequirement;
+ addLevel = false;
+ } else {
+ level += 1;
+ }
}
}
@@ -617,9 +622,40 @@ public class GuiProfileViewer extends GuiScreen {
Level levelObj = new Level();
levelObj.level = level;
levelObj.currentLevelRequirement = currentLevelRequirement;
+ levelObj.maxXP = xpTotal;
return levelObj;
}
+ private static final HashMap<String, HashMap<String, Float>> PET_STAT_BOOSTS = new HashMap<>();
+ static {
+ HashMap<String, Float> bigTeeth = new HashMap<>();
+ bigTeeth.put("CRIT_CHANCE", 5f);
+ PET_STAT_BOOSTS.put("PET_ITEM_BIG_TEETH_COMMON", bigTeeth);
+
+ HashMap<String, Float> hardenedScales = new HashMap<>();
+ hardenedScales.put("DEFENCE", 25f);
+ PET_STAT_BOOSTS.put("PET_ITEM_HARDENED_SCALES_UNCOMMON", hardenedScales);
+
+ HashMap<String, Float> luckyClover = new HashMap<>();
+ luckyClover.put("MAGIC_FIND", 7f);
+ PET_STAT_BOOSTS.put("PET_ITEM_LUCKY_CLOVER", luckyClover);
+
+ HashMap<String, Float> sharpenedClaws = new HashMap<>();
+ sharpenedClaws.put("CRIT_DAMAGE", 15f);
+ PET_STAT_BOOSTS.put("PET_ITEM_SHARPENED_CLAWS_UNCOMMON", sharpenedClaws);
+ }
+ private static final HashMap<String, HashMap<String, Float>> PET_STAT_BOOSTS_MULT = new HashMap<>();
+ static {
+ HashMap<String, Float> ironClaws = new HashMap<>();
+ ironClaws.put("CRIT_DAMAGE", 1.4f);
+ ironClaws.put("CRIT_CHANCE", 1.4f);
+ PET_STAT_BOOSTS_MULT.put("PET_ITEM_IRON_CLAWS_COMMON", ironClaws);
+
+ HashMap<String, Float> textbook = new HashMap<>();
+ textbook.put("INTELLIGENCE", 2f);
+ PET_STAT_BOOSTS_MULT.put("PET_ITEM_TEXTBOOK", textbook);
+ }
+
private int selectedPet = -1;
private int petsPage = 0;
private List<JsonObject> sortedPets = null;
@@ -682,6 +718,8 @@ public class GuiProfileViewer extends GuiScreen {
for(JsonObject pet : sortedPets) {
String petname = pet.get("type").getAsString();
String tier = pet.get("tier").getAsString();
+ String heldItem = Utils.getElementAsString(pet.get("heldItem"), null);
+ JsonObject heldItemJson = heldItem==null?null:NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(heldItem);
String tierNum = minionRarityToNumMap.get(tier);
float exp = pet.get("exp").getAsFloat();
if(tierNum == null) continue;
@@ -692,27 +730,85 @@ public class GuiProfileViewer extends GuiScreen {
Level levelObj = getLevel(levelsArr, petRarityOffset, exp);
float level = levelObj.level;
float currentLevelRequirement = levelObj.currentLevelRequirement;
+ float maxXP = levelObj.maxXP;
pet.addProperty("level", level);
pet.addProperty("currentLevelRequirement", currentLevelRequirement);
+ pet.addProperty("maxXP", maxXP);
JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(petname+";"+tierNum);
+ if(petItem == null) continue;
+
ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false);
HashMap<String, String> replacements = NotEnoughUpdates.INSTANCE.manager.getLoreReplacements(petname, tier, (int)Math.floor(level));
+ if(heldItem != null) {
+ HashMap<String, Float> petStatBoots = PET_STAT_BOOSTS.get(heldItem);
+ HashMap<String, Float> petStatBootsMult = PET_STAT_BOOSTS_MULT.get(heldItem);
+ if(petStatBoots != null) {
+ for(Map.Entry<String, Float> entryBoost : petStatBoots.entrySet()) {
+ try {
+ float value = Float.parseFloat(replacements.get(entryBoost.getKey()));
+ replacements.put(entryBoost.getKey(), String.valueOf((int)Math.floor(value+entryBoost.getValue())));
+ } catch(Exception ignored) {}
+ }
+
+ }
+ if(petStatBootsMult != null) {
+ for(Map.Entry<String, Float> entryBoost : petStatBootsMult.entrySet()) {
+ try {
+ float value = Float.parseFloat(replacements.get(entryBoost.getKey()));
+ replacements.put(entryBoost.getKey(), String.valueOf((int)Math.floor(value*entryBoost.getValue())));
+ } catch(Exception ignored) {}
+ }
+ }
+ }
+
NBTTagCompound tag = stack.getTagCompound()==null?new NBTTagCompound():stack.getTagCompound();
if(tag.hasKey("display", 10)) {
NBTTagCompound display = tag.getCompoundTag("display");
if(display.hasKey("Lore", 9)) {
+ NBTTagList newNewLore = new NBTTagList();
NBTTagList newLore = new NBTTagList();
NBTTagList lore = display.getTagList("Lore", 8);
+ HashMap<Integer, Integer> blankLocations = new HashMap<>();
for(int j=0; j<lore.tagCount(); j++) {
String line = lore.getStringTagAt(j);
+ if(line.trim().isEmpty()) {
+ blankLocations.put(blankLocations.size(), j);
+ }
for(Map.Entry<String, String> replacement : replacements.entrySet()) {
line = line.replace("{"+replacement.getKey()+"}", replacement.getValue());
}
newLore.appendTag(new NBTTagString(line));
}
- display.setTag("Lore", newLore);
+ Integer secondLastBlank = blankLocations.get(blankLocations.size()-2);
+ if(heldItemJson != null && secondLastBlank != null) {
+ for(int j=0; j<newLore.tagCount(); j++) {
+ String line = newLore.getStringTagAt(j);
+
+ if(j == secondLastBlank.intValue()) {
+ newNewLore.appendTag(new NBTTagString(""));
+ newNewLore.appendTag(new NBTTagString(EnumChatFormatting.GOLD+"Held Item: "+heldItemJson.get("displayname").getAsString()));
+ int blanks = 0;
+ JsonArray heldItemLore = heldItemJson.get("lore").getAsJsonArray();
+ for(int k=0; k<heldItemLore.size(); k++) {
+ String heldItemLine = heldItemLore.get(k).getAsString();
+ if(heldItemLine.trim().isEmpty()) {
+ blanks++;
+ } else if(blanks==2) {
+ newNewLore.appendTag(new NBTTagString(heldItemLine));
+ } else if(blanks>2) {
+ break;
+ }
+ }
+ }
+
+ newNewLore.appendTag(new NBTTagString(line));
+ }
+ display.setTag("Lore", newNewLore);
+ } else {
+ display.setTag("Lore", newLore);
+ }
}
if(display.hasKey("Name", 8)) {
String displayName = display.getString("Name");
@@ -836,14 +932,29 @@ public class GuiProfileViewer extends GuiScreen {
float level = pet.get("level").getAsFloat();
float currentLevelRequirement = pet.get("currentLevelRequirement").getAsFloat();
+ float exp = pet.get("exp").getAsFloat();
+ float maxXP = pet.get("maxXP").getAsFloat();
+
+ String[] split = display.split("] ");
+ String colouredName = split[split.length-1];
+
+ renderAlignedString(colouredName, EnumChatFormatting.WHITE+"Level "+(int)Math.floor(level), guiLeft+319, guiTop+28, 98);
- Utils.drawStringCenteredScaledMaxWidth(display, Minecraft.getMinecraft().fontRendererObj, guiLeft+368, guiTop+28+4, true, 98, 0);
+ //Utils.drawStringCenteredScaledMaxWidth(, Minecraft.getMinecraft().fontRendererObj, guiLeft+368, guiTop+28+4, true, 98, 0);
//renderAlignedString(display, EnumChatFormatting.YELLOW+"[LVL "+Math.floor(level)+"]", guiLeft+319, guiTop+28, 98);
renderBar(guiLeft+319, guiTop+38, 98, (float)Math.floor(level)/100f);
- renderAlignedString("To Next LVL", EnumChatFormatting.WHITE.toString()+(int)(level%1*100)+"%", guiLeft+319, guiTop+46, 98);
-
+ renderAlignedString(EnumChatFormatting.YELLOW+"To Next LVL", EnumChatFormatting.WHITE.toString()+(int)(level%1*100)+"%", guiLeft+319, guiTop+46, 98);
renderBar(guiLeft+319, guiTop+56, 98, level%1);
+
+ renderAlignedString(EnumChatFormatting.YELLOW+"To Max LVL", EnumChatFormatting.WHITE.toString()+Math.min(100, (int)(exp/maxXP*100))+"%", guiLeft+319, guiTop+64, 98);
+ renderBar(guiLeft+319, guiTop+74, 98, exp/maxXP);
+
+ renderAlignedString(EnumChatFormatting.YELLOW+"Total XP", EnumChatFormatting.WHITE.toString()+shortNumberFormat(exp, 0), guiLeft+319, guiTop+125, 98);
+ renderAlignedString(EnumChatFormatting.YELLOW+"Current LVL XP",
+ EnumChatFormatting.WHITE.toString()+shortNumberFormat((level%1)*currentLevelRequirement, 0), guiLeft+319, guiTop+143, 98);
+ renderAlignedString(EnumChatFormatting.YELLOW+"Required LVL XP", EnumChatFormatting.WHITE.toString()+shortNumberFormat(currentLevelRequirement, 0), guiLeft+319, guiTop+161, 98);
+
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/questing/requirements/RequirementApi.java b/src/main/java/io/github/moulberry/notenoughupdates/questing/requirements/RequirementApi.java
index a53ed56b..16da64fe 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/questing/requirements/RequirementApi.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/questing/requirements/RequirementApi.java
@@ -97,12 +97,12 @@ public class RequirementApi extends Requirement {
@Override
public void updateRequirement() {
if(valid) {
- JsonObject profile = NotEnoughUpdates.INSTANCE.manager.auctionManager.getPlayerInformation();
+ /*JsonObject profile = NotEnoughUpdates.INSTANCE.manager.auctionManager.getPlayerInformation();
if(profile != null) {
System.out.println("-----------");
JsonElement element = getElement(profile, requirementLeft);
completed = checkElementSatisfiesComparison(element, op, requirementRight);
- }
+ }*/
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
index 2769e18e..ca6c30af 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
@@ -17,13 +17,9 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
+import java.util.zip.GZIPInputStream;
public class HypixelApi {
-
- /**
- * Not currently used as of BETA-1.6.
- */
-
private Gson gson = new Gson();
private ExecutorService es = Executors.newFixedThreadPool(3);
@@ -32,20 +28,30 @@ public class HypixelApi {
}
public void getHypixelApiAsync(String apiKey, String method, HashMap<String, String> args, Consumer<JsonObject> consumer, Runnable error) {
- getHypixelApiAsync(generateApiUrl(apiKey.trim(), method, args), consumer, error);
+ getApiAsync(generateApiUrl(apiKey.trim(), method, args), consumer, error);
+ }
+
+ public void getApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) {
+ es.submit(() -> {
+ try {
+ consumer.accept(getApiSync(urlS));
+ } catch(IOException e) {
+ error.run();
+ }
+ });
}
- public void getHypixelApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) {
+ public void getApiGZIPAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) {
es.submit(() -> {
try {
- consumer.accept(getHypixelApiSync(urlS));
+ consumer.accept(getApiGZIPSync(urlS));
} catch(IOException e) {
error.run();
}
});
}
- public JsonObject getHypixelApiSync(String urlS) throws IOException {
+ public JsonObject getApiSync(String urlS) throws IOException {
URL url = new URL(urlS);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(3000);
@@ -56,6 +62,17 @@ public class HypixelApi {
return json;
}
+ public JsonObject getApiGZIPSync(String urlS) throws IOException {
+ URL url = new URL(urlS);
+ URLConnection connection = url.openConnection();
+ connection.setConnectTimeout(3000);
+
+ String response = IOUtils.toString(new GZIPInputStream(connection.getInputStream()), StandardCharsets.UTF_8);
+
+ JsonObject json = gson.fromJson(response, JsonObject.class);
+ return json;
+ }
+
public String generateApiUrl(String apiKey, String method, HashMap<String, String> args) {
StringBuilder url = new StringBuilder("https://api.hypixel.net/" + method + "?key=" + apiKey);
for(Map.Entry<String, String> entry : args.entrySet()) {