Skip to content

Commit

Permalink
Add debug config and a keybind to dump nearby entities (#961)
Browse files Browse the repository at this point in the history
* Add debug config

* Fix indents

---------

Co-authored-by: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
  • Loading branch information
Emirlol and kevinthegreat1 authored Oct 21, 2024
1 parent b0f9efd commit 135125f
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ public class SkyblockerConfig {

@SerialEntry
public MiscConfig misc = new MiscConfig();

@SerialEntry
public DebugConfig debug = new DebugConfig();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.categories.*;
import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
import dev.isxander.yacl3.api.YetAnotherConfigLib;
Expand Down Expand Up @@ -69,22 +70,27 @@ public static void save() {
}

public static Screen createGUI(Screen parent) {
return YetAnotherConfigLib.create(HANDLER, (defaults, config, builder) -> builder
.title(Text.translatable("skyblocker.config.title"))
.category(GeneralCategory.create(defaults, config))
.category(UIAndVisualsCategory.create(defaults, config))
.category(HelperCategory.create(defaults, config))
.category(DungeonsCategory.create(defaults, config))
//.category(ForagingCategory.create(defaults, config))
.category(CrimsonIsleCategory.create(defaults, config))
.category(MiningCategory.create(defaults, config))
.category(FarmingCategory.create(defaults, config))
.category(OtherLocationsCategory.create(defaults, config))
.category(SlayersCategory.create(defaults, config))
.category(ChatCategory.create(defaults, config))
.category(QuickNavigationCategory.create(defaults, config))
.category(EventNotificationsCategory.create(defaults, config))
.category(MiscCategory.create(defaults, config))).generateScreen(parent);
return YetAnotherConfigLib.create(HANDLER, (defaults, config, builder) -> {
builder.title(Text.translatable("skyblocker.config.title"))
.category(GeneralCategory.create(defaults, config))
.category(UIAndVisualsCategory.create(defaults, config))
.category(HelperCategory.create(defaults, config))
.category(DungeonsCategory.create(defaults, config))
//.category(ForagingCategory.create(defaults, config))
.category(CrimsonIsleCategory.create(defaults, config))
.category(MiningCategory.create(defaults, config))
.category(FarmingCategory.create(defaults, config))
.category(OtherLocationsCategory.create(defaults, config))
.category(SlayersCategory.create(defaults, config))
.category(ChatCategory.create(defaults, config))
.category(QuickNavigationCategory.create(defaults, config))
.category(EventNotificationsCategory.create(defaults, config))
.category(MiscCategory.create(defaults, config));
if (Debug.debugEnabled()) {
builder.category(DebugCategory.create(defaults, config));
}
return builder;
}).generateScreen(parent);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package de.hysky.skyblocker.config.categories;

import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
import dev.isxander.yacl3.api.ConfigCategory;
import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.OptionDescription;
import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder;
import net.minecraft.text.Text;

public class DebugCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("skyblocker.config.debug"))
.option(Option.<Integer>createBuilder()
.name(Text.translatable("skyblocker.config.debug.dumpRange"))
.description(OptionDescription.of(Text.translatable("skyblocker.config.debug.dumpRange.@Tooltip")))
.binding(defaults.debug.dumpRange,
() -> config.debug.dumpRange,
newValue -> config.debug.dumpRange = newValue)
.controller(option -> IntegerSliderControllerBuilder.create(option).range(1, 25).step(1))
.build())
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("skyblocker.config.debug.showInvisibleArmorStands"))
.binding(defaults.debug.showInvisibleArmorStands,
() -> config.debug.showInvisibleArmorStands,
newValue -> config.debug.showInvisibleArmorStands = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("skyblocker.config.debug.debugWebSockets"))
.binding(defaults.debug.webSocketDebug,
() -> config.debug.webSocketDebug,
newValue -> config.debug.webSocketDebug = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.build();
}
}
14 changes: 14 additions & 0 deletions src/main/java/de/hysky/skyblocker/config/configs/DebugConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package de.hysky.skyblocker.config.configs;

import dev.isxander.yacl3.config.v2.api.SerialEntry;

public class DebugConfig {
@SerialEntry
public int dumpRange = 5;

@SerialEntry
public boolean showInvisibleArmorStands = false;

@SerialEntry
public boolean webSocketDebug = false;
}
92 changes: 55 additions & 37 deletions src/main/java/de/hysky/skyblocker/debug/Debug.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.mojang.serialization.JsonOps;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.ItemUtils;
Expand All @@ -13,13 +14,18 @@
import net.azureaaron.networth.Calculation;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.screen.slot.Slot;
import net.minecraft.text.Text;
Expand All @@ -31,49 +37,59 @@

public class Debug {
private static final boolean DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("skyblocker.debug", "false"));

private static boolean showInvisibleArmorStands = false;
private static boolean webSocketDebug = false;
//This is necessary to not spam the chat with 20 messages per second
private static boolean keyDown = false;

public static boolean debugEnabled() {
return DEBUG_ENABLED || FabricLoader.getInstance().isDevelopmentEnvironment();
}

public static boolean shouldShowInvisibleArmorStands() {
return showInvisibleArmorStands;
}

public static boolean webSocketDebug() {
return webSocketDebug;
return SkyblockerConfigManager.get().debug.webSocketDebug;
}

@Init
public static void init() {
if (debugEnabled()) {
SnapshotDebug.init();
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("debug")
.then(dumpPlayersCommand())
.then(ItemUtils.dumpHeldItemCommand())
.then(ItemUtils.dumpHeldItemNetworthCalculationsCommand())
.then(toggleShowingInvisibleArmorStands())
.then(dumpArmorStandHeadTextures())
.then(toggleWebSocketDebug())
)));
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (screen instanceof HandledScreen<?> handledScreen) {
ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
if (!Screen.hasShiftDown()) {
client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow())));
} else {
client.player.sendMessage(Text.literal("[Skyblocker Debug] Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(focusedSlot.getStack()).calculations()).getOrThrow())));
}
}
});
if (!debugEnabled()) return;
SnapshotDebug.init();
KeyBinding dumpNearbyEntitiesKey = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.skyblocker.debug.dumpNearbyEntities", GLFW.GLFW_KEY_I, "key.categories.skyblocker"));
KeyBinding dumpHoveredItemKey = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.skyblocker.debug.dumpHoveredItem", GLFW.GLFW_KEY_U, "key.categories.skyblocker"));
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(
literal(SkyblockerMod.NAMESPACE).then(literal("debug")
.then(dumpPlayersCommand())
.then(ItemUtils.dumpHeldItemCommand())
.then(ItemUtils.dumpHeldItemNetworthCalculationsCommand())
.then(toggleShowingInvisibleArmorStands())
.then(dumpArmorStandHeadTextures())
.then(toggleWebSocketDebug())
)
));
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (client.player == null || client.world == null) return;
if (dumpNearbyEntitiesKey.wasPressed() && !keyDown) {
client.world.getOtherEntities(client.player, client.player.getBoundingBox().expand(SkyblockerConfigManager.get().debug.dumpRange))
.stream()
.map(entity -> entity.writeNbt(new NbtCompound()))
.map(NbtHelper::toPrettyPrintedText)
.forEach(client.player::sendMessage);
keyDown = true;
} else if (!dumpNearbyEntitiesKey.wasPressed() && keyDown) {
keyDown = false;
}
});
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (!(screen instanceof HandledScreen<?> handledScreen)) return;
ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
if (dumpHoveredItemKey.matchesKey(key, scancode) && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
if (!Screen.hasShiftDown()) {
client.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow()))));
} else {
client.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(focusedSlot.getStack()).calculations()).getOrThrow()))));
}
}
});
}
});
}

private static LiteralArgumentBuilder<FabricClientCommandSource> dumpPlayersCommand() {
Expand All @@ -87,21 +103,23 @@ private static LiteralArgumentBuilder<FabricClientCommandSource> dumpPlayersComm
private static LiteralArgumentBuilder<FabricClientCommandSource> toggleShowingInvisibleArmorStands() {
return literal("toggleShowingInvisibleArmorStands")
.executes(context -> {
showInvisibleArmorStands = !showInvisibleArmorStands;
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.debug.toggledShowingInvisibleArmorStands", showInvisibleArmorStands)));
SkyblockerConfigManager.get().debug.showInvisibleArmorStands = !SkyblockerConfigManager.get().debug.showInvisibleArmorStands;
SkyblockerConfigManager.save();
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.debug.toggledShowingInvisibleArmorStands", SkyblockerConfigManager.get().debug.showInvisibleArmorStands)));
return Command.SINGLE_SUCCESS;
});
}

private static LiteralArgumentBuilder<FabricClientCommandSource> toggleWebSocketDebug() {
return literal("toggleWebSocketDebug")
.executes(context -> {
webSocketDebug = !webSocketDebug;
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.debug.toggledWebSocketDebug", webSocketDebug)));
SkyblockerConfigManager.get().debug.webSocketDebug = !SkyblockerConfigManager.get().debug.webSocketDebug;
SkyblockerConfigManager.save();
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.debug.toggledWebSocketDebug", SkyblockerConfigManager.get().debug.webSocketDebug)));
return Command.SINGLE_SUCCESS;
});
}

private static LiteralArgumentBuilder<FabricClientCommandSource> dumpArmorStandHeadTextures() {
return literal("dumpArmorStandHeadTextures")
.executes(context -> {
Expand All @@ -118,4 +136,4 @@ private static LiteralArgumentBuilder<FabricClientCommandSource> dumpArmorStandH
return Command.SINGLE_SUCCESS;
});
}
}
}
29 changes: 29 additions & 0 deletions src/main/java/de/hysky/skyblocker/mixins/EntityMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package de.hysky.skyblocker.mixins;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.utils.Utils;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(Entity.class)
public abstract class EntityMixin {
@Shadow
@Final
private EntityType<?> type;

@Shadow
public abstract boolean isInvisible();

@Inject(method = "isInvisibleTo", at = @At("HEAD"), cancellable = true)
public void skyblocker$showInvisibleArmorStands(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
if (isInvisible() && Utils.isOnHypixel() && Debug.debugEnabled() && SkyblockerConfigManager.get().debug.showInvisibleArmorStands && type.equals(EntityType.ARMOR_STAND)) cir.setReturnValue(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.utils.ItemUtils;
Expand All @@ -12,7 +11,6 @@
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.decoration.ArmorStandEntity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -29,6 +27,6 @@ public class EntityRenderDispatcherMixin {

@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isInvisible()Z", ordinal = 1))
private <E extends Entity> boolean skyblocker$armorStandHitboxVisible(boolean invisible, E entity) {
return (!(entity instanceof ArmorStandEntity) || !Utils.isOnHypixel() || !Debug.debugEnabled() || !Debug.shouldShowInvisibleArmorStands()) && invisible;
return (!(entity instanceof ArmorStandEntity) || !Utils.isOnHypixel() || !Debug.debugEnabled() || !SkyblockerConfigManager.get().debug.showInvisibleArmorStands) && invisible;
}
}

This file was deleted.

9 changes: 9 additions & 0 deletions src/main/resources/assets/skyblocker/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"key.skyblocker.toggleB": "Toggle tab HUD to screen B",
"key.skyblocker.defaultTgl": "Switch tab HUD to default view",
"key.skyblocker.toggleA": "Toggle tab HUD to screen A",
"key.skyblocker.debug.dumpNearbyEntities": "Dump Nearby Entities",
"key.skyblocker.debug.dumpHoveredItem": "Dump Hovered Item",
"key.wikiLookup": "Wiki Lookup",
"key.itemProtection": "Protect Item",
"key.skyblocker.slottext": "Slot Text",
Expand Down Expand Up @@ -56,6 +58,13 @@
"skyblocker.config.crimsonIsle.kuudra.suppliesAndFuelWaypointType": "Supplies/Fuel Waypoint Type",
"skyblocker.config.crimsonIsle.kuudra.supplyWaypoints": "Supply Waypoints",

"skyblocker.config.debug": "Debug",

"skyblocker.config.debug.dumpRange": "Entity Dump Range",
"skyblocker.config.debug.dumpRange.@Tooltip": "The range in blocks around the player to dump entities within.",
"skyblocker.config.debug.showInvisibleArmorStands": "Show Invisible Armor Stands",
"skyblocker.config.debug.debugWebSockets": "Enable Websocket Debug Messages",

"skyblocker.config.dungeons": "Dungeons",

"skyblocker.config.dungeons.allowDroppingProtectedItems": "Enabled Dropping Protected Items & on Locked Slots",
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/skyblocker.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"DataTrackerMixin",
"DrawContextMixin",
"DyedColorComponentMixin",
"EntityMixin",
"EntityRenderDispatcherMixin",
"FarmlandBlockMixin",
"GenericContainerScreenHandlerMixin",
Expand All @@ -26,7 +27,6 @@
"InventoryScreenMixin",
"ItemStackMixin",
"LeverBlockMixin",
"LivingEntityRendererMixin",
"MinecraftClientMixin",
"MouseMixin",
"PingMeasurerMixin",
Expand Down

0 comments on commit 135125f

Please sign in to comment.