# Utilities-OG A collection of utilities and APIs used by [TrueOG Network](https://true-og.net/). Developed by christianniehaus & NotAlexNoyle. Current Target: Purpur 1.19.4 ## Building: ./gradlew build The resulting .jar file will be in build/libs Any config change requires a server restart to take effect. ## 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](https://store.true-og.net). * **Placeholder Test:** `/phtest [player]` resolves every MiniPlaceholder listed under `PlaceholderTestPlugins` in config.yml and marks each one `[OK]`, `[EMPTY]`, `[NOT REGISTERED]` or `[REGISTERED BUT UNRESOLVED]`. `/phtest raw [player]` expands any MiniMessage text. **Warning:** * **DisableEntityCramming (Default: true):** Disables entity cramming damage server-wide. This can cause lag if no other plugin manages entity limits. Keep this module enabled 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) * **`utilities.phtest`** * **Description:** Allows players to use the `/phtest` command. Grant it with LuckPerms; the console can always run it. * **Default:** `false` (nobody, until granted) **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` | ``, ``, `<#ff00aa>`, `&0`-`&f` | | `withDecorations` / `withoutDecorations` | ``, ``, ``, ``, ``, ``, `&k`-`&o` | | `withRainbow` / `withoutRainbow` | ``, ``, `&*` | | `withGradient` / `withoutGradient` | `` | | `withReset` / `withoutReset` | ``, `&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: ```kotlin val noGradient = MessageFormat.full().withoutGradient() UtilitiesOG.trueogMessage(player, "kept as markup rendered", noGradient) ``` Java: ```java MessageFormat noGradient = MessageFormat.full().withoutGradient(); UtilitiesOG.trueogMessage(player, "kept as markup rendered", 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: ```kotlin val targetPlayer = Bukkit.getPlayer("USERNAME") UtilitiesOG.trueogMessage(targetPlayer, "&6This is a &*message with True&4OG formatting!") ``` Java: ```java Player targetPlayer = Bukkit.getPlayer("USERNAME"); UtilitiesOG.trueogMessage(targetPlayer, "&6This is a &*message with True&4OG 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: ```kotlin UtilitiesOG.trueogMessage(targetPlayer, "colorful", MessageFormat.full().withoutRainbow()) ``` Java: ```java UtilitiesOG.trueogMessage(targetPlayer, "colorful", 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: ```kotlin val targetPlayer = Bukkit.getPlayer("USERNAME") UtilitiesOG.trueogRawMessage(targetPlayer, "&6Literal placeholder: ") ``` Java: ```java Player targetPlayer = Bukkit.getPlayer("USERNAME"); UtilitiesOG.trueogRawMessage(targetPlayer, "&6Literal placeholder: "); ``` **[void] trueogRawMessage(Player player, String message, MessageFormat format)** Format-aware raw send. Tags disabled by the format stay literal. Kotlin: ```kotlin UtilitiesOG.trueogRawMessage(targetPlayer, "&6hi", MessageFormat.full().withoutGradient()) ``` Java: ```java UtilitiesOG.trueogRawMessage(targetPlayer, "&6hi", 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: ```kotlin val targetPlayer = Bukkit.getPlayer("USERNAME") val component = MiniMessage.miniMessage().deserialize("Ready.") UtilitiesOG.trueogMessage(targetPlayer, component) ``` Java: ```java Player targetPlayer = Bukkit.getPlayer("USERNAME"); Component component = MiniMessage.miniMessage().deserialize("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: ```kotlin val colorless = MessageFormat.full().withoutColor() UtilitiesOG.trueogMessage(targetPlayer, component, colorless) ``` Java: ```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: ```kotlin val playerUUID = UUID.fromString("player_uuid") UtilitiesOG.trueogMessage(playerUUID, "&6Hello there!") ``` Java: ```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: ```kotlin UtilitiesOG.trueogMessage(playerUUID, "&6Hi!", MessageFormat.full().withoutDecorations()) ``` Java: ```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: ```kotlin val playerUUID = UUID.fromString("player_uuid") UtilitiesOG.trueogRawMessage(playerUUID, "&6Literal placeholder: ") ``` Java: ```java UUID playerUUID = UUID.fromString("player_uuid"); UtilitiesOG.trueogRawMessage(playerUUID, "&6Literal placeholder: "); ``` **[void] trueogRawMessage(UUID playerUUID, String message, MessageFormat format)** Format-aware UUID raw send. Same semantics as `trueogRawMessage(Player, String, MessageFormat)`. Kotlin: ```kotlin UtilitiesOG.trueogRawMessage(playerUUID, "&6hi", MessageFormat.full().withoutRainbow()) ``` Java: ```java UtilitiesOG.trueogRawMessage(playerUUID, "&6hi", 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: ```kotlin val message = "Welcome to the server, everyone!" val expandedMessage = UtilitiesOG.trueogExpand(message) ``` Java: ```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: ```kotlin val expandedMessage = UtilitiesOG.trueogExpand(message, MessageFormat.full().withoutGradient()) ``` Java: ```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: ```kotlin val targetPlayer = Bukkit.getPlayer("SomePlayer") val message = "Welcome back, !" val expandedMessage = UtilitiesOG.trueogExpand(message, targetPlayer) UtilitiesOG.trueogMessage(targetPlayer, expandedMessage) ``` Java: ```java Player targetPlayer = Bukkit.getPlayer("SomePlayer"); String message = "Welcome back, !"; TextComponent expandedMessage = UtilitiesOG.trueogExpand(message, targetPlayer); UtilitiesOG.trueogMessage(targetPlayer, expandedMessage); ``` **[TextComponent] trueogExpand(String message, Player player, MessageFormat format)** Format-aware audience expansion. Kotlin: ```kotlin val expanded = UtilitiesOG.trueogExpand(message, targetPlayer, MessageFormat.full().withoutRainbow()) ``` Java: ```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: ```kotlin val player = Bukkit.getPlayer("Player") val target = Bukkit.getPlayer("TargetPlayer") val message = " is sending a message to " val expandedMessage = UtilitiesOG.trueogExpand(message, player, target) UtilitiesOG.trueogMessage(player, expandedMessage) ``` Java: ```java Player player = Bukkit.getPlayer("Player"); Player target = Bukkit.getPlayer("TargetPlayer"); String message = " is sending a message to "; 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: ```kotlin val expanded = UtilitiesOG.trueogExpand(message, player, target, MessageFormat.full().withoutGradient()) ``` Java: ```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: ```kotlin val playerUUID = UUID.fromString("player_uuid") val message = "Welcome back, !" val expandedMessage = UtilitiesOG.trueogExpand(message, playerUUID) UtilitiesOG.trueogMessage(playerUUID, expandedMessage) ``` Java: ```java UUID playerUUID = UUID.fromString("player_uuid"); String message = "Welcome back, !"; 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: ```kotlin val expanded = UtilitiesOG.trueogExpand(message, playerUUID, MessageFormat.full().withoutRainbow()) ``` Java: ```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: ```kotlin UtilitiesOG.registerGlobalPlaceholder("server_name") { "&aTrue&cOG &eNetwork" } ``` Java: ```java UtilitiesOG.registerGlobalPlaceholder("server_name", () -> "&aTrue&cOG &eNetwork"); ``` Examples With Arguments: Kotlin: ```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: ```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: ```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: ```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: ```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: ```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: ```kotlin UtilitiesOG.registerRelationalPlaceholder("distance_between") { player, target -> val distance = player.location.distance(target.location) "Distance: ${distance.toInt()} blocks" } ``` Java: ```java UtilitiesOG.registerRelationalPlaceholder("distance_between", (player, target) -> { double distance = player.getLocation().distance(target.getLocation()); return "Distance: " + (int) distance + " blocks"; }); ``` Examples With Arguments: Kotlin: ```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: ```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: ```kotlin val colorized = UtilitiesOG.trueogColorize(message) ``` Java: ```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: ```kotlin val colorized = UtilitiesOG.trueogColorize(message, MessageFormat.full().withoutGradient()) ``` Java: ```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: ```kotlin val unformatted = UtilitiesOG.stripFormatting(content) ``` Java: ```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: ```kotlin val unformatted = UtilitiesOG.stripFormatting(component) ``` Java: ```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: ```kotlin UtilitiesOG.logToConsole("[MyPlugin-OG]", "&6This is a &*message with color codes!") ``` Java: ```java UtilitiesOG.logToConsole("[MyPlugin-OG]", "&6This is a &*message with color codes!"); ``` **Player data (TrueOG Purpur RocksDB storage)** Utilities-OG is the only bridge to the server's RocksDB player data. Profiles are the raw NMS `NBTTagCompound`, passed as `Object`. Wrap them with Item-NBT-API `NBTContainer(Object)` or BKCommonLib `CommonTagCompound.create(Object)`. The server stores one vanilla profile per player; a plugin that needs more keeps it inside that profile, best under `BukkitValues` (the persistent data container, which the server carries through the live player and writes back on every save; MyWorlds nests one profile per inventory group under `BukkitValues.myworlds:groups`). Every method throws `UnsupportedOperationException` on a server without the TrueOG Purpur patch. **[boolean] isPlayerDataApiAvailable()** True on a TrueOG Purpur server. **[Object] getPlayerData(UUID uuid)** Vanilla profile of the player, upgraded to the current data version, or null when there is none. Throws `IllegalStateException` (after the server logged it) when a stored profile can not be read, so a missing profile and a broken one are never confused: treat the exception as "do not touch this player". **[void] savePlayerData(UUID uuid, Object tag)** Replaces the vanilla profile. Throws `IllegalStateException` (after the server logged it) when the write failed; does nothing while player data saving is disabled. Read, modify and write under `lockPlayerData`, and keep every compound you found in the profile, other plugins' data lives there too. **[boolean] hasPlayerData(UUID uuid)** True when a vanilla profile exists. Players who never joined have none. Throws `IllegalStateException` when the storage failed. **[List] getSeenPlayers()** Every player with a vanilla profile. **[Object] upgradePlayerData(Object tag)** Runs the server's player data fixes on a tag kept elsewhere, from its `DataVersion` (absent counts as the oldest, like vanilla) to the current one, and stamps the current version on it. **[void] lockPlayerData(UUID uuid)** / **[void] unlockPlayerData(UUID uuid)** Hold this lock around any read-modify-write of one player's stored data (release it in a `finally`). `setInventoryData` and MyWorlds' saves use it so they never interleave. **Offline inventory helpers** Built on the vanilla profile and Item-NBT-API (a hard dependency, so it is always present). `isPlayerInventoryApiAvailable()` reports whether the TrueOG Purpur player data API is bound; the helpers throw `UnsupportedOperationException` otherwise. A stored record without a `Pos` list is not a profile (it holds only data other plugins keep for a player who never joined), and the helpers treat it as "no stored profile". **[ItemStack[]] getInventoryData(UUID uuid)** Gets the stored inventory contents of a player. 41 slots in `PlayerInventory.getContents()` order (36 main, 4 armor, offhand). All null when the player has no stored profile; throws `IllegalStateException` when the stored profile can not be read. On a MyWorlds server this is the main inventory group. Kotlin: ```kotlin val inventoryData = UtilitiesOG.getInventoryData(uuid) ``` Java: ```java ItemStack[] inventoryData = UtilitiesOG.getInventoryData(uuid); ``` **[boolean] setInventoryData(UUID uuid, ItemStack[] items)** Replaces the stored inventory contents of an offline player using the TrueOG Purpur player data API. Same 41 slot layout as `getInventoryData`. Returns false, and writes nothing, when the player has no stored profile; throws `IllegalStateException` when the stored profile can not be read (nothing is written then) or when the write failed. Use the live `Player` inventory for online players. Kotlin: ```kotlin UtilitiesOG.setInventoryData(uuid, inventoryData) ``` Java: ```java UtilitiesOG.setInventoryData(uuid, inventoryData); ``` **[int] getHeldItemSlot(UUID uuid)** Gets the held hotbar slot of a player's stored profile using the TrueOG Purpur player data API. 0 when the player has no stored profile. Kotlin: ```kotlin val heldItemSlot = UtilitiesOG.getHeldItemSlot(uuid) ``` Java: ```java int heldItemSlot = UtilitiesOG.getHeldItemSlot(uuid); ```