Skip to content

Commit

Permalink
Merge branch 'master' into 1.21.2
Browse files Browse the repository at this point in the history
# Conflicts:
#	gradle.properties
#	src/main/java/net/frozenblock/lib/cape/client/impl/ClientCapeData.java
#	src/main/java/net/frozenblock/lib/cape/impl/networking/CapeCustomizePacket.java
  • Loading branch information
Treetrain1 committed Sep 26, 2024
2 parents 6b713a5 + e898639 commit c01d47e
Show file tree
Hide file tree
Showing 22 changed files with 565 additions and 112 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ Put changelog here:
- Currently, these capes can only be accessed through FrozenLib's config.
- An optional list of allowed UUIDs can be defined for capes.
- Fixed the `ColumnWithDiskFeature` not generating as intended.
- Added an API to send and receive images from client and server.
- This is useful in cases where, for example, you want to send a screenshot from Minecraft to the server to be used as a texture.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ plugins {
idea
`java-library`
java
kotlin("jvm") version("2.0.10")
kotlin("jvm") version("2.0.20")
}

val minecraft_version: String by project
Expand Down Expand Up @@ -271,7 +271,7 @@ dependencies {
relocModApi(files("libs/xjs-data-0.5.jar"))
relocModApi("org.exjson:xjs-compat:$xjs_compat_version")
relocModApi("com.personthecat:fresult:$fresult_version")
compileOnly("org.projectlombok:lombok:1.18.30")?.let { annotationProcessor(it) }
compileOnly("org.projectlombok:lombok:1.18.34")?.let { annotationProcessor(it) }

"testmodImplementation"(sourceSets.main.get().output)
}
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
archives_base_name = FrozenLib

# Dependencies
fabric_api_version=0.104.2+1.21.2
fabric_kotlin_version=1.12.0+kotlin.2.0.10
fabric_api_version=0.105.0+1.21.2
fabric_kotlin_version=1.12.2+kotlin.2.0.20
toml4j_version=0.7.2
jankson_version=1.2.3
xjs_data_version=0.6
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
6 changes: 1 addition & 5 deletions jitpack.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
before_install:
- wget https://github.com/sormuras/bach/raw/releases/11/install-jdk.sh
- source install-jdk.sh --feature 21

jdk:
- openjdk21
- openjdk21
59 changes: 38 additions & 21 deletions src/main/java/net/frozenblock/lib/cape/api/CapeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,48 +29,65 @@
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);
return optionalCape.map(cape -> canPlayerUserCape(uuid, cape)).orElse(false);
Optional<Cape> optionalCape = CapeUtil.getCape(capeID);
return optionalCape.map(cape -> canPlayerUserCape(uuid, cape)).orElse(true);
}

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) {
return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, buildCapeTextureLocation(id), Optional.empty()));
public static void registerCape(ResourceLocation id, ResourceLocation textureId, Component capeName) {
CAPES.put(id, new Cape(id, capeName, textureId, 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, List<UUID> allowedPlayers) {
return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, 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, UUID... uuids) {
return Registry.register(FrozenRegistry.CAPE, id, new Cape(id, 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 @@ -83,9 +100,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 All @@ -98,8 +114,10 @@ private static void registerCapeFromURL(String urlString) {
JsonElement parsedJson = JsonParser.parseReader(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject capeJson = parsedJson.getAsJsonObject();
String capeId = capeJson.get("id").getAsString();
Component capeName = Component.literal(capeJson.get("name").getAsString());
String capeTexture = capeJson.get("texture").getAsString();
JsonArray allowedUUIDs = capeJson.get("allowed_uuids").getAsJsonArray();
JsonElement allowedUUIDElement = capeJson.get("allowed_uuids");
boolean whitelisted = allowedUUIDElement != null;

ResourceLocation capeLocation = ResourceLocation.tryParse(capeId);
if (capeLocation != null) {
Expand All @@ -108,13 +126,12 @@ private static void registerCapeFromURL(String urlString) {
ClientCapeUtil.registerCapeTextureFromURL(capeLocation, capeTextureLocation, capeTexture);
}

List<JsonElement> allowedUUIDList = allowedUUIDs.asList();
if (allowedUUIDList.isEmpty()) {
registerCape(capeLocation);
if (!whitelisted) {
registerCape(capeLocation, capeName);
} else {
List<UUID> uuidList = new ArrayList<>();
allowedUUIDList.forEach(jsonElement -> uuidList.add(UUID.fromString(jsonElement.getAsString())));
registerCapeWithWhitelist(capeLocation, ImmutableList.copyOf(uuidList));
allowedUUIDElement.getAsJsonArray().asList().forEach(jsonElement -> uuidList.add(UUID.fromString(jsonElement.getAsString())));
registerCapeWithWhitelist(capeLocation, capeName, ImmutableList.copyOf(uuidList));
}
}
} catch (IOException ignored) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import com.google.gson.JsonIOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand All @@ -35,28 +37,32 @@
@Environment(EnvType.CLIENT)
public class ClientCapeUtil {
public static final Path CAPE_CACHE_PATH = Minecraft.getInstance().gameDirectory.toPath().resolve("frozenlib_cape_cache");
private static final List<ResourceLocation> REGISTERED_CAPE_LISTENERS = new ArrayList<>();

public static void registerCapeTextureFromURL(
@NotNull ResourceLocation capeLocation, ResourceLocation capeTextureLocation, String textureURL
) throws JsonIOException {
ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override
public ResourceLocation getFabricId() {
return capeLocation;
}
if (!REGISTERED_CAPE_LISTENERS.contains(capeLocation)) {
ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override
public ResourceLocation getFabricId() {
return capeLocation;
}

@Override
public void onResourceManagerReload(@NotNull ResourceManager resourceManager) {
CompletableFuture<ResourceLocation> completableFuture = new CompletableFuture<>();
HttpTexture httpTexture = new HttpTexture(
CAPE_CACHE_PATH.resolve(capeLocation.getNamespace()).resolve(capeLocation.getPath() + ".png").toFile(),
textureURL,
DefaultPlayerSkin.getDefaultTexture(),
false,
() -> completableFuture.complete(capeTextureLocation)
);
Minecraft.getInstance().getTextureManager().register(capeTextureLocation, httpTexture);
}
});
@Override
public void onResourceManagerReload(@NotNull ResourceManager resourceManager) {
CompletableFuture<ResourceLocation> completableFuture = new CompletableFuture<>();
HttpTexture httpTexture = new HttpTexture(
CAPE_CACHE_PATH.resolve(capeLocation.getNamespace()).resolve(capeLocation.getPath() + ".png").toFile(),
textureURL,
DefaultPlayerSkin.getDefaultTexture(),
false,
() -> completableFuture.complete(capeTextureLocation)
);
Minecraft.getInstance().getTextureManager().register(capeTextureLocation, httpTexture);
}
});
REGISTERED_CAPE_LISTENERS.add(capeLocation);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,53 +27,44 @@
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;
import org.jetbrains.annotations.NotNull;

@Environment(EnvType.CLIENT)
public class ClientCapeData {
private static final Map<UUID, Cape> CAPES_IN_SERVER = new HashMap<>();
private static final Map<UUID, Cape> CAPES_IN_WORLD = new HashMap<>();

public static Optional<ResourceLocation> getCapeTexture(UUID uuid) {
return Optional.ofNullable(CAPES_IN_SERVER.get(uuid)).map(Cape::texture);
return Optional.ofNullable(CAPES_IN_WORLD.get(uuid)).map(Cape::texture);
}

public static void setCapeForUUID(UUID uuid, ResourceLocation capeId) {
Cape cape = FrozenRegistry.CAPE.getValue(capeId);
if (cape == null) {
removeCapeForUUID(uuid);
} else {
CAPES_IN_SERVER.put(uuid, cape);
setPlayerCapeTexture(uuid, Optional.of(cape));
}
CapeUtil.getCape(capeId).ifPresentOrElse(cape -> setPlayerCape(uuid, Optional.of(cape)), () -> removeCapeForUUID(uuid));
}

public static void removeCapeForUUID(UUID uuid) {
CAPES_IN_SERVER.remove(uuid);
setPlayerCapeTexture(uuid, Optional.empty());
setPlayerCape(uuid, Optional.empty());
}

private static void setPlayerCapeTexture(UUID uuid, @NotNull Optional<Cape> cape) {
private static void setPlayerCape(UUID uuid, @NotNull Optional<Cape> cape) {
cape.ifPresentOrElse(cape1 -> CAPES_IN_WORLD.put(uuid, cape1), () -> CAPES_IN_WORLD.remove(uuid));
ClientLevel level = Minecraft.getInstance().level;
if (level != null && level.getPlayerByUUID(uuid) instanceof PlayerCapeInterface capeInterface) {
capeInterface.frozenLib$setCape(cape.map(Cape::texture).orElse(null));
}
}

public static void init() {
ClientLifecycleEvents.CLIENT_STOPPING.register(client -> {
CAPES_IN_SERVER.clear();
});
ClientPlayConnectionEvents.DISCONNECT.register((clientPacketListener, minecraft) -> CAPES_IN_SERVER.clear());
ClientPlayConnectionEvents.JOIN.register((clientPacketListener, packetSender, minecraft) -> {
ClientPlayNetworking.send(CapeCustomizePacket.createPacket(minecraft.getUser().getProfileId(), ResourceLocation.parse(FrozenLibConfig.get().cape)));
});
ClientLifecycleEvents.CLIENT_STOPPING.register(client -> CAPES_IN_WORLD.clear());
ClientPlayConnectionEvents.DISCONNECT.register((clientPacketListener, minecraft) -> CAPES_IN_WORLD.clear());
ClientPlayConnectionEvents.JOIN.register((clientPacketListener, packetSender, minecraft) ->
ClientPlayNetworking.send(CapeCustomizePacket.createPacket(minecraft.getUser().getProfileId(), ResourceLocation.parse(FrozenLibConfig.get().cape))));
ClientEntityEvents.ENTITY_LOAD.register((entity, clientLevel) -> {
if (entity instanceof PlayerCapeInterface capeInterface) {
getCapeTexture(entity.getUUID()).ifPresent(capeInterface::frozenLib$setCape);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/net/frozenblock/lib/cape/impl/Cape.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;

public record Cape(ResourceLocation registryId, ResourceLocation texture, Optional<List<UUID>> allowedPlayers) {
public record Cape(ResourceLocation registryId, Component capeName, ResourceLocation texture, Optional<List<UUID>> allowedPlayers) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,19 @@
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
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.networking.CapeCustomizePacket;
import net.frozenblock.lib.cape.impl.networking.LoadCapeRepoPacket;
import net.minecraft.network.chat.Component;
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 All @@ -48,6 +52,8 @@ public static void init() {
}
});

CapeUtil.registerCape(FrozenSharedConstants.id("dummy"), null, Component.translatable("cape.frozenlib.dummy"));

// FrozenBlock
List<UUID> devs = ImmutableList.of(
UUID.fromString("097b76e8-ac32-410f-b81c-38dd4086b97c"), // Lunade
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 @@ -70,8 +70,8 @@ public void write(@NotNull FriendlyByteBuf buf) {
return new CapeCustomizePacket(uuid, false);
}

public static @NotNull CapeCustomizePacket createPacket(UUID uuid, @Nullable ResourceLocation capeId) {
return new CapeCustomizePacket(uuid, !shouldDisable(FrozenRegistry.CAPE.getValue(capeId)), capeId);
public static @NotNull CapeCustomizePacket createPacket(UUID uuid, @Nullable ResourceLocation capeId) {
return new CapeCustomizePacket(uuid, !shouldDisable(CapeUtil.getCape(capeId).orElse(null)), capeId);
}

@Contract("_, _ -> new")
Expand Down
Loading

0 comments on commit c01d47e

Please sign in to comment.