Minion Config²
This commit is contained in:
@@ -13,6 +13,8 @@ import com.electronwill.nightconfig.toml.TomlFormat;
|
||||
import com.electronwill.nightconfig.toml.TomlParser;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static com.electronwill.nightconfig.core.serde.annotations.SerdeSkipDeserializingIf.SkipDeIf.IS_MISSING;
|
||||
@@ -44,7 +46,15 @@ public class MinionsConfig {
|
||||
}
|
||||
|
||||
private static Path getPath() {
|
||||
return FabricLoader.getInstance().getConfigDir().resolve(Minions.MOD_ID + ".toml");
|
||||
Path minionsDir = FabricLoader.getInstance().getConfigDir().resolve("minions");
|
||||
if(!Files.isDirectory(minionsDir)) {
|
||||
try {
|
||||
Files.createDirectory(minionsDir);
|
||||
} catch (IOException e) {
|
||||
Minions.LOGGER.error("Could not create config dir", e);
|
||||
}
|
||||
}
|
||||
return minionsDir.resolve(Minions.MOD_ID + ".toml");
|
||||
}
|
||||
|
||||
public static MinionsConfig get() {
|
||||
@@ -55,7 +65,6 @@ public class MinionsConfig {
|
||||
}
|
||||
|
||||
public static void loadConfig() {
|
||||
System.out.println("loading");
|
||||
try {
|
||||
CommentedConfig config = new TomlParser().parse(getPath(), (file, configFormat) -> {
|
||||
CommentedConfig defaultConfig = ObjectSerializer.standard().serializeFields(new MinionsConfig(), TomlFormat::newConfig);
|
||||
@@ -65,8 +74,7 @@ public class MinionsConfig {
|
||||
|
||||
INSTANCE = ObjectDeserializer.standard().deserializeFields(config, MinionsConfig::new);
|
||||
} catch (SerdeException | ParsingException | WritingException e) {
|
||||
System.out.println("[minions] Error while reading config");
|
||||
e.printStackTrace();
|
||||
Minions.LOGGER.error("Error while reading config", e);
|
||||
INSTANCE = new MinionsConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MinionConfig {
|
||||
public static final Codec<MinionConfig> CODEC = Codec.<Option<?>, Object>dispatchedMap(
|
||||
MinionRegistries.MINION_CONFIG_OPTIONS.getCodec(),
|
||||
Option::codec
|
||||
).xmap(MinionConfig::new, config -> config.values);
|
||||
|
||||
private final Map<Option<?>, Object> values;
|
||||
|
||||
public MinionConfig() {
|
||||
values = new HashMap<>();
|
||||
}
|
||||
|
||||
private MinionConfig(Map<Option<?>, Object> values) {
|
||||
this.values = new HashMap<>(values);
|
||||
}
|
||||
|
||||
public <T> T getOption(Option<T> option) {
|
||||
if(values.containsKey(option)) {
|
||||
//noinspection unchecked
|
||||
return (T) values.get(option);
|
||||
} else {
|
||||
return option.defaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof MinionConfig that)) return false;
|
||||
return Objects.equals(values, that.values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(values);
|
||||
}
|
||||
|
||||
public static Option<Boolean> booleanOption(Identifier key, boolean defaultValue) {
|
||||
return new Option<>(key, defaultValue, Codec.BOOL);
|
||||
}
|
||||
|
||||
public record Option<T>(Identifier key, T defaultValue, Codec<T> codec) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Option<?> option)) return false;
|
||||
return Objects.equals(key, option.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,14 @@ import net.minecraft.util.dynamic.Codecs;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boolean isSpawned, SerializableListenerManager<MinionListener> listeners) {
|
||||
public record MinionData(
|
||||
UUID uuid,
|
||||
String name,
|
||||
Optional<PropertyMap> skin,
|
||||
boolean isSpawned,
|
||||
SerializableListenerManager<MinionListener> listeners,
|
||||
MinionConfig config
|
||||
) {
|
||||
public static final Codec<MinionData> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
Uuids.CODEC.fieldOf("uuid").forGetter(MinionData::uuid),
|
||||
@@ -22,23 +29,31 @@ public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boo
|
||||
SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners").xmap(
|
||||
optional -> optional.orElseGet(() -> new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS)),
|
||||
Optional::of
|
||||
).forGetter(MinionData::listeners)
|
||||
).forGetter(MinionData::listeners),
|
||||
MinionConfig.CODEC.optionalFieldOf("config", new MinionConfig()).forGetter(MinionData::config)
|
||||
).apply(instance, MinionData::new)
|
||||
);
|
||||
|
||||
public static MinionData createDefault(MinecraftServer server) {
|
||||
return new MinionData(UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(server), Optional.empty(), false, new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS));
|
||||
return new MinionData(
|
||||
UUID.randomUUID(),
|
||||
MinionProfileUtils.newDefaultMinionName(server),
|
||||
Optional.empty(),
|
||||
false,
|
||||
new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS),
|
||||
new MinionConfig()
|
||||
);
|
||||
}
|
||||
|
||||
public MinionData withName(String name) {
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners);
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
||||
}
|
||||
|
||||
public MinionData withSkin(Optional<PropertyMap> skin) {
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners);
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
||||
}
|
||||
|
||||
public MinionData withSpawned(boolean isSpawned) {
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners);
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.minion.fakeplayer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import io.github.skippyall.minions.registration.MinionItems;
|
||||
import io.github.skippyall.minions.minion.MinionListener;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
@@ -143,11 +144,11 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
}
|
||||
|
||||
public boolean canSpawnMobs() {
|
||||
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING);
|
||||
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING) || getData().config().getOption(MinionConfigOptions.spawnAndDespawnMobs);
|
||||
}
|
||||
|
||||
public boolean canDespawnMobs() {
|
||||
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING);
|
||||
return canSpawnMobs();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,22 +2,102 @@ package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.minecraft.dialog.AfterAction;
|
||||
import net.minecraft.dialog.DialogActionButtonData;
|
||||
import net.minecraft.dialog.DialogButtonData;
|
||||
import net.minecraft.dialog.DialogCommonData;
|
||||
import net.minecraft.dialog.action.DynamicCustomDialogAction;
|
||||
import net.minecraft.dialog.input.TextInputControl;
|
||||
import net.minecraft.dialog.type.Dialog;
|
||||
import net.minecraft.dialog.type.DialogInput;
|
||||
import net.minecraft.dialog.type.NoticeDialog;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Base64SkinProvider implements SkinProvider {
|
||||
public static final RegistryKey<Dialog> DIALOG = RegistryKey.of(RegistryKeys.DIALOG, Identifier.of(Minions.MOD_ID, "base_64_input"));
|
||||
public static final Identifier CUSTOM_DIALOG_ACTION = Identifier.of(Minions.MOD_ID, "base_64_submit");
|
||||
|
||||
private static long dialogIdCounter = 0;
|
||||
private static Map<Long, CompletableFuture<Optional<PropertyMap>>> futures = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Optional<PropertyMap>> openSkinMenu(ServerPlayerEntity player) {
|
||||
return TextInput.inputString(player, Text.translatable("minions.gui.look.skin.base64.title"), "")
|
||||
.thenApply(base64String -> {
|
||||
dialogIdCounter++;
|
||||
player.openDialog(getDialog());
|
||||
CompletableFuture<Optional<PropertyMap>> future = new CompletableFuture<>();
|
||||
futures.put(dialogIdCounter, future);
|
||||
return future;
|
||||
}
|
||||
|
||||
public static void onCustomDialogAction(Optional<NbtElement> element) {
|
||||
if(element.isPresent() && element.get() instanceof NbtCompound compound) {
|
||||
Optional<Long> id = compound.getLong("dialog_id");
|
||||
Optional<String> base64 = compound.getString("base_64");
|
||||
if(id.isPresent() && base64.isPresent() && !base64.get().isBlank()) {
|
||||
if(futures.containsKey(id.get())) {
|
||||
PropertyMap map = new PropertyMap();
|
||||
map.put("textures", new Property("textures", base64String));
|
||||
return Optional.of(map);
|
||||
});
|
||||
map.put("textures", new Property("textures", base64.get().strip()));
|
||||
|
||||
futures.get(id.get()).complete(Optional.of(map));
|
||||
futures.remove(id.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static RegistryEntry<Dialog> getDialog() {
|
||||
NbtCompound additionalData = new NbtCompound();
|
||||
additionalData.putLong("dialog_id", dialogIdCounter);
|
||||
return RegistryEntry.of(
|
||||
new NoticeDialog(
|
||||
new DialogCommonData(
|
||||
Text.translatable("minions.gui.look.skin.base64.title"),
|
||||
Optional.empty(),
|
||||
true,
|
||||
false,
|
||||
AfterAction.CLOSE,
|
||||
List.of(),
|
||||
List.of(
|
||||
new DialogInput("base_64", new TextInputControl(
|
||||
200,
|
||||
Text.empty(),
|
||||
false,
|
||||
"",
|
||||
2000,
|
||||
Optional.empty()
|
||||
))
|
||||
)
|
||||
),
|
||||
new DialogActionButtonData(
|
||||
new DialogButtonData(
|
||||
Text.translatable("gui.ok"),
|
||||
150
|
||||
),
|
||||
Optional.of(
|
||||
new DynamicCustomDialogAction(
|
||||
CUSTOM_DIALOG_ACTION,
|
||||
Optional.of(
|
||||
additionalData
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,21 +2,38 @@ package io.github.skippyall.minions.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.minion.skin.Base64SkinProvider;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(MinecraftServer.class)
|
||||
public class MinecraftServerMixin {
|
||||
|
||||
@ModifyExpressionValue(method = "createMetadataPlayers", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;getPlayerList()Ljava/util/List;"))
|
||||
public List<ServerPlayerEntity> ignoreFakePlayers(List<ServerPlayerEntity> original) {
|
||||
return original.stream()
|
||||
.filter(player -> !(player instanceof MinionFakePlayer))
|
||||
.filter(player -> !(player instanceof MinionFakePlayer minion
|
||||
&& !minion.getData().config().getOption(MinionConfigOptions.showInServerList)))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
@Inject(method = "handleCustomClickAction", at = @At("HEAD"), cancellable = true)
|
||||
private void onCustomClickAction(Identifier id, Optional<NbtElement> payload, CallbackInfo ci) {
|
||||
if(id.equals(Base64SkinProvider.CUSTOM_DIALOG_ACTION)) {
|
||||
Base64SkinProvider.onCustomDialogAction(payload);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ package io.github.skippyall.minions.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -12,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
public class PlayerListEntryS2CPacket$EntryMixin {
|
||||
@ModifyArg(method = "<init>(Lnet/minecraft/server/network/ServerPlayerEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/PlayerListS2CPacket$Entry;<init>(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/GameMode;Lnet/minecraft/text/Text;ZILnet/minecraft/network/encryption/PublicPlayerSession$Serialized;)V"), index = 2)
|
||||
private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayerEntity player) {
|
||||
if(player instanceof MinionFakePlayer) {
|
||||
if(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.showInTabList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.NetHandlerPlayServerFake;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.packet.c2s.common.SyncedClientOptions;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -61,7 +62,7 @@ public class PlayerListMixin {
|
||||
|
||||
@WrapOperation(method = "onPlayerConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V"))
|
||||
public void noLoginMessage(PlayerManager instance, Text message, boolean overlay, Operation<Void> original, @Local(argsOnly = true) ServerPlayerEntity player) {
|
||||
if(!(player instanceof MinionFakePlayer)) {
|
||||
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLoginMessage))) {
|
||||
original.call(instance, message, overlay);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +70,7 @@ public class PlayerListMixin {
|
||||
@ModifyReceiver(method = "checkCanJoin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
|
||||
public List<ServerPlayerEntity> noMinionCounting(List<ServerPlayerEntity> instance) {
|
||||
return instance.stream()
|
||||
.filter(player -> !(player instanceof MinionFakePlayer))
|
||||
.filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForPlayerLimit)))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.mixins;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -18,7 +19,7 @@ public class ServerPlayNetworkHandlerMixin {
|
||||
|
||||
@WrapOperation(method = "cleanUp", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V"))
|
||||
public void noLogoutMessage(PlayerManager instance, Text message, boolean overlay, Operation<Void> original) {
|
||||
if(!(player instanceof MinionFakePlayer)) {
|
||||
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLogoutMessage))) {
|
||||
original.call(instance, message, overlay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.mixins;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.registration.MinionConfigOptions;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.SleepManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -12,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
public class SleepManagerMixin {
|
||||
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;isSpectator()Z"))
|
||||
public boolean excludeMinions(ServerPlayerEntity instance, Operation<Boolean> original) {
|
||||
if (instance instanceof MinionFakePlayer) {
|
||||
if (instance instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForSleeping)) {
|
||||
return true;
|
||||
} else {
|
||||
return original.call(instance);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionConfig;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import static io.github.skippyall.minions.minion.MinionConfig.booleanOption;
|
||||
|
||||
public class MinionConfigOptions {
|
||||
public static final MinionConfig.Option<Boolean> showInServerList = register(booleanOption(id("showInServerList"), false));
|
||||
public static final MinionConfig.Option<Boolean> showInTabList = register(booleanOption(id("showInTabList"), false));
|
||||
public static final MinionConfig.Option<Boolean> sendLoginMessage = register(booleanOption(id("sendLoginMessage"), false));
|
||||
public static final MinionConfig.Option<Boolean> sendLogoutMessage = register(booleanOption(id("sendLogoutMessage"), false));
|
||||
public static final MinionConfig.Option<Boolean> countForSleeping = register(booleanOption(id("countForSleeping"), false));
|
||||
public static final MinionConfig.Option<Boolean> countForPlayerLimit = register(booleanOption(id("countForPlayerLimit"), false));
|
||||
public static final MinionConfig.Option<Boolean> spawnAndDespawnMobs = register(booleanOption(id("spawnAndDespawnMobs"), false));
|
||||
|
||||
private static <T> MinionConfig.Option<T> register(MinionConfig.Option<T> option) {
|
||||
return Registry.register(MinionRegistries.MINION_CONFIG_OPTIONS, option.key(), option);
|
||||
}
|
||||
|
||||
private static Identifier id(String name) {
|
||||
return Identifier.of(Minions.MOD_ID, name);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.mojang.serialization.MapCodec;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.docs.ReferenceEntry;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.MinionConfig;
|
||||
import io.github.skippyall.minions.minion.MinionListener;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.skin.SkinProvider;
|
||||
@@ -33,6 +34,7 @@ public class MinionRegistries {
|
||||
public static final Registry<Codec<? extends MinionListener>> MINION_LISTENER_CODECS = registry("minion_listener_codec");
|
||||
public static final Registry<MapCodec<? extends Clipboard>> CLIPBOARD_TYPES = registry("clipboard_type");
|
||||
public static final Registry<SpecialAbility> SPECIAL_ABILITIES = registry("special_ability");
|
||||
public static final Registry<MinionConfig.Option<?>> MINION_CONFIG_OPTIONS = registry("minion_config_option");
|
||||
|
||||
public static final RegistryKey<Registry<GuiDisplay>> GUI_DISPLAY = key("gui_display");
|
||||
public static final RegistryKey<Registry<ReferenceEntry>> REFERENCE_ENTRY = key("reference_entry");
|
||||
|
||||
Reference in New Issue
Block a user