NotAlexNoyle e3f08f7420 Merge pull request #5 from SKBotNL/main
Add player data API and remove FastOfflinePlayer
2026-09-16 08:09:25 -04:00
2025-07-24 09:08:23 -04:00
2026-09-15 23:19:36 +02:00
2025-07-30 12:00:56 -04:00
2026-09-15 23:19:36 +02:00
2025-06-05 09:53:43 -04:00
2025-06-05 09:53:43 -04:00
2023-05-30 21:29:42 -04:00
2024-07-11 08:39:31 -04:00

Utilities-OG

A collection of utilities and APIs used by TrueOG Network. Developed by christianniehaus & NotAlexNoyle.

Current Target: Purpur 1.19.4

Building:

./gradlew build

The resulting .jar file will be in build/libs

At the moment, any config change requires a server restart to take effect.

MiniPlaceholders support is always enabled. There is no config toggle for disabling the built-in placeholder registration.

Features:

  • Mock Bamboo: Enables crafting mock bamboo planks from 2x2 bamboo and mock bamboo wood from 2x2 mock bamboo planks.
  • Chain Armor: Enables crafting chain armor from chains.
  • Color Codes: Displays information to players about Bukkit's chat color codes and their syntax.
  • MiniPlaceholders: Includes MiniPlaceholders-based expansion helpers and registration utilities. MiniPlaceholders is the only supported placeholder provider.
  • NoFlippy: Honors WorldGuard's can-flippy flag: DENY blocks trapdoors and fence gates, ALLOW explicitly permits them, and an unset flag preserves normal protection (Requires WorldGuard plugin).
  • Random Spawner Drops: Gives Silk Touch spawner breaks a configurable chance to drop a spawner that retains its mob type. No Silk Touch means no drop.
  • Random Dragon Egg Drops: Gives dragon egg formation a configurable chance to succeed.
  • TogglePhantoms: Allows players to use the /togglephantoms command to turn phantom spawning on or off for themselves.
  • Ping: Provides two commands: /ping (displays real player ping) and /bing (replicates vanilla /ping functionality).
  • Ranks Menu: Displays information to players about available ranks at the TrueOG Network Store.

Warning:

  • DisableEntityCramming (Default: false): Disables entity cramming damage server-wide. This can cause lag if no other plugin manages entity limits. Enable this Module only if you have a separate plugin managing entity limitations.

Permissions:

  • utilities.about
    • Description: Allows players to use the base /utilities command to get information about the plugin.
    • Default: op (Server Operator)
  • utilities.colorcodes
    • Description: Grants permission to use the /colorcodes command to view Bukkit chat color code information.
    • Default: op (Server Operator)
  • utilities.togglephantoms
    • Description: Allows players to use the /togglephantoms command to enable or disable phantom spawning for themselves.
    • Default: op (Server Operator)
  • utilities.togglecramming
    • Description: Grants permission to use the /togglecramming command (if enabled) to manage entity cramming damage.
    • Default: op (Server Operator)
  • utilities.ranks
    • Description: Allows players to use the /ranks command to view information about available ranks on the TrueOG Network Store.
    • Default: op (Server Operator)
  • utilities.ping
    • Description: Grants permission to use the /ping (real ping) and /bing (mimics vanilla ping) commands.
    • Default: op (Server Operator)

Please note: These permissions can be modified in the Utilities-OG configuration file config.yml.

API Documentation:

Controlling which MiniMessage tags render: MessageFormat

Every messaging and formatting API below accepts an optional final MessageFormat argument that decides which MiniMessage StandardTags families get resolved. MessageFormat is immutable and fluent, so call sites read naturally and bad tag references become compile-time errors.

Supported tag families:

Method MiniMessage tags honored
withColor / withoutColor <color:...>, <red>, <#ff00aa>, &0-&f
withDecorations / withoutDecorations <bold>, <italic>, <underlined>, <strikethrough>, <obfuscated>, <!bold>, &k-&o
withRainbow / withoutRainbow <rainbow>, <rainbow:phase>, &*
withGradient / withoutGradient <gradient:color1:color2:...>
withReset / withoutReset <reset>, &r

Presets:

  • MessageFormat.full() — every supported tag enabled. This is the default for trueogMessage, trueogRawMessage, trueogColorize, and trueogExpand when no format is passed.
  • MessageFormat.none() — every supported tag disabled.

Semantics: tags enabled on the format are resolved as usual; tags disabled on the format stay as literal MiniMessage text in the rendered output. MessageFormat only applies to the send / format APIs — stripFormatting and logToConsole always strip everything and have no format overload.

Kotlin:

val noGradient = MessageFormat.full().withoutGradient()
UtilitiesOG.trueogMessage(player, "<gradient:red:blue>kept as markup</gradient> <red>rendered</red>", noGradient)

Java:

MessageFormat noGradient = MessageFormat.full().withoutGradient();
UtilitiesOG.trueogMessage(player, "<gradient:red:blue>kept as markup</gradient> <red>rendered</red>", noGradient);

MessageFormat instances are immutable and safe to share across threads. MiniMessage instances are cached internally per format.

Note: StandardTags.shadowColor() was added in Adventure 4.18+ and is not available in the Adventure 4.13.1 bundled with Purpur 1.19.4. It is therefore not part of MessageFormat in this release.

[void] trueogMessage(Player player, String message)

Sends a message to the specified player with TrueOG formatting on the caller's current thread. Supports both modern color codes and legacy Bukkit color codes (case-insensitive). Automatically expands MiniPlaceholders within the message.

Kotlin:

val targetPlayer = Bukkit.getPlayer("USERNAME")
UtilitiesOG.trueogMessage(targetPlayer, "&6This is a &*message with <green>True&4OG <bold>formatting!")

Java:

Player targetPlayer = Bukkit.getPlayer("USERNAME");
UtilitiesOG.trueogMessage(targetPlayer, "&6This is a &*message with <green>True&4OG <bold>formatting!");

[void] trueogMessage(Player player, String message, MessageFormat format)

Sends a message with the given MessageFormat controlling which tag families are resolved. Tags that the format disables remain as literal MiniMessage markup.

Kotlin:

UtilitiesOG.trueogMessage(targetPlayer, "<rainbow>colorful</rainbow>", MessageFormat.full().withoutRainbow())

Java:

UtilitiesOG.trueogMessage(targetPlayer, "<rainbow>colorful</rainbow>", MessageFormat.full().withoutRainbow());

[void] trueogRawMessage(Player player, String message)

Sends a message to the specified player with TrueOG formatting on the caller's current thread without expanding MiniPlaceholders within the message. Supports both modern color codes and legacy Bukkit color codes (case-insensitive).

Kotlin:

val targetPlayer = Bukkit.getPlayer("USERNAME")
UtilitiesOG.trueogRawMessage(targetPlayer, "&6Literal placeholder: <player_display_name>")

Java:

Player targetPlayer = Bukkit.getPlayer("USERNAME");
UtilitiesOG.trueogRawMessage(targetPlayer, "&6Literal placeholder: <player_display_name>");

[void] trueogRawMessage(Player player, String message, MessageFormat format)

Format-aware raw send. Tags disabled by the format stay literal.

Kotlin:

UtilitiesOG.trueogRawMessage(targetPlayer, "&6<gradient:red:blue>hi</gradient>", MessageFormat.full().withoutGradient())

Java:

UtilitiesOG.trueogRawMessage(targetPlayer, "&6<gradient:red:blue>hi</gradient>", MessageFormat.full().withoutGradient());

[void] trueogMessage(Player player, Component message)

Sends a pre-built Adventure Component to the specified player on the caller's current thread. This overload does not perform placeholder expansion or color-code processing.

Kotlin:

val targetPlayer = Bukkit.getPlayer("USERNAME")
val component = MiniMessage.miniMessage().deserialize("<green>Ready.")
UtilitiesOG.trueogMessage(targetPlayer, component)

Java:

Player targetPlayer = Bukkit.getPlayer("USERNAME");
Component component = MiniMessage.miniMessage().deserialize("<green>Ready.");
UtilitiesOG.trueogMessage(targetPlayer, component);

[void] trueogMessage(Player player, Component message, MessageFormat format)

Sends a pre-built Component after clearing styles that the format disables. withoutColor clears TextColor; withoutDecorations clears every TextDecoration. Rainbow and gradient are not distinguishable from color at the Component level, so those flags have no additional effect on this overload — use the String overloads to keep rainbow/gradient markup unresolved.

Kotlin:

val colorless = MessageFormat.full().withoutColor()
UtilitiesOG.trueogMessage(targetPlayer, component, colorless)

Java:

MessageFormat colorless = MessageFormat.full().withoutColor();
UtilitiesOG.trueogMessage(targetPlayer, component, colorless);

[void] trueogMessage(UUID playerUUID, String message)

Sends a message to a player identified by their UUID with TrueOG formatting. Useful when the Bukkit Player object is not available. Supports modern color codes and legacy Bukkit color codes (case-insensitive), and expands MiniPlaceholders within the message. If the UUID resolves to an online player, the message is sent immediately on the caller's current thread.

Kotlin:

val playerUUID = UUID.fromString("player_uuid")
UtilitiesOG.trueogMessage(playerUUID, "&6Hello there!")

Java:

UUID playerUUID = UUID.fromString("player_uuid");
UtilitiesOG.trueogMessage(playerUUID, "&6Hello there!");

[void] trueogMessage(UUID playerUUID, String message, MessageFormat format)

Format-aware UUID message send. Same semantics as trueogMessage(Player, String, MessageFormat).

Kotlin:

UtilitiesOG.trueogMessage(playerUUID, "&6Hi!", MessageFormat.full().withoutDecorations())

Java:

UtilitiesOG.trueogMessage(playerUUID, "&6Hi!", MessageFormat.full().withoutDecorations());

[void] trueogRawMessage(UUID playerUUID, String message)

Sends a message to a player identified by their UUID with TrueOG formatting but without MiniPlaceholder expansion. Useful when the Bukkit Player object is not available. Supports modern color codes and legacy Bukkit color codes (case-insensitive). If the UUID resolves to an online player, the message is sent immediately on the caller's current thread.

Kotlin:

val playerUUID = UUID.fromString("player_uuid")
UtilitiesOG.trueogRawMessage(playerUUID, "&6Literal placeholder: <player_display_name>")

Java:

UUID playerUUID = UUID.fromString("player_uuid");
UtilitiesOG.trueogRawMessage(playerUUID, "&6Literal placeholder: <player_display_name>");

[void] trueogRawMessage(UUID playerUUID, String message, MessageFormat format)

Format-aware UUID raw send. Same semantics as trueogRawMessage(Player, String, MessageFormat).

Kotlin:

UtilitiesOG.trueogRawMessage(playerUUID, "&6<rainbow>hi</rainbow>", MessageFormat.full().withoutRainbow())

Java:

UtilitiesOG.trueogRawMessage(playerUUID, "&6<rainbow>hi</rainbow>", MessageFormat.full().withoutRainbow());

[TextComponent] trueogExpand(String message)

Expands MiniPlaceholders within a message string without any player context. Supports color code processing via TrueOG's formatting.

Kotlin:

val message = "Welcome to the server, everyone!"
val expandedMessage = UtilitiesOG.trueogExpand(message)

Java:

String message = "Welcome to the server, everyone!";
TextComponent expandedMessage = UtilitiesOG.trueogExpand(message);

[TextComponent] trueogExpand(String message, MessageFormat format)

Format-aware global expansion. Tags disabled by the format stay literal.

Kotlin:

val expandedMessage = UtilitiesOG.trueogExpand(message, MessageFormat.full().withoutGradient())

Java:

TextComponent expandedMessage = UtilitiesOG.trueogExpand(message, MessageFormat.full().withoutGradient());

[TextComponent] trueogExpand(String message, Player player)

Expands MiniPlaceholders within a message string using the provided player's context. Supports color code processing.

Kotlin:

val targetPlayer = Bukkit.getPlayer("SomePlayer")
val message = "Welcome back, <player_display_name>!"
val expandedMessage = UtilitiesOG.trueogExpand(message, targetPlayer)
UtilitiesOG.trueogMessage(targetPlayer, expandedMessage)

Java:

Player targetPlayer = Bukkit.getPlayer("SomePlayer");
String message = "Welcome back, <player_display_name>!";
TextComponent expandedMessage = UtilitiesOG.trueogExpand(message, targetPlayer);
UtilitiesOG.trueogMessage(targetPlayer, expandedMessage);

[TextComponent] trueogExpand(String message, Player player, MessageFormat format)

Format-aware audience expansion.

Kotlin:

val expanded = UtilitiesOG.trueogExpand(message, targetPlayer, MessageFormat.full().withoutRainbow())

Java:

TextComponent expanded = UtilitiesOG.trueogExpand(message, targetPlayer, MessageFormat.full().withoutRainbow());

[TextComponent] trueogExpand(String message, Player player, Player target)

Expands MiniPlaceholders within a message string using both the sender's and the target's player contexts, which is useful for relational placeholders. Supports color code processing.

Kotlin:

val player = Bukkit.getPlayer("Player")
val target = Bukkit.getPlayer("TargetPlayer")
val message = "<player_display_name> is sending a message to <target_display_name>"
val expandedMessage = UtilitiesOG.trueogExpand(message, player, target)
UtilitiesOG.trueogMessage(player, expandedMessage)

Java:

Player player = Bukkit.getPlayer("Player");
Player target = Bukkit.getPlayer("TargetPlayer");
String message = "<player_display_name> is sending a message to <target_display_name>";
TextComponent expandedMessage = UtilitiesOG.trueogExpand(message, player, target);
UtilitiesOG.trueogMessage(player, expandedMessage);

[TextComponent] trueogExpand(String message, Player player, Player target, MessageFormat format)

Format-aware relational expansion.

Kotlin:

val expanded = UtilitiesOG.trueogExpand(message, player, target, MessageFormat.full().withoutGradient())

Java:

TextComponent expanded = UtilitiesOG.trueogExpand(message, player, target, MessageFormat.full().withoutGradient());

[TextComponent] trueogExpand(String message, UUID playerUUID)

Expands MiniPlaceholders within a message string using a player's UUID, useful when the Player object isn't available. Supports color code processing.

Kotlin:

val playerUUID = UUID.fromString("player_uuid")
val message = "Welcome back, <player_display_name>!"
val expandedMessage = UtilitiesOG.trueogExpand(message, playerUUID)
UtilitiesOG.trueogMessage(playerUUID, expandedMessage)

Java:

UUID playerUUID = UUID.fromString("player_uuid");
String message = "Welcome back, <player_display_name>!";
TextComponent expandedMessage = UtilitiesOG.trueogExpand(message, playerUUID);
UtilitiesOG.trueogMessage(playerUUID, expandedMessage);

[TextComponent] trueogExpand(String message, UUID playerUUID, MessageFormat format)

Format-aware UUID expansion. Falls back to the global context when the player is offline.

Kotlin:

val expanded = UtilitiesOG.trueogExpand(message, playerUUID, MessageFormat.full().withoutRainbow())

Java:

TextComponent expanded = UtilitiesOG.trueogExpand(message, playerUUID, MessageFormat.full().withoutRainbow());

[void] registerGlobalPlaceholder(String placeholderName, {String})

Registers a global MiniPlaceholder that can be used anywhere in your messages. The valueSupplier provides the placeholder's value at runtime. Prefixes are the values before the first underscore. For example, the prefix of server_name is server.

Examples Without Arguments:

Kotlin:

UtilitiesOG.registerGlobalPlaceholder("server_name") { "&aTrue&cOG &eNetwork" }

Java:

UtilitiesOG.registerGlobalPlaceholder("server_name", () -> "&aTrue&cOG &eNetwork");

Examples With Arguments:

Kotlin:

UtilitiesOG.registerGlobalPlaceholder("server_stat") { args ->
    val statName = args.getOrNull(0)?.lowercase() ?: return@registerGlobalPlaceholder "Invalid stat name"
    when (statName) {
        "uptime" -> "Up for 5 hours"
        "playercount" -> Bukkit.getOnlinePlayers().size.toString()
        else -> "Unknown stat"
    }
}

Java:

UtilitiesOG.registerGlobalPlaceholder("server_stat", args -> {
    if (args.isEmpty()) return "Invalid stat name";
    String statName = args.get(0).toLowerCase();
    switch (statName) {
        case "uptime":
            return "Up for 5 hours";
        case "playercount":
            return String.valueOf(Bukkit.getOnlinePlayers().size());
        default:
            return "Unknown stat";
    }
});

[void] registerAudiencePlaceholder(String name, player -> {String})

Registers an audience-specific MiniPlaceholder. The valueFunction uses the player's context to generate a dynamic value for the placeholder. Prefixes are the values before the first underscore. For example, the prefix of player_display_name is player.

Examples Without Arguments:

Kotlin:

UtilitiesOG.registerAudiencePlaceholder("player_display_name") { player ->
    val luckPerms = LuckPermsProvider.get()
    val user = luckPerms.getUserManager().getUser(player.uniqueId)
    val prefix = user?.cachedData?.metaData?.prefix ?: ""
    "$prefix ${player.name}"
}

Java:

UtilitiesOG.registerAudiencePlaceholder("player_display_name", player -> {
    LuckPerms luckPerms = LuckPermsProvider.get();
    User user = luckPerms.getUserManager().getUser(player.getUniqueId());
    String prefix = user != null ? user.getCachedData().getMetaData().getPrefix() : "";
    return prefix + " " + player.getName();
});

Examples With Arguments:

Kotlin:

UtilitiesOG.registerAudiencePlaceholder("essentials_kit_last_use") { player, args ->
    val kitName = args.getOrNull(0)?.lowercase() ?: return@registerAudiencePlaceholder "Invalid kit name"
    val kit = try {
        Kit(kitName, essentials) // Assume 'essentials' is properly initialized
    } catch (e: Exception) {
        return@registerAudiencePlaceholder "Invalid kit name"
    }
    val time = essentials.getUser(player.uniqueId).getKitTimestamp(kit.name)
    if (time <= 0) "Never used" else DateFormat.getDateInstance().format(Date(time))
}

Java:

UtilitiesOG.registerAudiencePlaceholder("essentials_kit_last_use", (player, args) -> {
    if (args.isEmpty()) return "Invalid kit name";
    String kitName = args.get(0).toLowerCase();
    Kit kit;
    try {
        kit = new Kit(kitName, essentials); // Assume 'essentials' is properly initialized
    } catch (Exception e) {
        return "Invalid kit name";
    }
    long time = essentials.getUser(player.getUniqueId()).getKitTimestamp(kit.getName());
    return time <= 0 ? "Never used" : DateFormat.getDateInstance().format(new Date(time));
});

[void] registerRelationalPlaceholder(String name, player, target -> {String})

Registers a relational MiniPlaceholder that depends on two players (e.g., viewer and target). The valueFunction provides a dynamic value based on both players' contexts. Prefixes are the values before the first underscore. For example, the prefix of distance_between is distance.

Examples Without Arguments:

Kotlin:

UtilitiesOG.registerRelationalPlaceholder("distance_between") { player, target ->
    val distance = player.location.distance(target.location)
    "Distance: ${distance.toInt()} blocks"
}

Java:

UtilitiesOG.registerRelationalPlaceholder("distance_between", (player, target) -> {
    double distance = player.getLocation().distance(target.getLocation());
    return "Distance: " + (int) distance + " blocks";
});

Examples With Arguments:

Kotlin:

UtilitiesOG.registerRelationalPlaceholder("relation_compare_stat") { player, target, args ->
    val stat = args.getOrNull(0)?.lowercase() ?: return@registerRelationalPlaceholder "No stat provided"
    when (stat) {
        "balance" -> {
            val playerBalance = getBalance(player) // Implement getBalance accordingly
            val targetBalance = getBalance(target) // Implement getBalance accordingly
            when {
                playerBalance > targetBalance -> "You have more money than ${target.name}"
                playerBalance < targetBalance -> "${target.name} has more money than you"
                else -> "You and ${target.name} have the same amount of money"
            }
        }
        else -> "Unknown stat"
    }
}

Java:

UtilitiesOG.registerRelationalPlaceholder("relation_compare_stat", (player, target, args) -> {
    if (args.isEmpty()) return "No stat provided";
    String stat = args.get(0).toLowerCase();
    switch (stat) {
        case "balance":
            double playerBalance = getBalance(player); // Implement getBalance accordingly
            double targetBalance = getBalance(target); // Implement getBalance accordingly
            if (playerBalance > targetBalance) {
                return "You have more money than " + target.getName();
            } else if (playerBalance < targetBalance) {
                return target.getName() + " has more money than you";
            } else {
                return "You and " + target.getName() + " have the same amount of money";
            }
        default:
            return "Unknown stat";
    }
});

[TextComponent] trueogColorize(String message)

Formats a String into a TextComponent. Supports modern and legacy color codes. Does not include custom MiniPlaceholder Expansion logic.

Kotlin:

val colorized = UtilitiesOG.trueogColorize(message)

Java:

TextComponent colorized = UtilitiesOG.trueogColorize(message);

[TextComponent] trueogColorize(String message, MessageFormat format)

Format-aware colorize. Tags disabled by the format stay as literal MiniMessage markup.

Kotlin:

val colorized = UtilitiesOG.trueogColorize(message, MessageFormat.full().withoutGradient())

Java:

TextComponent colorized = UtilitiesOG.trueogColorize(message, MessageFormat.full().withoutGradient());

[String] stripFormatting(String content)

Strips every legacy Bukkit code and every supported MiniMessage tag from a String, returning plain text. Parsing goes through MiniMessage, so hex colors, closing tags, nested gradients, and rainbow phase arguments all collapse correctly.

Kotlin:

val unformatted = UtilitiesOG.stripFormatting(content)

Java:

String unformatted = UtilitiesOG.stripFormatting(content);

[String] stripFormatting(Component component)

Flattens a Component tree to plain text, discarding every style and tag. Useful for passing player-visible messages into systems that only accept raw strings (logs, databases, web APIs).

Kotlin:

val unformatted = UtilitiesOG.stripFormatting(component)

Java:

String unformatted = UtilitiesOG.stripFormatting(component);

[void] logToConsole(String prefix, String message)

Logs a message to the server console with a prefix. The message and prefix have every legacy Bukkit code and every supported MiniMessage tag stripped before logging.

Kotlin:

UtilitiesOG.logToConsole("[MyPlugin-OG]", "&6This is a &*message with <green>color codes!")

Java:

UtilitiesOG.logToConsole("[MyPlugin-OG]", "&6This is a &*message with <green>color codes!");

[ItemStack[]] getInventoryData(UUID uuid)

Gets the inventory contents of an offline player using the TrueOG Purpur player data API.

Kotlin:

val inventoryData = UtilitiesOG.getInventoryData(uuid)

Java:

ItemStack[] inventoryData = UtilitiesOG.getInventoryData(uuid);

[void] setInventoryData(UUID uuid, ItemStack[] items)

Sets the inventory contents of an offline player using the TrueOG Purpur player data API.

Kotlin:

UtilitiesOG.setInventoryData(uuid, inventoryData)

Java:

UtilitiesOG.setInventoryData(uuid, inventoryData);

[int] getHeldItemSlot(UUID uuid)

Gets the held item slot of an offline player using the TrueOG Purpur player data API.

Kotlin:

val heldItemSlot = UtilitiesOG.getHeldItemSlot(uuid)

Java:

int heldItemSlot = UtilitiesOG.getHeldItemSlot(uuid);
S
Description
A collection of utilities and APIs used by TrueOG Network. Developed by christianniehaus & NotAlexNoyle.
Readme Unlicense
644 KiB
0 Stars 2 Watchers 0 Forks
Languages
Java 100%