From f8eb1578b2f1a934062515b70a2de3bc1021cd74 Mon Sep 17 00:00:00 2001 From: skippyall <121978267+skippyall@users.noreply.github.com> Date: Sat, 9 May 2026 17:04:27 +0200 Subject: [PATCH] Back to the Future Fun is still suspended though --- .gitignore | 1 + .../InstructionBoundBlock.java | 2 +- .../minions/command/ListSubcommand.java | 2 +- .../minions/command/MinionArgument.java | 2 +- .../skippyall/minions/gui/GuiDisplay.java | 8 +- .../skippyall/minions/gui/MinionLookGui.kt | 47 +++--- .../skippyall/minions/gui/MinionsGui.kt | 2 +- .../minions/gui/input/BooleanInput.kt | 32 ++--- .../skippyall/minions/gui/input/Result.java | 2 +- .../skippyall/minions/gui/input/TextInput.kt | 78 ++-------- .../minions/gui/instruction/ArgumentGui.java | 1 - .../instruction/ConfigureInstructionGui.java | 2 +- .../minions/gui/instruction/ConverterGui.java | 3 +- .../gui/instruction/ConverterListGui.java | 6 +- .../gui/instruction/InstructionGui.java | 2 +- .../minions/gui/minion/GuiContext.kt | 79 ++++++---- .../minions/gui/minion/GuiContextImpl.kt | 136 +++--------------- .../listener/BlockEntityMinionListener.java | 6 +- .../minions/listener/ListenerManager.kt | 48 +++---- .../listener/SerializableListenerManager.kt | 71 ++++----- .../skippyall/minions/minion/MinionData.kt | 108 ++++++++------ .../skippyall/minions/minion/MinionItem.java | 2 +- .../minions/minion/MinionPersistentState.java | 8 +- .../minion/fakeplayer/MinionFakePlayer.java | 12 +- .../minions/minion/skin/NameSkinProvider.java | 2 +- .../minions/minion/skin/UUIDSkinProvider.java | 2 +- ...oundPlayerInfoUpdatePacket$EntryMixin.java | 2 +- .../minions/mixins/MinecraftServerMixin.java | 2 +- .../minions/mixins/PlayerListMixin.java | 4 +- .../ServerGamePacketListenerImplMixin.java | 2 +- .../minions/mixins/SleepStatusMixin.java | 2 +- .../instruction/ConfiguredInstruction.java | 2 +- .../program/supplier/ValueSupplierList.java | 27 ++-- .../minions/registration/ValueTypes.java | 10 +- .../gui_display/value_converter/cast.json | 11 +- 35 files changed, 297 insertions(+), 429 deletions(-) diff --git a/.gitignore b/.gitignore index ab42d53..ec0a09d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # User-specific stuff .idea/ urlaub/ +.kotlin/ *.iml *.ipr diff --git a/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlock.java b/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlock.java index 1738131..53b6272 100644 --- a/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlock.java +++ b/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlock.java @@ -51,7 +51,7 @@ public abstract class InstructionBoundBlock extends Block implements EntityBlock } world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> { - String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name(); + String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).getName(); player.sendSystemMessage(Component.translatable("minions.reference.instruction.tooltip", be.getInstructionName(), name)); }); return InteractionResult.SUCCESS; diff --git a/src/main/java/io/github/skippyall/minions/command/ListSubcommand.java b/src/main/java/io/github/skippyall/minions/command/ListSubcommand.java index abc3571..0042c51 100644 --- a/src/main/java/io/github/skippyall/minions/command/ListSubcommand.java +++ b/src/main/java/io/github/skippyall/minions/command/ListSubcommand.java @@ -18,7 +18,7 @@ public class ListSubcommand { public static int list(CommandContext context) { Collection minions = MinionPersistentState.get(context.getSource().getServer()).getMinionData().values(); for (MinionData minion : minions) { - context.getSource().sendSuccess(() -> Component.literal(minion.name() + "(" + minion.uuid() + "):" + minion.isSpawned()), false); + context.getSource().sendSuccess(() -> Component.literal(minion.getName() + "(" + minion.getUuid() + "):" + minion.isSpawned()), false); } return 0; } diff --git a/src/main/java/io/github/skippyall/minions/command/MinionArgument.java b/src/main/java/io/github/skippyall/minions/command/MinionArgument.java index bd4308b..a773187 100644 --- a/src/main/java/io/github/skippyall/minions/command/MinionArgument.java +++ b/src/main/java/io/github/skippyall/minions/command/MinionArgument.java @@ -41,7 +41,7 @@ public class MinionArgument { @Override public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { for (MinionData data : MinionPersistentState.get(context.getSource().getServer()).getMinionDataList()) { - builder.suggest(data.name()); + builder.suggest(data.getName()); } return builder.buildFuture(); diff --git a/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java b/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java index 803f265..ea6a629 100644 --- a/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java +++ b/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java @@ -27,9 +27,10 @@ import java.util.UUID; public interface GuiDisplay { Codec CODEC = MinionRegistries.GUI_DISPLAY_TYPE.byNameCodec().dispatch(GuiDisplay::getCodec, codec -> codec.fieldOf("data")); GuiDisplay DEFAULT_DISPLAY = new ItemBased(Items.BARRIER); - TooltipDisplay TOOLTIP_DISPLAY = createTooltipDisplay(); - private static TooltipDisplay createTooltipDisplay() { + TooltipDisplay TOOLTIP_HIDE_ALL_COMPONENTS = createHideAllTooltip(); + + private static TooltipDisplay createHideAllTooltip() { LinkedHashSet> set = new LinkedHashSet<>(); for(DataComponentType type : BuiltInRegistries.DATA_COMPONENT_TYPE) { if(type != DataComponents.LORE) { @@ -106,7 +107,7 @@ public interface GuiDisplay { @Override public ItemStackTemplate createItemStackTemplate() { return new ItemStackTemplate(item, DataComponentPatch.builder() - .set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_DISPLAY) + .set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_HIDE_ALL_COMPONENTS) .set(DataComponents.RARITY, Rarity.COMMON) .build()); } @@ -130,6 +131,7 @@ public interface GuiDisplay { public ItemStackTemplate createItemStackTemplate() { return new ItemStackTemplate(Items.PLAYER_HEAD, DataComponentPatch.builder() .set(DataComponents.PROFILE, ResolvableProfile.createUnresolved(uuid)) + .set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_HIDE_ALL_COMPONENTS) .build() ); } diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.kt b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.kt index b892d0f..c4cde8f 100644 --- a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.kt +++ b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.kt @@ -10,6 +10,7 @@ import io.github.skippyall.minions.minion.MinionProfileUtils import io.github.skippyall.minions.minion.skin.SkinProvider import io.github.skippyall.minions.registration.MinionRegistries import io.github.skippyall.minions.registration.SkinProviders +import kotlinx.coroutines.future.await import kotlinx.coroutines.launch import net.fabricmc.fabric.api.entity.FakePlayer import net.minecraft.core.component.DataComponents @@ -20,8 +21,6 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items import net.minecraft.world.item.component.ResolvableProfile import java.util.Optional -import java.util.function.Consumer -import java.util.function.Function class MinionLookGui( viewer: ServerPlayer, @@ -82,20 +81,24 @@ class MinionLookGui( gui.setSlot(16, builder) } + private fun updateSkinProvider() { + gui.setSlot( + 25, GuiElementBuilder() + .setItem(Items.GREEN_STAINED_GLASS_PANE) + .setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName()) + .setCallback(Runnable { this.cycleSkinProvider() }) + ) + } + fun openSkinGui() { - currentSkinProvider.openSkinMenu(this) - .thenCompose(Function { profile: ResolvableProfile? -> - profile!!.resolveProfile( - viewer.level().server.services().profileResolver() - ) - }) - .thenAccept(Consumer { skin: GameProfile? -> - MinionItem.setData( - viewer.level().server, this.data.withSkin( - Optional.of(skin!!.properties()) - ), minionItem - ) - }) + scope.launch { + val profile = currentSkinProvider.openSkinMenu(this@MinionLookGui).await() + val skin = profile.resolveProfile(viewer.level().server.services().profileResolver()).await() + + data.skin = Optional.ofNullable(skin?.properties()) + + updateSkin() + } } private fun cycleSkinProvider() { @@ -109,15 +112,6 @@ class MinionLookGui( updateSkinProvider() } - private fun updateSkinProvider() { - gui.setSlot( - 25, GuiElementBuilder() - .setItem(Items.GREEN_STAINED_GLASS_PANE) - .setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName()) - .setCallback(Runnable { this.cycleSkinProvider() }) - ) - } - fun openRenameGui() { scope.launch { val newName = TextInput.input( @@ -126,10 +120,11 @@ class MinionLookGui( "Minion", ) { name -> MinionProfileUtils.checkMinionNameWithoutPrefix(viewer.level().server, name) - } + }.await() if(newName != null) { - this@MinionLookGui.data.withName(newName) + data.name = newName + updateName() } } } diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionsGui.kt b/src/main/java/io/github/skippyall/minions/gui/MinionsGui.kt index f3bacb8..77eacdc 100644 --- a/src/main/java/io/github/skippyall/minions/gui/MinionsGui.kt +++ b/src/main/java/io/github/skippyall/minions/gui/MinionsGui.kt @@ -38,7 +38,7 @@ abstract class MinionsGui { protected abstract fun open() - protected fun reopen() { + protected open fun reopen() { open() } diff --git a/src/main/java/io/github/skippyall/minions/gui/input/BooleanInput.kt b/src/main/java/io/github/skippyall/minions/gui/input/BooleanInput.kt index 09684a4..2f28b01 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/BooleanInput.kt +++ b/src/main/java/io/github/skippyall/minions/gui/input/BooleanInput.kt @@ -4,26 +4,26 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder import eu.pb4.sgui.api.gui.SimpleGui import io.github.skippyall.minions.gui.MinionsGui import io.github.skippyall.minions.gui.minion.SimpleMinionsGui -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.future.asCompletableFuture import net.minecraft.network.chat.Component import net.minecraft.world.inventory.MenuType import net.minecraft.world.item.Items import java.util.concurrent.CompletableFuture object BooleanInput { + @JvmStatic + @JvmOverloads fun confirm( parent: MinionsGui, title: Component, falseText: Component = Component.translatable("minions.gui.abort"), trueText: Component = Component.translatable("minions.gui.confirm") - ): CompletableDeferred { - val deferred = CompletableDeferred() + ): CompletableFuture { + val future = CompletableFuture() SimpleMinionsGui(parent) { onClose: Runnable, me: SimpleMinionsGui -> val gui: SimpleGui = object : SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) { override fun onPlayerClose(success: Boolean) { - deferred.complete(false) + future.complete(false) onClose.run() } } @@ -33,7 +33,7 @@ object BooleanInput { 3, GuiElementBuilder(Items.REDSTONE_BLOCK) .setName(falseText) .setCallback(Runnable { - deferred.complete(false) + future.complete(false) me.goBack() }) ) @@ -42,7 +42,7 @@ object BooleanInput { 5, GuiElementBuilder(Items.EMERALD_BLOCK) .setName(trueText) .setCallback(Runnable { - deferred.complete(true) + future.complete(true) me.goBack() }) ) @@ -50,22 +50,6 @@ object BooleanInput { gui.open() gui } - return deferred - } - - @JvmStatic - @JvmOverloads - fun confirmFuture( - parent: MinionsGui, - title: Component, - falseText: Component = Component.translatable("minions.gui.abort"), - trueText: Component = Component.translatable("minions.gui.confirm") - ): CompletableFuture { - return confirm( - parent, - title, - falseText, - trueText - ).asCompletableFuture() + return future } } \ No newline at end of file diff --git a/src/main/java/io/github/skippyall/minions/gui/input/Result.java b/src/main/java/io/github/skippyall/minions/gui/input/Result.java index f0ffdec..ffb31bd 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/Result.java +++ b/src/main/java/io/github/skippyall/minions/gui/input/Result.java @@ -8,7 +8,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -public interface Result { +public sealed interface Result permits Result.Success, Result.Error { static Result wrap(UnsafeOperation toWrap) { return wrapCustomError(toWrap, Exception::getMessage); } diff --git a/src/main/java/io/github/skippyall/minions/gui/input/TextInput.kt b/src/main/java/io/github/skippyall/minions/gui/input/TextInput.kt index 0442e31..ab7085a 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/TextInput.kt +++ b/src/main/java/io/github/skippyall/minions/gui/input/TextInput.kt @@ -3,9 +3,6 @@ package io.github.skippyall.minions.gui.input import eu.pb4.sgui.api.elements.GuiElementBuilder import eu.pb4.sgui.api.gui.AnvilInputGui import io.github.skippyall.minions.gui.MinionsGui -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.future.asCompletableFuture import kotlinx.coroutines.launch import net.minecraft.network.chat.Component import net.minecraft.world.inventory.AnvilMenu @@ -29,10 +26,9 @@ class TextInput( private lateinit var gui: AnvilInputGui private var result: Result? = null - val deferred = CompletableDeferred() + val future = CompletableFuture() init { - updateConfirmButton(defaultValue) open() } @@ -44,14 +40,15 @@ class TextInput( override fun onPlayerClose(success: Boolean) { onBackingClosed() - if (deferred.isActive) { - deferred.complete(null) + if (!future.isDone) { + future.complete(null) } } } gui.setTitle(title) gui.setDefaultInputValue(defaultValue) + updateConfirmButton(defaultValue) gui.open() } @@ -74,7 +71,8 @@ class TextInput( fun onConfirm() { result?.ifSuccess { success: T -> - deferred.complete(success) + future.complete(success) + goBack() } } @@ -85,7 +83,7 @@ class TextInput( title: Component, defaultValue: String, parser: suspend (String) -> Result, - ): Deferred { + ): CompletableFuture { val input = TextInput( parent = gui, title = title, @@ -93,22 +91,7 @@ class TextInput( parser = parser, ) - return input.deferred - } - - @JvmStatic - fun inputFuture( - gui: MinionsGui, - title: Component, - defaultValue: String, - parser: (String) -> Result, - ): CompletableFuture { - return input( - gui = gui, - title = title, - defaultValue = defaultValue, - parser = parser - ).asCompletableFuture() + return input.future } @JvmStatic @@ -116,7 +99,7 @@ class TextInput( gui: MinionsGui, title: Component, defaultValue: String, - ): Deferred { + ): CompletableFuture { return input( gui = gui, title = title, @@ -125,25 +108,12 @@ class TextInput( ) } - @JvmStatic - fun inputStringFuture( - gui: MinionsGui, - title: Component, - defaultValue: String, - ): CompletableFuture { - return inputString( - gui = gui, - title = title, - defaultValue = defaultValue, - ).asCompletableFuture() - } - @JvmStatic fun inputLong( gui: MinionsGui, title: Component, defaultValue: Long, - ): Deferred { + ): CompletableFuture { return input( gui = gui, title = title, @@ -157,25 +127,12 @@ class TextInput( ) } - @JvmStatic - fun inputLongFuture( - gui: MinionsGui, - title: Component, - defaultValue: Long, - ): CompletableFuture { - return inputLong( - gui = gui, - title = title, - defaultValue = defaultValue, - ).asCompletableFuture() - } - @JvmStatic fun inputDouble( gui: MinionsGui, title: Component, defaultValue: Double, - ): Deferred { + ): CompletableFuture { return input( gui = gui, title = title, @@ -188,18 +145,5 @@ class TextInput( }, ) } - - @JvmStatic - fun inputDoubleFuture( - gui: MinionsGui, - title: Component, - defaultValue: Double, - ): CompletableFuture { - return inputDouble( - gui = gui, - title = title, - defaultValue = defaultValue, - ).asCompletableFuture() - } } } diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java index b107e58..67da642 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java @@ -7,7 +7,6 @@ import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.PaginatedList; import io.github.skippyall.minions.gui.minion.GuiContext; import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.program.supplier.ValueSupplier; diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java index b775811..f45d507 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java @@ -60,7 +60,7 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns gui.setSlot(7, new GuiElementBuilder(Items.LAVA_BUCKET) .setName(Component.translatable("minions.gui.instruction.configure.delete")) - .setCallback(() -> BooleanInput.confirmFuture(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name)) + .setCallback(() -> BooleanInput.confirm(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name)) .thenAccept((confirmed) -> { if(confirmed) { minion.getInstructionManager().removeInstruction(name); diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java index 5d145a0..5b65721 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java @@ -28,7 +28,6 @@ public class ConverterGui extends MinionsGui { public ConverterGui(MinionsGui parent, @Nullable ValueConverter converter, ValueType from, ValueType to, ConverterList list, boolean isNew, int index) { super(parent); - open(); this.converter = converter; if(converter != null) { this.valueConverterType = converter.getType(); @@ -38,6 +37,8 @@ public class ConverterGui extends MinionsGui { this.list = list; this.isNew = isNew; this.index = index; + + open(); } @Override diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java index 69c1c50..acb18ac 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java @@ -54,7 +54,7 @@ public class ConverterListGui extends MinionsGui { gui.setSlot(23, new GuiElementBuilder(Items.ARROW) .setCallback(() -> { - if(page * 4 + 4 < converters.getConverters().size()) { + if(page * 4 + 4 < converters.getConverters().size() + 1) { page++; updateConverters(); } @@ -67,6 +67,10 @@ public class ConverterListGui extends MinionsGui { } public void updateConverters() { + for(int slot = 9; slot < 18; slot++) { + gui.clearSlot(slot); + } + int lastConverter = Math.min(5, converters.getConverters().size() + 2 - page * 4); for(int i = 0; i < lastConverter; i++) { //Each page has 5 converters, but the last is displayed on the next page as well diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java index 002b217..a899e2b 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java @@ -73,7 +73,7 @@ public class InstructionGui { } public static CompletableFuture inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) { - return TextInput.inputFuture(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> { + return TextInput.input(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, (name, _) -> { if (context.getMinion().getInstructionManager().hasInstruction(name)) { return new Result.Error<>(Component.translatable("minions.gui.instruction.name_already_used")); } diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.kt b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.kt index 29854db..c8e57fd 100644 --- a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.kt +++ b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.kt @@ -1,43 +1,64 @@ -package io.github.skippyall.minions.gui.minion; +package io.github.skippyall.minions.gui.minion -import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; -import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; -import io.github.skippyall.minions.program.supplier.Parameter; -import net.minecraft.server.level.ServerPlayer; +import io.github.skippyall.minions.gui.minion.GuiContextImpl.* +import io.github.skippyall.minions.minion.MinionRuntime +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer +import io.github.skippyall.minions.program.instruction.ConfiguredInstruction +import io.github.skippyall.minions.program.supplier.Parameter +import net.minecraft.server.level.ServerPlayer -public interface GuiContext { - ServerPlayer getViewer(); +interface GuiContext { + val viewer: ServerPlayer - static GuiContext create(ServerPlayer viewer) { - return new GuiContextImpl(viewer); - } - - interface Minion extends GuiContext { - MinionFakePlayer getMinion(); - - static GuiContext.Minion create(GuiContext context, MinionFakePlayer minion) { - return new GuiContextImpl.MinionImpl(context, minion); + companion object { + @JvmStatic + fun create(viewer: ServerPlayer): GuiContext { + return GuiContextImpl(viewer) } } - interface Instruction extends Minion { - ConfiguredInstruction getInstruction(); + interface Minion : GuiContext { + val minion: MinionFakePlayer - String getName(); - - void setName(String name); - - static GuiContext.Instruction create(GuiContext.Minion context, ConfiguredInstruction instruction, String name) { - return new GuiContextImpl.InstructionImpl(context, instruction, name); + companion object { + @JvmStatic + fun create(context: GuiContext, minion: MinionFakePlayer): Minion { + return MinionImpl( + if(context is MinionImpl) context.context else context, + minion + ) + } } } - interface ValueSupplier extends Instruction { - Parameter getParameter(); + interface Instruction : Minion { + val instruction: ConfiguredInstruction - static GuiContext.ValueSupplier create(GuiContext.Instruction context, Parameter parameter) { - return new GuiContextImpl.ValueSupplierImpl(context, parameter); + var name: String + + companion object { + @JvmStatic + fun create(context: Minion, instruction: ConfiguredInstruction, name: String): Instruction { + return InstructionImpl( + if(context is InstructionImpl) context.context else context, + instruction, + name + ) + } + } + } + + interface ValueSupplier : Instruction { + val parameter: Parameter<*> + + companion object { + @JvmStatic + fun create(context: Instruction, parameter: Parameter<*>): ValueSupplier { + return ValueSupplierImpl( + if(context is ValueSupplierImpl) context.context else context, + parameter + ) + } } } } diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.kt b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.kt index f3613bb..0be9df5 100644 --- a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.kt +++ b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.kt @@ -1,120 +1,26 @@ -package io.github.skippyall.minions.gui.minion; +package io.github.skippyall.minions.gui.minion -import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; -import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; -import io.github.skippyall.minions.program.supplier.Parameter; -import net.minecraft.server.level.ServerPlayer; +import io.github.skippyall.minions.minion.MinionRuntime +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer +import io.github.skippyall.minions.program.instruction.ConfiguredInstruction +import io.github.skippyall.minions.program.supplier.Parameter +import net.minecraft.server.level.ServerPlayer -//If only this mod was kotlin -public class GuiContextImpl implements GuiContext { - private final ServerPlayer viewer; +//Thank you kotlin +class GuiContextImpl(override val viewer: ServerPlayer) : GuiContext { + class MinionImpl( + val context: GuiContext, + override val minion: MinionFakePlayer + ) : GuiContext by context, GuiContext.Minion - public GuiContextImpl(ServerPlayer viewer) { - this.viewer = viewer; - } + class InstructionImpl( + val context: GuiContext.Minion, + override val instruction: ConfiguredInstruction, + override var name: String + ) : GuiContext.Minion by context, GuiContext.Instruction - @Override - public ServerPlayer getViewer() { - return viewer; - } - - public static class MinionImpl extends DelegatingGuiContextImpl implements GuiContext.Minion { - private final MinionFakePlayer minion; - - public MinionImpl(GuiContext context, MinionFakePlayer minion) { - super(context instanceof DelegatingGuiContextImpl impl ? impl.context : context); - this.minion = minion; - } - - @Override - public MinionFakePlayer getMinion() { - return minion; - } - } - - public static class InstructionImpl extends DelegatingMinionImpl implements GuiContext.Instruction { - private final ConfiguredInstruction instruction; - private String name; - - public InstructionImpl(GuiContext.Minion context, ConfiguredInstruction instruction, String name) { - super(context instanceof DelegatingMinionImpl impl ? impl.context : context); - this.instruction = instruction; - this.name = name; - } - - @Override - public ConfiguredInstruction getInstruction() { - return instruction; - } - - @Override - public String getName() { - return name; - } - - @Override - public void setName(String name) { - this.name = name; - } - } - - public static class ValueSupplierImpl extends DelegatingInstructionImpl implements GuiContext.ValueSupplier { - private final Parameter parameter; - - public ValueSupplierImpl(GuiContext.Instruction context, Parameter parameter) { - super(context instanceof DelegatingInstructionImpl impl ? impl.context : context); - this.parameter = parameter; - } - - @Override - public Parameter getParameter() { - return parameter; - } - } - - public static class DelegatingGuiContextImpl implements GuiContext { - protected final C context; - - public DelegatingGuiContextImpl(C context) { - this.context = context; - } - - @Override - public ServerPlayer getViewer() { - return context.getViewer(); - } - } - - public static class DelegatingMinionImpl extends DelegatingGuiContextImpl implements GuiContext.Minion { - public DelegatingMinionImpl(C context) { - super(context); - } - - @Override - public MinionFakePlayer getMinion() { - return context.getMinion(); - } - } - - public static class DelegatingInstructionImpl extends DelegatingMinionImpl implements GuiContext.Instruction { - public DelegatingInstructionImpl(C context) { - super(context); - } - - @Override - public ConfiguredInstruction getInstruction() { - return context.getInstruction(); - } - - @Override - public String getName() { - return context.getName(); - } - - @Override - public void setName(String name) { - context.setName(name); - } - } + class ValueSupplierImpl( + val context: GuiContext.Instruction, + override val parameter: Parameter<*> + ) : GuiContext.Instruction by context, GuiContext.ValueSupplier } diff --git a/src/main/java/io/github/skippyall/minions/listener/BlockEntityMinionListener.java b/src/main/java/io/github/skippyall/minions/listener/BlockEntityMinionListener.java index 505b755..46bbd3a 100644 --- a/src/main/java/io/github/skippyall/minions/listener/BlockEntityMinionListener.java +++ b/src/main/java/io/github/skippyall/minions/listener/BlockEntityMinionListener.java @@ -47,7 +47,7 @@ public abstract class BlockEntityMinionListener implement public static > T getListener(Level world, BlockPos pos, UUID minionUuid, Class clazz) { if(minionUuid != null) { - for (MinionListener listener : MinionPersistentState.get(world.getServer()).getMinionData(minionUuid).listeners()) { + for (MinionListener listener : MinionPersistentState.get(world.getServer()).getMinionData(minionUuid).getListeners()) { if (listener instanceof BlockEntityMinionListener tl && tl.pos.equals(pos) && tl.worldKey.equals(world.dimension()) && clazz.isInstance(tl)) { return clazz.cast(tl); } @@ -95,13 +95,13 @@ public abstract class BlockEntityMinionListener implement } public void add(MinecraftServer server) { - MinionPersistentState.get(server).getMinionData(minionUuid).listeners().addListener(this); + MinionPersistentState.get(server).getMinionData(minionUuid).getListeners().addListener(this); MinionPersistentState.get(server).setDirty(); this.minion = (MinionFakePlayer) server.getPlayerList().getPlayer(minionUuid); } public void remove(MinecraftServer server) { - MinionPersistentState.get(server).getMinionData(minionUuid).listeners().removeListener(this); + MinionPersistentState.get(server).getMinionData(minionUuid).getListeners().removeListener(this); MinionPersistentState.get(server).setDirty(); } diff --git a/src/main/java/io/github/skippyall/minions/listener/ListenerManager.kt b/src/main/java/io/github/skippyall/minions/listener/ListenerManager.kt index 6e5ae6f..94fc0d4 100644 --- a/src/main/java/io/github/skippyall/minions/listener/ListenerManager.kt +++ b/src/main/java/io/github/skippyall/minions/listener/ListenerManager.kt @@ -1,37 +1,29 @@ -package io.github.skippyall.minions.listener; +package io.github.skippyall.minions.listener -import org.jetbrains.annotations.NotNull; +import java.util.concurrent.CopyOnWriteArraySet -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +open class ListenerManager( + protected val listeners: MutableSet = CopyOnWriteArraySet(), + val onChange: () -> Unit = {}, +) : MutableIterable by listeners { -public class ListenerManager implements Iterable { - protected final Set listeners; - - public ListenerManager() { - this(new CopyOnWriteArraySet<>()); + fun addListener(listener: T) { + listeners.add(listener) + onChange() } - protected ListenerManager(Set listeners) { - this.listeners = listeners; + fun removeListener(listener: T) { + listeners.remove(listener) + onChange() } - public void addListener(T listener) { - listeners.add(listener); - } - - public void removeListener(T listener) { - listeners.remove(listener); - } - - @Override - public @NotNull Iterator iterator() { - return listeners.iterator(); - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj); + override fun iterator(): MutableIterator { + val iterator = listeners.iterator() + return object : MutableIterator by iterator { + override fun remove() { + iterator.remove() + onChange() + } + } } } diff --git a/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.kt b/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.kt index 0f2a1fb..c5b9b63 100644 --- a/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.kt +++ b/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.kt @@ -1,46 +1,47 @@ -package io.github.skippyall.minions.listener; +package io.github.skippyall.minions.listener -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import net.minecraft.core.Registry; -import net.minecraft.resources.Identifier; +import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec +import io.github.skippyall.minions.listener.SerializableListenerManager.SerializableListener +import net.minecraft.core.Registry +import net.minecraft.resources.Identifier +import java.util.Optional +import java.util.concurrent.CopyOnWriteArraySet -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +class SerializableListenerManager( + listeners: MutableSet = CopyOnWriteArraySet(), + onChange: () -> Unit = {}, +) : ListenerManager(listeners, onChange) { -public class SerializableListenerManager extends ListenerManager { - public SerializableListenerManager() { - super(); + interface SerializableListener { + val codecId: Optional + get() = Optional.empty() } - protected SerializableListenerManager(Set listeners) { - super(listeners); - } - - public static Codec> getCodec(Registry> registry) { - return registry.byNameCodec().dispatch( - listener -> listener.getCodecId().map(registry::getValue).orElse(MapCodec.unitCodec(null)), - codec -> codec.fieldOf("data") + companion object { + @JvmStatic + @JvmOverloads + fun getCodec( + registry: Registry>, + onChange: () -> Unit = {}, + ): Codec> { + return registry.byNameCodec().dispatch( + { listener -> listener.codecId.map(registry::getValue) + .orElseGet { MapCodec.unitCodec(null) } + }, + { codec -> codec.fieldOf("data") } ).listOf().xmap( - list -> new SerializableListenerManager<>(new CopyOnWriteArraySet<>(list)), - manager -> { - List serializableListeners = new ArrayList<>(); - for(T listener : manager.listeners) { - if(listener.getCodecId().isPresent()) { - serializableListeners.add(listener); - } + { list -> SerializableListenerManager(CopyOnWriteArraySet(list), onChange) }, + { manager -> + val serializableListeners: MutableList = mutableListOf() + for (listener in manager.listeners) { + if (listener.codecId.isPresent) { + serializableListeners.add(listener) } - return serializableListeners; } - ); - } - - public interface SerializableListener { - default Optional getCodecId() { - return Optional.empty(); + return@xmap serializableListeners + } + ) } } } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionData.kt b/src/main/java/io/github/skippyall/minions/minion/MinionData.kt index 274471d..d535a1c 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionData.kt +++ b/src/main/java/io/github/skippyall/minions/minion/MinionData.kt @@ -1,58 +1,82 @@ -package io.github.skippyall.minions.minion; +package io.github.skippyall.minions.minion -import com.mojang.authlib.properties.PropertyMap; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.skippyall.minions.listener.SerializableListenerManager; -import io.github.skippyall.minions.registration.MinionRegistries; -import net.minecraft.core.UUIDUtil; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ExtraCodecs; -import java.util.Optional; -import java.util.UUID; +import com.mojang.authlib.properties.PropertyMap +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import io.github.skippyall.minions.listener.SerializableListenerManager +import io.github.skippyall.minions.registration.MinionRegistries +import net.minecraft.core.UUIDUtil +import net.minecraft.server.MinecraftServer +import net.minecraft.util.ExtraCodecs +import java.util.Optional +import java.util.UUID +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty -public record MinionData( - UUID uuid, - String name, - Optional skin, - boolean isSpawned, - SerializableListenerManager listeners, - MinionConfig config +class MinionData( + initialUuid: UUID, + initialName: String, + initialSkin: Optional, + initialIsSpawned: Boolean, + val listeners: SerializableListenerManager, + initialConfig: MinionConfig, + var onDirty: Runnable = {}, ) { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( + var uuid by DirtyProperty(initialUuid, this::setDirty) + var name by DirtyProperty(initialName, this::setDirty) + var skin by DirtyProperty(initialSkin, this::setDirty) + var isSpawned by DirtyProperty(initialIsSpawned, this::setDirty) + var config by DirtyProperty(initialConfig, this::setDirty) + + fun setDirty() { + this@MinionData.onDirty.run() + } + + companion object { + @JvmField + val CODEC: Codec = + RecordCodecBuilder.create { instance -> + instance.group( UUIDUtil.AUTHLIB_CODEC.fieldOf("uuid").forGetter(MinionData::uuid), Codec.STRING.fieldOf("name").forGetter(MinionData::name), ExtraCodecs.PROPERTY_MAP.optionalFieldOf("skin").forGetter(MinionData::skin), Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned), - SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners").xmap( - optional -> optional.orElseGet(SerializableListenerManager::new), - Optional::of - ).forGetter(MinionData::listeners), - MinionConfig.CODEC.optionalFieldOf("config", new MinionConfig()).forGetter(MinionData::config) - ).apply(instance, MinionData::new) - ); + SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS) + .optionalFieldOf("listeners").xmap( + { optional -> optional.orElseGet { SerializableListenerManager() } }, + Optional>::of + ).forGetter(MinionData::listeners), + MinionConfig.CODEC.optionalFieldOf("config", MinionConfig()) + .forGetter(MinionData::config) + ).apply( + instance, + ::MinionData + ) + } - public static MinionData createDefault(MinecraftServer server) { - return new MinionData( + @JvmStatic + fun createDefault(server: MinecraftServer): MinionData { + return MinionData( UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(server), - Optional.empty(), + Optional.empty(), false, - new SerializableListenerManager<>(), - new MinionConfig() - ); + SerializableListenerManager(), + MinionConfig() + ) { + MinionPersistentState.get(server).isDirty = true + } + } } - public MinionData withName(String name) { - return new MinionData(uuid, name, skin, isSpawned, listeners, config); - } + class DirtyProperty(var value: V, val onDirty: () -> Unit) : ReadWriteProperty { + override fun getValue(thisRef: Any?, property: KProperty<*>): V { + return value + } - public MinionData withSkin(Optional skin) { - return new MinionData(uuid, name, skin, isSpawned, listeners, config); - } - - public MinionData withSpawned(boolean isSpawned) { - return new MinionData(uuid, name, skin, isSpawned, listeners, config); + override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) { + this.value = value + onDirty() + } } } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionItem.java b/src/main/java/io/github/skippyall/minions/minion/MinionItem.java index b4c5205..97c78f8 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionItem.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionItem.java @@ -79,7 +79,7 @@ public class MinionItem extends Item implements PolymerItem { } public static void setData(MinecraftServer server, MinionData data, ItemStack item) { - item.set(MinionComponentTypes.MINION_DATA, data.uuid()); + item.set(MinionComponentTypes.MINION_DATA, data.getUuid()); MinionPersistentState.get(server).updateMinionData(data); } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java b/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java index f86afdb..8eac4ca 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java @@ -31,7 +31,8 @@ public class MinionPersistentState extends SavedData { public MinionPersistentState(List dataList) { for (MinionData data : dataList) { - minionData.put(data.uuid(), data); + data.setOnDirty(this::setDirty); + minionData.put(data.getUuid(), data); } } @@ -48,7 +49,8 @@ public class MinionPersistentState extends SavedData { } public void updateMinionData(MinionData data) { - minionData.put(data.uuid(), data); + minionData.put(data.getUuid(), data); + data.setOnDirty(this::setDirty); setDirty(); } @@ -62,7 +64,7 @@ public class MinionPersistentState extends SavedData { public Optional getMinionWithName(String name) { return minionData.values().stream() - .filter(data -> data.name().equals(name)) + .filter(data -> data.getName().equals(name)) .findFirst(); } diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java index 8194ad1..ca0f73e 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java @@ -73,16 +73,16 @@ public class MinionFakePlayer extends ServerPlayer { if(!data.isSpawned() || force) { MinecraftServer server = level.getServer(); - PropertyMap skin = data.skin().orElse(null); + PropertyMap skin = data.getSkin().orElse(null); - GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.uuid(), data.name(), skin); + GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.getUuid(), data.getName(), skin); server.schedule(server.wrapRunnable(() -> doSpawn(data, profile, server, level, pos, rot))); } } private static void doSpawn(MinionData data, GameProfile profile, MinecraftServer server, ServerLevel level, @Nullable Vec3 pos, @Nullable Vec2 rot) { MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, ClientInformation.createDefault()); - MinionPersistentState.get(server).updateMinionData(data.withSpawned(true)); + data.setSpawned(true); if(pos != null && rot != null) { instance.fixStartingPosition = () -> instance.snapTo(pos.x, pos.y, pos.z, rot.x, rot.y); @@ -158,7 +158,7 @@ public class MinionFakePlayer extends ServerPlayer { } public SerializableListenerManager listeners() { - return getData().listeners(); + return getData().getListeners(); } public void addMinionListener(MinionListener listener) { @@ -174,7 +174,7 @@ public class MinionFakePlayer extends ServerPlayer { } public boolean canSpawnMobs() { - return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING) || getData().config().getOption(MinionConfigOptions.spawnAndDespawnMobs); + return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING) || getData().getConfig().getOption(MinionConfigOptions.spawnAndDespawnMobs); } public boolean canDespawnMobs() { @@ -213,7 +213,7 @@ public class MinionFakePlayer extends ServerPlayer { })); } - MinionPersistentState.get(getServer()).updateMinionData(getData().withSpawned(false)); + getData().setSpawned(false); } @Override diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/NameSkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/NameSkinProvider.java index c5773e6..e4eee78 100644 --- a/src/main/java/io/github/skippyall/minions/minion/skin/NameSkinProvider.java +++ b/src/main/java/io/github/skippyall/minions/minion/skin/NameSkinProvider.java @@ -10,7 +10,7 @@ import java.util.concurrent.CompletableFuture; public class NameSkinProvider implements SkinProvider { @Override public CompletableFuture openSkinMenu(MinionsGui parent) { - return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.name.title"), "") + return TextInput.inputString(parent, Component.translatable("minions.gui.look.skin.name.title"), "") .thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null); } diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/UUIDSkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/UUIDSkinProvider.java index 75b6c5e..b71ff4a 100644 --- a/src/main/java/io/github/skippyall/minions/minion/skin/UUIDSkinProvider.java +++ b/src/main/java/io/github/skippyall/minions/minion/skin/UUIDSkinProvider.java @@ -10,7 +10,7 @@ import java.util.concurrent.CompletableFuture; public class UUIDSkinProvider implements SkinProvider { @Override public CompletableFuture openSkinMenu(MinionsGui parent) { - return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.uuid.title"), "") + return TextInput.inputString(parent, Component.translatable("minions.gui.look.skin.uuid.title"), "") .thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null); } diff --git a/src/main/java/io/github/skippyall/minions/mixins/ClientboundPlayerInfoUpdatePacket$EntryMixin.java b/src/main/java/io/github/skippyall/minions/mixins/ClientboundPlayerInfoUpdatePacket$EntryMixin.java index 097b280..8c1528a 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/ClientboundPlayerInfoUpdatePacket$EntryMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/ClientboundPlayerInfoUpdatePacket$EntryMixin.java @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; public class ClientboundPlayerInfoUpdatePacket$EntryMixin { @ModifyArg(method = "(Lnet/minecraft/server/level/ServerPlayer;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket$Entry;(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/level/GameType;Lnet/minecraft/network/chat/Component;ZILnet/minecraft/network/chat/RemoteChatSession$Data;)V"), index = 2) private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayer player) { - if(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.showInTabList)) { + if(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.showInTabList)) { return false; } diff --git a/src/main/java/io/github/skippyall/minions/mixins/MinecraftServerMixin.java b/src/main/java/io/github/skippyall/minions/mixins/MinecraftServerMixin.java index b95536c..e9af0f8 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/MinecraftServerMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/MinecraftServerMixin.java @@ -24,7 +24,7 @@ public class MinecraftServerMixin { public List ignoreFakePlayers(List original) { return original.stream() .filter(player -> !(player instanceof MinionFakePlayer minion - && !minion.getData().config().getOption(MinionConfigOptions.showInServerList))) + && !minion.getData().getConfig().getOption(MinionConfigOptions.showInServerList))) .collect(Collectors.toCollection(ArrayList::new)); } diff --git a/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java b/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java index 6d39935..e9a99ff 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java @@ -59,7 +59,7 @@ public class PlayerListMixin { @WrapOperation(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V")) public void noLoginMessage(PlayerList instance, Component message, boolean overlay, Operation original, @Local(argsOnly = true) ServerPlayer player) { - if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLoginMessage))) { + if(!(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.sendLoginMessage))) { original.call(instance, message, overlay); } } @@ -67,7 +67,7 @@ public class PlayerListMixin { @ModifyReceiver(method = "canPlayerLogin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I")) public List noMinionCounting(List instance) { return instance.stream() - .filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForPlayerLimit))) + .filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.countForPlayerLimit))) .collect(Collectors.toCollection(ArrayList::new)); } } diff --git a/src/main/java/io/github/skippyall/minions/mixins/ServerGamePacketListenerImplMixin.java b/src/main/java/io/github/skippyall/minions/mixins/ServerGamePacketListenerImplMixin.java index 0c4de14..b02c360 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/ServerGamePacketListenerImplMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/ServerGamePacketListenerImplMixin.java @@ -19,7 +19,7 @@ public class ServerGamePacketListenerImplMixin { @WrapOperation(method = "removePlayerFromWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V")) public void noLogoutMessage(PlayerList instance, Component message, boolean overlay, Operation original) { - if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLogoutMessage))) { + if(!(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.sendLogoutMessage))) { original.call(instance, message, overlay); } } diff --git a/src/main/java/io/github/skippyall/minions/mixins/SleepStatusMixin.java b/src/main/java/io/github/skippyall/minions/mixins/SleepStatusMixin.java index 1a8d101..f0d22e6 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/SleepStatusMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/SleepStatusMixin.java @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; public class SleepStatusMixin { @WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;isSpectator()Z")) public boolean excludeMinions(ServerPlayer instance, Operation original) { - if (instance instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForSleeping)) { + if (instance instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.countForSleeping)) { return true; } else { return original.call(instance); diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java index 2e181c7..9232a37 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java @@ -78,8 +78,8 @@ public class ConfiguredInstruction> { public void run(R minion) { if(canRun() && !isRunning()) { - ParameterValueList resolvedArguments = arguments.resolve(minion); try { + ParameterValueList resolvedArguments = arguments.resolve(minion); execution = instruction.createExecution(resolvedArguments, minion); execution.start(minion); } catch (Exception e) { diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java index 6811728..f6ae328 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java @@ -37,11 +37,6 @@ public class ValueSupplierList> { return List.copyOf(arguments.values()); } - public T getValue(Parameter parameter, R runtime) { - ValueSupplierEntry entry = getEntry(parameter); - return parameter.type().checkedCast(entry.getValue(runtime)); - } - public ValueSupplier getArgument(Parameter parameter) { if(arguments.containsKey(parameter)) { return arguments.get(parameter).supplier; @@ -153,20 +148,24 @@ public class ValueSupplierList> { this.supplier = supplier; } - private void addToList(ParameterValueList list, R runtime) { - list.setValue(parameter, getValue(runtime)); + private @Nullable Component addToList(ParameterValueList list, R runtime) { + Result result = getValue(supplier, runtime); + switch (result) { + case Result.Success success -> { + list.setValue(parameter, success.result()); + return null; + } + case Result.Error error -> { + return error.message(); + } + } } - public @Nullable P getValue(R runtime) { - return getValue(supplier, runtime); - } - - //Ich liebe generische Typen (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) - private @Nullable P getValue(ValueSupplier supplier, R runtime) { + private Result getValue(ValueSupplier supplier, R runtime) { S value = supplier.resolve(runtime); Result, Component> convertedResult = converters.convert(new TypedValue<>(value, supplier.getValueType())); - return convertedResult.flatMap(convertedValue -> Casts.castOrError(convertedValue, parameter.type())).getOrDefault(null); + return convertedResult.flatMap(convertedValue -> Casts.castOrError(convertedValue, parameter.type())); } public @Nullable Component check() { diff --git a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java index 202c1e1..0299739 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java +++ b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java @@ -22,7 +22,7 @@ public class ValueTypes { Codec.LONG, 0L, o -> o instanceof Long l ? l : null, - (parent, oldValue) -> TextInput.inputLongFuture( + (parent, oldValue) -> TextInput.inputLong( parent, Component.literal("Integer"), oldValue @@ -37,10 +37,10 @@ public class ValueTypes { Codec.DOUBLE, 0D, o -> o instanceof Double d ? d : null, - (parent, oldValue) -> TextInput.inputDoubleFuture( + (parent, oldValue) -> TextInput.inputDouble( parent, Component.literal("Number"), - oldValue + oldValue != null ? oldValue : 0D ), value -> Component.literal(value.toString()) ) @@ -52,7 +52,7 @@ public class ValueTypes { Codec.BOOL, false, o -> o instanceof Boolean b ? b : null, - (parent, value) -> BooleanInput.confirmFuture(parent, Component.literal(""), Component.translatable("value_type.minions.boolean.false"), Component.translatable("value_type.minions.boolean.true")), + (parent, value) -> BooleanInput.confirm(parent, Component.literal(""), Component.translatable("value_type.minions.boolean.false"), Component.translatable("value_type.minions.boolean.true")), value -> Component.literal(value.toString()) ) ); @@ -63,7 +63,7 @@ public class ValueTypes { Codec.STRING, "", o -> o instanceof String s ? s : null, - ((parent, oldValue) -> TextInput.inputStringFuture( + ((parent, oldValue) -> TextInput.inputString( parent, Component.literal("Text"), oldValue diff --git a/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json b/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json index f53b224..20310be 100644 --- a/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json +++ b/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json @@ -1,11 +1,4 @@ { - "type": "minions:stack", - "data": { - "id": "minecraft:player_head", - "components": { - "minecraft:profile": { - "name": "CastCrafter" - } - } - } + "type": "minions:head", + "data": "459dbceed3ea4abc903cfdcae3065dd3" } \ No newline at end of file