Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ItemCooldowns.java #636

Merged
merged 6 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/de/hysky/skyblocker/SkyblockerMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import de.hysky.skyblocker.skyblock.waypoint.Relics;
import de.hysky.skyblocker.utils.ApiUtils;
import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.ProfileUtils;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.chat.ChatMessageListener;
import de.hysky.skyblocker.utils.discord.DiscordRPCManager;
Expand Down Expand Up @@ -166,6 +167,7 @@ public void onInitializeClient() {
MuseumItemCache.init();
SecretsTracker.init();
ApiUtils.init();
ProfileUtils.init();
Debug.init();
Kuudra.init();
RenderHelper.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.SkyblockEvents;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import de.hysky.skyblocker.utils.ApiUtils;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Http;
import de.hysky.skyblocker.utils.ProfileUtils;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
Expand All @@ -26,12 +23,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.StreamSupport;

public class DungeonScore {
private static final SkyblockerConfig.DungeonScore SCORE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore;
Expand Down Expand Up @@ -68,11 +61,9 @@ public class DungeonScore {
private static int puzzleCount;
private static int deathCount;
private static int score;
private static final Map<String, Boolean> SpiritPetCache = new HashMap<>();

public static void init() {
public static void init() {
Scheduler.INSTANCE.scheduleCyclic(DungeonScore::tick, 20);
SkyblockEvents.LEAVE.register(SpiritPetCache::clear);
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset());
ClientReceiveMessageEvents.GAME.register((message, overlay) -> {
if (overlay || !Utils.isInDungeons()) return;
Expand Down Expand Up @@ -288,36 +279,18 @@ private static int getCrypts() {
return matcher != null ? Integer.parseInt(matcher.group("crypts")) : 0;
}

public static boolean hasSpiritPet(String name) {
return SpiritPetCache.computeIfAbsent(name, k -> {
String playeruuid = ApiUtils.name2Uuid(name);
try (Http.ApiResponse response = Http.sendHypixelRequest("skyblock/profiles", "?uuid=" + playeruuid)) {
if (!response.ok()) throw new IllegalStateException("Failed to get profile uuid for player " + name + "! Response: " + response.content());
JsonObject responseJson = JsonParser.parseString(response.content()).getAsJsonObject();

JsonObject player = StreamSupport.stream(responseJson.getAsJsonArray("profiles").spliterator(), false)
.map(JsonElement::getAsJsonObject)
.filter(profile -> profile.getAsJsonPrimitive("selected").getAsBoolean())
.findFirst()
.orElseThrow(() -> new IllegalStateException("No selected profile found!?"))
.getAsJsonObject("members").entrySet().stream()
.filter(entry -> entry.getKey().equals(playeruuid))
.map(Map.Entry::getValue)
.map(JsonElement::getAsJsonObject)
.findFirst()
.orElseThrow(() -> new IllegalStateException("Player somehow not found inside their own profile!"));

for (JsonElement element : player.getAsJsonObject("pets_data").getAsJsonArray("pets")) {
if (!element.getAsJsonObject().get("type").getAsString().equals("SPIRIT")) continue;
if (!element.getAsJsonObject().get("tier").getAsString().equals("LEGENDARY")) continue;

return true;
}
} catch (Exception e) {
LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {}", name, e);
public static boolean hasSpiritPet(JsonObject player, String name) {
try {
for (JsonElement pet : player.getAsJsonObject("pets_data").getAsJsonArray("pets")) {
if (!pet.getAsJsonObject().get("type").getAsString().equals("SPIRIT")) continue;
if (!pet.getAsJsonObject().get("tier").getAsString().equals("LEGENDARY")) continue;

return true;
}
return false;
});
} catch (Exception e) {
LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {}", name, e);
}
return false;
}

private static void checkMessageForDeaths(String message) {
Expand All @@ -327,11 +300,10 @@ private static void checkMessageForDeaths(String message) {
deathCount++;
if (deathCount > 1) return;
final String whoDied = matcher.group("whodied").transform(s -> {
if (s.equals("You")) return MinecraftClient.getInstance().player.getName().getString(); //This will be wrong if the dead player is called 'You' but that's unlikely
if (s.equals("You")) return MinecraftClient.getInstance().getSession().getUsername(); //This will be wrong if the dead player is called 'You' but that's unlikely
else return s;
});
CompletableFuture.supplyAsync(() -> hasSpiritPet(whoDied))
.thenAccept(hasSpiritPet -> firstDeathHasSpiritPet = hasSpiritPet);
ProfileUtils.updateProfile(whoDied).thenAccept(player -> firstDeathHasSpiritPet = hasSpiritPet(player, whoDied));
}

private static void checkMessageForWatcher(String message) {
Expand Down
67 changes: 53 additions & 14 deletions src/main/java/de/hysky/skyblocker/skyblock/item/ItemCooldowns.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package de.hysky.skyblocker.skyblock.item;

import com.google.common.collect.ImmutableList;
import com.google.gson.JsonElement;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.ProfileUtils;
import net.fabricmc.fabric.api.event.client.player.ClientPlayerBlockBreakEvents;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.minecraft.block.BlockState;
Expand All @@ -15,43 +16,81 @@
import net.minecraft.world.World;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ItemCooldowns {
private static final String JUNGLE_AXE_ID = "JUNGLE_AXE";
private static final String TREECAPITATOR_ID = "TREECAPITATOR_AXE";
private static final String GRAPPLING_HOOK_ID = "GRAPPLING_HOOK";
private static final ImmutableList<String> BAT_ARMOR_IDS = ImmutableList.of("BAT_PERSON_HELMET", "BAT_PERSON_CHESTPLATE", "BAT_PERSON_LEGGINGS", "BAT_PERSON_BOOTS");

private static final List<String> BAT_ARMOR_IDS = List.of("BAT_PERSON_HELMET", "BAT_PERSON_CHESTPLATE", "BAT_PERSON_LEGGINGS", "BAT_PERSON_BOOTS");
private static final Map<String, CooldownEntry> ITEM_COOLDOWNS = new HashMap<>();
private static final int[] EXPERIENCE_LEVELS = {
0, 660, 730, 800, 880, 960, 1050, 1150, 1260, 1380, 1510, 1650, 1800, 1960, 2130,
2310, 2500, 2700, 2920, 3160, 3420, 3700, 4000, 4350, 4750, 5200, 5700, 6300, 7000,
7800, 8700, 9700, 10800, 12000, 13300, 14700, 16200, 17800, 19500, 21300, 23200,
25200, 27400, 29800, 32400, 35200, 38200, 41400, 44800, 48400, 52200, 56200, 60400,
64800, 69400, 74200, 79200, 84700, 90700, 97200, 104200, 111700, 119700, 128200,
137200, 147700, 156700, 167700, 179700, 192700, 206700, 221700, 237700, 254700,
272700, 291700, 311700, 333700, 357700, 383700, 411700, 441700, 476700, 516700,
561700, 611700, 666700, 726700, 791700, 861700, 936700, 1016700, 1101700, 1191700,
1286700, 1386700, 1496700, 1616700, 1746700, 1886700
};
public static int monkeyLevel = 1;
public static double monkeyExp = 0;

public static void init() {
ClientPlayerBlockBreakEvents.AFTER.register(ItemCooldowns::afterBlockBreak);
UseItemCallback.EVENT.register(ItemCooldowns::onItemInteract);
}

public static void updateCooldown() {
ProfileUtils.updateProfile().thenAccept(player -> {
for (JsonElement pet : player.getAsJsonObject("pets_data").getAsJsonArray("pets")) {
if (!pet.getAsJsonObject().get("type").getAsString().equals("MONKEY")) continue;
if (!pet.getAsJsonObject().get("active").getAsString().equals("true")) continue;
if (pet.getAsJsonObject().get("tier").getAsString().equals("LEGENDARY")) {
monkeyExp = Double.parseDouble(pet.getAsJsonObject().get("exp").getAsString());
monkeyLevel = 0;
for (int xpLevel : EXPERIENCE_LEVELS) {
if (monkeyExp < xpLevel) {
break;
} else {
monkeyExp -= xpLevel;
monkeyLevel++;
}
}
}
}
}).exceptionally(e -> {
ProfileUtils.LOGGER.error("[Skyblocker Item Cooldown] Failed to get Player Pet Data, is the API Down/Limited?", e);
return null;
});
}

private static int getCooldown() {
int baseCooldown = 2000;
int monkeyPetCooldownReduction = baseCooldown * monkeyLevel / 200;
return baseCooldown - monkeyPetCooldownReduction;
}

public static void afterBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state) {
if (!SkyblockerConfigManager.get().general.itemCooldown.enableItemCooldowns) return;

String usedItemId = ItemUtils.getItemId(player.getMainHandStack());
if (usedItemId.isEmpty()) return;

if (state.isIn(BlockTags.LOGS)) {
if (usedItemId.equals(JUNGLE_AXE_ID)) {
if (!isOnCooldown(JUNGLE_AXE_ID)) {
ITEM_COOLDOWNS.put(JUNGLE_AXE_ID, new CooldownEntry(2000));
}
} else if (usedItemId.equals(TREECAPITATOR_ID)) {
if (!isOnCooldown(TREECAPITATOR_ID)) {
ITEM_COOLDOWNS.put(TREECAPITATOR_ID, new CooldownEntry(2000));
if (usedItemId.equals(JUNGLE_AXE_ID) || usedItemId.equals(TREECAPITATOR_ID)) {
updateCooldown();
if (!isOnCooldown(JUNGLE_AXE_ID) || !isOnCooldown(TREECAPITATOR_ID)) {
ITEM_COOLDOWNS.put(usedItemId, new CooldownEntry(getCooldown()));
}
}
}
}

private static TypedActionResult<ItemStack> onItemInteract(PlayerEntity player, World world, Hand hand) {
if (!SkyblockerConfigManager.get().general.itemCooldown.enableItemCooldowns) return TypedActionResult.pass(ItemStack.EMPTY);

if (!SkyblockerConfigManager.get().general.itemCooldown.enableItemCooldowns)
return TypedActionResult.pass(ItemStack.EMPTY);
String usedItemId = ItemUtils.getItemId(player.getMainHandStack());
if (usedItemId.equals(GRAPPLING_HOOK_ID) && player.fishHook != null) {
if (!isOnCooldown(GRAPPLING_HOOK_ID) && !isWearingBatArmor(player)) {
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/de/hysky/skyblocker/utils/ProfileUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package de.hysky.skyblocker.utils;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import de.hysky.skyblocker.SkyblockerMod;
import it.unimi.dsi.fastutil.objects.ObjectLongPair;
import net.minecraft.client.MinecraftClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

public class ProfileUtils {
public static final Logger LOGGER = LoggerFactory.getLogger(ProfileUtils.class);
private static final long HYPIXEL_API_COOLDOWN = 300000; // 5min = 300000

public static Map<String, ObjectLongPair<JsonObject>> players = new HashMap<>();

public static void init() {
updateProfile();
}

public static CompletableFuture<JsonObject> updateProfile() {
return updateProfile(MinecraftClient.getInstance().getSession().getUsername());
}

public static CompletableFuture<JsonObject> updateProfile(String name) {
ObjectLongPair<JsonObject> playerCache = players.get(name);
if (playerCache != null && playerCache.rightLong() + HYPIXEL_API_COOLDOWN > System.currentTimeMillis()) {
return CompletableFuture.completedFuture(playerCache.left());
}

return CompletableFuture.supplyAsync(() -> {
String uuid = ApiUtils.name2Uuid(name);
try (Http.ApiResponse response = Http.sendHypixelRequest("skyblock/profiles", "?uuid=" + uuid)) {
if (!response.ok()) {
throw new IllegalStateException("Failed to get profile uuid for players " + name + "! Response: " + response.content());
}
JsonObject responseJson = SkyblockerMod.GSON.fromJson(response.content(), JsonObject.class);

JsonObject player = responseJson.getAsJsonArray("profiles").asList().stream()
.map(JsonElement::getAsJsonObject)
.filter(profile -> profile.getAsJsonPrimitive("selected").getAsBoolean())
.findFirst()
.orElseThrow(() -> new IllegalStateException("No selected profile found!?"))
.getAsJsonObject("members").get(uuid).getAsJsonObject();

players.put(name, ObjectLongPair.of(player, System.currentTimeMillis()));
return player;
} catch (Exception e) {
LOGGER.error("[Skyblocker Profile Utils] Failed to get Player Profile Data for players {}, is the API Down/Limited?", name, e);
}
return null;
});
}
}