From 19318480681c20f5bcf266132fa14bf377c535a5 Mon Sep 17 00:00:00 2001 From: skippyall <> Date: Thu, 24 Apr 2025 22:09:38 +0200 Subject: [PATCH] Skin Improvements --- build.gradle | 4 + gradle.properties | 2 +- .../skippyall/minions/gui/CommandsGui.java | 2 +- .../skippyall/minions/gui/MinionLookGui.java | 49 +++++++---- .../minions/gui/ModuleInventory.java | 2 +- .../skippyall/minions/input/TextInput.java | 45 ++++++---- .../skippyall/minions/minion/MinionData.java | 21 ++--- .../skippyall/minions/minion/MinionItem.java | 18 ++++ .../minions/minion/MinionPersistentState.java | 41 ++------- .../minions/minion/MinionProfileUtils.java | 83 +++++++------------ .../minion/fakeplayer/MinionFakePlayer.java | 29 ++++--- .../minion/skin/Base64SkinProvider.java | 27 ++++++ .../minion/skin/CachedSkinProvider.java | 41 --------- .../minion/skin/DirectSkinProvider.java | 33 -------- .../minions/minion/skin/NameSkinProvider.java | 46 ++++------ .../minions/minion/skin/SkinProvider.java | 10 +-- .../minions/minion/skin/SkinProviders.java | 17 ++-- .../minions/minion/skin/UUIDSkinProvider.java | 47 ++++------- .../minions/mixins/EntityViewMixin.java | 2 +- .../minions/mixins/PlayerListMixin.java | 2 +- .../minions/module/ActionModules.java | 2 +- .../minions/module/AttackModule.java | 2 +- .../skippyall/minions/module/ChatModule.java | 2 +- .../minions/module/InteractModule.java | 2 +- .../skippyall/minions/module/ModuleItem.java | 2 +- .../skippyall/minions/module/Modules.java | 2 +- .../skippyall/minions/module/MountModule.java | 2 +- .../skippyall/minions/module/MoveModule.java | 2 +- .../minions/module/SimpleModuleItem.java | 2 +- .../minions/{ => module}/command/Command.java | 2 +- .../{ => module}/command/CommandExecutor.java | 2 +- .../{ => module}/command/SimpleCommand.java | 2 +- .../resources/data/minions/lang/en_us.json | 13 ++- 33 files changed, 235 insertions(+), 323 deletions(-) create mode 100644 src/main/java/io/github/skippyall/minions/minion/skin/Base64SkinProvider.java delete mode 100644 src/main/java/io/github/skippyall/minions/minion/skin/CachedSkinProvider.java delete mode 100644 src/main/java/io/github/skippyall/minions/minion/skin/DirectSkinProvider.java rename src/main/java/io/github/skippyall/minions/{ => module}/command/Command.java (79%) rename src/main/java/io/github/skippyall/minions/{ => module}/command/CommandExecutor.java (81%) rename src/main/java/io/github/skippyall/minions/{ => module}/command/SimpleCommand.java (95%) diff --git a/build.gradle b/build.gradle index 6a5f567..4bc5e93 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,10 @@ base { archivesName = project.archives_base_name } +loom { + accessWidenerPath = file("src/main/resources/minions.accesswidener") +} + repositories { // Add repositories to retrieve artifacts from in here. // You should only use this when depending on other mods because diff --git a/gradle.properties b/gradle.properties index 8fa819a..9244aa8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html minecraft_version=1.21.3 - loader_version=0.16.7 + loader_version=0.16.13 yarn_mappings=1.21.3+build.2 # Mod Properties diff --git a/src/main/java/io/github/skippyall/minions/gui/CommandsGui.java b/src/main/java/io/github/skippyall/minions/gui/CommandsGui.java index 68d47a9..743918b 100644 --- a/src/main/java/io/github/skippyall/minions/gui/CommandsGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/CommandsGui.java @@ -2,7 +2,7 @@ package io.github.skippyall.minions.gui; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; -import io.github.skippyall.minions.command.Command; +import io.github.skippyall.minions.module.command.Command; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.module.ModuleItem; import net.minecraft.screen.ScreenHandlerType; diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java index 0cdab2f..bbef5b0 100644 --- a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java @@ -6,8 +6,8 @@ import io.github.skippyall.minions.input.TextInput; import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.minion.MinionItem; import io.github.skippyall.minions.minion.MinionProfileUtils; -import net.minecraft.block.PlayerSkullBlock; -import net.minecraft.block.entity.SkullBlockEntity; +import io.github.skippyall.minions.minion.skin.SkinProvider; +import io.github.skippyall.minions.minion.skin.SkinProviders; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.ProfileComponent; import net.minecraft.item.ItemStack; @@ -20,10 +20,18 @@ import java.util.Optional; public class MinionLookGui extends SimpleGui { private ItemStack minionItem; + private SkinProvider currentSkinProvider; public MinionLookGui(ServerPlayerEntity player, ItemStack minionItem) { super(ScreenHandlerType.GENERIC_9X3, player, false); this.minionItem = minionItem; + this.currentSkinProvider = SkinProviders.NAME; + } + + public void update() { + updateName(); + updateSkin(); + updateSkinProvider(); } private void updateName() { @@ -37,45 +45,50 @@ public class MinionLookGui extends SimpleGui { } private void updateSkin() { - setSlot(16, new GuiElementBuilder() + GuiElementBuilder builder = new GuiElementBuilder() .setItem(Items.PLAYER_HEAD) - ); - - getData().getSkin(player.server).thenAccept(skin -> { - setSlot(16, new GuiElementBuilder() - .setItem(Items.PLAYER_HEAD) - .setComponent(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.empty(), skin)) - .setCallback(this::cycleSkinProvider) - ); - }); + .setCallback(() -> currentSkinProvider.openSkinMenu(player).thenAccept(skin -> { + MinionItem.setData(getData().withSkin(skin), minionItem); + })); + if(MinionItem.getData(minionItem) != null && MinionItem.getData(minionItem).skin().isPresent()) { + builder.setComponent(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.empty(), getData().skin().get())); + } + setSlot(16, builder); } private void cycleSkinProvider() { + int currentId = SkinProviders.SKIN_PROVIDERS.getRawId(currentSkinProvider); + currentId++; + if(SkinProviders.SKIN_PROVIDERS.size() == currentId) { + currentId = 0; + } + currentSkinProvider = SkinProviders.SKIN_PROVIDERS.get(currentId); + updateSkinProvider(); } private void updateSkinProvider() { setSlot(25, new GuiElementBuilder() .setItem(Items.GREEN_STAINED_GLASS_PANE) - .setComponent(DataComponentTypes.CUSTOM_NAME, Text.literal()) + .setComponent(DataComponentTypes.CUSTOM_NAME, currentSkinProvider.getDisplayName()) + .setCallback(this::cycleSkinProvider) ); - updateSkin(); } private MinionData getData() { - return MinionItem.getData(minionItem); + return MinionItem.getDataOrDefault(minionItem); } public static void open(ServerPlayerEntity player, ItemStack minionItem) { MinionLookGui gui = new MinionLookGui(player, minionItem); - + gui.update(); gui.open(); } public void openRenameGui(ServerPlayerEntity player, ItemStack minionItem) { - TextInput.input(player, Text.translatable("minions.gui.look.rename.title"), "Minion", MinionProfileUtils::checkMinionName) + TextInput.inputSync(player, Text.translatable("minions.gui.look.rename.title"), "Minion", MinionProfileUtils::checkMinionNameWithoutPrefix) .thenAccept(name -> { - MinionItem.setData(MinionItem.getDataOrDefault(minionItem).withName(name), minionItem); + MinionItem.setData(getData().withName(MinionProfileUtils.PREFIX + name), minionItem); open(); }); } diff --git a/src/main/java/io/github/skippyall/minions/gui/ModuleInventory.java b/src/main/java/io/github/skippyall/minions/gui/ModuleInventory.java index 470e80e..97eb479 100644 --- a/src/main/java/io/github/skippyall/minions/gui/ModuleInventory.java +++ b/src/main/java/io/github/skippyall/minions/gui/ModuleInventory.java @@ -1,6 +1,6 @@ package io.github.skippyall.minions.gui; -import io.github.skippyall.minions.command.Command; +import io.github.skippyall.minions.module.command.Command; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.module.ModuleItem; import io.github.skippyall.minions.program.block.CodeBlock; diff --git a/src/main/java/io/github/skippyall/minions/input/TextInput.java b/src/main/java/io/github/skippyall/minions/input/TextInput.java index d92cb86..1ad03d5 100644 --- a/src/main/java/io/github/skippyall/minions/input/TextInput.java +++ b/src/main/java/io/github/skippyall/minions/input/TextInput.java @@ -9,6 +9,7 @@ import net.minecraft.text.Text; import java.util.concurrent.CompletableFuture; import java.util.function.Function; +import java.util.function.Predicate; public class TextInput extends AnvilInputGui { private final GuiElementBuilder valid = new GuiElementBuilder() @@ -18,11 +19,11 @@ public class TextInput extends AnvilInputGui { private final GuiElementBuilder invalid = new GuiElementBuilder() .setItem(Items.REDSTONE_BLOCK); - private final Function> parser; + private final Function>> parser; private final CompletableFuture future; private Result result; - public TextInput(ServerPlayerEntity player, Text title, String defaultValue, Function> parser, CompletableFuture future) { + public TextInput(ServerPlayerEntity player, Text title, String defaultValue, Function>> parser, CompletableFuture future) { super(player, false); setTitle(title); setDefaultInputValue(defaultValue); @@ -32,18 +33,26 @@ public class TextInput extends AnvilInputGui { updateConfirmButton(defaultValue); } - public static CompletableFuture input(ServerPlayerEntity player, Text title, String defaultValue, Function> parser) { + public static CompletableFuture inputSync(ServerPlayerEntity player, Text title, String defaultValue, Function> parser) { + return input(player, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string))); + } + + public static CompletableFuture input(ServerPlayerEntity player, Text title, String defaultValue, Function>> parser) { CompletableFuture future = new CompletableFuture<>(); new TextInput<>(player, title, defaultValue, parser, future).open(); return future; } + public static CompletableFuture inputString(ServerPlayerEntity player, Text title, String defaultValue) { + return inputSync(player, title, defaultValue, Result.Success::new); + } + public static CompletableFuture inputInt(ServerPlayerEntity player, Text title, String defaultValue) { - return input(player, title, defaultValue, string -> Result.wrapCustomError(() -> Integer.valueOf(string), Text.translatable("minions.command.input.int.fail"))); + return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Integer.valueOf(string), Text.translatable("minions.command.input.int.fail"))); } public static CompletableFuture inputFloat(ServerPlayerEntity player, Text title, String defaultValue) { - return input(player, title, defaultValue, string -> Result.wrapCustomError(() -> Float.valueOf(string), Text.translatable("minions.command.input.float.fail"))); + return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Float.valueOf(string), Text.translatable("minions.command.input.float.fail"))); } @Override @@ -52,13 +61,15 @@ public class TextInput extends AnvilInputGui { } public void updateConfirmButton(String input) { - result = parser.apply(input); - if(result.isSuccess()) { - setSlot(AnvilScreenHandler.OUTPUT_ID, valid); - } else { - Text text = result.getErrorOrThrow(); - setSlot(AnvilScreenHandler.OUTPUT_ID, invalid.setName(text)); - } + parser.apply(input).thenAccept(result -> { + this.result = result; + if(result.isSuccess()) { + setSlot(AnvilScreenHandler.OUTPUT_ID, valid); + } else { + Text text = result.getErrorOrThrow(); + setSlot(AnvilScreenHandler.OUTPUT_ID, invalid.setName(text)); + } + }); } @Override @@ -69,9 +80,11 @@ public class TextInput extends AnvilInputGui { } public void onConfirm() { - result.ifSuccess(success -> { - future.complete(success); - close(); - }); + if(result != null) { + result.ifSuccess(success -> { + future.complete(success); + close(); + }); + } } } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionData.java b/src/main/java/io/github/skippyall/minions/minion/MinionData.java index c386766..35235e8 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionData.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionData.java @@ -6,27 +6,25 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import eu.pb4.polymer.core.api.other.PolymerComponent; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.minion.skin.SkinProvider; -import io.github.skippyall.minions.minion.skin.SkinProviders; import net.minecraft.component.ComponentType; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtOps; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; -import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; import net.minecraft.util.Uuids; +import net.minecraft.util.dynamic.Codecs; import org.jetbrains.annotations.Nullable; +import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CompletableFuture; -public record MinionData(UUID uuid, String name, @Nullable SkinProvider skin, boolean isSpawned) { +public record MinionData(UUID uuid, String name, Optional skin, boolean isSpawned) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Uuids.CODEC.fieldOf("uuid").forGetter(MinionData::uuid), Codec.STRING.fieldOf("name").forGetter(MinionData::name), - SkinProviders.CODEC.optionalFieldOf("skin", null).forGetter(MinionData::skin), + Codecs.GAME_PROFILE_PROPERTY_MAP.optionalFieldOf("skin").forGetter(MinionData::skin), Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned) ).apply(instance, MinionData::new) ); @@ -34,7 +32,7 @@ public record MinionData(UUID uuid, String name, @Nullable SkinProvider skin, bo public static final ComponentType COMPONENT = Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, "minion_data"), ComponentType.builder().codec(Uuids.CODEC).build()); public static MinionData createDefault() { - return new MinionData(UUID.randomUUID(), "Minion", null, false); + return new MinionData(UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(), Optional.empty(), false); } public MinionData withUuid(UUID uuid) { @@ -45,17 +43,10 @@ public record MinionData(UUID uuid, String name, @Nullable SkinProvider skin, bo return new MinionData(uuid, name, skin, isSpawned); } - public MinionData withSkin(@Nullable SkinProvider skin) { + public MinionData withSkin(Optional skin) { return new MinionData(uuid, name, skin, isSpawned); } - public CompletableFuture<@Nullable PropertyMap> getSkin(MinecraftServer server) { - if(skin != null) { - return skin.getSkin(server); - } - return CompletableFuture.completedFuture(null); - } - public MinionData withSpawned(boolean isSpawned) { return new MinionData(uuid, name, skin, isSpawned); } 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 3f10cb8..ca5bdbe 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionItem.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionItem.java @@ -2,18 +2,23 @@ package io.github.skippyall.minions.minion; import eu.pb4.polymer.core.api.item.PolymerItem; import eu.pb4.polymer.core.api.item.PolymerItemUtils; +import io.github.skippyall.minions.gui.MinionLookGui; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import net.minecraft.component.DataComponentTypes; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.Items; import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec2f; +import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import xyz.nucleoid.packettweaker.PacketContext; @@ -49,6 +54,17 @@ public class MinionItem extends Item implements PolymerItem { } } + @Override + public ActionResult use(World world, PlayerEntity user, Hand hand) { + if(user instanceof ServerPlayerEntity serverPlayer) { + ItemStack stack = user.getStackInHand(hand); + MinionLookGui.open(serverPlayer, stack); + return ActionResult.SUCCESS; + } + + return ActionResult.SUCCESS_SERVER; + } + @Override public ActionResult useOnBlock(ItemUsageContext context) { if(!context.getWorld().isClient) { @@ -61,6 +77,7 @@ public class MinionItem extends Item implements PolymerItem { public static void setData(MinionData data, ItemStack item) { item.set(MinionData.COMPONENT, data.uuid()); + MinionPersistentState.INSTANCE.updateMinionData(data); } @Nullable @@ -75,6 +92,7 @@ public class MinionItem extends Item implements PolymerItem { MinionData data = getData(item); if(data == null) { data = MinionData.createDefault(); + setData(data, item); } return 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 638dfbb..f84aa44 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java @@ -18,7 +18,6 @@ public class MinionPersistentState extends PersistentState { public static MinionPersistentState INSTANCE; private final Map minionData = new HashMap<>(); - //private final List minionUuids = new ArrayList<>(); @Override public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { @@ -28,13 +27,6 @@ public class MinionPersistentState extends PersistentState { } nbt.put("minions", list); - /*NbtList uuids = new NbtList(); - for(UUID uuid : minionUuids) { - NbtCompound compound = new NbtCompound(); - compound.putUuid("uuid", uuid); - uuids.add(compound); - } - nbt.put("uuids", uuids);*/ return nbt; } @@ -43,39 +35,13 @@ public class MinionPersistentState extends PersistentState { MinionPersistentState instance = new MinionPersistentState(); for(NbtElement element : list) { if(element instanceof NbtCompound compound1) { - MinionData data = MinionData.readNbt((NbtCompound) element); + MinionData data = MinionData.readNbt(compound1); instance.minionData.put(data.uuid(), data); } } - - /*NbtList uuids = compound.getList("uuids", NbtElement.COMPOUND_TYPE); - for(NbtElement element : uuids) { - instance.minionUuids.add(((NbtCompound) element).getUuid("uuid")); - }*/ return instance; } - /*public void addMinionUUID(UUID uuid) { - if(!minionUuids.contains(uuid)) { - minionUuids.add(uuid); - } - }*/ - - public void addMinion(MinionData data) { - System.out.println("add Minion " + data.name()); - minionData.put(data.uuid(), data); - markDirty(); - } - - public void removeMinion(MinionData minionData) { - removeMinion(minionData.uuid()); - } - - public void removeMinion(UUID minionUUID) { - minionData.remove(minionUUID); - markDirty(); - } - public MinionData getMinionData(UUID uuid) { return minionData.get(uuid); } @@ -86,12 +52,17 @@ public class MinionPersistentState extends PersistentState { public void updateMinionData(MinionData data) { minionData.put(data.uuid(), data); + markDirty(); } public boolean isMinion(UUID uuid) { return minionData.containsKey(uuid); } + public boolean isMinionNameTaken(String name) { + return minionData.values().stream().anyMatch(data -> data.name().equals(name)); + } + public static void create(MinecraftServer server) { INSTANCE = server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE, "minion"); } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionProfileUtils.java b/src/main/java/io/github/skippyall/minions/minion/MinionProfileUtils.java index 6fc51ef..799f0bd 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionProfileUtils.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionProfileUtils.java @@ -4,7 +4,9 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.yggdrasil.ProfileResult; +import com.mojang.brigadier.StringReader; import io.github.skippyall.minions.input.Result; +import net.minecraft.block.entity.SkullBlockEntity; import net.minecraft.server.MinecraftServer; import net.minecraft.text.Text; import net.minecraft.util.StringHelper; @@ -17,54 +19,7 @@ import java.util.concurrent.ForkJoinPool; import static io.github.skippyall.minions.Minions.LOGGER; public class MinionProfileUtils { - public static final String PREFIX = "#"; - - public static CompletableFuture<@Nullable GameProfile> lookupSkinOwnerProfile(MinecraftServer server, String username) { - CompletableFuture future = new CompletableFuture<>(); - - ForkJoinPool.commonPool().execute(() -> { - try { - server.getGameProfileRepo().findProfilesByNames(new String[]{username}, new ProfileLookupCallback() { - @Override - public void onProfileLookupSucceeded(GameProfile found) { - LOGGER.info("SkinProfile: {}", found); - try { - getSkinOwnerProfile(server, found.getId()).thenAccept(future::complete); - } catch (Throwable ex) { - LOGGER.warn("Exception during Game Profile creation", ex); - } - } - - @Override - public void onProfileLookupFailed(String profileName, Exception exception) { - LOGGER.warn("Lookup Error: ", exception); - future.complete(null); - } - }); - } catch (Throwable e) { - LOGGER.warn("Failed to get UUID for username " + username, e); - future.complete(null); - } - }); - - return future; - } - - public static CompletableFuture<@Nullable GameProfile> getSkinOwnerProfile(MinecraftServer server, @Nullable UUID uuid) { - CompletableFuture future = new CompletableFuture<>(); - future.completeAsync(() -> { - GameProfile profile = null; - if(uuid != null) { - ProfileResult result = server.getSessionService().fetchProfile(uuid, true); - if (result != null) { - profile = result.profile(); - LOGGER.info("Full SkinProfile: {}", profile); - } - } - return profile; - }); - return future; - } + public static final String PREFIX = "+"; public static GameProfile makeNewMinionProfile(UUID uuidMinion, String username, PropertyMap skin) { if(uuidMinion == null) { @@ -79,16 +34,34 @@ public class MinionProfileUtils { return newProfile; } - public static Result checkMinionName(String name) { - if(StringHelper.isValidPlayerName(PREFIX + name)) { - return new Result.Success<>(name); - } else { - return new Result.Error<>(Text.translatable("minions.generic.minion_name_too_long")); + public static Result checkMinionNameWithoutPrefix(String name) { + for(char c : name.toCharArray()) { + if(!StringReader.isAllowedInUnquotedString(c)) { + return new Result.Error<>(Text.translatable("minions.generic.name.invalid_char")); + } } + + if((PREFIX + name).length() > 16) { + return new Result.Error<>(Text.translatable("minions.generic.name.too_long")); + } + + if(!StringHelper.isValidPlayerName(PREFIX + name)) { + return new Result.Error<>(Text.translatable("minions.generic.name.invalid")); + } + + if(MinionPersistentState.INSTANCE.isMinionNameTaken(PREFIX + name)) { + return new Result.Error<>(Text.translatable("minions.generic.name.taken")); + } + + return new Result.Success<>(name); } - public static boolean isValidMinionName(String name) { - return checkMinionName(name).isSuccess(); + public static String newDefaultMinionName() { + int i = 0; + while (MinionPersistentState.INSTANCE.isMinionNameTaken("+Minion" + i)) { + i++; + } + return "+Minion" + i; } public static boolean isMinion(UUID uuid) { 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 9295eba..4c1986f 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 @@ -58,22 +58,22 @@ public class MinionFakePlayer extends ServerPlayerEntity { private final ModuleInventory moduleInventory = new ModuleInventory(); private final MinionRuntime runtime = new MinionRuntime(this); - private MinionData data; + private final MinionData data; public static void spawnMinion(MinionData data, ServerWorld level, @Nullable Vec3d pos, @Nullable Vec2f rot) { MinecraftServer server = level.getServer(); - CompletableFuture future = data.getSkin(server); + PropertyMap skin = data.skin().orElse(null); + + GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.uuid(), data.name(), skin); + doSpawn(data, profile, server, level, pos, rot); - future.thenAccept((skin) -> { - GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.uuid(), data.name(), skin); - MinionsTickExecutor.addExecuteOnNextTick(() -> doSpawn(data, profile, server, level, pos, rot)); - }); } private static void doSpawn(MinionData data, GameProfile profile, MinecraftServer server, ServerWorld level, @Nullable Vec3d pos, @Nullable Vec2f rot) { - MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, SyncedClientOptions.createDefault()); + MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, SyncedClientOptions.createDefault(), data); + MinionPersistentState.INSTANCE.updateMinionData(data.withSpawned(true)); if(pos != null && rot != null) { instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, rot.x, rot.y); @@ -95,14 +95,15 @@ public class MinionFakePlayer extends ServerPlayerEntity { instance.getAbilities().flying = false; } - public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli) + public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli, MinionData data) { - return new MinionFakePlayer(server, level, profile, cli); + return new MinionFakePlayer(server, level, profile, cli, data); } - private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli) + private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli, MinionData data) { super(server, worldIn, profile, cli); + this.data = data; } public boolean isProgrammable() { @@ -162,9 +163,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { })); } - data.withSpawned(false); - - MinionPersistentState.INSTANCE.updateMinionData(data); + MinionPersistentState.INSTANCE.updateMinionData(data.withSpawned(false)); } @Override @@ -291,6 +290,10 @@ public class MinionFakePlayer extends ServerPlayerEntity { return stack; } + public MinionData getData() { + return data; + } + @Override public void writeCustomDataToNbt(NbtCompound nbt) { super.writeCustomDataToNbt(nbt); diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/Base64SkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/Base64SkinProvider.java new file mode 100644 index 0000000..6251307 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/minion/skin/Base64SkinProvider.java @@ -0,0 +1,27 @@ +package io.github.skippyall.minions.minion.skin; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import io.github.skippyall.minions.input.TextInput; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +public class Base64SkinProvider implements SkinProvider { + @Override + public CompletableFuture> openSkinMenu(ServerPlayerEntity player) { + return TextInput.inputString(player, Text.translatable("minions.gui.look.skin.base64.title"), "") + .thenApply(base64String -> { + PropertyMap map = new PropertyMap(); + map.put("textures", new Property("textures", base64String)); + return Optional.of(map); + }); + } + + @Override + public Text getDisplayName() { + return Text.translatable("minions.gui.look.skin.base64"); + } +} diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/CachedSkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/CachedSkinProvider.java deleted file mode 100644 index bb3f61d..0000000 --- a/src/main/java/io/github/skippyall/minions/minion/skin/CachedSkinProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.skippyall.minions.minion.skin; - -import com.mojang.authlib.properties.PropertyMap; -import net.minecraft.server.MinecraftServer; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.CompletableFuture; - -public abstract class CachedSkinProvider implements SkinProvider { - private @Nullable PropertyMap cache = null; - - protected CachedSkinProvider(@Nullable PropertyMap cache) { - this.cache = cache; - } - - public abstract CompletableFuture<@Nullable PropertyMap> fetchSkin(MinecraftServer server); - - public @Nullable PropertyMap getCache() { - return cache; - } - - public CompletableFuture<@Nullable PropertyMap> updateCache(MinecraftServer server) { - CompletableFuture future = fetchSkin(server); - future.thenAccept(result -> { - this.cache = result; - }); - return future; - } - - @Override - public CompletableFuture<@Nullable PropertyMap> getSkin(MinecraftServer server) { - CompletableFuture future = new CompletableFuture<>(); - if(cache == null) { - fetchSkin(server).thenAccept(skin -> { - cache = skin; - future.complete(skin); - }); - } - return CompletableFuture.completedFuture(cache); - } -} diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/DirectSkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/DirectSkinProvider.java deleted file mode 100644 index 1c5a6a2..0000000 --- a/src/main/java/io/github/skippyall/minions/minion/skin/DirectSkinProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.github.skippyall.minions.minion.skin; - -import com.mojang.authlib.properties.PropertyMap; -import com.mojang.serialization.Codec; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.dynamic.Codecs; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.CompletableFuture; - -public class DirectSkinProvider implements SkinProvider { - private final PropertyMap propertyMap; - - public static final Codec CODEC = Codecs.GAME_PROFILE_PROPERTY_MAP.xmap(DirectSkinProvider::new, DirectSkinProvider::getPropertyMap); - - public DirectSkinProvider(PropertyMap propertyMap) { - this.propertyMap = propertyMap; - } - - public PropertyMap getPropertyMap() { - return propertyMap; - } - - @Override - public CompletableFuture<@Nullable PropertyMap> getSkin(MinecraftServer server) { - return CompletableFuture.completedFuture(propertyMap); - } - - @Override - public Codec getCodec() { - return null; - } -} 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 cc65161..9b0d6a2 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 @@ -1,43 +1,25 @@ package io.github.skippyall.minions.minion.skin; +import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.PropertyMap; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.skippyall.minions.minion.MinionProfileUtils; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.dynamic.Codecs; -import org.jetbrains.annotations.Nullable; +import io.github.skippyall.minions.input.TextInput; +import net.minecraft.block.entity.SkullBlockEntity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import java.util.Optional; import java.util.concurrent.CompletableFuture; -public class NameSkinProvider extends CachedSkinProvider { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codec.STRING.fieldOf("name").forGetter(NameSkinProvider::getName), - Codecs.GAME_PROFILE_PROPERTY_MAP.optionalFieldOf("cache", null).forGetter(NameSkinProvider::getCache) - ).apply(instance, NameSkinProvider::new)); - - private final String name; - - public NameSkinProvider(String name, @Nullable PropertyMap cache) { - super(cache); - this.name = name; - } - - public NameSkinProvider(String name) { - this(name, null); - } - - public String getName() { - return name; +public class NameSkinProvider implements SkinProvider { + @Override + public CompletableFuture> openSkinMenu(ServerPlayerEntity player) { + return TextInput.inputString(player, Text.translatable("minions.gui.look.skin.name.title"), "") + .thenCompose(SkullBlockEntity::fetchProfileByName) + .thenApply(gameProfile -> gameProfile.map(GameProfile::getProperties)); } @Override - public CompletableFuture fetchSkin(MinecraftServer server) { - return MinionProfileUtils.lookupSkinOwnerProfile(server, name).thenApply(gameProfile -> gameProfile != null ? gameProfile.getProperties() : null); - } - - @Override - public Codec getCodec() { - return null; + public Text getDisplayName() { + return Text.translatable("minions.gui.look.skin.name"); } } diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/SkinProvider.java b/src/main/java/io/github/skippyall/minions/minion/skin/SkinProvider.java index f65d208..9068ecc 100644 --- a/src/main/java/io/github/skippyall/minions/minion/skin/SkinProvider.java +++ b/src/main/java/io/github/skippyall/minions/minion/skin/SkinProvider.java @@ -1,14 +1,14 @@ package io.github.skippyall.minions.minion.skin; import com.mojang.authlib.properties.PropertyMap; -import com.mojang.serialization.Codec; -import net.minecraft.server.MinecraftServer; -import org.jetbrains.annotations.Nullable; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import java.util.Optional; import java.util.concurrent.CompletableFuture; public interface SkinProvider { - CompletableFuture<@Nullable PropertyMap> getSkin(MinecraftServer server); + CompletableFuture> openSkinMenu(ServerPlayerEntity player); - Codec getCodec(); + Text getDisplayName(); } diff --git a/src/main/java/io/github/skippyall/minions/minion/skin/SkinProviders.java b/src/main/java/io/github/skippyall/minions/minion/skin/SkinProviders.java index 6164061..06f230d 100644 --- a/src/main/java/io/github/skippyall/minions/minion/skin/SkinProviders.java +++ b/src/main/java/io/github/skippyall/minions/minion/skin/SkinProviders.java @@ -1,6 +1,5 @@ package io.github.skippyall.minions.minion.skin; -import com.mojang.serialization.Codec; import com.mojang.serialization.Lifecycle; import io.github.skippyall.minions.Minions; import net.minecraft.registry.Registry; @@ -9,18 +8,18 @@ import net.minecraft.registry.SimpleRegistry; import net.minecraft.util.Identifier; public class SkinProviders { - public static final Registry> REGISTRY = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, "skin_providers")), Lifecycle.stable()); + public static final Registry SKIN_PROVIDERS = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, "skin_providers")), Lifecycle.stable()); - public static final Codec CODEC = REGISTRY.getCodec().dispatchStable(SkinProvider::getCodec, codec -> codec.fieldOf("data")); + public static NameSkinProvider NAME = register(new NameSkinProvider(), "name"); + public static UUIDSkinProvider UUID = register(new UUIDSkinProvider(), "uuid"); + public static Base64SkinProvider BASE64 = register(new Base64SkinProvider(), "base64"); - public static > T register(T skinProvider, Identifier id) { - Registry.register(REGISTRY, id, skinProvider); - return skinProvider; + + public static T register(T skinProvider, String path) { + return Registry.register(SKIN_PROVIDERS, Identifier.of(Minions.MOD_ID, path), skinProvider); } public static void register() { - register(UUIDSkinProvider.CODEC, Identifier.of(Minions.MOD_ID, "uuid")); - register(NameSkinProvider.CODEC, Identifier.of(Minions.MOD_ID, "name")); - register(DirectSkinProvider.CODEC, Identifier.of(Minions.MOD_ID, "direct")); + } } 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 e51d0e1..520957c 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 @@ -1,51 +1,32 @@ package io.github.skippyall.minions.minion.skin; +import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.PropertyMap; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.github.skippyall.minions.input.TextInput; import io.github.skippyall.minions.minion.MinionProfileUtils; +import net.minecraft.block.entity.SkullBlockEntity; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; import net.minecraft.util.Uuids; import net.minecraft.util.dynamic.Codecs; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class UUIDSkinProvider extends CachedSkinProvider { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - Codecs.GAME_PROFILE_PROPERTY_MAP.optionalFieldOf("cache", null).forGetter(CachedSkinProvider::getCache), - Uuids.CODEC.fieldOf("uuid").forGetter(UUIDSkinProvider::getUuid) - ).apply(instance, UUIDSkinProvider::new)); - - private final UUID uuid; - - public UUIDSkinProvider(UUID uuid) { - this(null, uuid); - } - - public UUIDSkinProvider(PropertyMap cache, UUID uuid) { - super(cache); - this.uuid = uuid; - } - - public UUID getUuid() { - return uuid; +public class UUIDSkinProvider implements SkinProvider { + @Override + public CompletableFuture> openSkinMenu(ServerPlayerEntity player) { + return TextInput.inputString(player, Text.translatable("minions.gui.look.skin.uuid.title"), "") + .thenCompose(uuidString -> SkullBlockEntity.fetchProfileByUuid(UUID.fromString(uuidString))) + .thenApply(gameProfile -> gameProfile.map(GameProfile::getProperties)); } @Override - public CompletableFuture fetchSkin(MinecraftServer server) { - return MinionProfileUtils.getSkinOwnerProfile(server, uuid).thenApply(gameProfile -> { - if (gameProfile != null) { - return gameProfile.getProperties(); - } else { - return null; - } - }); - } - - @Override - public Codec getCodec() { - return CODEC; + public Text getDisplayName() { + return Text.translatable("minions.gui.look.skin.uuid"); } } diff --git a/src/main/java/io/github/skippyall/minions/mixins/EntityViewMixin.java b/src/main/java/io/github/skippyall/minions/mixins/EntityViewMixin.java index 22e55cf..2663699 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/EntityViewMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/EntityViewMixin.java @@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; import java.util.function.Predicate; @Mixin(EntityView.class) -public class EntityViewMixin { +public interface EntityViewMixin { @ModifyArg(method = "getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/EntityView;getClosestPlayer(DDDDLjava/util/function/Predicate;)Lnet/minecraft/entity/player/PlayerEntity;")) private @Nullable Predicate addMinionPredicate(@Nullable Predicate targetPredicate) { Predicate predicate = EntityViewMixinHelper.ADDITIONAL_PREDICATE.get(); 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 e364629..8ff9d69 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java @@ -52,7 +52,7 @@ public class PlayerListMixin { @WrapOperation(method = "respawnPlayer", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/server/world/ServerWorld;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/packet/c2s/common/SyncedClientOptions;)Lnet/minecraft/server/network/ServerPlayerEntity;")) public ServerPlayerEntity makePlayerForRespawn(MinecraftServer minecraftServer, ServerWorld serverLevel, GameProfile gameProfile, SyncedClientOptions clientInformation, Operation original, ServerPlayerEntity serverPlayer, boolean bl) { if (serverPlayer instanceof MinionFakePlayer minion) { - return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation); + return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation, minion.getData()); } return original.call(minecraftServer, serverLevel, gameProfile, clientInformation); } diff --git a/src/main/java/io/github/skippyall/minions/module/ActionModules.java b/src/main/java/io/github/skippyall/minions/module/ActionModules.java index 2d90f9a..6c13e7b 100644 --- a/src/main/java/io/github/skippyall/minions/module/ActionModules.java +++ b/src/main/java/io/github/skippyall/minions/module/ActionModules.java @@ -2,7 +2,7 @@ package io.github.skippyall.minions.module; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; -import io.github.skippyall.minions.command.CommandExecutor; +import io.github.skippyall.minions.module.command.CommandExecutor; import io.github.skippyall.minions.input.TextInput; import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; diff --git a/src/main/java/io/github/skippyall/minions/module/AttackModule.java b/src/main/java/io/github/skippyall/minions/module/AttackModule.java index 7dc1557..5f18ff1 100644 --- a/src/main/java/io/github/skippyall/minions/module/AttackModule.java +++ b/src/main/java/io/github/skippyall/minions/module/AttackModule.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.command.SimpleCommand; +import io.github.skippyall.minions.module.command.SimpleCommand; import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import net.minecraft.item.Items; import net.minecraft.text.Text; diff --git a/src/main/java/io/github/skippyall/minions/module/ChatModule.java b/src/main/java/io/github/skippyall/minions/module/ChatModule.java index 6ea8d0c..a541598 100644 --- a/src/main/java/io/github/skippyall/minions/module/ChatModule.java +++ b/src/main/java/io/github/skippyall/minions/module/ChatModule.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.command.SimpleCommand; +import io.github.skippyall.minions.module.command.SimpleCommand; import net.minecraft.item.Items; import net.minecraft.text.Text; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/module/InteractModule.java b/src/main/java/io/github/skippyall/minions/module/InteractModule.java index 3bd9169..fc5aa3a 100644 --- a/src/main/java/io/github/skippyall/minions/module/InteractModule.java +++ b/src/main/java/io/github/skippyall/minions/module/InteractModule.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.command.SimpleCommand; +import io.github.skippyall.minions.module.command.SimpleCommand; import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import net.minecraft.item.Items; import net.minecraft.text.Text; diff --git a/src/main/java/io/github/skippyall/minions/module/ModuleItem.java b/src/main/java/io/github/skippyall/minions/module/ModuleItem.java index a2a21e1..b91091b 100644 --- a/src/main/java/io/github/skippyall/minions/module/ModuleItem.java +++ b/src/main/java/io/github/skippyall/minions/module/ModuleItem.java @@ -1,6 +1,6 @@ package io.github.skippyall.minions.module; -import io.github.skippyall.minions.command.Command; +import io.github.skippyall.minions.module.command.Command; import io.github.skippyall.minions.program.block.CodeBlock; import net.minecraft.item.ItemConvertible; diff --git a/src/main/java/io/github/skippyall/minions/module/Modules.java b/src/main/java/io/github/skippyall/minions/module/Modules.java index b6cbe34..1e465b2 100644 --- a/src/main/java/io/github/skippyall/minions/module/Modules.java +++ b/src/main/java/io/github/skippyall/minions/module/Modules.java @@ -1,6 +1,6 @@ package io.github.skippyall.minions.module; -import io.github.skippyall.minions.command.Command; +import io.github.skippyall.minions.module.command.Command; import io.github.skippyall.minions.program.block.CodeBlock; import net.minecraft.item.Item; import net.minecraft.registry.Registries; diff --git a/src/main/java/io/github/skippyall/minions/module/MountModule.java b/src/main/java/io/github/skippyall/minions/module/MountModule.java index 0ba460c..6c23f16 100644 --- a/src/main/java/io/github/skippyall/minions/module/MountModule.java +++ b/src/main/java/io/github/skippyall/minions/module/MountModule.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.command.SimpleCommand; +import io.github.skippyall.minions.module.command.SimpleCommand; import net.minecraft.item.Items; import net.minecraft.text.Text; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/module/MoveModule.java b/src/main/java/io/github/skippyall/minions/module/MoveModule.java index 9fb99c3..5c251a7 100644 --- a/src/main/java/io/github/skippyall/minions/module/MoveModule.java +++ b/src/main/java/io/github/skippyall/minions/module/MoveModule.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.command.SimpleCommand; +import io.github.skippyall.minions.module.command.SimpleCommand; import io.github.skippyall.minions.input.TextInput; import net.minecraft.item.Items; import net.minecraft.text.Text; diff --git a/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java b/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java index ef2863c..1071998 100644 --- a/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java +++ b/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.module; import eu.pb4.polymer.core.api.item.SimplePolymerItem; -import io.github.skippyall.minions.command.Command; +import io.github.skippyall.minions.module.command.Command; import io.github.skippyall.minions.program.block.CodeBlock; import net.minecraft.item.Item; diff --git a/src/main/java/io/github/skippyall/minions/command/Command.java b/src/main/java/io/github/skippyall/minions/module/command/Command.java similarity index 79% rename from src/main/java/io/github/skippyall/minions/command/Command.java rename to src/main/java/io/github/skippyall/minions/module/command/Command.java index 29b06e6..b056bad 100644 --- a/src/main/java/io/github/skippyall/minions/command/Command.java +++ b/src/main/java/io/github/skippyall/minions/module/command/Command.java @@ -1,4 +1,4 @@ -package io.github.skippyall.minions.command; +package io.github.skippyall.minions.module.command; import net.minecraft.item.Item; import net.minecraft.text.Text; diff --git a/src/main/java/io/github/skippyall/minions/command/CommandExecutor.java b/src/main/java/io/github/skippyall/minions/module/command/CommandExecutor.java similarity index 81% rename from src/main/java/io/github/skippyall/minions/command/CommandExecutor.java rename to src/main/java/io/github/skippyall/minions/module/command/CommandExecutor.java index f46b48f..603d341 100644 --- a/src/main/java/io/github/skippyall/minions/command/CommandExecutor.java +++ b/src/main/java/io/github/skippyall/minions/module/command/CommandExecutor.java @@ -1,4 +1,4 @@ -package io.github.skippyall.minions.command; +package io.github.skippyall.minions.module.command; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import net.minecraft.server.network.ServerPlayerEntity; diff --git a/src/main/java/io/github/skippyall/minions/command/SimpleCommand.java b/src/main/java/io/github/skippyall/minions/module/command/SimpleCommand.java similarity index 95% rename from src/main/java/io/github/skippyall/minions/command/SimpleCommand.java rename to src/main/java/io/github/skippyall/minions/module/command/SimpleCommand.java index 5a5f926..dc7708d 100644 --- a/src/main/java/io/github/skippyall/minions/command/SimpleCommand.java +++ b/src/main/java/io/github/skippyall/minions/module/command/SimpleCommand.java @@ -1,4 +1,4 @@ -package io.github.skippyall.minions.command; +package io.github.skippyall.minions.module.command; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import net.minecraft.item.Item; diff --git a/src/main/resources/data/minions/lang/en_us.json b/src/main/resources/data/minions/lang/en_us.json index 2ce3c2d..c64504c 100644 --- a/src/main/resources/data/minions/lang/en_us.json +++ b/src/main/resources/data/minions/lang/en_us.json @@ -8,6 +8,13 @@ "minions.gui.commands.title": "%s's Commands", "minions.gui.modules.title": "%s's Modules", "minions.gui.ok": "OK", + "minions.gui.look.skin.name": "Name", + "minions.gui.look.skin.name.title": "Enter a player name", + "minions.gui.look.skin.uuid": "UUID", + "minions.gui.look.skin.uuid.title": "Enter a player UUID", + "minions.gui.look.skin.base64": "Base64", + "minions.gui.look.skin.base64.title": "Enter a skin in base64 encoding", + "minions.gui.look.rename.title": "Enter a name", "minions.command.input.int.fail": "Not an integer", "minions.command.input.float.fail": "Not a number", @@ -31,5 +38,9 @@ "item.minions.basic_upgrade_base": "Basic Upgrade Base", "item.minions.advanced_upgrade_base": "Advanced Upgrade Base", - "minions.minion_item.tooltip": "Name: %s" + "minions.minion_item.tooltip": "Name: %s", + "minions.generic.name.invalid_char": "Name contains invalid character", + "minions.generic.name.too_long": "Name is too long", + "minions.generic.name.invalid": "Name is invalid", + "minions.generic.name.taken": "This name is already used" } \ No newline at end of file