Implement Chat-OG API

This commit is contained in:
NotAlexNoyle committed 2026-08-05 17:08:43 -04:00
1 parent 19ea51fea0
commit 1d1e142e4f
5 files changed
+61 -51

No files matched your search

+5 -38
View File
@@ -21,7 +21,6 @@ import org.bukkit.inventory.ItemStack;
import com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent;
import gui.SpleggShopGUI;
import io.papermc.paper.event.player.AsyncChatEvent;
import main.SpleggOG;
import managers.Game;
import net.trueog.diamondbankog.DiamondBankException.EconomyDisabledException;
@@ -476,42 +475,10 @@ public class Listeners implements Listener {
}
@EventHandler
public void onAsyncPlayerChat(AsyncChatEvent asyncChatEvent) {
final Player sender = asyncChatEvent.getPlayer();
final SpleggOG splegg = SpleggOG.getPlugin();
if (!splegg.isSpleggWorld(sender.getWorld())) {
// Not in a Splegg world, don't filter.
return;
}
final UtilPlayer senderState = splegg.pm.getPlayer(sender);
final Game senderGame = senderState != null ? senderState.getGame() : null;
final String senderWorldName = sender.getWorld().getName();
asyncChatEvent.viewers().removeIf(viewer -> {
if (!(viewer instanceof Player recipient)) {
return false;
}
if (senderGame != null) {
final UtilPlayer recipientState = splegg.pm.getPlayer(recipient);
return recipientState == null || recipientState.getGame() != senderGame;
}
return !recipient.getWorld().getName().equals(senderWorldName);
});
}
// Chat scoping now belongs to Chat-OG, which routes per world and mirrors to
// the Splegg Discord
// channel. Filtering viewers() here never worked anyway, because Chat-OG
// cancels AsyncChatEvent
// and builds its own recipient set.
}
+2 -2
View File
@@ -13,7 +13,6 @@ import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import main.SpleggOG;
import managers.GameWorldManager;
import utils.UtilPlayer;
import utils.Utils;
@@ -171,7 +170,8 @@ public class PlayerListener implements Listener {
}
String worldName = world.getName();
return SpleggOG.getPlugin().isSpleggWorld(worldName) || worldName.startsWith(GameWorldManager.COPY_PREFIX);
return SpleggOG.getPlugin().isSpleggWorld(worldName)
|| SpleggOG.getPlugin().getGameWorldManager().isGameCopyName(worldName);
}
+8
View File
@@ -353,6 +353,14 @@ public class SpleggOG extends JavaPlugin {
}
// Per-game worlds are named <prefix><gameId>-<map> so Chat-OG can link them to
// a Discord channel.
public String getGameWorldPrefix() {
return this.getConfig().getString("Worlds.GamePrefix", "SP");
}
// Returns the configured MapBase directory containing cold-storage world
// templates, or null when the feature is opt-out (empty/missing config).
// Relative paths resolve against the server's world container (which equals
+41 -11
View File
@@ -12,7 +12,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -27,18 +26,11 @@ import main.SpleggOG;
// Owns the per-game world lifecycle for Splegg matches.
// Each game is bound to a copy of its template world; the copy lives at
// <worldContainer>/splegg-<gameId>-<templateName>/ and is deleted when the game
// <worldContainer>/<prefix><gameId>-<templateName>/ and is deleted when the game
// ends. The original template world remains loaded for admin editing and is
// never modified by gameplay.
public class GameWorldManager {
public static final String COPY_PREFIX = "splegg-";
// Per-game world names, splegg-<gameId>-<template>. Safe to purge wholesale
// before any game registers: every match builds its own copy from scratch.
private static final Pattern COPY_NAME = Pattern.compile("^" + Pattern.quote(COPY_PREFIX) + ".+$",
Pattern.CASE_INSENSITIVE);
private final SpleggOG plugin;
public GameWorldManager(SpleggOG plugin) {
@@ -47,6 +39,44 @@ public class GameWorldManager {
}
// Matches <prefix><digits>-<rest>, the shape prepareWorld builds. Walks the
// name instead of a regex.
public boolean isGameCopyName(String name) {
String prefix = plugin.getGameWorldPrefix();
if (prefix.isEmpty() || !name.regionMatches(true, 0, prefix, 0, prefix.length()))
return false;
int index = prefix.length();
int digitStart = index;
while (index < name.length() && Character.isDigit(name.charAt(index)))
index++;
if (index == digitStart || index >= name.length() || name.charAt(index) != '-')
return false;
if (index + 1 >= name.length())
return false;
// A configured lobby or template world is the admin's, never a match copy.
return !isConfiguredWorld(name);
}
private boolean isConfiguredWorld(String name) {
for (String configured : plugin.getLobbyWorlds())
if (configured.equalsIgnoreCase(name))
return true;
for (String configured : plugin.getInGameWorlds())
if (configured.equalsIgnoreCase(name))
return true;
return false;
}
// Removes stale per-game world directories left behind from a previous run
// (e.g. server crash). Safe to call at plugin enable before any games register.
// Returns how many worlds were removed.
@@ -61,7 +91,7 @@ public class GameWorldManager {
for (File child : children) {
String name = child.getName();
if (!COPY_NAME.matcher(name).matches())
if (!isGameCopyName(name))
continue;
if (SpleggOG.isProtectedMainWorld(name)) {
@@ -307,7 +337,7 @@ public class GameWorldManager {
// folder name and may differ in case from the configured one.
templateName = template.getName();
String copyName = COPY_PREFIX + game.getGameId() + "-" + templateName;
String copyName = plugin.getGameWorldPrefix() + game.getGameId() + "-" + templateName;
if (SpleggOG.isProtectedMainWorld(copyName)) {
plugin.getLogger()
+5
View File
@@ -80,9 +80,14 @@ Options:
# VoidGenerator: pin the bundled void chunk generator onto every world Splegg
# loads or copies. A copied world folder carries no MyWorlds generator setting,
# so without this chunks outside the built arena generate vanilla terrain.
#
# GamePrefix: per-game worlds are named <GamePrefix><gameId>-<map>, for example SP1-Shake_It.
# Lobby worlds use the matching <GamePrefix><number>-hub shape, for example SP1-hub.
# Chat-OG keys its per-game Discord channel off this prefix, so keep the two in sync.
Worlds:
MapBase: ''
VoidGenerator: true
GamePrefix: SP
Lobby:
- SP1-hub
InGame: