Skip to content

Commit

Permalink
Initial resource packs implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Castle <[email protected]>
  • Loading branch information
Kas-tle committed May 5, 2024
1 parent 25cbf7c commit 7217755
Show file tree
Hide file tree
Showing 14 changed files with 472 additions and 50 deletions.
1 change: 1 addition & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
compileOnly(libs.configurate.yaml)
compileOnly(libs.bundles.cloud.core)
compileOnly(libs.bundles.adventure.core)
compileOnly(libs.bundles.fastutil)
compileOnly(libs.guava)
compileOnly(libs.connectorplugin.core)
compileOnly(libs.log4j.slf4j.impl)
Expand Down
182 changes: 182 additions & 0 deletions core/src/main/java/net/paradisu/core/packs/PackManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package net.paradisu.core.packs;

import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.kyori.adventure.resource.ResourcePackInfo;
import net.kyori.adventure.resource.ResourcePackRequest;
import net.paradisu.core.ParadisuPlugin;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
* Class to manage resource packs
*/
@Accessors(fluent = true)
@Getter
public class PackManager {
/**
* The plugin instance
*/
private ParadisuPlugin paradisu;
/**
* The list of resource pack urls
*/
private List<String> resourcePackUrls;
/**
* The default request for the resource packs
*/
private CompletableFuture<ResourcePackRequest> defaultRequest;
/**
* The staging pack requests
*/
private Object2ObjectMap<String, Optional<CompletableFuture<ResourcePackRequest>>> stagingPackRequests;

/**
* Constructor for PackManager class to manage resource packs
*
* @param paradisu the plugin instance
* @param resourcePackUrls the list of resource pack urls
*/
public PackManager(ParadisuPlugin paradisu, List<String> resourcePackUrls) {
this.paradisu = paradisu;
this.resourcePackUrls = resourcePackUrls;
this.stagingPackRequests = new Object2ObjectOpenHashMap<>();
this.defaultRequest = this.buildDefaultRequest(this.buildDefaultList(this.resourcePackUrls));
}

/**
* Clear the staging pack requests
*/
public void clearStagingRequests() {
this.stagingPackRequests.clear();
}

/**
* Reload the default resource packs and clear the staging requests
*/
public void reload() {
this.defaultRequest = this.buildDefaultRequest(this.buildDefaultList(this.resourcePackUrls));
this.clearStagingRequests();
}

/**
* Set the resource pack urls
*
* @param resourcePackUrls the list of resource pack urls
*/
public void resourcePackUrls(List<String> resourcePackUrls) {
this.resourcePackUrls = resourcePackUrls;
this.defaultRequest = this.buildDefaultRequest(this.buildDefaultList(this.resourcePackUrls));
}

/**
* Get the staging request for a resource pack
*
* @param url the url of the resource pack
* @param tag the tag of the resource pack
* @return the staging request
*/
public Optional<CompletableFuture<ResourcePackRequest>> stagingRequest(String url, String tag) {
return this.stagingPackRequests.computeIfAbsent(tag, k -> {
return this.buildPackInfo(url).map(this::buildRequestFuture);
});
}

/**
* Get the staging request for a resource pack
*
* @param tag the tag of the resource pack
* @return the staging request
*/
public Optional<CompletableFuture<ResourcePackRequest>> stagingRequest(String tag) {
return this.stagingPackRequests.getOrDefault(tag, Optional.empty());
}

/**
* Build the default list of resource packs
*
* @param urls the list of resource pack urls
* @return the list of resource pack info futures
*/
private List<CompletableFuture<ResourcePackInfo>> buildDefaultList(List<String> urls) {
List<CompletableFuture<ResourcePackInfo>> packs = new ArrayList<>();

for (String url : urls) {
buildPackInfo(url).ifPresent(packInfo -> {
packs.add(packInfo);
});
}

return packs;
}

private CompletableFuture<ResourcePackRequest> buildDefaultRequest(List<CompletableFuture<ResourcePackInfo>> packInfos) {
return this.buildRequestFuture(packInfos).whenCompleteAsync((request, e) -> {
if (e == null) {
this.paradisu.logger().info("Successfully loaded the default resource packs");
} else {
this.paradisu.logger().error("Failed to build default request: " + e.getMessage());
}
});
}

/**
* Build the pack info for a resource pack
*
* @param url the url of the resource pack
* @return the pack info future
*/
private Optional<CompletableFuture<ResourcePackInfo>> buildPackInfo(String url) {
try {
return Optional.of(ResourcePackInfo.resourcePackInfo().uri(new URI(url)).computeHashAndBuild());
} catch (URISyntaxException e) {
this.paradisu.logger().error("Failed to load pack: " + url + ": " + e.getMessage());
return Optional.empty();
}
}

/**
* Build the request future for a resource pack
*
* @param packInfo the pack info future
* @return the request future
*/
private CompletableFuture<ResourcePackRequest> buildRequestFuture(CompletableFuture<ResourcePackInfo> packInfo) {
return packInfo.thenApply(info -> {
return ResourcePackRequest.resourcePackRequest().packs(info).build();
});
}

/**
* Build the request future for a list of resource packs
*
* @param packInfos the list of pack info futures
* @return the request future
*/
private CompletableFuture<ResourcePackRequest> buildRequestFuture(List<CompletableFuture<ResourcePackInfo>> packInfos) {
@SuppressWarnings("unchecked")
CompletableFuture<ResourcePackInfo>[] packFutures = packInfos.toArray(new CompletableFuture[0]);

return CompletableFuture.allOf(packFutures).thenApply(v -> {
List<ResourcePackInfo> packs = new ArrayList<>();

for (CompletableFuture<ResourcePackInfo> packFuture : packFutures) {
try {
packs.add(packFuture.get());
} catch (InterruptedException | ExecutionException e) {
this.paradisu.logger().error("Failed to load pack: " + e.getMessage());
}

}
return ResourcePackRequest.resourcePackRequest().packs(packs).build();
});
}
}
11 changes: 11 additions & 0 deletions core/src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ paradisu.command.help.back.0=The target player
paradisu.command.help.locate=Returns the server the target player is connected to and their position
paradisu.command.help.ls=Returns a list of all online players
paradisu.command.help.locate.0=The target player
paradisu.command.help.packs=General utility command for managing resource packs
paradisu.command.help.packs.clear=Clears all resource packs from the specified player
paradisu.command.help.packs.clear.0=The target player
paradisu.command.help.packs.reload=Reloads the default resource packs and optionally resends them to all players
paradisu.command.help.packs.reload.0=Resend the resource packs to all players
paradisu.command.help.packs.resend=Resends the default resource packs to the specified player
paradisu.command.help.packs.resend.0=The target player
paradisu.command.help.tp=Teleports you to a player, or a player to another player
paradisu.command.help.tp.0=The target player
paradisu.command.help.tp.1=The player to be telported to the target player
Expand Down Expand Up @@ -54,6 +61,10 @@ paradisu.command.output.locate={0} is now on {1} at [{2}, {3}, {4}]
paradisu.command.output.ls.0=There are no players are online.
paradisu.command.output.ls.1=There is 1 player online:
paradisu.command.output.ls.2=There are {0} players online:
paradisu.command.output.packs.clear=Removed all resource packs from {0}
paradisu.command.output.packs.reload.0=Reloaded the default resource packs
paradisu.command.output.packs.reload.1=Reloaded and resent the default resource packs to all players
paradisu.command.output.packs.resend=Resent the default resource packs to {0}
paradisu.command.output.tp=Teleported {0} to {1}
paradisu.command.output.tpa.0=Teleported you to {0}
paradisu.command.output.tpa.1=Teleported {0} to you
Expand Down
69 changes: 36 additions & 33 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,62 +1,65 @@
[versions]
dotenv-kotlin = "6.4.1"
mariadb-java-client = "3.3.3"
mysql-connector-j = "8.3.0"
cloud = "1.8.4"
inventorygui = "1.6.2-SNAPSHOT"
paper-api = "1.20.4-R0.1-SNAPSHOT"
protocollib = "5.2.0-SNAPSHOT"
luckperms-api = "5.4"
configurate-yaml = "4.1.2"
adventure = "4.17.0-SNAPSHOT"
adventure-platform = "4.3.3-SNAPSHOT"
blossom = "1.2.0"
cloud = "1.8.4"
configurate-yaml = "4.1.2"
connectorplugin = "1.5.1-SNAPSHOT"
dotenv-kotlin = "6.4.1"
fastutil = "8.5.2"
guava = "31.1-jre"
log4j-slf4j-impl = "2.23.1"
velocity-api = "3.3.0-SNAPSHOT"
shadow = "8.1.1"
blossom = "1.2.0"
indra = "3.1.3"
inventorygui = "1.6.2-SNAPSHOT"
log4j-slf4j-impl = "2.23.1"
lombok = "8.6"
luckperms-api = "5.4"
mariadb-java-client = "3.3.3"
mysql-connector-j = "8.3.0"
paper-api = "1.20.4-R0.1-SNAPSHOT"
protocollib = "5.2.0-SNAPSHOT"
shadow = "8.1.1"
velocity-api = "3.3.0-SNAPSHOT"

[libraries]
dotenv-kotlin = { group = "io.github.cdimascio", name = "dotenv-kotlin", version.ref = "dotenv-kotlin" }
mariadb-java-client = { group = "org.mariadb.jdbc", name = "mariadb-java-client", version.ref = "mariadb-java-client" }
mysql-connector-j = { group = "com.mysql", name = "mysql-connector-j", version.ref = "mysql-connector-j" }
adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" }
adventure-platform-bukkit = { group = "net.kyori", name = "adventure-platform-bukkit", version.ref = "adventure-platform" }
adventure-text-minimessage = { group = "net.kyori", name = "adventure-text-minimessage", version.ref = "adventure" }
cloud-core = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" }
cloud-minecraft-extras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" }
cloud-paper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" }
cloud-velocity = { group = "cloud.commandframework", name = "cloud-velocity", version.ref = "cloud" }
cloud-minecraft-extras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" }
inventorygui = { group = "de.themoep", name = "inventorygui", version.ref = "inventorygui" }
paper-api = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper-api" }
protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version.ref = "protocollib" }
luckperms-api = { group = "net.luckperms", name = "api", version.ref = "luckperms-api" }
configurate-yaml = { group = "org.spongepowered", name = "configurate-yaml", version.ref = "configurate-yaml" }
adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" }
adventure-text-minimessage = { group = "net.kyori", name = "adventure-text-minimessage", version.ref = "adventure" }
adventure-platform-bukkit = { group = "net.kyori", name = "adventure-platform-bukkit", version.ref = "adventure-platform" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity-api" }
connectorplugin-bukkit = { group = "de.themoep.connectorplugin", name = "bukkit", version.ref = "connectorplugin" }
connectorplugin-core = { group = "de.themoep.connectorplugin", name = "core", version.ref = "connectorplugin" }
connectorplugin-velocity = { group = "de.themoep.connectorplugin", name = "velocity", version.ref = "connectorplugin" }
connectorplugin-bukkit = { group = "de.themoep.connectorplugin", name = "bukkit", version.ref = "connectorplugin" }
dotenv-kotlin = { group = "io.github.cdimascio", name = "dotenv-kotlin", version.ref = "dotenv-kotlin" }
fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
inventorygui = { group = "de.themoep", name = "inventorygui", version.ref = "inventorygui" }
log4j-slf4j-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j-impl", version.ref = "log4j-slf4j-impl" }
luckperms-api = { group = "net.luckperms", name = "api", version.ref = "luckperms-api" }
mariadb-java-client = { group = "org.mariadb.jdbc", name = "mariadb-java-client", version.ref = "mariadb-java-client" }
mysql-connector-j = { group = "com.mysql", name = "mysql-connector-j", version.ref = "mysql-connector-j" }
paper-api = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper-api" }
protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version.ref = "protocollib" }
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity-api" }

[bundles]
cloud-velocity = ["cloud-velocity", "cloud-minecraft-extras"]
cloud-paper = ["cloud-paper", "cloud-minecraft-extras"]
cloud-core = ["cloud-core", "cloud-minecraft-extras"]
adventure-core = ["adventure-api", "adventure-text-minimessage"]
adventure-velocity = ["adventure-api", "adventure-text-minimessage"]
adventure-bukkit = [
"adventure-api",
"adventure-text-minimessage",
"adventure-platform-bukkit",
]
adventure-core = ["adventure-api", "adventure-text-minimessage"]
adventure-velocity = ["adventure-api", "adventure-text-minimessage"]
cloud-core = ["cloud-core", "cloud-minecraft-extras"]
cloud-paper = ["cloud-paper", "cloud-minecraft-extras"]
cloud-velocity = ["cloud-velocity", "cloud-minecraft-extras"]
fastutil = ["fastutil-object-object-maps"]

[plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
indra-git = { id = "net.kyori.indra.git", version.ref = "indra" }
lombok = { id = "io.freefair.lombok", version.ref = "lombok" }
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
1 change: 1 addition & 0 deletions velocity/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies {
api(project(":core"))
implementation(libs.bundles.cloud.velocity)
implementation(libs.bundles.adventure.velocity)
implementation(libs.bundles.fastutil)
implementation(libs.configurate.yaml)
implementation(libs.guava)
compileOnly(libs.velocity.api)
Expand Down
Loading

0 comments on commit 7217755

Please sign in to comment.