Skip to content

Commit

Permalink
Send server's cape repos to the client upon join
Browse files Browse the repository at this point in the history
  • Loading branch information
AViewFromTheTop committed Sep 19, 2024
1 parent 13d2bc9 commit 74458e7
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 40 deletions.
39 changes: 25 additions & 14 deletions src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,49 +29,61 @@
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;
import net.fabricmc.loader.api.FabricLoader;
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<Cape> getCapes() {
return ImmutableList.copyOf(FrozenRegistry.CAPE);
private static final Map<ResourceLocation, Cape> CAPES = new HashMap<>();
private static final List<String> CAPE_REPOS = new ArrayList<>();

public static @NotNull @Unmodifiable List<String> getCapeRepos() {
return ImmutableList.copyOf(CAPE_REPOS);
}

public static @NotNull @Unmodifiable Collection<Cape> getCapes() {
return CAPES.values();
}

public static @NotNull @Unmodifiable List<Cape> getUsableCapes(UUID uuid) {
return ImmutableList.copyOf(getCapes().stream().filter(cape -> canPlayerUserCape(uuid, cape)).toList());
}

public static Optional<Cape> getCape(ResourceLocation location) {
return Optional.ofNullable(CAPES.get(location));
}

public static boolean canPlayerUserCape(UUID uuid, ResourceLocation capeID) {
Optional<Cape> optionalCape = FrozenRegistry.CAPE.getOptional(capeID);
Optional<Cape> optionalCape = CapeUtil.getCape(capeID);
return optionalCape.map(cape -> canPlayerUserCape(uuid, cape)).orElse(false);
}

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<UUID> 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<UUID> 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) {
Expand All @@ -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) {}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -45,13 +45,7 @@ public static Optional<ResourceLocation> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
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 {
private static final Map<UUID, Cape> CAPES_IN_SERVER = new HashMap<>();

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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/

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<LoadCapeRepoPacket> PACKET_TYPE = new Type<>(
FrozenSharedConstants.id("load_cape_repo")
);
public static final StreamCodec<FriendlyByteBuf, LoadCapeRepoPacket> 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<? extends CustomPacketPayload> type() {
return PACKET_TYPE;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -140,18 +139,14 @@ private static void setupEntries(@NotNull ConfigCategory category, @NotNull Conf
UUID playerUUID = Minecraft.getInstance().getUser().getProfileId();
List<String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -104,6 +106,7 @@ public static void registerClientReceivers() {
receiveWindSyncPacket();
receiveWindDisturbancePacket();
receiveCapePacket();
receiveCapeRepoPacket();
ClientPlayNetworking.registerGlobalReceiver(ConfigSyncPacket.PACKET_TYPE, (packet, ctx) ->
ConfigSyncPacket.receive(packet, null)
);
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -46,7 +43,6 @@ public class FrozenRegistry {
public static final ResourceKey<Registry<SpottingIconPredicate<?>>> SPOTTING_ICON_PREDICATE_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("spotting_icon_predicate"));
public static final ResourceKey<Registry<WindDisturbanceLogic<?>>> WIND_DISTURBANCE_LOGIC_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("wind_disturbance_logic"));
public static final ResourceKey<Registry<WindDisturbanceLogic<?>>> WIND_DISTURBANCE_LOGIC_UNSYNCED_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("wind_disturbance_logic_unsynced"));
public static final ResourceKey<Registry<Cape>> CAPE_REGISTRY = ResourceKey.createRegistryKey(FrozenSharedConstants.id("cape"));

public static final MappedRegistry<ModIntegrationSupplier<?>> MOD_INTEGRATION = createSimple(MOD_INTEGRATION_REGISTRY, Lifecycle.stable(), null,
registry -> Registry.register(registry, FrozenSharedConstants.id("dummy"), new ModIntegrationSupplier<>(() -> new ModIntegration("dummy") {
Expand Down Expand Up @@ -77,11 +73,6 @@ public void init() {}
registry -> Registry.register(registry, FrozenSharedConstants.id("dummy"), new WindDisturbanceLogic(WindDisturbanceLogic.defaultPredicate()))
);

public static final MappedRegistry<Cape> 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();
Expand Down

0 comments on commit 74458e7

Please sign in to comment.