Compare commits
1 Commits
0521ee688d
...
v1.0.4
| Author | SHA1 | Date | |
|---|---|---|---|
| 062d398d71 |
@@ -1,5 +1,5 @@
|
|||||||
# Project
|
# Project
|
||||||
projectVersion=1.0.0
|
projectVersion=1.0.4
|
||||||
projectGroup=com.nickcore
|
projectGroup=com.nickcore
|
||||||
|
|
||||||
# Minecraft / Paper
|
# Minecraft / Paper
|
||||||
|
|||||||
@@ -302,9 +302,11 @@ public final class NickCorePlugin extends JavaPlugin {
|
|||||||
private void registerVelocityMessaging(NickCoreConfig config) {
|
private void registerVelocityMessaging(NickCoreConfig config) {
|
||||||
if (config.velocity().enabled()) {
|
if (config.velocity().enabled()) {
|
||||||
velocityMessaging = new VelocityMessaging(this, profileCache,
|
velocityMessaging = new VelocityMessaging(this, profileCache,
|
||||||
placeholderService, nametagService, scheduler,
|
placeholderService, nametagService, nameOverrideService,
|
||||||
getLogger(), config.velocity().serverName());
|
scheduler, getLogger(), config.velocity().serverName());
|
||||||
velocityMessaging.register();
|
velocityMessaging.register();
|
||||||
|
// Let NickService auto-sync changes to other servers
|
||||||
|
nickService.setVelocityMessaging(velocityMessaging);
|
||||||
getLogger().info("Velocity messaging enabled (server: " + config.velocity().serverName() + ")");
|
getLogger().info("Velocity messaging enabled (server: " + config.velocity().serverName() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,13 +172,12 @@ public final class NickCommand implements CommandExecutor, TabCompleter {
|
|||||||
sendMessage(player, "<red>You don't have permission for that rank.");
|
sendMessage(player, "<red>You don't have permission for that rank.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NickProfile profile = profileCache.get(player.getUniqueId())
|
// Save rank to DB and sync to Velocity
|
||||||
.orElse(NickProfile.empty(player.getUniqueId()));
|
nickService.saveRankChange(player.getUniqueId(), rankId).thenRun(() -> {
|
||||||
NickProfile updated = profile.withRank(rankId);
|
|
||||||
profileCache.put(updated);
|
|
||||||
sendMessage(player, "<green>Rank set to <white>" +
|
sendMessage(player, "<green>Rank set to <white>" +
|
||||||
rankService.getRank(rankId).map(r -> r.displayName()).orElse(rankId));
|
rankService.getRank(rankId).map(r -> r.displayName()).orElse(rankId));
|
||||||
applyDisplay(player);
|
applyDisplay(player);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSkin(Player player, String[] args) {
|
private void handleSkin(Player player, String[] args) {
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ public final class GuiManager implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void openRankMenu(Player player) {
|
public void openRankMenu(Player player) {
|
||||||
RankMenuGui gui = new RankMenuGui(player, this, rankService, profileCache,
|
RankMenuGui gui = new RankMenuGui(player, this, nickService, rankService,
|
||||||
placeholderService, nametagService);
|
profileCache, placeholderService, nametagService);
|
||||||
openGuis.put(player.getUniqueId(), gui);
|
openGuis.put(player.getUniqueId(), gui);
|
||||||
gui.open();
|
gui.open();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.nickcore.paper.gui;
|
|||||||
import com.nickcore.common.model.NickProfile;
|
import com.nickcore.common.model.NickProfile;
|
||||||
import com.nickcore.common.model.RankDefinition;
|
import com.nickcore.common.model.RankDefinition;
|
||||||
import com.nickcore.paper.cache.ProfileCache;
|
import com.nickcore.paper.cache.ProfileCache;
|
||||||
|
import com.nickcore.paper.service.NickService;
|
||||||
import com.nickcore.paper.service.NametagService;
|
import com.nickcore.paper.service.NametagService;
|
||||||
import com.nickcore.paper.service.PlaceholderService;
|
import com.nickcore.paper.service.PlaceholderService;
|
||||||
import com.nickcore.paper.service.RankService;
|
import com.nickcore.paper.service.RankService;
|
||||||
@@ -21,6 +22,7 @@ import java.util.List;
|
|||||||
public final class RankMenuGui extends AbstractGui {
|
public final class RankMenuGui extends AbstractGui {
|
||||||
|
|
||||||
private final GuiManager guiManager;
|
private final GuiManager guiManager;
|
||||||
|
private final NickService nickService;
|
||||||
private final RankService rankService;
|
private final RankService rankService;
|
||||||
private final ProfileCache profileCache;
|
private final ProfileCache profileCache;
|
||||||
private final PlaceholderService placeholderService;
|
private final PlaceholderService placeholderService;
|
||||||
@@ -28,11 +30,12 @@ public final class RankMenuGui extends AbstractGui {
|
|||||||
private final MiniMessage mm = MiniMessage.miniMessage();
|
private final MiniMessage mm = MiniMessage.miniMessage();
|
||||||
private int page = 0;
|
private int page = 0;
|
||||||
|
|
||||||
public RankMenuGui(Player viewer, GuiManager guiManager, RankService rankService,
|
public RankMenuGui(Player viewer, GuiManager guiManager, NickService nickService,
|
||||||
ProfileCache profileCache, PlaceholderService placeholderService,
|
RankService rankService, ProfileCache profileCache,
|
||||||
NametagService nametagService) {
|
PlaceholderService placeholderService, NametagService nametagService) {
|
||||||
super(viewer, 54, Component.text("Select Rank", NamedTextColor.GOLD, TextDecoration.BOLD));
|
super(viewer, 54, Component.text("Select Rank", NamedTextColor.GOLD, TextDecoration.BOLD));
|
||||||
this.guiManager = guiManager;
|
this.guiManager = guiManager;
|
||||||
|
this.nickService = nickService;
|
||||||
this.rankService = rankService;
|
this.rankService = rankService;
|
||||||
this.profileCache = profileCache;
|
this.profileCache = profileCache;
|
||||||
this.placeholderService = placeholderService;
|
this.placeholderService = placeholderService;
|
||||||
@@ -57,15 +60,15 @@ public final class RankMenuGui extends AbstractGui {
|
|||||||
Component.text("Click to select", NamedTextColor.YELLOW)
|
Component.text("Click to select", NamedTextColor.YELLOW)
|
||||||
)),
|
)),
|
||||||
e -> {
|
e -> {
|
||||||
NickProfile profile = profileCache.get(viewer.getUniqueId())
|
// Save to DB and sync via Velocity
|
||||||
.orElse(NickProfile.empty(viewer.getUniqueId()));
|
nickService.saveRankChange(viewer.getUniqueId(), rank.id()).thenRun(() -> {
|
||||||
profileCache.put(profile.withRank(rank.id()));
|
|
||||||
viewer.closeInventory();
|
viewer.closeInventory();
|
||||||
viewer.sendMessage(Component.text("Rank set to ", NamedTextColor.GREEN)
|
viewer.sendMessage(Component.text("Rank set to ", NamedTextColor.GREEN)
|
||||||
.append(mm.deserialize(rank.displayName())));
|
.append(mm.deserialize(rank.displayName())));
|
||||||
placeholderService.invalidate(viewer.getUniqueId(), viewer.getName());
|
placeholderService.invalidate(viewer.getUniqueId(), viewer.getName());
|
||||||
nametagService.updateNametag(viewer);
|
nametagService.updateNametag(viewer);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back button
|
// Back button
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.nickcore.paper.integration;
|
|||||||
import com.nickcore.common.dto.NickSyncMessage;
|
import com.nickcore.common.dto.NickSyncMessage;
|
||||||
import com.nickcore.common.model.NickProfile;
|
import com.nickcore.common.model.NickProfile;
|
||||||
import com.nickcore.paper.cache.ProfileCache;
|
import com.nickcore.paper.cache.ProfileCache;
|
||||||
|
import com.nickcore.paper.service.NameOverrideService;
|
||||||
import com.nickcore.paper.service.PlaceholderService;
|
import com.nickcore.paper.service.PlaceholderService;
|
||||||
import com.nickcore.paper.service.NametagService;
|
import com.nickcore.paper.service.NametagService;
|
||||||
import com.nickcore.paper.scheduler.SchedulerAdapter;
|
import com.nickcore.paper.scheduler.SchedulerAdapter;
|
||||||
@@ -19,6 +20,10 @@ import java.util.logging.Logger;
|
|||||||
/**
|
/**
|
||||||
* Velocity plugin messaging integration.
|
* Velocity plugin messaging integration.
|
||||||
* Sends/receives NickSyncMessages for cross-server nick synchronization.
|
* Sends/receives NickSyncMessages for cross-server nick synchronization.
|
||||||
|
*
|
||||||
|
* <p>When a player switches servers (hub → survival), the Velocity proxy forwards
|
||||||
|
* their profile to the new server. This handler receives that sync and applies
|
||||||
|
* the full name override so the nick persists across servers.</p>
|
||||||
*/
|
*/
|
||||||
public final class VelocityMessaging implements PluginMessageListener {
|
public final class VelocityMessaging implements PluginMessageListener {
|
||||||
|
|
||||||
@@ -26,17 +31,20 @@ public final class VelocityMessaging implements PluginMessageListener {
|
|||||||
private final ProfileCache profileCache;
|
private final ProfileCache profileCache;
|
||||||
private final PlaceholderService placeholderService;
|
private final PlaceholderService placeholderService;
|
||||||
private final NametagService nametagService;
|
private final NametagService nametagService;
|
||||||
|
private final NameOverrideService nameOverrideService;
|
||||||
private final SchedulerAdapter scheduler;
|
private final SchedulerAdapter scheduler;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final String serverName;
|
private final String serverName;
|
||||||
|
|
||||||
public VelocityMessaging(Plugin plugin, ProfileCache profileCache,
|
public VelocityMessaging(Plugin plugin, ProfileCache profileCache,
|
||||||
PlaceholderService placeholderService, NametagService nametagService,
|
PlaceholderService placeholderService, NametagService nametagService,
|
||||||
SchedulerAdapter scheduler, Logger logger, String serverName) {
|
NameOverrideService nameOverrideService, SchedulerAdapter scheduler,
|
||||||
|
Logger logger, String serverName) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.profileCache = profileCache;
|
this.profileCache = profileCache;
|
||||||
this.placeholderService = placeholderService;
|
this.placeholderService = placeholderService;
|
||||||
this.nametagService = nametagService;
|
this.nametagService = nametagService;
|
||||||
|
this.nameOverrideService = nameOverrideService;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.serverName = serverName;
|
this.serverName = serverName;
|
||||||
@@ -71,12 +79,34 @@ public final class VelocityMessaging implements PluginMessageListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a full profile sync for a player.
|
* Sends a full profile sync to Velocity for cross-server propagation.
|
||||||
|
* Called every time a nick/rank/skin changes on this server.
|
||||||
*/
|
*/
|
||||||
public void syncProfile(NickProfile profile) {
|
public void syncProfile(NickProfile profile) {
|
||||||
sendSync(NickSyncMessage.fullSync(profile, serverName));
|
sendSync(NickSyncMessage.fullSync(profile, serverName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a nick update to Velocity.
|
||||||
|
*/
|
||||||
|
public void syncNickUpdate(java.util.UUID uuid, String nickname) {
|
||||||
|
sendSync(NickSyncMessage.nickUpdate(uuid, nickname, serverName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a rank update to Velocity.
|
||||||
|
*/
|
||||||
|
public void syncRankUpdate(java.util.UUID uuid, String rankId) {
|
||||||
|
sendSync(NickSyncMessage.rankUpdate(uuid, rankId, serverName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a reset to Velocity.
|
||||||
|
*/
|
||||||
|
public void syncReset(java.util.UUID uuid) {
|
||||||
|
sendSync(NickSyncMessage.reset(uuid, serverName));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] data) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] data) {
|
||||||
if (!NickSyncMessage.CHANNEL.equals(channel)) return;
|
if (!NickSyncMessage.CHANNEL.equals(channel)) return;
|
||||||
@@ -109,7 +139,11 @@ public final class VelocityMessaging implements PluginMessageListener {
|
|||||||
Player player = Bukkit.getPlayer(msg.playerUuid());
|
Player player = Bukkit.getPlayer(msg.playerUuid());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
placeholderService.invalidate(msg.playerUuid(), player.getName());
|
placeholderService.invalidate(msg.playerUuid(), player.getName());
|
||||||
scheduler.runAtEntity(plugin, player, () -> nametagService.updateNametag(player));
|
scheduler.runAtEntity(plugin, player, () -> {
|
||||||
|
// Apply full name override so the nick appears everywhere on this server
|
||||||
|
nameOverrideService.applyFullOverride(player);
|
||||||
|
nametagService.updateNametag(player);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,13 +171,24 @@ public final class VelocityMessaging implements PluginMessageListener {
|
|||||||
private void handleCacheInvalidate(NickSyncMessage msg) {
|
private void handleCacheInvalidate(NickSyncMessage msg) {
|
||||||
profileCache.remove(msg.playerUuid());
|
profileCache.remove(msg.playerUuid());
|
||||||
placeholderService.remove(msg.playerUuid());
|
placeholderService.remove(msg.playerUuid());
|
||||||
|
Player player = Bukkit.getPlayer(msg.playerUuid());
|
||||||
|
if (player != null) {
|
||||||
|
scheduler.runAtEntity(plugin, player, () -> {
|
||||||
|
nameOverrideService.clearMapping(player);
|
||||||
|
nameOverrideService.applyFullOverride(player);
|
||||||
|
nametagService.updateNametag(player);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshPlayer(java.util.UUID uuid) {
|
private void refreshPlayer(java.util.UUID uuid) {
|
||||||
Player player = Bukkit.getPlayer(uuid);
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
placeholderService.invalidate(uuid, player.getName());
|
placeholderService.invalidate(uuid, player.getName());
|
||||||
scheduler.runAtEntity(plugin, player, () -> nametagService.updateNametag(player));
|
scheduler.runAtEntity(plugin, player, () -> {
|
||||||
|
nameOverrideService.applyFullOverride(player);
|
||||||
|
nametagService.updateNametag(player);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.nickcore.common.model.NickProfile;
|
|||||||
import com.nickcore.common.validation.InputSanitizer;
|
import com.nickcore.common.validation.InputSanitizer;
|
||||||
import com.nickcore.common.validation.NicknameValidator;
|
import com.nickcore.common.validation.NicknameValidator;
|
||||||
import com.nickcore.paper.cache.ProfileCache;
|
import com.nickcore.paper.cache.ProfileCache;
|
||||||
|
import com.nickcore.paper.integration.VelocityMessaging;
|
||||||
import com.nickcore.paper.repository.NickRepository;
|
import com.nickcore.paper.repository.NickRepository;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -45,6 +46,9 @@ public final class NickService {
|
|||||||
private volatile boolean allowDuplicateNicks = false;
|
private volatile boolean allowDuplicateNicks = false;
|
||||||
private volatile boolean allowCustomNames = false;
|
private volatile boolean allowCustomNames = false;
|
||||||
|
|
||||||
|
// Optional: set when Velocity is enabled for cross-server sync
|
||||||
|
private volatile VelocityMessaging velocityMessaging;
|
||||||
|
|
||||||
public NickService(NickRepository repository, ProfileCache cache,
|
public NickService(NickRepository repository, ProfileCache cache,
|
||||||
NicknameValidator validator, Logger logger) {
|
NicknameValidator validator, Logger logger) {
|
||||||
this.repository = Objects.requireNonNull(repository);
|
this.repository = Objects.requireNonNull(repository);
|
||||||
@@ -138,6 +142,11 @@ public final class NickService {
|
|||||||
return repository.save(newProfile).thenCompose(v -> {
|
return repository.save(newProfile).thenCompose(v -> {
|
||||||
cache.put(newProfile);
|
cache.put(newProfile);
|
||||||
|
|
||||||
|
// Sync to other servers via Velocity
|
||||||
|
if (velocityMessaging != null) {
|
||||||
|
velocityMessaging.syncProfile(newProfile);
|
||||||
|
}
|
||||||
|
|
||||||
// Record history
|
// Record history
|
||||||
NickHistory history = NickHistory.nickChange(
|
NickHistory history = NickHistory.nickChange(
|
||||||
uuid, oldProfile.nickname(), sanitized,
|
uuid, oldProfile.nickname(), sanitized,
|
||||||
@@ -189,6 +198,11 @@ public final class NickService {
|
|||||||
return repository.save(resetProfile).thenCompose(v -> {
|
return repository.save(resetProfile).thenCompose(v -> {
|
||||||
cache.put(resetProfile);
|
cache.put(resetProfile);
|
||||||
|
|
||||||
|
// Sync reset to other servers
|
||||||
|
if (velocityMessaging != null) {
|
||||||
|
velocityMessaging.syncReset(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
NickHistory history = NickHistory.reset(
|
NickHistory history = NickHistory.reset(
|
||||||
uuid, oldProfile.nickname(), oldProfile.rankId(), changedBy
|
uuid, oldProfile.nickname(), oldProfile.rankId(), changedBy
|
||||||
);
|
);
|
||||||
@@ -239,6 +253,28 @@ public final class NickService {
|
|||||||
return allowCustomNames;
|
return allowCustomNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the VelocityMessaging instance for cross-server sync.
|
||||||
|
*/
|
||||||
|
public void setVelocityMessaging(VelocityMessaging velocityMessaging) {
|
||||||
|
this.velocityMessaging = velocityMessaging;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a rank change to the database and syncs to Velocity.
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Void> saveRankChange(java.util.UUID uuid, String rankId) {
|
||||||
|
NickProfile profile = cache.get(uuid).orElse(NickProfile.empty(uuid));
|
||||||
|
NickProfile updated = profile.withRank(rankId);
|
||||||
|
cache.put(updated);
|
||||||
|
|
||||||
|
if (velocityMessaging != null) {
|
||||||
|
velocityMessaging.syncRankUpdate(uuid, rankId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository.save(updated);
|
||||||
|
}
|
||||||
|
|
||||||
// ── Result Container ────────────────────────────────────────────────
|
// ── Result Container ────────────────────────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
name: NickCore
|
name: NickCore
|
||||||
version: '1.0.0'
|
version: '1.0.4'
|
||||||
main: com.nickcore.paper.NickCorePlugin
|
main: com.nickcore.paper.NickCorePlugin
|
||||||
api-version: '1.21'
|
api-version: '1.21'
|
||||||
description: Enterprise Minecraft Nickname Plugin
|
description: Enterprise Minecraft Nickname Plugin
|
||||||
author: NickCore Team
|
author: BaileyCodes
|
||||||
website: https://nickcore.com
|
website: https://nickcore.com
|
||||||
folia-supported: true
|
folia-supported: true
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* NickCore Velocity proxy plugin.
|
* NickCore Velocity proxy plugin.
|
||||||
* Maintains a cross-server nick profile cache and routes sync messages.
|
* Maintains a cross-server nick profile cache and routes sync messages.
|
||||||
*/
|
*/
|
||||||
@Plugin(id = "nickcore", name = "NickCore", version = "1.0.0",
|
@Plugin(id = "nickcore", name = "NickCore", version = "1.0.4",
|
||||||
authors = {"NickCore Team"}, description = "Enterprise nickname system - Velocity module")
|
authors = {"BaileyCodes"}, description = "Enterprise nickname system - Velocity module")
|
||||||
public final class NickCoreVelocity {
|
public final class NickCoreVelocity {
|
||||||
|
|
||||||
private static final MinecraftChannelIdentifier CHANNEL =
|
private static final MinecraftChannelIdentifier CHANNEL =
|
||||||
|
|||||||
Reference in New Issue
Block a user