Introduce support for web chat integration.

- Replaced synchronous permission checks with asynchronous LuckPerms user loading.
- Added `getOrLoadUser` utility to simplify user-related operations.
- Introduced web-originated chat command processing via new `PunishmentCommandBuilder` and `PunishFromWebHandler`.
- Updated `MuteServer`, `ToggleGlobalChat`, and `ToggleableForCustomChannel` to use async permission checks.
- Added test suite for `PunishmentCommandBuilder`.
- Expanded chat handling to process party messages from web events.
This commit is contained in:
2026-08-09 19:39:55 +02:00
parent 0d2ac3763f
commit 9e647f83a8
26 changed files with 900 additions and 169 deletions
@@ -432,7 +432,8 @@ public final class Config {
getList(key + "servers", Collections.EMPTY_LIST),
getList(key + "alias", Collections.EMPTY_LIST),
getBoolean(key + "proxy", false),
getBoolean(key + "local", false)
getBoolean(key + "local", false),
getBoolean(key + "web", false)
);
}
@@ -2,6 +2,8 @@ package com.alttd.chat.objects;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.luckperms.api.model.user.User;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.ArrayList;
@@ -60,4 +62,5 @@ public abstract class Toggleable {
public abstract void sendMessage(Player player, String message);
public abstract void sendMessage(User user, OfflinePlayer offlinePlayer, String message);
}
@@ -1,50 +1,37 @@
package com.alttd.chat.objects.channels;
import lombok.Getter;
import java.util.Collection;
import java.util.HashMap;
@Getter
public class Channel {
public static HashMap<String, Channel> channels = new HashMap<>();
protected String permission;
protected String channelName;
protected String format;
protected boolean proxy;
protected boolean local;
private final String permission;
private final String channelName;
private final String format;
private final boolean proxy;
private final boolean local;
private final boolean web;
private final String webPath;
public Channel(String channelName, String format, boolean proxy, boolean local) {
public Channel(String channelName, String format, boolean proxy, boolean local, boolean web) {
this.permission = "chat.channel." + channelName.toLowerCase();
this.channelName = channelName;
this.format = format;
this.proxy = proxy;
this.local = local;
channels.put(channelName.toLowerCase(), this);
this.web = web;
this.webPath = web ? "web_" + channelName + "_chat" : null;
}
public static Collection<Channel> getChannels() {
return channels.values();
}
public String getPermission() {
return permission;
}
public String getChannelName() {
return channelName;
}
public String getFormat() {
return format;
}
public boolean isProxy() {
return proxy;
}
public boolean isLocal() {
return local;
}
public static Channel getChatChannel(String channelName) {
return channels.get(channelName.toLowerCase());
}
@@ -1,27 +1,19 @@
package com.alttd.chat.objects.channels;
import lombok.Getter;
import java.util.List;
@Getter
public class CustomChannel extends Channel {
private final List<String> servers;
private final List<String> aliases;
public CustomChannel(String channelName, String format, List<String> servers, List<String> aliases, boolean proxy,
boolean local) {
super(channelName, format, proxy, local);
this.permission = "chat.channel." + channelName.toLowerCase();
this.channelName = channelName;
this.format = format;
boolean local, boolean web) {
super(channelName, format, proxy, local, web);
this.servers = servers;
this.proxy = proxy;
this.aliases = aliases;
}
public List<String> getServers() {
return servers;
}
public List<String> getAliases() {
return aliases;
}
}
@@ -1,7 +1,7 @@
package com.alttd.chat.objects.channels;
public abstract class DefaultChannel extends Channel{
public abstract class DefaultChannel extends Channel {
public DefaultChannel(String channelName, String format, boolean proxy) {
super(channelName, format, proxy, false);
super(channelName, format, proxy, false, false);
}
}
@@ -9,11 +9,14 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.Node;
import net.luckperms.api.query.QueryOptions;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -180,13 +183,27 @@ public class Utility {
});
}
public static boolean hasPermission(UUID uuid, String permission) {
public static CompletableFuture<User> getOrLoadUser(UUID uuid) {
return ChatAPI.get().getLuckPerms().getUserManager().loadUser(uuid);
}
public static CompletableFuture<Boolean> hasPermission(UUID uuid, String permission) {
LuckPerms luckPerms = ChatAPI.get().getLuckPerms();
User user = luckPerms.getUserManager().getUser(uuid);
if (user == null) {
return false;
return getOrLoadUser(uuid)
.thenApply(loadedUser -> hasPermission(loadedUser, permission))
.exceptionally(throwable -> false);
}
return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
return CompletableFuture.completedFuture(hasPermission(user, permission));
}
public static boolean hasPermission(User user, String permission) {
LuckPerms luckPerms = ChatAPI.get().getLuckPerms();
return user.getCachedData()
.getPermissionData(QueryOptions.contextual(ImmutableContextSet.of("server", luckPerms.getServerName())))
.checkPermission(permission)
.asBoolean();
}
public static ComponentLike applyColor(String message) {
@@ -0,0 +1,16 @@
package com.alttd.chat.web.handler_class;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@NoArgsConstructor
public class PartyChatFromWeb {
private UUID sender;
private String message;
private String partyId;
}
@@ -0,0 +1,16 @@
package com.alttd.chat.web.handler_class;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@NoArgsConstructor
public class PrivateChatFromWeb {
private UUID sender;
private String message;
private UUID recipient;
}
@@ -0,0 +1,18 @@
package com.alttd.chat.web.handler_class;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@NoArgsConstructor
public class PunishFromWeb {
private UUID executor;
private UUID target;
private String type;
private String reason;
private String time;
}