Skin Improvements
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<T> extends AnvilInputGui {
|
||||
private final GuiElementBuilder valid = new GuiElementBuilder()
|
||||
@@ -18,11 +19,11 @@ public class TextInput<T> extends AnvilInputGui {
|
||||
|
||||
private final GuiElementBuilder invalid = new GuiElementBuilder()
|
||||
.setItem(Items.REDSTONE_BLOCK);
|
||||
private final Function<String, Result<T, Text>> parser;
|
||||
private final Function<String, CompletableFuture<Result<T, Text>>> parser;
|
||||
private final CompletableFuture<T> future;
|
||||
private Result<T, Text> result;
|
||||
|
||||
public TextInput(ServerPlayerEntity player, Text title, String defaultValue, Function<String, Result<T, Text>> parser, CompletableFuture<T> future) {
|
||||
public TextInput(ServerPlayerEntity player, Text title, String defaultValue, Function<String, CompletableFuture<Result<T, Text>>> parser, CompletableFuture<T> future) {
|
||||
super(player, false);
|
||||
setTitle(title);
|
||||
setDefaultInputValue(defaultValue);
|
||||
@@ -32,18 +33,26 @@ public class TextInput<T> extends AnvilInputGui {
|
||||
updateConfirmButton(defaultValue);
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<T> input(ServerPlayerEntity player, Text title, String defaultValue, Function<String, Result<T, Text>> parser) {
|
||||
public static <T> CompletableFuture<T> inputSync(ServerPlayerEntity player, Text title, String defaultValue, Function<String, Result<T, Text>> parser) {
|
||||
return input(player, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string)));
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<T> input(ServerPlayerEntity player, Text title, String defaultValue, Function<String, CompletableFuture<Result<T, Text>>> parser) {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
new TextInput<>(player, title, defaultValue, parser, future).open();
|
||||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<String> inputString(ServerPlayerEntity player, Text title, String defaultValue) {
|
||||
return inputSync(player, title, defaultValue, Result.Success::new);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Integer> 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<Float> 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<T> extends AnvilInputGui {
|
||||
}
|
||||
|
||||
public void updateConfirmButton(String input) {
|
||||
result = parser.apply(input);
|
||||
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<T> extends AnvilInputGui {
|
||||
}
|
||||
|
||||
public void onConfirm() {
|
||||
if(result != null) {
|
||||
result.ifSuccess(success -> {
|
||||
future.complete(success);
|
||||
close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PropertyMap> skin, boolean isSpawned) {
|
||||
public static final Codec<MinionData> 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<UUID> COMPONENT = Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, "minion_data"), ComponentType.<UUID>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<PropertyMap> 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ public class MinionPersistentState extends PersistentState {
|
||||
public static MinionPersistentState INSTANCE;
|
||||
|
||||
private final Map<UUID, MinionData> minionData = new HashMap<>();
|
||||
//private final List<UUID> 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");
|
||||
}
|
||||
|
||||
@@ -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<GameProfile> 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<GameProfile> 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<String, Text> 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<String, Text> checkMinionNameWithoutPrefix(String name) {
|
||||
for(char c : name.toCharArray()) {
|
||||
if(!StringReader.isAllowedInUnquotedString(c)) {
|
||||
return new Result.Error<>(Text.translatable("minions.generic.name.invalid_char"));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isValidMinionName(String name) {
|
||||
return checkMinionName(name).isSuccess();
|
||||
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 String newDefaultMinionName() {
|
||||
int i = 0;
|
||||
while (MinionPersistentState.INSTANCE.isMinionNameTaken("+Minion" + i)) {
|
||||
i++;
|
||||
}
|
||||
return "+Minion" + i;
|
||||
}
|
||||
|
||||
public static boolean isMinion(UUID uuid) {
|
||||
|
||||
@@ -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<PropertyMap> future = data.getSkin(server);
|
||||
PropertyMap skin = data.skin().orElse(null);
|
||||
|
||||
future.thenAccept((skin) -> {
|
||||
GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.uuid(), data.name(), skin);
|
||||
MinionsTickExecutor.addExecuteOnNextTick(() -> doSpawn(data, profile, server, level, pos, rot));
|
||||
});
|
||||
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);
|
||||
|
||||
@@ -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<Optional<PropertyMap>> 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");
|
||||
}
|
||||
}
|
||||
@@ -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<PropertyMap> future = fetchSkin(server);
|
||||
future.thenAccept(result -> {
|
||||
this.cache = result;
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<@Nullable PropertyMap> getSkin(MinecraftServer server) {
|
||||
CompletableFuture<PropertyMap> future = new CompletableFuture<>();
|
||||
if(cache == null) {
|
||||
fetchSkin(server).thenAccept(skin -> {
|
||||
cache = skin;
|
||||
future.complete(skin);
|
||||
});
|
||||
}
|
||||
return CompletableFuture.completedFuture(cache);
|
||||
}
|
||||
}
|
||||
@@ -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<DirectSkinProvider> 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<? extends SkinProvider> getCodec() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -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<NameSkinProvider> 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<Optional<PropertyMap>> 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<PropertyMap> fetchSkin(MinecraftServer server) {
|
||||
return MinionProfileUtils.lookupSkinOwnerProfile(server, name).thenApply(gameProfile -> gameProfile != null ? gameProfile.getProperties() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec<? extends SkinProvider> getCodec() {
|
||||
return null;
|
||||
public Text getDisplayName() {
|
||||
return Text.translatable("minions.gui.look.skin.name");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Optional<PropertyMap>> openSkinMenu(ServerPlayerEntity player);
|
||||
|
||||
Codec<? extends SkinProvider> getCodec();
|
||||
Text getDisplayName();
|
||||
}
|
||||
|
||||
@@ -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<Codec<? extends SkinProvider>> REGISTRY = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, "skin_providers")), Lifecycle.stable());
|
||||
public static final Registry<SkinProvider> SKIN_PROVIDERS = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, "skin_providers")), Lifecycle.stable());
|
||||
|
||||
public static final Codec<SkinProvider> 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 extends Codec<? extends SkinProvider>> T register(T skinProvider, Identifier id) {
|
||||
Registry.register(REGISTRY, id, skinProvider);
|
||||
return skinProvider;
|
||||
|
||||
public static <T extends SkinProvider> 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"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<UUIDSkinProvider> 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<Optional<PropertyMap>> 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<PropertyMap> fetchSkin(MinecraftServer server) {
|
||||
return MinionProfileUtils.getSkinOwnerProfile(server, uuid).thenApply(gameProfile -> {
|
||||
if (gameProfile != null) {
|
||||
return gameProfile.getProperties();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec<? extends SkinProvider> getCodec() {
|
||||
return CODEC;
|
||||
public Text getDisplayName() {
|
||||
return Text.translatable("minions.gui.look.skin.uuid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Entity> addMinionPredicate(@Nullable Predicate<Entity> targetPredicate) {
|
||||
Predicate<Entity> predicate = EntityViewMixinHelper.ADDITIONAL_PREDICATE.get();
|
||||
|
||||
@@ -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<ServerPlayerEntity> 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
+1
-1
@@ -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;
|
||||
+1
-1
@@ -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;
|
||||
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user