diff options
7 files changed, 322 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index c11e4c86..6bdf619e 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -23,6 +23,7 @@ import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip; import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.skyblock.quicknav.QuickNav; import de.hysky.skyblocker.skyblock.rift.TheRift; +import de.hysky.skyblocker.skyblock.searchOverlay.SearchOverManager; import de.hysky.skyblocker.skyblock.shortcut.Shortcuts; import de.hysky.skyblocker.skyblock.special.SpecialEffects; import de.hysky.skyblocker.skyblock.tabhud.TabHud; @@ -119,6 +120,7 @@ public class SkyblockerMod implements ClientModInitializer { FireFreezeStaffTimer.init(); GuardianHealth.init(); TheRift.init(); + SearchOverManager.init(); TitleContainer.init(); ScreenMaster.init(); DungeonTextures.init(); diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 4acb8064..714229dc 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -238,6 +238,9 @@ public class SkyblockerConfig { public FlameOverlay flameOverlay = new FlameOverlay(); @SerialEntry + public SearchOverlay searchOverlay = new SearchOverlay(); + + @SerialEntry public List<Integer> lockedSlots = new ArrayList<>(); @SerialEntry @@ -411,6 +414,16 @@ public class SkyblockerConfig { @SerialEntry public Alignment alignment = Alignment.MIDDLE; } + public static class SearchOverlay { + @SerialEntry + public boolean enableBazaar = true; + + @SerialEntry + public boolean enableAuctionHouse = true; + + @SerialEntry + public int maxSuggestions = 3; + } public static class TeleportOverlay { @SerialEntry diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 808b3c2c..a9b965cf 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -642,6 +642,32 @@ public class GeneralCategory { .controller(opt -> FloatSliderControllerBuilder.create(opt).range(0.0f, 0.8f).step(0.1f)) .build()) .build()) + //Search overlay + .group(OptionGroup.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.searchOverlay")) //todo description + .collapsed(true) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.searchOverlay.enableBazaar")) + .binding(defaults.general.searchOverlay.enableBazaar, + () -> config.general.searchOverlay.enableBazaar, + newValue -> config.general.searchOverlay.enableBazaar = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.searchOverlay.enableAuctionHouse")) + .binding(defaults.general.searchOverlay.enableAuctionHouse, + () -> config.general.searchOverlay.enableAuctionHouse, + newValue -> config.general.searchOverlay.enableAuctionHouse = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Integer>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.searchOverlay.maxSuggestions")) + .binding(defaults.general.searchOverlay.maxSuggestions, + () -> config.general.searchOverlay.maxSuggestions, + newValue -> config.general.searchOverlay.maxSuggestions = newValue) + .controller(opt -> IntegerSliderControllerBuilder.create(opt).range(0, 5 ).step(1)) + .build()) + .build()) .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java index 1d54b02c..1e2fd111 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java @@ -7,12 +7,16 @@ import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; import de.hysky.skyblocker.skyblock.item.HotbarSlotLock; import de.hysky.skyblocker.skyblock.item.ItemProtection; import de.hysky.skyblocker.skyblock.rift.HealingMelonIndicator; +import de.hysky.skyblocker.skyblock.searchOverlay.OverlayScreen; +import de.hysky.skyblocker.skyblock.searchOverlay.SearchOverManager; import de.hysky.skyblocker.utils.Utils; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; +import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -57,4 +61,23 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity } } } + @Inject(method = "openEditSignScreen", at = @At("HEAD"), cancellable = true) + public void skyblocker$searchOverlay(SignBlockEntity sign, boolean front, CallbackInfo callbackInfo) { + + assert client.currentScreen != null; + if (SkyblockerConfigManager.get().general.searchOverlay.enableAuctionHouse && (FabricLoader.getInstance().isDevelopmentEnvironment() || client.currentScreen.getTitle().getString().toLowerCase().contains("auction")) ) { + if (sign.getText(front).getMessage(3, false).getString().equalsIgnoreCase("enter query")) { + SearchOverManager.updateSign(sign, front,true); + client.setScreen(new OverlayScreen(Text.of(""))); + callbackInfo.cancel(); + } + } + else if (SkyblockerConfigManager.get().general.searchOverlay.enableBazaar && (FabricLoader.getInstance().isDevelopmentEnvironment() || client.currentScreen.getTitle().getString().toLowerCase().contains("bazaar")) ) { + if (sign.getText(front).getMessage(3, false).getString().equalsIgnoreCase("enter query")) { + SearchOverManager.updateSign(sign, front,true); + client.setScreen(new OverlayScreen(Text.of(""))); + callbackInfo.cancel(); + } + } + } }
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/OverlayScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/OverlayScreen.java new file mode 100644 index 00000000..a4bee7ae --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/OverlayScreen.java @@ -0,0 +1,107 @@ +package de.hysky.skyblocker.skyblock.searchOverlay; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; + +import java.util.Objects; + +public class OverlayScreen extends Screen { + + protected static final Identifier SEARCH_ICON_TEXTURE = new Identifier("icon/search"); + + private TextFieldWidget searchField; + private ButtonWidget finishedButton; + private ButtonWidget[] suggestionButtons; + //todo history buttons + + public OverlayScreen(Text title) { + super(title); + } + @Override + protected void init() { + super.init(); + int rowHeight = 20; + int rowWidth = (int)(this.width * 0.33); + + int startX = (int)(this.width * 0.5) - rowWidth/2; + int startY = (int)(this.height * 0.5)- (rowHeight * (1+ SkyblockerConfigManager.get().general.searchOverlay.maxSuggestions)) /2; + + // Search field + this.searchField = new TextFieldWidget(textRenderer, startX, startY, rowWidth - 30, rowHeight, Text.literal("Search...")); + searchField.setChangedListener(SearchOverManager::updateSearch); + searchField.setFocused(true); + searchField.active = true; + + // finish buttons + finishedButton = ButtonWidget.builder(Text.literal("SEARCH").setStyle(Style.EMPTY.withColor(Formatting.GREEN)), (a) -> { //todo search icon + close(); + }) + .position(startX + rowWidth - 30, startY) + .size(30, rowHeight).build(); + // suggested item buttons + int totalSuggestions = SkyblockerConfigManager.get().general.searchOverlay.maxSuggestions; + this.suggestionButtons = new ButtonWidget[totalSuggestions]; + for (int i = 0; i < totalSuggestions; i++) { + suggestionButtons[i] = ButtonWidget.builder(Text.literal(SearchOverManager.getSuggestion(i)).setStyle(Style.EMPTY), (a) -> { + SearchOverManager.updateSearch(a.getMessage().getString()); + close(); + }) + .position(startX , startY + rowHeight * (i+1)) + .size(rowWidth, rowHeight).build(); + suggestionButtons[i].visible = false; + } + + addDrawableChild(searchField); + for (ButtonWidget suggestion : suggestionButtons){ + addDrawableChild(suggestion); + } + addDrawableChild(finishedButton); + + + + } + + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + super.renderBackground(context, mouseX, mouseY, delta); + //todo draw custom background + + } + + @Override + public void close() { + assert this.client != null; + assert this.client.player != null; + SearchOverManager.pushSearch(); + super.close(); + } + @Override + public final void tick() { + super.tick(); + //update suggestion buttons text + for (int i = 0; i < SkyblockerConfigManager.get().general.searchOverlay.maxSuggestions; i++) { + String text = SearchOverManager.getSuggestion(i); + if (!Objects.equals(text, "")){ + suggestionButtons[i].visible = true; + suggestionButtons[i].setMessage(Text.literal(text).setStyle(Style.EMPTY)); + }else{ + suggestionButtons[i].visible = false; + } + + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/SearchOverManager.java b/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/SearchOverManager.java new file mode 100644 index 00000000..5846dbf3 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/searchOverlay/SearchOverManager.java @@ -0,0 +1,147 @@ +package de.hysky.skyblocker.skyblock.searchOverlay; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Http; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class SearchOverManager { + + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + public static boolean visible = false; + public static String search = ""; + private static @Nullable SignBlockEntity Sign = null; + private static boolean SignFront = true; + + private static boolean IsAuction; + + + public static Map<String,String> itemNameLookup = new HashMap<>(); + public static List<String> bazaarItems =new ArrayList<>(); + public static List<String> auctionItems =new ArrayList<>(); + + public static String[] suggestionsArray = {}; + public static void init() { + //get bazaar items + System.out.println("is there somethin"); + try { + String response = Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/items"); + System.out.println("response:"); + JsonArray items = JsonParser.parseString(response).getAsJsonObject().getAsJsonArray("items"); + System.out.println("jsonItem:"); + for (JsonElement entry : items) { + if (entry.isJsonObject()) { + JsonObject item = entry.getAsJsonObject(); + String itemId = item.get("id").getAsString(); + String itemName = item.get("name").getAsString(); + itemNameLookup.put(itemId,itemName); + } + + } + } catch (Exception e) { + //can not get items skyblock items + } + try (Http.ApiResponse response = Http.sendHypixelRequest("skyblock/bazaar", "")) { + JsonObject products = JsonParser.parseString(response.content()).getAsJsonObject().get("products").getAsJsonObject(); + for (Map.Entry<String, JsonElement> entry : products.entrySet()) { + if (entry.getValue().isJsonObject()) { + JsonObject product = entry.getValue().getAsJsonObject(); + String name = itemNameLookup.get(product.get("product_id").getAsString()); //todo work with enchants + if (name != null){ + bazaarItems.add(name); + } + + } + + } + + + } catch (Exception e) { + //can not get items for bazaar search + } + //get auction items + //items not in bazaar? todo work out how to get this (e.g. there are no pets) (there is a can auction flag) + for (String itemName : itemNameLookup.values()){ + if (!bazaarItems.contains(itemName)){ + auctionItems.add(itemName); + } + } + + } + + public static void updateSign(SignBlockEntity sign, boolean front, boolean isAuction) { + visible= true; + SignFront = front; + Sign = sign; + IsAuction = isAuction; + search = ""; //todo load form sign data if needed + suggestionsArray = new String[]{}; + + } + protected static void updateSearch(String newValue) { + search = newValue; + //update the suggestion values + int totalSuggestions = SkyblockerConfigManager.get().general.searchOverlay.maxSuggestions; + suggestionsArray = new String[totalSuggestions]; + if (newValue.isBlank() || totalSuggestions == 0) return; //do not search for empty value + if (IsAuction){ + suggestionsArray = auctionItems.stream().filter(item -> item.toLowerCase().contains(search.toLowerCase())).limit(totalSuggestions).toList().toArray(suggestionsArray); + }else { + suggestionsArray = bazaarItems.stream().filter(item -> item.toLowerCase().contains(search.toLowerCase())).limit(totalSuggestions).toList().toArray(suggestionsArray); + } + } + protected static String getSuggestion(int index){ + if (suggestionsArray.length> index && suggestionsArray[index] != null ){ + return suggestionsArray[index]; + }else{//there are no suggestions yet + return ""; + } + } + + protected static void pushSearch() { + //splits text into 2 lines max = 30 chars + StringBuilder line0 = new StringBuilder(); + String line1; + if (search.length() <= 15){ + line0 = new StringBuilder(search); + line1 = ""; + }else { + String[] words = search.split(" "); + for (String word : words){ + if (line0.isEmpty()) { + line0 = new StringBuilder(word); + continue; + } + if (line0.length() + word.length() < 14 ){ //max 15 but including space is 14 + line0.append(" ").append(word); + } + else { + break; + } + } + line1 = search.substring(line0.length(),Math.min(search.length(),30)); + } + + // send packet to update sign + if (CLIENT.player != null || Sign != null) { + Text[] messages = Sign.getText(SignFront).getMessages(CLIENT.shouldFilterText()); + CLIENT.player.networkHandler.sendPacket(new UpdateSignC2SPacket(Sign.getPos(), SignFront, + line0.toString(), + line1, + messages[2].getString(), + messages[3].getString() + )); + } + } + +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index f17f109e..bdbc51dd 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -130,6 +130,10 @@ "text.autoconfig.skyblocker.option.general.flameOverlay": "Flame Overlay", "text.autoconfig.skyblocker.option.general.flameOverlay.flameHeight": "Flame Height", "text.autoconfig.skyblocker.option.general.flameOverlay.flameOpacity": "Flame Opacity", + "text.autoconfig.skyblocker.option.general.searchOverlay": "Search Overlay", + "text.autoconfig.skyblocker.option.general.searchOverlay.enableBazaar": "Enable For Bazaar", + "text.autoconfig.skyblocker.option.general.searchOverlay.enableAuctionHouse": "Enable For Auction House", + "text.autoconfig.skyblocker.option.general.searchOverlay.maxSuggestions": "Maximum Suggestions", "text.autoconfig.skyblocker.option.general.betterPartyFinder": "Better Party Finder", "skyblocker.itemTooltip.nullMessage": "§cItem price information on tooltip will renew in max 60 seconds. If not, check latest.log", "skyblocker.itemTooltip.noData": "§cNo Data", |