From 50b43b6648ebd67efc8be12682c69fd70fbd154e Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Fri, 22 Nov 2024 18:55:41 +0100 Subject: [PATCH] Migrate PlayerMeta, add ReadyEvent, change name --- gradle.properties | 2 +- .../java/cc/reconnected/library/RccLib.java | 27 --- .../cc/reconnected/library/RccLibConfig.java | 2 +- .../cc/reconnected/library/RccLibrary.java | 51 +++++ .../library/config/ConfigManager.java | 4 +- .../reconnected/library/data/PlayerMeta.java | 179 ++++++++++++++++++ .../reconnected/library/event/ReadyEvent.java | 17 ++ .../library/text/parser/LinkParser.java | 6 +- .../text/parser/MarkdownComponentParser.java | 6 +- src/main/resources/fabric.mod.json | 7 +- 10 files changed, 260 insertions(+), 41 deletions(-) delete mode 100644 src/main/java/cc/reconnected/library/RccLib.java create mode 100644 src/main/java/cc/reconnected/library/RccLibrary.java create mode 100644 src/main/java/cc/reconnected/library/data/PlayerMeta.java create mode 100644 src/main/java/cc/reconnected/library/event/ReadyEvent.java diff --git a/gradle.properties b/gradle.properties index 53de9aa..ca6cad7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ loader_version=0.16.9 # Mod Properties mod_version=1.0.0 maven_group=cc.reconnected -archives_base_name=rcc-lib +archives_base_name=rcc-library # Dependencies # check this on https://modmuss50.me/fabric.html fabric_version=0.92.2+1.20.1 diff --git a/src/main/java/cc/reconnected/library/RccLib.java b/src/main/java/cc/reconnected/library/RccLib.java deleted file mode 100644 index 13bd770..0000000 --- a/src/main/java/cc/reconnected/library/RccLib.java +++ /dev/null @@ -1,27 +0,0 @@ -package cc.reconnected.library; - -import cc.reconnected.library.config.ConfigManager; -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -public class RccLib implements ModInitializer { - public static final String MOD_ID = "rcclib"; - public static RccLibConfig CONFIG; - public static Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - @Override - public void onInitialize() { - try { - loadConfig(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static void loadConfig() throws IOException { - CONFIG = ConfigManager.load(RccLibConfig.class); - } -} diff --git a/src/main/java/cc/reconnected/library/RccLibConfig.java b/src/main/java/cc/reconnected/library/RccLibConfig.java index a43c1aa..688345a 100644 --- a/src/main/java/cc/reconnected/library/RccLibConfig.java +++ b/src/main/java/cc/reconnected/library/RccLibConfig.java @@ -2,7 +2,7 @@ package cc.reconnected.library; import cc.reconnected.library.config.Config; -@Config(RccLib.MOD_ID) +@Config(RccLibrary.MOD_ID) public class RccLibConfig { public String link = "${label}"; public String linkHover = "${url}"; diff --git a/src/main/java/cc/reconnected/library/RccLibrary.java b/src/main/java/cc/reconnected/library/RccLibrary.java new file mode 100644 index 0000000..57e0d1d --- /dev/null +++ b/src/main/java/cc/reconnected/library/RccLibrary.java @@ -0,0 +1,51 @@ +package cc.reconnected.library; + +import cc.reconnected.library.config.ConfigManager; +import cc.reconnected.library.event.ReadyEvent; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class RccLibrary implements ModInitializer { + public static final String MOD_ID = "rcc-library"; + public static RccLibConfig CONFIG; + public static Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + private LuckPerms luckPerms; + + public LuckPerms luckPerms() { + return luckPerms; + } + + private static RccLibrary instance; + public static RccLibrary getInstance() { + return instance; + } + + public RccLibrary() { + instance = this; + } + + @Override + public void onInitialize() { + try { + loadConfig(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + ServerLifecycleEvents.SERVER_STARTED.register(server -> { + luckPerms = LuckPermsProvider.get(); + ReadyEvent.EVENT.invoker().onReady(server, this); + }); + } + + public static void loadConfig() throws IOException { + CONFIG = ConfigManager.load(RccLibConfig.class); + } +} diff --git a/src/main/java/cc/reconnected/library/config/ConfigManager.java b/src/main/java/cc/reconnected/library/config/ConfigManager.java index 7123b1b..f112c92 100644 --- a/src/main/java/cc/reconnected/library/config/ConfigManager.java +++ b/src/main/java/cc/reconnected/library/config/ConfigManager.java @@ -1,6 +1,6 @@ package cc.reconnected.library.config; -import cc.reconnected.library.RccLib; +import cc.reconnected.library.RccLibrary; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import net.fabricmc.loader.api.FabricLoader; @@ -57,7 +57,7 @@ public class ConfigManager { try (var fw = new FileWriter(path.toFile(), StandardCharsets.UTF_8)) { fw.write(json); } catch (Exception e) { - RccLib.LOGGER.error("Error saving {} config file.", id, e); + RccLibrary.LOGGER.error("Error saving {} config file.", id, e); } } } diff --git a/src/main/java/cc/reconnected/library/data/PlayerMeta.java b/src/main/java/cc/reconnected/library/data/PlayerMeta.java new file mode 100644 index 0000000..0370e67 --- /dev/null +++ b/src/main/java/cc/reconnected/library/data/PlayerMeta.java @@ -0,0 +1,179 @@ +package cc.reconnected.library.data; + +import cc.reconnected.library.RccLibrary; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.model.user.User; +import net.luckperms.api.node.Node; +import net.luckperms.api.node.NodeBuilder; +import net.luckperms.api.node.NodeType; +import net.luckperms.api.node.types.MetaNode; +import net.minecraft.server.network.ServerPlayerEntity; +import org.jetbrains.annotations.Nullable; + +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +public class PlayerMeta { + public static final String nodePrefix = "rcc"; + + private static LuckPerms luckPerms() { + return RccLibrary.getInstance().luckPerms(); + } + + public static class KEYS { + public static final String username = "username"; + public static final String discordId = "discord_id"; + public static final String isBot = "is_bot"; + public static final String isAlt = "is_alt"; + public static final String pronouns = "pronouns"; + public static final String firstJoinedDate = "first_joined_date"; + public static final String supporterLevel = "supporter_level"; + public static final String activeTime = "active_time"; + } + + private final User lpUser; + + private final UUID uuid; + @Nullable + private String name; + + private Set rawNodes; + private Map nodes; + + private PlayerMeta(UUID uuid, User lpUser) { + this.uuid = uuid; + this.lpUser = lpUser; + + refreshNodes(); + } + + public UUID getUuid() { + return uuid; + } + + public @Nullable String getUsername() { + var username = get(KEYS.username); + if (username == null) { + return name; + } + return username; + } + + public String getEffectiveName() { + var effName = getUsername(); + if (effName == null) + return uuid.toString(); + return effName; + } + + public void refreshNodes() { + rawNodes = lpUser.getNodes(NodeType.META) + .parallelStream() + .filter(node -> node.getMetaKey().startsWith(nodePrefix + ".")) + .collect(Collectors.toSet()); + + nodes = rawNodes.stream().collect(Collectors.toMap(MetaNode::getMetaKey, MetaNode::getMetaValue)); + } + + @SuppressWarnings("UnusedReturnValue") + public CompletableFuture set(String key, @Nullable String value) { + var node = meta(key, value).build(); + return luckPerms().getUserManager().modifyUser(uuid, user -> { + user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals(key))); + user.data().add(node); + refreshNodes(); + }); + } + + @SuppressWarnings("UnusedReturnValue") + public CompletableFuture set(String key, @Nullable String value, boolean replace) { + if (replace) delete(key); + return set(key, value); + } + + public @Nullable String get(String key) { + if (!nodes.containsKey(nodePrefix + "." + key)) + return null; + return nodes.get(nodePrefix + "." + key); + } + + public @Nullable MetaNode getNode(String key) { + return rawNodes.stream().filter(rawNode -> rawNode.getMetaKey().equals(key)).findFirst().orElse(null); + } + + @SuppressWarnings("UnusedReturnValue") + public CompletableFuture setBoolean(String key, boolean value) { + return set(key, Boolean.toString(value)); + } + + public boolean getBoolean(String key) { + if (!nodes.containsKey(nodePrefix + "." + key)) + return false; + return Boolean.parseBoolean(nodes.get(nodePrefix + "." + key)); + } + + public boolean getBoolean(String key, boolean defaultValue) { + if (!nodes.containsKey(nodePrefix + "." + key)) + return defaultValue; + return Boolean.parseBoolean(nodes.get(nodePrefix + "." + key)); + } + + @SuppressWarnings("UnusedReturnValue") + public CompletableFuture setDate(String key, Date date) { + var dateString = DateTimeFormatter.ISO_INSTANT.format(date.toInstant()); + return set(key, dateString); + } + + public Date getDate(String key) { + if (!nodes.containsKey(nodePrefix + "." + key)) + return null; + var dateString = nodes.get(nodePrefix + "." + key); + var ta = DateTimeFormatter.ISO_INSTANT.parse(dateString); + return Date.from(Instant.from(ta)); + } + + @SuppressWarnings("UnusedReturnValue") + public CompletableFuture delete(String key) { + return luckPerms().getUserManager().modifyUser(uuid, user -> { + user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals(nodePrefix + "." + key))); + }); + } + + public String getPrimaryGroup() { + return lpUser.getPrimaryGroup(); + } + + public static PlayerMeta getPlayer(UUID uuid) { + var lp = luckPerms(); + var userManager = lp.getUserManager(); + + var userFuture = userManager.loadUser(uuid); + // TODO: ouch, not good... + var lpUser = userFuture.join(); + + var playerData = new PlayerMeta(uuid, lpUser); + playerData.name = lpUser.getUsername(); + return playerData; + } + + public static PlayerMeta getPlayer(ServerPlayerEntity player) { + var user = luckPerms().getPlayerAdapter(ServerPlayerEntity.class).getUser(player); + var playerData = new PlayerMeta(player.getUuid(), user); + playerData.name = player.getEntityName(); + return playerData; + } + + public static NodeBuilder node(String key) { + return Node.builder(nodePrefix + "." + key); + } + + public static NodeBuilder meta(String key, String value) { + return MetaNode.builder(nodePrefix + "." + key, value); + } +} diff --git a/src/main/java/cc/reconnected/library/event/ReadyEvent.java b/src/main/java/cc/reconnected/library/event/ReadyEvent.java new file mode 100644 index 0000000..ee7b7da --- /dev/null +++ b/src/main/java/cc/reconnected/library/event/ReadyEvent.java @@ -0,0 +1,17 @@ +package cc.reconnected.library.event; + +import cc.reconnected.library.RccLibrary; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.server.MinecraftServer; + +public interface ReadyEvent { + Event EVENT = EventFactory.createArrayBacked(ReadyEvent.class, + (listeners) -> (server, instance) -> { + for (var listener : listeners) { + listener.onReady(server, instance); + } + }); + + void onReady(MinecraftServer server, RccLibrary instance); +} diff --git a/src/main/java/cc/reconnected/library/text/parser/LinkParser.java b/src/main/java/cc/reconnected/library/text/parser/LinkParser.java index 0dcb09d..9aed537 100644 --- a/src/main/java/cc/reconnected/library/text/parser/LinkParser.java +++ b/src/main/java/cc/reconnected/library/text/parser/LinkParser.java @@ -1,6 +1,6 @@ package cc.reconnected.library.text.parser; -import cc.reconnected.library.RccLib; +import cc.reconnected.library.RccLibrary; import cc.reconnected.library.text.Placeholder; import eu.pb4.placeholders.api.node.DirectTextNode; import eu.pb4.placeholders.api.node.LiteralNode; @@ -51,12 +51,12 @@ public class LinkParser implements NodeParser { ); var display = Placeholder.parse( - RccLib.CONFIG.link, + RccLibrary.CONFIG.link, placeholders ); var hover = Placeholder.parse( - RccLib.CONFIG.linkHover, + RccLibrary.CONFIG.linkHover, placeholders ); diff --git a/src/main/java/cc/reconnected/library/text/parser/MarkdownComponentParser.java b/src/main/java/cc/reconnected/library/text/parser/MarkdownComponentParser.java index 9ebca01..bd8c4ae 100644 --- a/src/main/java/cc/reconnected/library/text/parser/MarkdownComponentParser.java +++ b/src/main/java/cc/reconnected/library/text/parser/MarkdownComponentParser.java @@ -1,6 +1,6 @@ package cc.reconnected.library.text.parser; -import cc.reconnected.library.RccLib; +import cc.reconnected.library.RccLibrary; import cc.reconnected.library.text.Placeholder; import eu.pb4.placeholders.api.node.TextNode; import eu.pb4.placeholders.api.node.parent.ClickActionNode; @@ -37,8 +37,8 @@ public class MarkdownComponentParser { "label", TextNode.wrap(textNodes).toText(), "url", url.toText() ); - var text = Placeholder.parse(RccLib.CONFIG.link, placeholders); - var hover = Placeholder.parse(RccLib.CONFIG.linkHover, placeholders); + var text = Placeholder.parse(RccLibrary.CONFIG.link, placeholders); + var hover = Placeholder.parse(RccLibrary.CONFIG.linkHover, placeholders); return new HoverNode<>(TextNode.array( new ClickActionNode( diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 61bb0b1..74dec91 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,17 +1,16 @@ { "schemaVersion": 1, - "id": "rcc-lib", + "id": "rcc-library", "version": "${version}", - "name": "rcc-lib", + "name": "rcc-library", "description": "", "authors": [], "contact": {}, "license": "MIT", - "icon": "assets/rcc-lib/icon.png", "environment": "server", "entrypoints": { "main": [ - "cc.reconnected.library.RccLib" + "cc.reconnected.library.RccLibrary" ] }, "depends": {