diff --git a/src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java b/src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java index 3ca0ef801..0d18cc5f0 100644 --- a/src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java +++ b/src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java @@ -29,7 +29,10 @@ import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import net.fabricmc.api.EnvType; @@ -37,24 +40,33 @@ import net.frozenblock.lib.FrozenSharedConstants; import net.frozenblock.lib.cape.client.api.ClientCapeUtil; import net.frozenblock.lib.cape.impl.Cape; -import net.frozenblock.lib.registry.api.FrozenRegistry; -import net.minecraft.core.Registry; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; public class CapeUtil { - public static @NotNull @Unmodifiable List getCapes() { - return ImmutableList.copyOf(FrozenRegistry.CAPE); + private static final Map CAPES = new HashMap<>(); + private static final List CAPE_REPOS = new ArrayList<>(); + + public static @NotNull @Unmodifiable List getCapeRepos() { + return ImmutableList.copyOf(CAPE_REPOS); + } + + public static @NotNull @Unmodifiable Collection getCapes() { + return CAPES.values(); } public static @NotNull @Unmodifiable List getUsableCapes(UUID uuid) { return ImmutableList.copyOf(getCapes().stream().filter(cape -> canPlayerUserCape(uuid, cape)).toList()); } + public static Optional getCape(ResourceLocation location) { + return Optional.ofNullable(CAPES.get(location)); + } + public static boolean canPlayerUserCape(UUID uuid, ResourceLocation capeID) { - Optional optionalCape = FrozenRegistry.CAPE.getOptional(capeID); + Optional optionalCape = CapeUtil.getCape(capeID); return optionalCape.map(cape -> canPlayerUserCape(uuid, cape)).orElse(false); } @@ -62,16 +74,16 @@ public static boolean canPlayerUserCape(UUID uuid, @NotNull Cape cape) { return cape.allowedPlayers().map(uuids -> uuids.contains(uuid)).orElse(true); } - public static @NotNull Cape registerCape(ResourceLocation id, Component capeName) { - return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.empty())); + public static void registerCape(ResourceLocation id, Component capeName) { + CAPES.put(id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.empty())); } - public static @NotNull Cape registerCapeWithWhitelist(ResourceLocation id, Component capeName, List allowedPlayers) { - return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.of(allowedPlayers))); + public static void registerCapeWithWhitelist(ResourceLocation id, Component capeName, List allowedPlayers) { + CAPES.put(id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.of(allowedPlayers))); } - public static @NotNull Cape registerCapeWithWhitelist(ResourceLocation id, Component capeName, UUID... uuids) { - return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.of(ImmutableList.copyOf(uuids)))); + public static void registerCapeWithWhitelist(ResourceLocation id, Component capeName, UUID... uuids) { + CAPES.put(id, new Cape(id, capeName, buildCapeTextureLocation(id), Optional.of(ImmutableList.copyOf(uuids)))); } public static void registerCapesFromURL(String urlString) { @@ -84,9 +96,8 @@ public static void registerCapesFromURL(String urlString) { JsonObject capeDir = parsedJson.getAsJsonObject(); JsonArray capeArray = capeDir.get("capes").getAsJsonArray(); - capeArray.forEach(jsonElement -> { - registerCapeFromURL(jsonElement.getAsString()); - }); + capeArray.forEach(jsonElement -> registerCapeFromURL(jsonElement.getAsString())); + CAPE_REPOS.add(urlString); } catch (IOException ignored) {} } diff --git a/src/main/java/net/frozenblock/lib/cape/client/impl/ClientCapeData.java b/src/main/java/net/frozenblock/lib/cape/client/impl/ClientCapeData.java index 6af6ef3b2..820d669ee 100644 --- a/src/main/java/net/frozenblock/lib/cape/client/impl/ClientCapeData.java +++ b/src/main/java/net/frozenblock/lib/cape/client/impl/ClientCapeData.java @@ -27,10 +27,10 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.frozenblock.lib.cape.api.CapeUtil; import net.frozenblock.lib.cape.impl.Cape; import net.frozenblock.lib.cape.impl.networking.CapeCustomizePacket; import net.frozenblock.lib.config.frozenlib_config.FrozenLibConfig; -import net.frozenblock.lib.registry.api.FrozenRegistry; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.resources.ResourceLocation; @@ -45,13 +45,7 @@ public static Optional getCapeTexture(UUID uuid) { } public static void setCapeForUUID(UUID uuid, ResourceLocation capeId) { - Cape cape = FrozenRegistry.CAPE.get(capeId); - if (cape == null) { - removeCapeForUUID(uuid); - } else { - CAPES_IN_WORLD.put(uuid, cape); - setPlayerCapeTexture(uuid, Optional.of(cape)); - } + CapeUtil.getCape(capeId).ifPresentOrElse(cape -> CAPES_IN_WORLD.put(uuid, cape), () -> removeCapeForUUID(uuid)); } public static void removeCapeForUUID(UUID uuid) { diff --git a/src/main/java/net/frozenblock/lib/cape/impl/ServerCapeData.java b/src/main/java/net/frozenblock/lib/cape/impl/ServerCapeData.java index 7c87a3f80..76ba2368f 100644 --- a/src/main/java/net/frozenblock/lib/cape/impl/ServerCapeData.java +++ b/src/main/java/net/frozenblock/lib/cape/impl/ServerCapeData.java @@ -28,6 +28,7 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.frozenblock.lib.cape.api.CapeUtil; import net.frozenblock.lib.cape.impl.networking.CapeCustomizePacket; +import net.frozenblock.lib.cape.impl.networking.LoadCapeRepoPacket; import net.minecraft.server.level.ServerPlayer; public class ServerCapeData { @@ -35,6 +36,7 @@ public class ServerCapeData { public static void sendAllCapesToPlayer(ServerPlayer recipent) { CAPES_IN_SERVER.forEach((uuid, cape) -> ServerPlayNetworking.send(recipent, CapeCustomizePacket.createPacket(uuid, cape))); + CapeUtil.getCapeRepos().forEach(repoURL -> ServerPlayNetworking.send(recipent, new LoadCapeRepoPacket(repoURL))); } public static void init() { diff --git a/src/main/java/net/frozenblock/lib/cape/impl/networking/CapeCustomizePacket.java b/src/main/java/net/frozenblock/lib/cape/impl/networking/CapeCustomizePacket.java index ce324264d..4f27da774 100644 --- a/src/main/java/net/frozenblock/lib/cape/impl/networking/CapeCustomizePacket.java +++ b/src/main/java/net/frozenblock/lib/cape/impl/networking/CapeCustomizePacket.java @@ -21,8 +21,8 @@ import net.fabricmc.fabric.api.networking.v1.PlayerLookup; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.frozenblock.lib.FrozenSharedConstants; +import net.frozenblock.lib.cape.api.CapeUtil; import net.frozenblock.lib.cape.impl.Cape; -import net.frozenblock.lib.registry.api.FrozenRegistry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; @@ -71,7 +71,7 @@ public void write(@NotNull FriendlyByteBuf buf) { } public static @NotNull CapeCustomizePacket createPacket(UUID uuid, @Nullable ResourceLocation capeId) { - return new CapeCustomizePacket(uuid, !shouldDisable(FrozenRegistry.CAPE.get(capeId)), capeId); + return new CapeCustomizePacket(uuid, !shouldDisable(CapeUtil.getCape(capeId).orElse(null)), capeId); } @Contract("_, _ -> new") diff --git a/src/main/java/net/frozenblock/lib/cape/impl/networking/LoadCapeRepoPacket.java b/src/main/java/net/frozenblock/lib/cape/impl/networking/LoadCapeRepoPacket.java new file mode 100644 index 000000000..fa3cc169b --- /dev/null +++ b/src/main/java/net/frozenblock/lib/cape/impl/networking/LoadCapeRepoPacket.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.frozenblock.lib.cape.impl.networking; + +import net.frozenblock.lib.FrozenSharedConstants; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +public record LoadCapeRepoPacket(String capeRepo) implements CustomPacketPayload { + public static final Type PACKET_TYPE = new Type<>( + FrozenSharedConstants.id("load_cape_repo") + ); + public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember(LoadCapeRepoPacket::write, LoadCapeRepoPacket::create); + + @Contract("_ -> new") + public static @NotNull LoadCapeRepoPacket create(@NotNull FriendlyByteBuf buf) { + return new LoadCapeRepoPacket(buf.readUtf()); + } + + public void write(@NotNull FriendlyByteBuf buf) { + buf.writeUtf(this.capeRepo()); + } + + @Override + @NotNull + public Type type() { + return PACKET_TYPE; + } +} + diff --git a/src/main/java/net/frozenblock/lib/config/frozenlib_config/gui/FrozenLibConfigGui.java b/src/main/java/net/frozenblock/lib/config/frozenlib_config/gui/FrozenLibConfigGui.java index 3b5a0a5a0..23f5aff37 100644 --- a/src/main/java/net/frozenblock/lib/config/frozenlib_config/gui/FrozenLibConfigGui.java +++ b/src/main/java/net/frozenblock/lib/config/frozenlib_config/gui/FrozenLibConfigGui.java @@ -34,7 +34,6 @@ import net.frozenblock.lib.config.api.instance.Config; import net.frozenblock.lib.config.clothconfig.FrozenClothConfig; import net.frozenblock.lib.config.frozenlib_config.FrozenLibConfig; -import net.frozenblock.lib.registry.api.FrozenRegistry; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -140,18 +139,14 @@ private static void setupEntries(@NotNull ConfigCategory category, @NotNull Conf UUID playerUUID = Minecraft.getInstance().getUser().getProfileId(); List usableCapes = new ArrayList<>(); CapeUtil.getUsableCapes(playerUUID).forEach(cape -> usableCapes.add(cape.registryId().toString())); - if (!usableCapes.isEmpty() && usableCapes.size() > 1) { + if (usableCapes.size() > 1) { var capeEntry = category.addEntry( FrozenClothConfig.syncedEntry( entryBuilder.startSelector(text("cape"), usableCapes.toArray(), modifiedConfig.cape) .setDefaultValue(defaultConfig.cape) .setNameProvider(o -> { ResourceLocation capeId = ResourceLocation.parse(((String) o)); - Cape cape = FrozenRegistry.CAPE.get(capeId); - if (cape != null) { - return cape.capeName(); - } - return Component.translatable("cape.frozenlib.invalid"); + return CapeUtil.getCape(capeId).map(Cape::capeName).orElse(Component.translatable("cape.frozenlib.invalid")); }) .setSaveConsumer(newValue -> { ResourceLocation capeId = ResourceLocation.parse((String) newValue); diff --git a/src/main/java/net/frozenblock/lib/networking/FrozenClientNetworking.java b/src/main/java/net/frozenblock/lib/networking/FrozenClientNetworking.java index 3b0be5664..54d3eaf05 100644 --- a/src/main/java/net/frozenblock/lib/networking/FrozenClientNetworking.java +++ b/src/main/java/net/frozenblock/lib/networking/FrozenClientNetworking.java @@ -24,8 +24,10 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.frozenblock.lib.cape.api.CapeUtil; import net.frozenblock.lib.cape.client.impl.ClientCapeData; import net.frozenblock.lib.cape.impl.networking.CapeCustomizePacket; +import net.frozenblock.lib.cape.impl.networking.LoadCapeRepoPacket; import net.frozenblock.lib.config.api.instance.Config; import net.frozenblock.lib.config.api.registry.ConfigRegistry; import net.frozenblock.lib.config.impl.network.ConfigSyncPacket; @@ -104,6 +106,7 @@ public static void registerClientReceivers() { receiveWindSyncPacket(); receiveWindDisturbancePacket(); receiveCapePacket(); + receiveCapeRepoPacket(); ClientPlayNetworking.registerGlobalReceiver(ConfigSyncPacket.PACKET_TYPE, (packet, ctx) -> ConfigSyncPacket.receive(packet, null) ); @@ -339,6 +342,12 @@ private static void receiveCapePacket() { }); } + private static void receiveCapeRepoPacket() { + ClientPlayNetworking.registerGlobalReceiver(LoadCapeRepoPacket.PACKET_TYPE, (packet, ctx) -> { + CapeUtil.registerCapesFromURL(packet.capeRepo()); + }); + } + public static boolean notConnected() { Minecraft minecraft = Minecraft.getInstance(); ClientPacketListener listener = minecraft.getConnection(); diff --git a/src/main/java/net/frozenblock/lib/networking/FrozenNetworking.java b/src/main/java/net/frozenblock/lib/networking/FrozenNetworking.java index 8575e197c..a2c676a9e 100644 --- a/src/main/java/net/frozenblock/lib/networking/FrozenNetworking.java +++ b/src/main/java/net/frozenblock/lib/networking/FrozenNetworking.java @@ -26,6 +26,7 @@ import net.frozenblock.lib.cape.api.CapeUtil; import net.frozenblock.lib.cape.impl.ServerCapeData; import net.frozenblock.lib.cape.impl.networking.CapeCustomizePacket; +import net.frozenblock.lib.cape.impl.networking.LoadCapeRepoPacket; import net.frozenblock.lib.config.impl.network.ConfigSyncPacket; import net.frozenblock.lib.debug.networking.GoalDebugRemovePayload; import net.frozenblock.lib.debug.networking.ImprovedGameEventDebugPayload; @@ -116,6 +117,7 @@ public static void registerNetworking() { registry.register(WindSyncPacket.PACKET_TYPE, WindSyncPacket.CODEC); registry.register(WindDisturbancePacket.PACKET_TYPE, WindDisturbancePacket.CODEC); registry.register(CapeCustomizePacket.PACKET_TYPE, CapeCustomizePacket.CODEC); + registry.register(LoadCapeRepoPacket.PACKET_TYPE, LoadCapeRepoPacket.STREAM_CODEC); c2sRegistry.register(CapeCustomizePacket.PACKET_TYPE, CapeCustomizePacket.CODEC); ServerPlayNetworking.registerGlobalReceiver(CapeCustomizePacket.PACKET_TYPE, (packet, ctx) -> { diff --git a/src/main/java/net/frozenblock/lib/registry/api/FrozenRegistry.java b/src/main/java/net/frozenblock/lib/registry/api/FrozenRegistry.java index 2136fbb63..fb5e5503e 100644 --- a/src/main/java/net/frozenblock/lib/registry/api/FrozenRegistry.java +++ b/src/main/java/net/frozenblock/lib/registry/api/FrozenRegistry.java @@ -18,12 +18,10 @@ package net.frozenblock.lib.registry.api; import com.mojang.serialization.Lifecycle; -import java.util.Optional; import lombok.experimental.UtilityClass; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.RegistryAttribute; import net.frozenblock.lib.FrozenSharedConstants; -import net.frozenblock.lib.cape.impl.Cape; import net.frozenblock.lib.integration.api.ModIntegration; import net.frozenblock.lib.integration.api.ModIntegrationSupplier; import net.frozenblock.lib.sound.api.predicate.SoundPredicate; @@ -34,7 +32,6 @@ import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.registries.VanillaRegistries; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import org.jetbrains.annotations.NotNull; @@ -46,7 +43,6 @@ public class FrozenRegistry { public static final ResourceKey>> SPOTTING_ICON_PREDICATE_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("spotting_icon_predicate")); public static final ResourceKey>> WIND_DISTURBANCE_LOGIC_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("wind_disturbance_logic")); public static final ResourceKey>> WIND_DISTURBANCE_LOGIC_UNSYNCED_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("wind_disturbance_logic_unsynced")); - public static final ResourceKey> CAPE_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("cape")); public static final MappedRegistry> MOD_INTEGRATION = createSimple(MOD_INTEGRATION_REGISTRY, Lifecycle.stable(), null, registry -> Registry.register(registry, FrozenSharedConstants.id("dummy"), new ModIntegrationSupplier<>(() -> new ModIntegration("dummy") { @@ -77,11 +73,6 @@ public void init() {} registry -> Registry.register(registry, FrozenSharedConstants.id("dummy"), new WindDisturbanceLogic(WindDisturbanceLogic.defaultPredicate())) ); - public static final MappedRegistry CAPE = createSimple(CAPE_REGISTRY, Lifecycle.stable(), null, - registry -> Registry.register(registry, FrozenSharedConstants.id("dummy"), new Cape(FrozenSharedConstants.id("dummy"), Component.translatable("cape.frozenlib.dummy"), null, Optional.empty())) - ); - - @NotNull public static HolderLookup.Provider vanillaRegistries() { return VanillaRegistries.createLookup();