Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,30 @@ Usage of formatting codes in names can be disabled in the config file.

Alongside the `/name` command, this mod also supports reading prefixes and suffixes from the LuckPerms mod.

## API

Other Fabric or NeoForge mods can read names managed by Custom Names through `CustomNameApi`:

```java
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import xyz.eclipseisoffline.eclipsescustomname.api.CustomNameApi;

Component prefix = CustomNameApi.getPrefix(player);
Component nickname = CustomNameApi.getNickname(player);
Component displayNickname = CustomNameApi.getDisplayNickname(player);
Component suffix = CustomNameApi.getSuffix(player);
Component fullName = CustomNameApi.getFullName(player);
```

`getPrefix`, `getNickname`, and `getSuffix` return `null` when that Custom Names value is not set. `getDisplayNickname`
falls back to the player's vanilla name, and `getFullName` returns the complete display name used by Custom Names.
LuckPerms names can be read with `getLuckPermsPrefix` and `getLuckPermsSuffix`.

On Fabric, if [Patbox's Placeholder API](https://modrinth.com/mod/placeholder-api) is installed, Custom Names also registers these player placeholders:
`%eclipsescustomname:prefix%`, `%eclipsescustomname:nickname%`, `%eclipsescustomname:suffix%`,
`%eclipsescustomname:luckperms_prefix%`, `%eclipsescustomname:luckperms_suffix%`, and `%eclipsescustomname:full_name%`.

## Config file

The mod's configuration file is present in `{root config directory}/eclipsescustomname.json`.
Expand Down
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ multimod {
name = "eclipseisoffline"
url = uri("https://maven.eclipseisoffline.xyz/releases")
}
maven {
name = "Nucleoid"
url = uri("https://maven.nucleoid.xyz")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ public void initialize() {
LOGGER.info("Reading config");
config = CustomNameConfig.readOrCreate(getConfigDir());

registerPlatformIntegrations();
registerCommands(CustomNameCommands::register);
}

protected abstract String getVersion();

protected abstract Path getConfigDir();

protected void registerPlatformIntegrations() {
}

protected abstract void registerCommands(Consumer<CommandDispatcher<CommandSourceStack>> registerer);

public static CustomNameConfig getConfig() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ public void updatePlayerName(ServerPlayer player, @Nullable Component name, Name
markDirty(player);
}

public @Nullable Component getCustomPlayerName(ServerPlayer player, NameType nameType) {
return switch (nameType) {
case PREFIX -> playerPrefixes.get(player.getUUID());
case SUFFIX -> playerSuffixes.get(player.getUUID());
case NICKNAME -> playerNicknames.get(player.getUUID());
default -> throw new IllegalArgumentException("Unsupported custom name type " + nameType);
};
}

public Component getFullPlayerName(ServerPlayer player) {
if (!fullPlayerNames.containsKey(player.getUUID())) {
updateFullPlayerName(player);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package xyz.eclipseisoffline.eclipsescustomname.api;

import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.jspecify.annotations.Nullable;
import xyz.eclipseisoffline.eclipsescustomname.NameType;
import xyz.eclipseisoffline.eclipsescustomname.PlayerNameManager;

/**
* Public API for reading player names managed by Custom Names.
*/
public final class CustomNameApi {

private CustomNameApi() {
}

/**
* Returns the player's Custom Names prefix, or {@code null} when no prefix is set.
*/
public static @Nullable Component getPrefix(ServerPlayer player) {
return getCustomName(player, NameType.PREFIX);
}

/**
* Returns the player's Custom Names nickname, or {@code null} when no nickname is set.
*/
public static @Nullable Component getNickname(ServerPlayer player) {
return getCustomName(player, NameType.NICKNAME);
}

/**
* Returns the player's Custom Names nickname, or their vanilla player name when no nickname is set.
*/
public static Component getDisplayNickname(ServerPlayer player) {
Component nickname = getNickname(player);
return nickname == null ? player.getName() : nickname;
}

/**
* Returns the player's Custom Names suffix, or {@code null} when no suffix is set.
*/
public static @Nullable Component getSuffix(ServerPlayer player) {
return getCustomName(player, NameType.SUFFIX);
}

/**
* Returns the player's LuckPerms prefix, or {@code null} when LuckPerms is unavailable or no prefix is set.
*/
public static @Nullable Component getLuckPermsPrefix(ServerPlayer player) {
return getName(player, NameType.LUCKPERMS_PREFIX);
}

/**
* Returns the player's LuckPerms suffix, or {@code null} when LuckPerms is unavailable or no suffix is set.
*/
public static @Nullable Component getLuckPermsSuffix(ServerPlayer player) {
return getName(player, NameType.LUCKPERMS_SUFFIX);
}

/**
* Returns the player's full display name as used by Custom Names.
*/
public static Component getFullName(ServerPlayer player) {
return manager(player).getFullPlayerName(player);
}

private static @Nullable Component getCustomName(ServerPlayer player, NameType nameType) {
return manager(player).getCustomPlayerName(player, nameType);
}

private static @Nullable Component getName(ServerPlayer player, NameType nameType) {
return manager(player).getPlayerName(player, nameType);
}

private static PlayerNameManager manager(ServerPlayer player) {
return PlayerNameManager.getPlayerNameManager(player.level().getServer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NullMarked
package xyz.eclipseisoffline.eclipsescustomname.api;

import org.jspecify.annotations.NullMarked;
4 changes: 4 additions & 0 deletions fabric/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ multimod.modPublishing {
}
}

dependencies {
compileOnly(libs.placeholder.api)
}

multimod.fabric(project(":common"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package xyz.eclipseisoffline.eclipsescustomname.compat;

import eu.pb4.placeholders.api.PlaceholderResult;
import eu.pb4.placeholders.api.Placeholders;
import eu.pb4.placeholders.api.ServerPlaceholderContext;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.jspecify.annotations.Nullable;
import xyz.eclipseisoffline.eclipsescustomname.CustomName;
import xyz.eclipseisoffline.eclipsescustomname.NameType;
import xyz.eclipseisoffline.eclipsescustomname.PlayerNameManager;

public final class PlaceholderApiCompat {

private PlaceholderApiCompat() {
}

public static void register() {
register("prefix", NameType.PREFIX);
register("nickname", NameType.NICKNAME);
register("suffix", NameType.SUFFIX);
register("luckperms_prefix", NameType.LUCKPERMS_PREFIX);
register("luckperms_suffix", NameType.LUCKPERMS_SUFFIX);
Placeholders.registerServer(CustomName.getModdedIdentifier("full_name"), (context, _) -> value(getPlayerName(context)));
}

private static void register(String id, NameType nameType) {
Placeholders.registerServer(CustomName.getModdedIdentifier(id), (context, _) -> value(getPlayerName(context, nameType)));
}

private static @Nullable Component getPlayerName(ServerPlaceholderContext context, NameType nameType) {
ServerPlayer player = context.serverPlayer();
if (player == null) {
return null;
}
return PlayerNameManager.getPlayerNameManager(context.server()).getPlayerName(player, nameType);
}

private static @Nullable Component getPlayerName(ServerPlaceholderContext context) {
ServerPlayer player = context.serverPlayer();
if (player == null) {
return null;
}
return PlayerNameManager.getPlayerNameManager(context.server()).getFullPlayerName(player);
}

private static PlaceholderResult value(@Nullable Component value) {
return PlaceholderResult.value(value == null ? Component.empty() : value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NullMarked
package xyz.eclipseisoffline.eclipsescustomname.compat;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.commands.CommandSourceStack;
import xyz.eclipseisoffline.eclipsescustomname.CustomName;
import xyz.eclipseisoffline.eclipsescustomname.compat.PlaceholderApiCompat;

import java.nio.file.Path;
import java.util.function.Consumer;
Expand All @@ -27,6 +28,17 @@ protected Path getConfigDir() {
return FabricLoader.getInstance().getConfigDir();
}

@Override
protected void registerPlatformIntegrations() {
if (FabricLoader.getInstance().isModLoaded("placeholder-api")) {
try {
PlaceholderApiCompat.register();
} catch (LinkageError exception) {
LOGGER.warn("Failed to register Placeholder API support", exception);
}
}
}

@Override
protected void registerCommands(Consumer<CommandDispatcher<CommandSourceStack>> registerer) {
CommandRegistrationCallback.EVENT.register((dispatcher, _, _) -> registerer.accept(dispatcher));
Expand Down
3 changes: 2 additions & 1 deletion fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"commonpermissionsapi": "*"
},
"suggests": {
"luckperms": "*"
"luckperms": "*",
"placeholder-api": "*"
},
"custom": {
"modmenu": {
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fabric-api = "0.152.1+26.2"
neoforge = "26.2.0.0-beta"

luckperms = "5.4"
placeholder-api = "3.1.0-beta.1+26.2"
commonpermissionsapi = "0.1.3-26.2"
filefixutils = "0.1.3-26.1"

Expand All @@ -18,6 +19,7 @@ minecraft = {group = "com.mojang", name = "minecraft", version.ref = "minecraft"
fabric-api = {group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api"}

luckperms = {group = "net.luckperms", name = "api", version.ref = "luckperms"}
placeholder-api = {group = "eu.pb4", name = "placeholder-api", version.ref = "placeholder-api"}
commonpermissionsapi = {group = "xyz.eclipseisoffline", name = "commonpermissionsapi", version.ref = "commonpermissionsapi"}
filefixutils = {group = "xyz.eclipseisoffline", name = "filefixutils", version.ref = "filefixutils"}

Expand Down