Scope
Expand the PlaceholderAPI and WiFlowPlaceholderAPI integrations with additional placeholders for colored name/tag combinations (both hex and legacy formats), faction color as a legacy & code, and proper relational placeholders between two players.
color_legacy — faction color as a Minecraft &X code (e.g., &b) instead of the current hex stringname_colored / tag_colored — faction name and tag pre-wrapped with the faction's hex color (&#RRGGBB format)name_colored_legacy / tag_colored_legacy — same but using legacy &X code (nearest match)- Relational placeholders via the
Relational interface — relation type between two players (sender ↔ recipient)
Implementation Details
Current color placeholder returns a raw hex string (e.g., #55FFFF):
// HyperFactionsExpansion.java:219-224privateStringgetFactionColor(UUIDuuid) {
Factionfaction = plugin.getFactionManager().getPlayerFaction(uuid);
if (faction == null) return"";
returnfaction.color() != null ? faction.color() : "";
}Current display placeholder returns name or tag based on config but without any color applied.
Werchat's ChatListener.parseColoredString() already handles &#RRGGBB, &X legacy codes, and §x§R§R§G§G§B§B extended hex. Any placeholder output in these formats will be correctly parsed and rendered in chat.
New standard placeholders (add to both HyperFactionsExpansion and WiFlowExpansion):
| Placeholder | Output | Example |
|---|
color_legacy | Faction color as nearest &X code (reverse lookup from LegacyColorParser.LEGACY_COLORS) | &b |
name_colored | &#RRGGBB + faction name (exact faction hex color) | 7FFFFMyFaction |
tag_colored | &#RRGGBB + faction tag (falls back to first 3 chars of name like display does) | 7FFFFMYF |
name_colored_legacy | &X + faction name (nearest legacy code) | &bMyFaction |
tag_colored_legacy | &X + faction tag (nearest legacy code) | &bMYF |
color_legacy utility method — add LegacyColorParser.hexToLegacyCode(String hex):
- Exact match: reverse lookup from
LEGACY_COLORS map - No exact match: find nearest legacy color by RGB distance (Euclidean distance on R/G/B components)
- Returns
&X string (e.g., &b)
Relational placeholders — implement at.helpch.placeholderapi.expansion.Relational interface:
PlaceholderAPI has a dedicated relational system:
- Interface:
Relational with method onPlaceholderRequest(PlayerRef one, PlayerRef two, String params) - Usage pattern:
%rel_factions_<param>% (resolved by PlaceholderAPI.setRelationalPlaceholders()) - Werchat already calls
papi.setRelationalPlaceholders(sender, recipient, text) on every chat message (ChatListener.java:649)
HyperFactionsExpansion should implement Relational and add:
// Relational interface methodpublicStringonPlaceholderRequest(PlayerRefone, PlayerReftwo, Stringparams) {
// params = "relation" for %rel_factions_relation%UUIDuuid1 = one.getUuid(), uuid2 = two.getUuid();
RelationTyperel = plugin.getRelationManager().getPlayerRelation(uuid1, uuid2);
returnswitch (params) {
case"relation" -> rel != null ? rel.getDisplayName() : ""; // "Ally", "Enemy", "Neutral", "Your"case"relation_color" -> rel != null ? rel.getColorCode() : ""; // §a, §c, §7default -> null;
};
}| Relational Placeholder | Output | Example |
|---|
%rel_factions_relation% | Display name of relation between sender and recipient | Ally, Enemy, Neutral, Your |
%rel_factions_relation_color% | Minecraft color code for the relation | §a (ally/own), §c (enemy), §7 (neutral) |
WiFlow expansion: Check if WiFlowPlaceholderAPI has an equivalent relational interface. If not, relational placeholders are PAPI-only and the WiFlow expansion just gets the standard (non-relational) placeholders.
Both expansion classes (HyperFactionsExpansion and WiFlowExpansion) must be updated in sync for the standard placeholders. Also update WiFlowExpansion.getPlaceholders() list.
Risks and Alternatives
- Risk:
color_legacy nearest-match for custom hex colors may not map intuitively — e.g., #FF8800 (orange) maps to &6 (gold). This is inherent to the 16-color legacy palette and should be documented. - Risk: Relational placeholders require both players to be online and in the same chat context. Returns empty string if either player has no faction. This is standard PAPI behavior.
- Alternative: For
name_colored/tag_colored, could output Hytale Message color format instead of &-code strings — but &-code/hex strings are what chat plugins (Werchat, scoreboards) expect and already parse. - Alternative: Could skip the
_legacy variants and only provide hex — but some third-party plugins may only support &X codes, not &#RRGGBB.
References and Media
- Current placeholder implementations:
HyperFactionsExpansion.java and WiFlowExpansion.java in com.hyperfactions.integration.placeholder - Legacy color map:
LegacyColorParser.LEGACY_COLORS (16 standard Minecraft color codes with hex values) - Werchat color parsing:
ChatListener.parseColoredString() — handles &X, &#RRGGBB, and §x§R§R§G§G§B§B - Relational interface:
at.helpch.placeholderapi.expansion.Relational — onPlaceholderRequest(PlayerRef, PlayerRef, String) - Werchat relational call:
ChatListener.java:649 — papi.setRelationalPlaceholders(sender, recipient, resolved) - Relation system:
RelationManager.getPlayerRelation(UUID, UUID) returns RelationType enum RelationType values: OWN (§a), ALLY (§a), NEUTRAL (§7), ENEMY (§c)
Scope
Expand the PlaceholderAPI and WiFlowPlaceholderAPI integrations with additional placeholders for colored name/tag combinations (both hex and legacy formats), faction color as a legacy
&code, and proper relational placeholders between two players.color_legacy— faction color as a Minecraft&Xcode (e.g.,&b) instead of the current hex stringname_colored/tag_colored— faction name and tag pre-wrapped with the faction's hex color (&#RRGGBBformat)name_colored_legacy/tag_colored_legacy— same but using legacy&Xcode (nearest match)Relationalinterface — relation type between two players (sender ↔ recipient)Implementation Details
Current
colorplaceholder returns a raw hex string (e.g.,#55FFFF):Current
displayplaceholder returns name or tag based on config but without any color applied.Werchat's
ChatListener.parseColoredString()already handles&#RRGGBB,&Xlegacy codes, and§x§R§R§G§G§B§Bextended hex. Any placeholder output in these formats will be correctly parsed and rendered in chat.New standard placeholders (add to both
HyperFactionsExpansionandWiFlowExpansion):color_legacy&Xcode (reverse lookup fromLegacyColorParser.LEGACY_COLORS)&bname_colored&#RRGGBB+ faction name (exact faction hex color)7FFFFMyFactiontag_colored&#RRGGBB+ faction tag (falls back to first 3 chars of name likedisplaydoes)7FFFFMYFname_colored_legacy&X+ faction name (nearest legacy code)&bMyFactiontag_colored_legacy&X+ faction tag (nearest legacy code)&bMYFcolor_legacyutility method — addLegacyColorParser.hexToLegacyCode(String hex):LEGACY_COLORSmap&Xstring (e.g.,&b)Relational placeholders — implement
at.helpch.placeholderapi.expansion.Relationalinterface:PlaceholderAPI has a dedicated relational system:
Relationalwith methodonPlaceholderRequest(PlayerRef one, PlayerRef two, String params)%rel_factions_<param>%(resolved byPlaceholderAPI.setRelationalPlaceholders())papi.setRelationalPlaceholders(sender, recipient, text)on every chat message (ChatListener.java:649)HyperFactionsExpansionshould implementRelationaland add:%rel_factions_relation%Ally,Enemy,Neutral,Your%rel_factions_relation_color%§a(ally/own),§c(enemy),§7(neutral)WiFlow expansion: Check if WiFlowPlaceholderAPI has an equivalent relational interface. If not, relational placeholders are PAPI-only and the WiFlow expansion just gets the standard (non-relational) placeholders.
Both expansion classes (
HyperFactionsExpansionandWiFlowExpansion) must be updated in sync for the standard placeholders. Also updateWiFlowExpansion.getPlaceholders()list.Risks and Alternatives
color_legacynearest-match for custom hex colors may not map intuitively — e.g.,#FF8800(orange) maps to&6(gold). This is inherent to the 16-color legacy palette and should be documented.name_colored/tag_colored, could output HytaleMessagecolor format instead of&-code strings — but&-code/hex strings are what chat plugins (Werchat, scoreboards) expect and already parse._legacyvariants and only provide hex — but some third-party plugins may only support&Xcodes, not&#RRGGBB.References and Media
HyperFactionsExpansion.javaandWiFlowExpansion.javaincom.hyperfactions.integration.placeholderLegacyColorParser.LEGACY_COLORS(16 standard Minecraft color codes with hex values)ChatListener.parseColoredString()— handles&X,&#RRGGBB, and§x§R§R§G§G§B§Bat.helpch.placeholderapi.expansion.Relational—onPlaceholderRequest(PlayerRef, PlayerRef, String)ChatListener.java:649—papi.setRelationalPlaceholders(sender, recipient, resolved)RelationManager.getPlayerRelation(UUID, UUID)returnsRelationTypeenumRelationTypevalues:OWN(§a),ALLY(§a),NEUTRAL(§7),ENEMY(§c)