2
0
mirror of https://github.com/proxiodev/RedisBungee.git synced 2025-03-09 22:25:31 +00:00

finishup bungeecord, move to mini message as serialzier

This commit is contained in:
Mohammed Alteneiji 2025-02-22 19:04:06 +04:00
parent 338297192c
commit 1fb429ea77
Signed by: ham1255
GPG Key ID: EF343502046229F4
18 changed files with 165 additions and 92 deletions

View File

@ -46,7 +46,7 @@ tasks {
val jedisVersion = libs.jedis.get().version
val configurateVersion = libs.configurateV3.get().version
val guavaVersion = libs.guava.get().version
val adventureVersion = libs.adventure.plain.get().version
val adventureVersion = libs.adventure.api.get().version
options.links(
"https://configurate.aoeu.xyz/$configurateVersion/apidocs/", // configurate
"https://javadoc.io/doc/redis.clients/jedis/$jedisVersion/", // jedis

View File

@ -299,6 +299,28 @@ public abstract class AbstractRedisBungeeAPI {
return this.plugin.getSummoner();
}
/**
* Kicks a player from the network using miniMessage
* calls {@link #getUuidFromName(String)} to get uuid
* <a href="https://docs.advntr.dev/minimessage/format.html">...</a>
* @param playerName player name
* @param miniMessage kick message that player will see on kick using minimessage as format
* @since 0.13.0
*/
public void kickPlayer(String playerName, String miniMessage) {
kickPlayer(getUuidFromName(playerName), miniMessage);
}
/**
* Kicks a player from the network
* <a href="https://docs.advntr.dev/minimessage/format.html">...</a>
* @param player player uuid
* @param miniMessage kick message that player will see on kick using minimessage as format
* @since 0.13.0
*/
public void kickPlayer(UUID player, String miniMessage) {
plugin.playerDataManager().serializedPlayerKick(player, miniMessage);
}
/**
* shows what mode is RedisBungee is on

View File

@ -139,14 +139,19 @@ public abstract class PlayerDataManager<P> {
}
// must check if player is on the local proxy
protected abstract boolean handleSerializedKick(UUID player, String serializedMessage);
// https://docs.advntr.dev/minimessage/index.html
// implemented downstream in Velocity and Bungeecord
protected abstract boolean handleSerializedKick(UUID player, String serializedMiniMessage);
public void serializedPlayerKick(UUID player, String serializedMessage) {
// https://docs.advntr.dev/minimessage/index.html
// implemented downstream in Velocity and Bungeecord
// called by kickPlayer in each impl of this class `NOT OVERRIDE`
public void serializedPlayerKick(UUID player, String serializedMiniMessage) {
JSONObject data = new JSONObject();
data.put("proxy", this.proxyId);
data.put("uuid", player);
data.put("serialized-message", serializedMessage);
if (!handleSerializedKick(player, serializedMessage))
data.put("serialized-message", serializedMiniMessage);
if (!handleSerializedKick(player, serializedMiniMessage))
plugin.proxyDataManager().sendChannelMessage("redisbungee-player-kick", data.toString());
}

View File

@ -199,7 +199,7 @@ public abstract class ProxyDataManager implements Runnable {
Set<UUID> storedRedisUuids = getProxyMembers(this.proxyId);
if (!localOnlineUUIDs.equals(storedRedisUuids)) {
plugin.logWarn("De-synced playerS set detected correcting....");
plugin.logWarn("De-synced players set detected correcting....");
Set<UUID> add = new HashSet<>(localOnlineUUIDs);
Set<UUID> remove = new HashSet<>(storedRedisUuids);
add.removeAll(storedRedisUuids);

View File

@ -7,7 +7,6 @@ dependencies {
implementation(libs.acf.core)
compileOnly(libs.adventure.api)
compileOnly(libs.adventure.miniMessage)
compileOnly(libs.adventure.gson)
}
description = "RedisBungee common commands"

View File

@ -14,7 +14,6 @@ import co.aikar.commands.CommandIssuer;
import co.aikar.commands.annotation.*;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.commands.utils.AdventureBaseCommand;
import net.kyori.adventure.text.Component;
import java.util.UUID;
@ -33,16 +32,14 @@ public class CommandRedisBungeeDebug extends AdventureBaseCommand {
@Description("kicks a player from the network by name")
@Private
public void kick(CommandIssuer issuer, String playerName) {
String message = serializeMessage(Component.text("kicked using redisbungee api using name"));
plugin.playerDataManager().serializedPlayerKick(plugin.getUuidTranslator().getTranslatedUuid(playerName, false), message);
plugin.playerDataManager().serializedPlayerKick(plugin.getUuidTranslator().getTranslatedUuid(playerName, false), "kicked using redisbungee api using name");
}
@Subcommand("kickByUUID")
@Description("kicks a player from the network by UUID")
@Private
public void kick(CommandIssuer issuer, UUID uuid) {
String message = serializeMessage(Component.text("kicked using redisbungee api using uuid"));
plugin.playerDataManager().serializedPlayerKick(uuid, message);
plugin.playerDataManager().serializedPlayerKick(uuid, "kicked using redisbungee api using uuid");
}

View File

@ -13,7 +13,6 @@ package com.imaginarycode.minecraft.redisbungee.commands.utils;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.CommandIssuer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
/**
* this just dumb class that wraps the adventure stuff into base command
@ -24,10 +23,4 @@ public abstract class AdventureBaseCommand extends BaseCommand {
CommandPlatformHelper.getPlatformHelper().sendMessage(issuer, component);
}
private static final GsonComponentSerializer COMPONENT_SERIALIZER = GsonComponentSerializer.gson();
protected String serializeMessage(Component message) {
return COMPONENT_SERIALIZER.serialize(message);
}
}

View File

@ -23,9 +23,6 @@ configurateV3 = { module = "org.spongepowered:configurate-yaml", version.ref = "
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" }
adventure-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "adventure" }
adventure-legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "adventure" }
adventure-plain = { module = "net.kyori:adventure-text-serializer-plain", version.ref = "adventure" }
adventure-miniMessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure" }
acf-core = { module = "com.github.ProxioDev.commands:acf-core", version.ref = "acf" }

View File

@ -22,7 +22,7 @@ tasks {
val options = options as StandardJavadocDocletOptions
options.use()
options.isDocFilesSubDirs = true
val adventureVersion = libs.adventure.plain.get().version
val adventureVersion = libs.adventure.api.get().version
options.links(
"https://jd.advntr.dev/api/$adventureVersion"
)

View File

@ -5,15 +5,12 @@ plugins {
dependencies {
implementation(project(":RedisBungee-Bungee"))
compileOnly(libs.platform.bungeecord) {
exclude("com.google.guava", "guava")
exclude("com.google.code.gson", "gson")
exclude("net.kyori","adventure-api")
}
compileOnly(libs.platform.bungeecord)
implementation(libs.adventure.platforms.bungeecord)
implementation(libs.adventure.gson)
implementation(libs.adventure.miniMessage)
implementation(libs.acf.bungeecord)
implementation(project(":RedisBungee-Commands"))
implementation(project(":RedisBungee-Lang"))
}
description = "RedisBungee Bungeecord implementation"
@ -24,11 +21,6 @@ java {
tasks {
//runWaterfall {
//waterfallVersion("1.20")
//environment["REDISBUNGEE_PROXY_ID"] = "bungeecord-1"
//["REDISBUNGEE_NETWORK_ID"] = "dev"
//}
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)

View File

@ -5,11 +5,8 @@ plugins {
dependencies {
api(project(":RedisBungee-API"))
compileOnly(libs.platform.bungeecord) {
exclude("com.google.guava", "guava")
exclude("com.google.code.gson", "gson")
exclude("net.kyori","adventure-api")
}
compileOnly(libs.adventure.platforms.bungeecord)
compileOnly(libs.platform.bungeecord)
}
description = "RedisBungee Bungeecord API"

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2013-present RedisBungee contributors
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.imaginarycode.minecraft.redisbungee;
import net.kyori.adventure.text.Component;
import java.util.UUID;
// this class used to redirect calls to keep the implementation and api separate
public interface ApiPlatformSupport {
void kickPlayer(UUID player, Component message);
}

View File

@ -11,6 +11,9 @@
package com.imaginarycode.minecraft.redisbungee;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -29,6 +32,8 @@ public class RedisBungeeAPI extends AbstractRedisBungeeAPI {
private static RedisBungeeAPI redisBungeeApi;
private static final BungeeComponentSerializer BUNGEE_COMPONENT_SERIALIZER = BungeeComponentSerializer.get();
public RedisBungeeAPI(RedisBungeePlugin<?> plugin) {
super(plugin);
if (redisBungeeApi == null) {
@ -51,6 +56,52 @@ public class RedisBungeeAPI extends AbstractRedisBungeeAPI {
return ((Plugin) this.plugin).getProxy().getServerInfo(serverName);
}
/**
* Kicks a player from the network
* calls {@link #getUuidFromName(String)} to get uuid
*
* @param playerName player name
* @param message kick message that player will see on kick
* @since 0.13.0
*/
public void kickPlayer(String playerName, BaseComponent[] message) {
kickPlayer(getUuidFromName(playerName), message);
}
/**
* Kicks a player from the network
*
* @param player player uuid
* @param message kick message that player will see on kick
* @since 0.13.0
*/
public void kickPlayer(UUID player, BaseComponent[] message) {
kickPlayer(player, BUNGEE_COMPONENT_SERIALIZER.deserialize(message));
}
/**
* Kicks a player from the network
* calls {@link #getUuidFromName(String)} to get uuid
*
* @param playerName player name
* @param message kick message that player will see on kick
* @since 0.12.0
*/
public void kickPlayer(String playerName, Component message) {
kickPlayer(getUuidFromName(playerName), message);
}
/**
* Kicks a player from the network
*
* @param player player uuid
* @param message kick message that player will see on kick
* @since 0.12.0
*/
public void kickPlayer(UUID player, Component message) {
((ApiPlatformSupport) this.plugin).kickPlayer(player, message);
}
/**
* Api instance
*

View File

@ -16,7 +16,10 @@ import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetwork
import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
@ -26,13 +29,16 @@ import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer> implements Listener {
public BungeePlayerDataManager(RedisBungeePlugin<ProxiedPlayer> plugin) {
private final RedisBungee bPlugin;
public BungeePlayerDataManager(RedisBungee plugin) {
super(plugin);
bPlugin = plugin;
}
@EventHandler
@ -62,6 +68,29 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer> im
super.playerChangedServer(event.getPlayer().getUniqueId(), oldServer, currentServer);
}
private final BungeeComponentSerializer BUNGEE_COMPONENT_SERIALIZER = BungeeComponentSerializer.get();
private final static MiniMessage MINI_MESSAGE_SERIALIZER = MiniMessage.miniMessage();
@Override
public boolean handleSerializedKick(UUID uuid, String serializedMiniMessage) {
ProxiedPlayer player = plugin.getPlayer(uuid);
if (player == null) return false;
// decode the adventure component
if (serializedMiniMessage == null) {
// kick the player too even if the message is invalid
player.disconnect(BUNGEE_COMPONENT_SERIALIZER.serialize(Component.empty()));
plugin.logWarn("unable to decode serialized adventure component because its empty or null");
} else {
Component message = MINI_MESSAGE_SERIALIZER.deserialize(serializedMiniMessage);
player.disconnect(BUNGEE_COMPONENT_SERIALIZER.serialize(message));
}
return true;
}
public void kickPlayer(UUID player, Component message) {
serializedPlayerKick(player, MINI_MESSAGE_SERIALIZER.serialize(message));
}
@EventHandler
public void onLoginEvent(LoginEvent event) {
event.registerIntent((Plugin) plugin);
@ -74,12 +103,12 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer> im
event.completeIntent((Plugin) plugin);
} else {
if (plugin.configuration().kickWhenOnline()) {
serializedPlayerKick(event.getConnection().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
kickPlayer(event.getConnection().getUniqueId(), bPlugin.langConfiguration().messages().loggedInFromOtherLocation());
// wait 3 seconds before releasing the event
plugin.executeAsyncAfter(() -> event.completeIntent((Plugin) plugin), TimeUnit.SECONDS, 3);
} else {
event.setCancelled(true);
event.setCancelReason(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().alreadyLoggedIn()));
event.setCancelReason(BungeeComponentSerializer.get().serialize(bPlugin.langConfiguration().messages().alreadyLoggedIn()));
event.completeIntent((Plugin) plugin);
}
}
@ -89,11 +118,13 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer> im
}
@EventHandler
public void onLoginEvent(PostLoginEvent event) {
super.addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getName(), event.getPlayer().getAddress().getAddress());
}
@EventHandler
public void onDisconnectEvent(PlayerDisconnectEvent event) {
super.removePlayer(event.getPlayer().getUniqueId());

View File

@ -15,10 +15,8 @@ import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
import com.imaginarycode.minecraft.redisbungee.api.ProxyDataManager;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.ConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.LangConfigLoader;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerChangedServerNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerJoinedNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerLeftNetworkEvent;
@ -33,7 +31,8 @@ import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.limework.valiobungee.config.lang.LangConfigLoader;
import net.limework.valiobungee.config.lang.LangConfiguration;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Event;
@ -41,7 +40,6 @@ import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
import java.io.IOException;
import java.lang.reflect.Field;
@ -53,9 +51,8 @@ import java.util.concurrent.*;
import java.util.logging.Level;
public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlayer>, ConfigLoader, LangConfigLoader {
public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlayer>, ConfigLoader, LangConfigLoader, ApiPlatformSupport {
private static RedisBungeeAPI apiStatic;
private AbstractRedisBungeeAPI api;
private RedisBungeeMode redisBungeeMode;
private ProxyDataManager proxyDataManager;
@ -76,7 +73,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
return this.configuration;
}
@Override
public LangConfiguration langConfiguration() {
return this.langConfiguration;
}
@ -161,15 +157,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
return this.getProxy().getPlayer(player).getName();
}
@Override
public boolean handlePlatformKick(UUID uuid, Component message) {
ProxiedPlayer player = getPlayer(uuid);
if (player == null) return false;
if (!player.isConnected()) return false;
player.disconnect(BungeeComponentSerializer.get().serialize(message));
return true;
}
@Override
public String getPlayerServerName(ProxiedPlayer player) {
return player.getServer().getInfo().getName();
@ -243,7 +230,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
// init the api
this.api = new RedisBungeeAPI(this);
apiStatic = (RedisBungeeAPI) this.api;
// commands
CommandPlatformHelper.init(new BungeeCommandPlatformHelper());
@ -337,22 +323,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
this.summoner = summoner;
}
/**
* This returns an instance of {@link RedisBungeeAPI}
*
* @return the {@link AbstractRedisBungeeAPI} object instance.
* @deprecated Please use {@link RedisBungeeAPI#getRedisBungeeApi()} this class intended to for old plugins that no longer updated.
*/
@Deprecated
public static RedisBungeeAPI getApi() {
return apiStatic;
}
@Deprecated
public JedisPool getPool() {
return api.getJedisPool();
}
@Override
public void onLangConfigLoad(LangConfiguration langConfiguration) {
this.langConfiguration = langConfiguration;
@ -362,4 +332,9 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
public String platformId() {
return "bungeecord";
}
@Override
public void kickPlayer(UUID player, Component message) {
this.playerDataManager.kickPlayer(player, message);
}
}

View File

@ -37,9 +37,9 @@ import static com.imaginarycode.minecraft.redisbungee.api.util.serialize.MultiMa
public class RedisBungeeListener implements Listener {
private final RedisBungeePlugin<ProxiedPlayer> plugin;
private final RedisBungee plugin;
public RedisBungeeListener(RedisBungeePlugin<ProxiedPlayer> plugin) {
public RedisBungeeListener(RedisBungee plugin) {
this.plugin = plugin;
}

View File

@ -24,6 +24,7 @@ import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import java.util.UUID;
@ -70,34 +71,25 @@ public class VelocityPlayerDataManager extends PlayerDataManager<Player> {
super.playerChangedServer(event.getPlayer().getUniqueId(), oldServer, currentServer);
}
private final GsonComponentSerializer COMPONENT_SERIALIZER = GsonComponentSerializer.gson();
private final static MiniMessage MINI_MESSAGE_SERIALIZER = MiniMessage.miniMessage();
@Override
public boolean handleSerializedKick(UUID uuid, String serializedMessage) {
public boolean handleSerializedKick(UUID uuid, String serializedMiniMessage) {
Player player = plugin.getPlayer(uuid);
if (player == null) return false;
// decode the adventure component
if (serializedMessage == null || serializedMessage.isEmpty()) {
if (serializedMiniMessage == null) {
// kick the player too even if the message is invalid
player.disconnect(Component.empty());
plugin.logWarn("unable to decode serialized adventure component because its empty or null");
} else {
try {
Component message = COMPONENT_SERIALIZER.deserialize(serializedMessage);
Component message = MINI_MESSAGE_SERIALIZER.deserialize(serializedMiniMessage);
player.disconnect(message);
} catch (Exception e) {
plugin.logFatal("Kick message is invalid", e);
plugin.logFatal("The serialized kick message:");
plugin.logFatal(serializedMessage);
// kick the player too even if the message is invalid
player.disconnect(Component.empty());
}
}
return true;
}
public void kickPlayer(UUID player, Component message) {
serializedPlayerKick(player, COMPONENT_SERIALIZER.serialize(message));
serializedPlayerKick(player, MINI_MESSAGE_SERIALIZER.serialize(message));
}
@Subscribe

View File

@ -20,6 +20,6 @@ public interface ApiPlatformSupport {
ProxyServer getProxy();
void kickPlayer(UUID Player, Component message);
void kickPlayer(UUID player, Component message);
}