mirror of
https://github.com/proxiodev/RedisBungee.git
synced 2026-05-03 03:30:26 +00:00
Compare commits
39 Commits
0.12.4
...
0.13.0-SNA
| Author | SHA1 | Date | |
|---|---|---|---|
| 4221ebb892 | |||
|
d93076eb81
|
|||
|
1d2c11c538
|
|||
|
e495b11587
|
|||
|
b250776c82
|
|||
|
13cfe8db13
|
|||
|
d30c70c8c4
|
|||
|
3aa76384c3
|
|||
|
92c965bfc6
|
|||
|
1fb429ea77
|
|||
|
338297192c
|
|||
|
1d3bd7e101
|
|||
|
96c0dff8c1
|
|||
|
|
23aeb81308 | ||
|
|
c84b987b9e | ||
|
8177260991
|
|||
|
287f037774
|
|||
|
c633f1a106
|
|||
|
9fd1da5f92
|
|||
|
0050575aff
|
|||
|
6eab4ef602
|
|||
|
12acc16376
|
|||
|
8b9af8838d
|
|||
|
|
81bf06e2df
|
||
|
41b1dab8cc
|
|||
|
a437db32b8
|
|||
|
2bd79f628e
|
|||
|
93c1cd8e4c
|
|||
|
f27d54beb8
|
|||
|
91ea0b08dc
|
|||
|
199c1c7135
|
|||
|
dab5f26e2c
|
|||
|
c622bc7b63
|
|||
|
881691a92d
|
|||
| 079606c9da | |||
|
ea54a0bc49
|
|||
|
69e91c3e42
|
|||
|
|
d8704c8a8f
|
||
|
|
981d42d4a8
|
14
.github/workflows/gradle.yml
vendored
14
.github/workflows/gradle.yml
vendored
@@ -5,9 +5,9 @@ name: RedisBungee Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ stable, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches: [ stable, develop ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,27 +16,27 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 17
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
- name: Build with gradle
|
||||
run: ./gradlew shadowJar
|
||||
- name: Upload Bungee
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
uses: actions/upload-artifact@v4.4.0
|
||||
with:
|
||||
# Artifact name
|
||||
name: RedisBungee-Bungee
|
||||
# Destination path
|
||||
path: proxies/bungeecord/build/libs/*
|
||||
- name: Upload Velocity
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
uses: actions/upload-artifact@v4.4.0
|
||||
with:
|
||||
name: RedisBungee-Velocity
|
||||
path: proxies/velocity/build/libs/*
|
||||
- name: Upload API
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
uses: actions/upload-artifact@v4.4.0
|
||||
with:
|
||||
name: RedisBungee-API
|
||||
path: api/build/libs/*
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# RedisBungee Limework's Fork
|
||||
# ValioBungee: The RedisBungee Limework's Fork
|
||||
|
||||
The original project of RedisBungee is no longer maintained, so we have forked the plugin.
|
||||
RedisBungee uses [Redis](https://redis.io) with Java client [Jedis](https://github.com/redis/jedis/)
|
||||
to Synchronize players data between [BungeeCord](https://github.com/SpigotMC/BungeeCord)
|
||||
or [Velocity*](https://github.com/PaperMC/Velocity) proxies
|
||||
## Why different name?
|
||||
Because from our current understanding we cant use Redis name due trademark restrictions.
|
||||
so we settled with valiobungee. But it doesnt not effect any internals naming schemes like plugin id and so on.
|
||||
|
||||
## Downloads
|
||||
|
||||
@@ -11,7 +14,7 @@ or [Velocity*](https://github.com/PaperMC/Velocity) proxies
|
||||
|
||||
## Wiki
|
||||
|
||||
https://github.com/ProxioDev/RedisBungee/wiki
|
||||
https://github.com/ProxioDev/ValioBungee/wiki
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import java.time.Instant
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("net.kyori.blossom") version "1.2.0"
|
||||
alias(libs.plugins.blossom)
|
||||
alias(libs.plugins.indragit)
|
||||
|
||||
}
|
||||
|
||||
@@ -12,32 +12,23 @@ dependencies {
|
||||
api(libs.guava)
|
||||
api(libs.jedis)
|
||||
api(libs.okhttp)
|
||||
api(libs.configurate)
|
||||
api(libs.configurateV3)
|
||||
api(libs.caffeine)
|
||||
api(libs.adventure.api)
|
||||
api(libs.adventure.gson)
|
||||
api(libs.adventure.legacy)
|
||||
api(libs.adventure.plain)
|
||||
api(libs.adventure.miniMessage)
|
||||
}
|
||||
|
||||
description = "RedisBungee interfaces"
|
||||
|
||||
blossom {
|
||||
replaceToken("@version@", "$version")
|
||||
// GIT
|
||||
val commit: String;
|
||||
val commitStdout = ByteArrayOutputStream()
|
||||
rootProject.exec {
|
||||
standardOutput = commitStdout
|
||||
commandLine("git", "rev-parse", "HEAD")
|
||||
sourceSets {
|
||||
main {
|
||||
blossom {
|
||||
javaSources {
|
||||
property("version", "$version")
|
||||
property("git-commit", indraGit.commit().toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
commit = "$commitStdout".replace("\n", "") // for some reason it adds new line so remove it.
|
||||
commitStdout.close()
|
||||
replaceToken("@git_commit@", commit)
|
||||
}
|
||||
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
@@ -50,9 +41,9 @@ tasks {
|
||||
options.use()
|
||||
options.isDocFilesSubDirs = true
|
||||
val jedisVersion = libs.jedis.get().version
|
||||
val configurateVersion = libs.configurate.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
|
||||
|
||||
@@ -14,16 +14,10 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisClusterSummoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisPooledSummoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPooled;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
@@ -216,19 +210,6 @@ public abstract class AbstractRedisBungeeAPI {
|
||||
return plugin.proxyDataManager().proxyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current BungeeCord / Velocity proxy ID for this server.
|
||||
*
|
||||
* @return the current server ID
|
||||
* @see #getAllServers()
|
||||
* @since 0.2.5
|
||||
* @deprecated to avoid confusion between A server and A proxy see #getProxyId()
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final String getServerId() {
|
||||
return getProxyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the linked proxies in this network.
|
||||
*
|
||||
@@ -240,41 +221,6 @@ public abstract class AbstractRedisBungeeAPI {
|
||||
return plugin.proxyDataManager().proxiesIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the linked proxies in this network.
|
||||
*
|
||||
* @return the list of all proxies
|
||||
* @see #getServerId()
|
||||
* @since 0.2.5
|
||||
* @deprecated to avoid confusion between A server and A proxy see see {@link #getAllProxies()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final List<String> getAllServers() {
|
||||
return getAllProxies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register (a) PubSub channel(s), so that you may handle PubSubMessageEvent for it.
|
||||
*
|
||||
* @param channels the channels to register
|
||||
* @since 0.3
|
||||
* @deprecated No longer required
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final void registerPubSubChannels(String... channels) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister (a) PubSub channel(s).
|
||||
*
|
||||
* @param channels the channels to unregister
|
||||
* @since 0.3
|
||||
* @deprecated No longer required
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final void unregisterPubSubChannels(String... channels) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a name from the specified UUID. UUIDs are cached locally and in Redis. This function falls back to Mojang
|
||||
* as a last resort, so calls <strong>may</strong> be blocking.
|
||||
@@ -343,132 +289,6 @@ public abstract class AbstractRedisBungeeAPI {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.8.0
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void kickPlayer(String playerName, String message) {
|
||||
kickPlayer(getUuidFromName(playerName), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks a player from the network
|
||||
*
|
||||
* @param playerUUID player name
|
||||
* @param message kick message that player will see on kick
|
||||
* @since 0.8.0
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void kickPlayer(UUID playerUUID, String message) {
|
||||
kickPlayer(playerUUID, Component.text(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 playerUUID player name
|
||||
* @param message kick message that player will see on kick
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public void kickPlayer(UUID playerUUID, Component message) {
|
||||
this.plugin.playerDataManager().kickPlayer(playerUUID, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This gives you instance of Jedis
|
||||
*
|
||||
* @return {@link Jedis}
|
||||
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE}
|
||||
* @see #getJedisPool()
|
||||
* @since 0.7.0
|
||||
* @deprecated use {@link #getSummoner() }
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public Jedis requestJedis() {
|
||||
if (getMode() == RedisBungeeMode.SINGLE) {
|
||||
return getJedisPool().getResource();
|
||||
} else {
|
||||
throw new IllegalStateException("Mode is not " + RedisBungeeMode.SINGLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets Redis Bungee {@link JedisPool}
|
||||
*
|
||||
* @return {@link JedisPool}
|
||||
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE}
|
||||
* @throws IllegalStateException if JedisPool compatibility mode is disabled in the config
|
||||
* @since 0.6.5
|
||||
*/
|
||||
public JedisPool getJedisPool() {
|
||||
if (getMode() == RedisBungeeMode.SINGLE) {
|
||||
JedisPool jedisPool = ((JedisPooledSummoner) this.plugin.getSummoner()).getCompatibilityJedisPool();
|
||||
if (jedisPool == null) {
|
||||
throw new IllegalStateException("JedisPool compatibility mode is disabled, Please enable it in the RedisBungee config.yml");
|
||||
}
|
||||
return jedisPool;
|
||||
} else {
|
||||
throw new IllegalStateException("Mode is not " + RedisBungeeMode.SINGLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This gives you an instance of JedisCluster that can't be closed
|
||||
* see {@link com.imaginarycode.minecraft.redisbungee.api.summoners.NotClosableJedisCluster}
|
||||
*
|
||||
* @return {@link redis.clients.jedis.JedisCluster}
|
||||
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#CLUSTER}
|
||||
* @since 0.8.0
|
||||
* @deprecated use {@link #getSummoner()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public JedisCluster requestClusterJedis() {
|
||||
if (getMode() == RedisBungeeMode.CLUSTER) {
|
||||
return ((JedisClusterSummoner) this.plugin.getSummoner()).obtainResource();
|
||||
} else {
|
||||
throw new IllegalStateException("Mode is not " + RedisBungeeMode.CLUSTER);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This gives you an instance of JedisPooled that can't be closed
|
||||
* see {@link com.imaginarycode.minecraft.redisbungee.api.summoners.NotClosableJedisPooled}
|
||||
*
|
||||
* @return {@link redis.clients.jedis.JedisPooled}
|
||||
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE}
|
||||
* @since 0.8.0
|
||||
* @deprecated use {@link #getSummoner()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public JedisPooled requestJedisPooled() {
|
||||
if (getMode() == RedisBungeeMode.SINGLE) {
|
||||
return ((JedisPooledSummoner) this.plugin.getSummoner()).obtainResource();
|
||||
} else {
|
||||
throw new IllegalStateException("Mode is not " + RedisBungeeMode.SINGLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns Summoner class responsible for Single Jedis {@link redis.clients.jedis.JedisPooled} with {@link JedisPool}, Cluster Jedis {@link redis.clients.jedis.JedisCluster} handling
|
||||
*
|
||||
@@ -479,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
|
||||
|
||||
@@ -13,11 +13,11 @@ package com.imaginarycode.minecraft.redisbungee;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public final static String VERSION = "@version@";
|
||||
public final static String GIT_COMMIT = "@git_commit@";
|
||||
public final static String VERSION = "{{ version }}";
|
||||
public final static String GIT_COMMIT = "{{ git-commit }}";
|
||||
|
||||
public static String getGithubCommitLink() {
|
||||
return "https://github.com/ProxioDev/RedisBungee/commit/" + GIT_COMMIT;
|
||||
return "https://github.com/ProxioDev/ValioBungee/commit/" + GIT_COMMIT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@ import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerChangedServerNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerJoinedNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPlayerLeftNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPubSubMessageEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.tasks.RedisPipelineTask;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||
import org.json.JSONObject;
|
||||
import redis.clients.jedis.ClusterPipeline;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
@@ -28,13 +27,10 @@ import redis.clients.jedis.Response;
|
||||
import redis.clients.jedis.UnifiedJedis;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEvent, SC extends IPlayerChangedServerNetworkEvent, NJE extends IPlayerLeftNetworkEvent, CE> {
|
||||
public abstract class PlayerDataManager<P> {
|
||||
|
||||
protected final RedisBungeePlugin<P> plugin;
|
||||
private final Object SERVERS_TO_PLAYERS_KEY = new Object();
|
||||
@@ -45,8 +41,8 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
private final LoadingCache<UUID, String> lastServerCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getLastServerFromRedis);
|
||||
private final LoadingCache<UUID, String> proxyCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getProxyFromRedis);
|
||||
private final LoadingCache<UUID, InetAddress> ipCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getIpAddressFromRedis);
|
||||
private final LoadingCache<UUID, Long> lastOnlineCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getLastOnlineFromRedis);
|
||||
private final LoadingCache<Object, Multimap<String, UUID>> serverToPlayersCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build(this::serversToPlayersBuilder);
|
||||
private final JSONComponentSerializer COMPONENT_SERIALIZER = JSONComponentSerializer.json();
|
||||
|
||||
public PlayerDataManager(RedisBungeePlugin<P> plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -57,18 +53,20 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
|
||||
// handle network wide
|
||||
// server change
|
||||
public abstract void onPlayerChangedServerNetworkEvent(SC event);
|
||||
// public void onPlayerChangedServerNetworkEvent
|
||||
|
||||
public abstract void onNetworkPlayerQuit(NJE event);
|
||||
// public void onNetworkPlayerQuit
|
||||
|
||||
// public void onNetworkPlayerJoin
|
||||
|
||||
// local events
|
||||
public abstract void onPubSubMessageEvent(PS event);
|
||||
// public void onPubSubMessageEvent
|
||||
|
||||
public abstract void onServerConnectedEvent(CE event);
|
||||
// public void onServerConnectedEvent
|
||||
|
||||
public abstract void onLoginEvent(LE event);
|
||||
// public void onLoginEvent
|
||||
|
||||
public abstract void onDisconnectEvent(DE event);
|
||||
// public void onDisconnectEvent
|
||||
|
||||
protected void handleNetworkPlayerServerChange(IPlayerChangedServerNetworkEvent event) {
|
||||
this.serverCache.invalidate(event.getUuid());
|
||||
@@ -82,56 +80,50 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
this.proxyCache.invalidate(event.getUuid());
|
||||
this.serverCache.invalidate(event.getUuid());
|
||||
this.ipCache.invalidate(event.getUuid());
|
||||
this.lastOnlineCache.invalidate(event.getUuid());
|
||||
|
||||
//TODO: We could also rely on redisbungee-serverchange pubsub messages to update the cache in-place without querying redis. That would be a lot more efficient.
|
||||
this.serverToPlayersCache.invalidate(SERVERS_TO_PLAYERS_KEY);
|
||||
}
|
||||
|
||||
protected void handleNetworkPlayerJoin(IPlayerJoinedNetworkEvent event) {
|
||||
this.proxyCache.invalidate(event.getUuid());
|
||||
this.serverCache.invalidate(event.getUuid());
|
||||
this.ipCache.invalidate(event.getUuid());
|
||||
this.lastOnlineCache.invalidate(event.getUuid());
|
||||
|
||||
//TODO: We could also rely on redisbungee-serverchange pubsub messages to update the cache in-place without querying redis. That would be a lot more efficient.
|
||||
this.serverToPlayersCache.invalidate(SERVERS_TO_PLAYERS_KEY);
|
||||
}
|
||||
|
||||
|
||||
protected void handlePubSubMessageEvent(IPubSubMessageEvent event) {
|
||||
// kick api
|
||||
if (event.getChannel().equals("redisbungee-kick")) {
|
||||
switch (event.getChannel()) {
|
||||
case "redisbungee-serverchange" -> {
|
||||
JSONObject data = new JSONObject(event.getMessage());
|
||||
String proxy = data.getString("proxy");
|
||||
if (proxy.equals(this.proxyId)) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = UUID.fromString(data.getString("uuid"));
|
||||
String message = data.getString("message");
|
||||
plugin.handlePlatformKick(uuid, COMPONENT_SERIALIZER.deserialize(message));
|
||||
return;
|
||||
}
|
||||
if (event.getChannel().equals("redisbungee-serverchange")) {
|
||||
JSONObject data = new JSONObject(event.getMessage());
|
||||
String proxy = data.getString("proxy");
|
||||
if (proxy.equals(this.proxyId)) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = UUID.fromString(data.getString("uuid"));
|
||||
String from = null;
|
||||
if (data.has("from")) from = data.getString("from");
|
||||
String to = data.getString("to");
|
||||
plugin.fireEvent(plugin.createPlayerChangedServerNetworkEvent(uuid, from, to));
|
||||
return;
|
||||
}
|
||||
if (event.getChannel().equals("redisbungee-player-join")) {
|
||||
case "redisbungee-player-join" -> {
|
||||
JSONObject data = new JSONObject(event.getMessage());
|
||||
String proxy = data.getString("proxy");
|
||||
if (proxy.equals(this.proxyId)) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = UUID.fromString(data.getString("uuid"));
|
||||
plugin.fireEvent(plugin.createPlayerJoinedNetworkEvent(uuid));
|
||||
return;
|
||||
}
|
||||
if (event.getChannel().equals("redisbungee-player-leave")) {
|
||||
case "redisbungee-player-leave" -> {
|
||||
JSONObject data = new JSONObject(event.getMessage());
|
||||
String proxy = data.getString("proxy");
|
||||
if (proxy.equals(this.proxyId)) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = UUID.fromString(data.getString("uuid"));
|
||||
plugin.fireEvent(plugin.createPlayerLeftNetworkEvent(uuid));
|
||||
}
|
||||
case "redisbungee-player-kick" -> {
|
||||
JSONObject data = new JSONObject(event.getMessage());
|
||||
UUID uuid = UUID.fromString(data.getString("uuid"));
|
||||
String message = data.getString("serialized-message");
|
||||
handleSerializedKick(uuid, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -146,21 +138,28 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
handleServerChangeRedis(uuid, to);
|
||||
}
|
||||
|
||||
public void kickPlayer(UUID uuid, Component message) {
|
||||
if (!plugin.handlePlatformKick(uuid, message)) { // handle locally before SENDING a message
|
||||
// must check if player is on the local proxy
|
||||
// https://docs.advntr.dev/minimessage/index.html
|
||||
// implemented downstream in Velocity and Bungeecord
|
||||
protected abstract boolean handleSerializedKick(UUID player, String serializedMiniMessage);
|
||||
|
||||
// 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", uuid);
|
||||
data.put("message", COMPONENT_SERIALIZER.serialize(message));
|
||||
plugin.proxyDataManager().sendChannelMessage("redisbungee-kick", data.toString());
|
||||
}
|
||||
data.put("uuid", player);
|
||||
data.put("serialized-message", serializedMiniMessage);
|
||||
if (!handleSerializedKick(player, serializedMiniMessage))
|
||||
plugin.proxyDataManager().sendChannelMessage("redisbungee-player-kick", data.toString());
|
||||
}
|
||||
|
||||
private void handleServerChangeRedis(UUID uuid, String server) {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("server", server);
|
||||
data.put("last-server", server);
|
||||
unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", data);
|
||||
unifiedJedis.hset("redisbungee::" + this.networkId + "::player::" + uuid + "::data", data);
|
||||
}
|
||||
|
||||
protected void addPlayer(final UUID uuid, final String name, final InetAddress inetAddress) {
|
||||
@@ -168,7 +167,7 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
redisData.put("last-online", String.valueOf(0));
|
||||
redisData.put("proxy", this.proxyId);
|
||||
redisData.put("ip", inetAddress.getHostAddress());
|
||||
unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", redisData);
|
||||
unifiedJedis.hset("redisbungee::" + this.networkId + "::player::" + uuid + "::data", redisData);
|
||||
plugin.getUuidTranslator().persistInfo(name, uuid, this.unifiedJedis);
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("proxy", this.proxyId);
|
||||
@@ -179,8 +178,8 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
}
|
||||
|
||||
protected void removePlayer(UUID uuid) {
|
||||
unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "last-online", String.valueOf(System.currentTimeMillis()));
|
||||
unifiedJedis.hdel("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "server", "proxy", "ip");
|
||||
unifiedJedis.hset("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "last-online", String.valueOf(System.currentTimeMillis()));
|
||||
unifiedJedis.hdel("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "server", "proxy", "ip");
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("proxy", this.proxyId);
|
||||
data.put("uuid", uuid);
|
||||
@@ -191,25 +190,25 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
|
||||
|
||||
protected String getProxyFromRedis(UUID uuid) {
|
||||
return unifiedJedis.hget("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "proxy");
|
||||
return unifiedJedis.hget("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "proxy");
|
||||
}
|
||||
|
||||
protected String getServerFromRedis(UUID uuid) {
|
||||
return unifiedJedis.hget("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "server");
|
||||
return unifiedJedis.hget("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "server");
|
||||
}
|
||||
|
||||
protected String getLastServerFromRedis(UUID uuid) {
|
||||
return unifiedJedis.hget("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "last-server");
|
||||
return unifiedJedis.hget("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "last-server");
|
||||
}
|
||||
|
||||
protected InetAddress getIpAddressFromRedis(UUID uuid) {
|
||||
String ip = unifiedJedis.hget("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "ip");
|
||||
String ip = unifiedJedis.hget("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "ip");
|
||||
if (ip == null) return null;
|
||||
return InetAddresses.forString(ip);
|
||||
}
|
||||
|
||||
protected long getLastOnlineFromRedis(UUID uuid) {
|
||||
String unixString = unifiedJedis.hget("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", "last-online");
|
||||
String unixString = unifiedJedis.hget("redisbungee::" + this.networkId + "::player::" + uuid + "::data", "last-online");
|
||||
if (unixString == null) return -1;
|
||||
return Long.parseLong(unixString);
|
||||
}
|
||||
@@ -231,7 +230,7 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
}
|
||||
|
||||
public long getLastOnline(UUID uuid) {
|
||||
return getLastOnlineFromRedis(uuid);
|
||||
return this.lastOnlineCache.get(uuid);
|
||||
}
|
||||
|
||||
public Multimap<String, UUID> serversToPlayers() {
|
||||
@@ -248,10 +247,17 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
public Multimap<String, UUID> doPooledPipeline(Pipeline pipeline) {
|
||||
HashMap<UUID, Response<String>> responses = new HashMap<>();
|
||||
for (UUID uuid : uuids) {
|
||||
responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server"));
|
||||
Optional.ofNullable(pipeline.hget("redisbungee::" + networkId + "::player::" + uuid + "::data", "server")).ifPresent(stringResponse -> {
|
||||
responses.put(uuid, stringResponse);
|
||||
});
|
||||
}
|
||||
pipeline.sync();
|
||||
responses.forEach((uuid, response) -> builder.put(response.get(), uuid));
|
||||
responses.forEach((uuid, response) -> {
|
||||
String key = response.get();
|
||||
if (key == null) return;
|
||||
|
||||
builder.put(key, uuid);
|
||||
});
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -259,10 +265,16 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
|
||||
public Multimap<String, UUID> clusterPipeline(ClusterPipeline pipeline) {
|
||||
HashMap<UUID, Response<String>> responses = new HashMap<>();
|
||||
for (UUID uuid : uuids) {
|
||||
responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server"));
|
||||
Optional.ofNullable(pipeline.hget("redisbungee::" + networkId + "::player::" + uuid + "::data", "server")).ifPresent(stringResponse -> {
|
||||
responses.put(uuid, stringResponse);
|
||||
});
|
||||
}
|
||||
pipeline.sync();
|
||||
responses.forEach((uuid, response) -> builder.put(response.get(), uuid));
|
||||
responses.forEach((uuid, response) -> {
|
||||
String key = response.get();
|
||||
if (key == null) return;
|
||||
builder.put(key, uuid);
|
||||
});
|
||||
return builder.build();
|
||||
}
|
||||
}.call();
|
||||
|
||||
@@ -66,9 +66,9 @@ public abstract class ProxyDataManager implements Runnable {
|
||||
this.plugin = plugin;
|
||||
this.proxyId = this.plugin.configuration().getProxyId();
|
||||
this.unifiedJedis = plugin.getSummoner().obtainResource();
|
||||
this.destroyProxyMembers();
|
||||
this.networkId = plugin.configuration().networkId();
|
||||
this.STREAM_ID = "network-" + this.networkId + "-redisbungee-stream";
|
||||
this.destroyProxyMembers();
|
||||
}
|
||||
|
||||
public abstract Set<UUID> getLocalOnlineUUIDs();
|
||||
@@ -82,6 +82,13 @@ public abstract class ProxyDataManager implements Runnable {
|
||||
return getProxyMembers(proxyId);
|
||||
}
|
||||
|
||||
// this skip checking if proxy is and its package private
|
||||
// due proxy shutdown shenanigans
|
||||
public boolean isPlayerTrulyOnProxy(String proxyId, UUID uuid) {
|
||||
return unifiedJedis.sismember("redisbungee::" + this.networkId + "::proxies::" + proxyId + "::online-players", uuid.toString());
|
||||
}
|
||||
|
||||
|
||||
public List<String> proxiesIds() {
|
||||
return Collections.list(this.heartbeats.keys());
|
||||
}
|
||||
@@ -96,7 +103,6 @@ public abstract class ProxyDataManager implements Runnable {
|
||||
|
||||
public synchronized void sendChannelMessage(String channel, String message) {
|
||||
if (isClosed()) return;
|
||||
this.plugin.fireEvent(this.plugin.createPubSubEvent(channel, message));
|
||||
publishPayload(new PubSubPayload(this.proxyId, channel, message));
|
||||
}
|
||||
|
||||
@@ -193,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);
|
||||
|
||||
@@ -11,12 +11,10 @@
|
||||
package com.imaginarycode.minecraft.redisbungee.api;
|
||||
|
||||
import com.imaginarycode.minecraft.redisbungee.AbstractRedisBungeeAPI;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.EventsPlatform;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDTranslator;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.UUID;
|
||||
@@ -55,8 +53,6 @@ public interface RedisBungeePlugin<P> extends EventsPlatform {
|
||||
|
||||
RedisBungeeConfiguration configuration();
|
||||
|
||||
LangConfiguration langConfiguration();
|
||||
|
||||
Summoner<?> getSummoner();
|
||||
|
||||
RedisBungeeMode getRedisBungeeMode();
|
||||
@@ -65,7 +61,7 @@ public interface RedisBungeePlugin<P> extends EventsPlatform {
|
||||
|
||||
ProxyDataManager proxyDataManager();
|
||||
|
||||
PlayerDataManager<P, ?, ?, ?, ?, ?, ?> playerDataManager();
|
||||
PlayerDataManager<P> playerDataManager();
|
||||
|
||||
UUIDTranslator getUuidTranslator();
|
||||
|
||||
@@ -77,11 +73,8 @@ public interface RedisBungeePlugin<P> extends EventsPlatform {
|
||||
|
||||
UUID getPlayerUUID(String player);
|
||||
|
||||
|
||||
String getPlayerName(UUID player);
|
||||
|
||||
boolean handlePlatformKick(UUID uuid, Component message);
|
||||
|
||||
String getPlayerServerName(P player);
|
||||
|
||||
boolean isPlayerOnAServer(P player);
|
||||
@@ -92,5 +85,5 @@ public interface RedisBungeePlugin<P> extends EventsPlatform {
|
||||
|
||||
void executeAsyncAfter(Runnable runnable, TimeUnit timeUnit, int time);
|
||||
|
||||
|
||||
String platformId();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.api.config;
|
||||
|
||||
public enum HandleMotdOrder {
|
||||
FIRST,
|
||||
NORMAL,
|
||||
LAST
|
||||
}
|
||||
@@ -13,7 +13,6 @@ package com.imaginarycode.minecraft.redisbungee.api.config;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.net.InetAddresses;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.net.InetAddress;
|
||||
import java.util.List;
|
||||
|
||||
@@ -25,12 +24,13 @@ public class RedisBungeeConfiguration {
|
||||
|
||||
private final boolean handleReconnectToLastServer;
|
||||
private final boolean handleMotd;
|
||||
private final HandleMotdOrder handleMotdOrder;
|
||||
|
||||
private final CommandsConfiguration commandsConfiguration;
|
||||
private final String networkId;
|
||||
|
||||
|
||||
public RedisBungeeConfiguration(String networkId, String proxyId, List<String> exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, CommandsConfiguration commandsConfiguration) {
|
||||
public RedisBungeeConfiguration(String networkId, String proxyId, List<String> exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, HandleMotdOrder handleMotdOrder, CommandsConfiguration commandsConfiguration) {
|
||||
this.proxyId = proxyId;
|
||||
ImmutableList.Builder<InetAddress> addressBuilder = ImmutableList.builder();
|
||||
for (String s : exemptAddresses) {
|
||||
@@ -40,6 +40,7 @@ public class RedisBungeeConfiguration {
|
||||
this.kickWhenOnline = kickWhenOnline;
|
||||
this.handleReconnectToLastServer = handleReconnectToLastServer;
|
||||
this.handleMotd = handleMotd;
|
||||
this.handleMotdOrder = handleMotdOrder;
|
||||
this.commandsConfiguration = commandsConfiguration;
|
||||
this.networkId = networkId;
|
||||
}
|
||||
@@ -60,12 +61,16 @@ public class RedisBungeeConfiguration {
|
||||
return this.handleMotd;
|
||||
}
|
||||
|
||||
public HandleMotdOrder handleMotdOrder() {
|
||||
return handleMotdOrder;
|
||||
}
|
||||
|
||||
public boolean handleReconnectToLastServer() {
|
||||
return this.handleReconnectToLastServer;
|
||||
}
|
||||
|
||||
public record CommandsConfiguration(boolean redisbungeeEnabled, boolean redisbungeeLegacyEnabled,
|
||||
@Nullable LegacySubCommandsConfiguration legacySubCommandsConfiguration) {
|
||||
LegacySubCommandsConfiguration legacySubCommandsConfiguration) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ package com.imaginarycode.minecraft.redisbungee.api.config.loaders;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisClusterSummoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisPooledSummoner;
|
||||
@@ -96,14 +97,25 @@ public interface ConfigLoader extends GenericConfigLoader {
|
||||
}
|
||||
|
||||
plugin.logInfo("Loaded network id " + networkId);
|
||||
|
||||
|
||||
// TO avoid proxies from different platforms from seeing each other.
|
||||
networkId = plugin.platformId() + "-" + networkId;
|
||||
plugin.logInfo("Platform is {} so network id is now is {}", plugin.platformId(), networkId);
|
||||
|
||||
boolean reconnectToLastServer = node.getNode("reconnect-to-last-server").getBoolean();
|
||||
boolean handleMotd = node.getNode("handle-motd").getBoolean(true);
|
||||
plugin.logInfo("handle reconnect to last server: {}", reconnectToLastServer);
|
||||
plugin.logInfo("handle motd: {}", handleMotd);
|
||||
|
||||
HandleMotdOrder handleMotdOrder = HandleMotdOrder.NORMAL;
|
||||
String handleMotdOrderName = node.getNode("handle-motd-priority").getString();
|
||||
if (handleMotdOrderName != null) {
|
||||
try {
|
||||
handleMotdOrder = HandleMotdOrder.valueOf(handleMotdOrderName.toUpperCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException e) {
|
||||
plugin.logWarn("handle motd order value '{}' is unsupported (allowed: {})", handleMotdOrderName, HandleMotdOrder.values());
|
||||
}
|
||||
}
|
||||
plugin.logInfo("handle motd order: {}", handleMotdOrder);
|
||||
|
||||
// commands
|
||||
boolean redisBungeeEnabled = node.getNode("commands", "redisbungee", "enabled").getBoolean(true);
|
||||
@@ -130,7 +142,8 @@ public interface ConfigLoader extends GenericConfigLoader {
|
||||
boolean installPlist = node.getNode("commands", "redisbungee-legacy", "subcommands", "plist", "install").getBoolean(false);
|
||||
|
||||
|
||||
RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(networkId, proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, new RedisBungeeConfiguration.CommandsConfiguration(
|
||||
RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(networkId, proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, handleMotdOrder,
|
||||
new RedisBungeeConfiguration.CommandsConfiguration(
|
||||
redisBungeeEnabled, redisBungeeLegacyEnabled,
|
||||
new RedisBungeeConfiguration.LegacySubCommandsConfiguration(
|
||||
findEnabled, glistEnabled, ipEnabled,
|
||||
|
||||
@@ -13,28 +13,7 @@ package com.imaginarycode.minecraft.redisbungee.api.util.uuid;
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CachedUUIDEntry {
|
||||
private final String name;
|
||||
private final UUID uuid;
|
||||
private final Calendar expiry;
|
||||
|
||||
public CachedUUIDEntry(String name, UUID uuid, Calendar expiry) {
|
||||
this.name = name;
|
||||
this.uuid = uuid;
|
||||
this.expiry = expiry;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public Calendar getExpiry() {
|
||||
return expiry;
|
||||
}
|
||||
public record CachedUUIDEntry(String name, UUID uuid, Calendar expiry) {
|
||||
|
||||
public boolean expired() {
|
||||
return Calendar.getInstance().after(expiry);
|
||||
|
||||
@@ -12,9 +12,9 @@ package com.imaginarycode.minecraft.redisbungee.api.util.uuid;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.ResponseBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
@@ -22,13 +22,9 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NameFetcher {
|
||||
private static OkHttpClient httpClient;
|
||||
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
public static void setHttpClient(OkHttpClient httpClient) {
|
||||
NameFetcher.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public static List<String> nameHistoryFromUuid(UUID uuid) throws IOException {
|
||||
String name = getName(uuid);
|
||||
if (name == null) return Collections.emptyList();
|
||||
|
||||
@@ -12,7 +12,7 @@ package com.imaginarycode.minecraft.redisbungee.api.util.uuid;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.Gson;
|
||||
import com.squareup.okhttp.*;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -28,13 +28,7 @@ public class UUIDFetcher implements Callable<Map<String, UUID>> {
|
||||
private final List<String> names;
|
||||
private final boolean rateLimiting;
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
|
||||
public static void setHttpClient(OkHttpClient httpClient) {
|
||||
UUIDFetcher.httpClient = httpClient;
|
||||
}
|
||||
|
||||
private static OkHttpClient httpClient;
|
||||
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||
|
||||
private UUIDFetcher(List<String> names, boolean rateLimiting) {
|
||||
this.names = ImmutableList.copyOf(names);
|
||||
|
||||
@@ -61,7 +61,7 @@ public final class UUIDTranslator {
|
||||
CachedUUIDEntry cachedUUIDEntry = nameToUuidMap.get(player.toLowerCase());
|
||||
if (cachedUUIDEntry != null) {
|
||||
if (!cachedUUIDEntry.expired())
|
||||
return cachedUUIDEntry.getUuid();
|
||||
return cachedUUIDEntry.uuid();
|
||||
else
|
||||
nameToUuidMap.remove(player);
|
||||
}
|
||||
@@ -93,11 +93,11 @@ public final class UUIDTranslator {
|
||||
if (entry.expired()) {
|
||||
unifiedJedis.hdel("uuid-cache", player.toLowerCase());
|
||||
// Doesn't hurt to also remove the UUID entry as well.
|
||||
unifiedJedis.hdel("uuid-cache", entry.getUuid().toString());
|
||||
unifiedJedis.hdel("uuid-cache", entry.uuid().toString());
|
||||
} else {
|
||||
nameToUuidMap.put(player.toLowerCase(), entry);
|
||||
uuidToNameMap.put(entry.getUuid(), entry);
|
||||
return entry.getUuid();
|
||||
uuidToNameMap.put(entry.uuid(), entry);
|
||||
return entry.uuid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ public final class UUIDTranslator {
|
||||
CachedUUIDEntry cachedUUIDEntry = uuidToNameMap.get(player);
|
||||
if (cachedUUIDEntry != null) {
|
||||
if (!cachedUUIDEntry.expired())
|
||||
return cachedUUIDEntry.getName();
|
||||
return cachedUUIDEntry.name();
|
||||
else
|
||||
uuidToNameMap.remove(player);
|
||||
}
|
||||
@@ -159,11 +159,11 @@ public final class UUIDTranslator {
|
||||
unifiedJedis.hdel("uuid-cache", player.toString());
|
||||
// Doesn't hurt to also remove the named entry as well.
|
||||
// TODO: Since UUIDs are fixed, we could look up the name and see if the UUID matches.
|
||||
unifiedJedis.hdel("uuid-cache", entry.getName());
|
||||
unifiedJedis.hdel("uuid-cache", entry.name());
|
||||
} else {
|
||||
nameToUuidMap.put(entry.getName().toLowerCase(), entry);
|
||||
nameToUuidMap.put(entry.name().toLowerCase(), entry);
|
||||
uuidToNameMap.put(player, entry);
|
||||
return entry.getName();
|
||||
return entry.name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ useSSL: false
|
||||
|
||||
# An identifier for this network, which helps to separate redisbungee instances on same redis instance.
|
||||
# You can use environment variable 'REDISBUNGEE_NETWORK_ID' to override
|
||||
# Depending on the platform bungeecord or velocity system will append platform id to the network id
|
||||
# to prevent proxies from different platforms from seeing each other. since 0.13.0
|
||||
network-id: "main"
|
||||
|
||||
# An identifier for this BungeeCord / Velocity instance. Will randomly generate if leaving it blank.
|
||||
@@ -77,6 +79,13 @@ kick-when-online: true
|
||||
# you can disable this when you want to handle motd yourself, use RedisBungee api to get total players when needed :)
|
||||
handle-motd: true
|
||||
|
||||
# MOTD plugins compatibility setting
|
||||
# Allowed values: FIRST, NORMAL, LAST
|
||||
# This option enables RedisBungee to manage various interactions between other plugins and the online player count,
|
||||
# which is dynamically updated to a global player count in ping responses if the handle-motd option is enabled.
|
||||
# If you encounter issues with other plugins accessing or modifying the player count, try using a value of FIRST or LAST.
|
||||
handle-motd-order: NORMAL
|
||||
|
||||
# A list of IP addresses for which RedisBungee will not modify the response for, useful for automatic
|
||||
# restart scripts.
|
||||
# Automatically disabled if handle-motd is disabled.
|
||||
|
||||
@@ -3,8 +3,10 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":RedisBungee-API"))
|
||||
compileOnly(project(":RedisBungee-API"))
|
||||
implementation(libs.acf.core)
|
||||
compileOnly(libs.adventure.api)
|
||||
compileOnly(libs.adventure.miniMessage)
|
||||
}
|
||||
|
||||
description = "RedisBungee common commands"
|
||||
|
||||
@@ -10,14 +10,19 @@
|
||||
|
||||
package com.imaginarycode.minecraft.redisbungee.commands;
|
||||
|
||||
import co.aikar.commands.CommandContexts;
|
||||
import co.aikar.commands.CommandManager;
|
||||
import co.aikar.commands.InvalidCommandArgument;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
|
||||
import com.imaginarycode.minecraft.redisbungee.commands.legacy.LegacyRedisBungeeCommands;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommandLoader {
|
||||
|
||||
public static void initCommands(CommandManager<?, ?, ?, ?, ?, ?> commandManager, RedisBungeePlugin<?> plugin) {
|
||||
registerContexts(commandManager);
|
||||
var commandsConfiguration = plugin.configuration().commandsConfiguration();
|
||||
if (commandsConfiguration.redisbungeeEnabled()) {
|
||||
commandManager.registerCommand(new CommandRedisBungee(plugin));
|
||||
@@ -26,6 +31,20 @@ public class CommandLoader {
|
||||
commandManager.registerCommand(new LegacyRedisBungeeCommands(commandManager,plugin));
|
||||
}
|
||||
|
||||
commandManager.registerCommand(new CommandRedisBungeeDebug(plugin));
|
||||
|
||||
|
||||
}
|
||||
private static void registerContexts(CommandManager<?, ?, ?, ?, ?, ?> commandManager) {
|
||||
CommandContexts<?> commandContexts = commandManager.getCommandContexts();
|
||||
commandContexts.registerContext(UUID.class, c -> {
|
||||
String uuidString = c.popFirstArg();
|
||||
try {
|
||||
return UUID.fromString(uuidString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidCommandArgument("invaild uuid");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.commands;
|
||||
|
||||
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 java.util.UUID;
|
||||
|
||||
@CommandAlias("rbd|redisbungeedebug")
|
||||
@CommandPermission("redisbungee.command.debug.use")
|
||||
@Description("debug commands")
|
||||
public class CommandRedisBungeeDebug extends AdventureBaseCommand {
|
||||
|
||||
private final RedisBungeePlugin<?> plugin;
|
||||
|
||||
public CommandRedisBungeeDebug(RedisBungeePlugin<?> plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Subcommand("kickByName")
|
||||
@Description("kicks a player from the network by name")
|
||||
@Private
|
||||
public void kick(CommandIssuer issuer, String playerName) {
|
||||
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) {
|
||||
plugin.playerDataManager().serializedPlayerKick(uuid, "kicked using redisbungee api using uuid");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import net.kyori.adventure.text.Component;
|
||||
*/
|
||||
public abstract class AdventureBaseCommand extends BaseCommand {
|
||||
|
||||
public static void sendMessage(CommandIssuer issuer, Component component) {
|
||||
protected void sendMessage(CommandIssuer issuer, Component component) {
|
||||
CommandPlatformHelper.getPlatformHelper().sendMessage(issuer, component);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
group=com.imaginarycode.minecraft
|
||||
version=0.12.4
|
||||
version=0.13.0-SNAPSHOT
|
||||
36
gradle/libs.versions.toml
Normal file
36
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,36 @@
|
||||
[versions]
|
||||
guava = "33.5.0-jre"
|
||||
jedis = "5.2.0"
|
||||
okhttp = "4.12.0"
|
||||
configurateV3 = "3.7.3"
|
||||
caffeine = "3.2.3"
|
||||
adventure = "4.26.1"
|
||||
adventure-bungeecord-platform = "4.4.1"
|
||||
acf = "e2005dd62d"
|
||||
bungeecordApi = "1.21-R0.5-SNAPSHOT"
|
||||
velocity = "3.5.0-SNAPSHOT"
|
||||
|
||||
[plugins]
|
||||
blossom = { id = "net.kyori.blossom", version = "2.2.0" }
|
||||
indragit = {id = "net.kyori.indra.git", version="4.0.0"}
|
||||
shadow = { id = "com.gradleup.shadow", version = "9.3.1" }
|
||||
run-velocity = { id = "xyz.jpenilla.run-velocity", version = "2.3.1" }
|
||||
|
||||
[libraries]
|
||||
guava = { module = "com.google.guava:guava", version.ref = "guava" }
|
||||
jedis = { module = "redis.clients:jedis", version.ref = "jedis" }
|
||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
configurateV3 = { module = "org.spongepowered:configurate-yaml", version.ref = "configurateV3" }
|
||||
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
|
||||
|
||||
adventure-api = { module = "net.kyori:adventure-api", 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" }
|
||||
acf-bungeecord = { module = "com.github.ProxioDev.commands:acf-bungee", version.ref = "acf" }
|
||||
acf-velocity = { module = "com.github.ProxioDev.commands:acf-velocity", version.ref = "acf" }
|
||||
|
||||
platform-bungeecord = { module = "net.md-5:bungeecord-api", version.ref = "bungeecordApi" }
|
||||
adventure-platforms-bungeecord = { module = "net.kyori:adventure-platform-bungeecord", version.ref = "adventure-bungeecord-platform" }
|
||||
|
||||
platform-velocity = { module = "com.velocitypowered:velocity-api", version.ref = "velocity" }
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
12
gradlew
vendored
12
gradlew
vendored
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -84,7 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -112,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -203,7 +205,7 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
@@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
26
gradlew.bat
vendored
26
gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,22 +59,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
jdk:
|
||||
- openjdk17
|
||||
- openjdk21
|
||||
|
||||
49
lang/build.gradle.kts
Normal file
49
lang/build.gradle.kts
Normal file
@@ -0,0 +1,49 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":RedisBungee-API"))
|
||||
compileOnly(libs.adventure.api)
|
||||
compileOnly(libs.adventure.miniMessage)
|
||||
}
|
||||
|
||||
description = "RedisBungee languages"
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
tasks {
|
||||
// thanks again for paper too
|
||||
withType<Javadoc> {
|
||||
val options = options as StandardJavadocDocletOptions
|
||||
options.use()
|
||||
options.isDocFilesSubDirs = true
|
||||
val adventureVersion = libs.adventure.api.get().version
|
||||
options.links(
|
||||
"https://jd.advntr.dev/api/$adventureVersion"
|
||||
)
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
}
|
||||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
processResources {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
|
||||
package com.imaginarycode.minecraft.redisbungee.api.config.loaders;
|
||||
package net.limework.valiobungee.config.lang;
|
||||
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.LangConfiguration;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.loaders.GenericConfigLoader;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
@@ -8,7 +8,7 @@
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
|
||||
package com.imaginarycode.minecraft.redisbungee.api.config;
|
||||
package net.limework.valiobungee.config.lang;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
@@ -1,20 +1,16 @@
|
||||
plugins {
|
||||
java
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("xyz.jpenilla.run-waterfall") version "2.0.0"
|
||||
alias(libs.plugins.shadow)
|
||||
}
|
||||
|
||||
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 +20,7 @@ java {
|
||||
}
|
||||
|
||||
tasks {
|
||||
runWaterfall {
|
||||
waterfallVersion("1.20")
|
||||
environment["REDISBUNGEE_PROXY_ID"] = "bungeecord-1"
|
||||
environment["REDISBUNGEE_NETWORK_ID"] = "dev"
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
@@ -46,7 +38,8 @@ tasks {
|
||||
relocate("redis.clients.jedis", "com.imaginarycode.minecraft.redisbungee.internal.jedis")
|
||||
relocate("redis.clients.util", "com.imaginarycode.minecraft.redisbungee.internal.jedisutil")
|
||||
relocate("org.apache.commons.pool", "com.imaginarycode.minecraft.redisbungee.internal.commonspool")
|
||||
relocate("com.squareup.okhttp", "com.imaginarycode.minecraft.redisbungee.internal.okhttp")
|
||||
relocate("okhttp3", "com.imaginarycode.minecraft.redisbungee.internal.okhttp3")
|
||||
relocate("kotlin", "com.imaginarycode.minecraft.redisbungee.internal.kotlin")
|
||||
relocate("okio", "com.imaginarycode.minecraft.redisbungee.internal.okio")
|
||||
relocate("org.json", "com.imaginarycode.minecraft.redisbungee.internal.json")
|
||||
// configurate shade
|
||||
@@ -60,6 +53,8 @@ tasks {
|
||||
relocate("com.github.benmanes.caffeine", "com.imaginarycode.minecraft.redisbungee.internal.caffeine")
|
||||
// acf shade
|
||||
relocate("co.aikar.commands", "com.imaginarycode.minecraft.redisbungee.internal.acf.commands")
|
||||
// adventure :/
|
||||
relocate("net.kyori", "com.imaginarycode.minecraft.redisbungee.internal.net.kyori")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -27,7 +24,7 @@ tasks {
|
||||
options.use()
|
||||
options.isDocFilesSubDirs = true
|
||||
options.links(
|
||||
"https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/", // bungeecord api
|
||||
"https://hub.spigotmc.org/jenkins/job/BungeeCord/ws/api/target/reports/apidocs", // bungeecord api
|
||||
)
|
||||
val apiDocs = File(rootProject.projectDir, "api/build/docs/javadoc")
|
||||
options.linksOffline("https://ci.limework.net/ValioBungee/api/build/docs/javadoc", apiDocs.path)
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -11,11 +11,15 @@
|
||||
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;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@@ -29,6 +33,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 +57,100 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current BungeeCord / Velocity proxy ID for this server.
|
||||
*
|
||||
* @return the current server ID
|
||||
* @see #getAllServers()
|
||||
* @since 0.2.5
|
||||
* @deprecated to avoid confusion between A server and A proxy see #getProxyId()
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final String getServerId() {
|
||||
return getProxyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the linked proxies in this network.
|
||||
*
|
||||
* @return the list of all proxies
|
||||
* @see #getServerId()
|
||||
* @since 0.2.5
|
||||
* @deprecated to avoid confusion between A server and A proxy see see {@link #getAllProxies()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final List<String> getAllServers() {
|
||||
return getAllProxies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register (a) PubSub channel(s), so that you may handle PubSubMessageEvent for it.
|
||||
*
|
||||
* @param channels the channels to register
|
||||
* @since 0.3
|
||||
* @deprecated No longer required
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final void registerPubSubChannels(String... channels) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister (a) PubSub channel(s).
|
||||
*
|
||||
* @param channels the channels to unregister
|
||||
* @since 0.3
|
||||
* @deprecated No longer required
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final void unregisterPubSubChannels(String... channels) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Api instance
|
||||
*
|
||||
|
||||
@@ -13,10 +13,13 @@ package com.imaginarycode.minecraft.redisbungee;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
|
||||
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,34 +29,38 @@ 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, PostLoginEvent, PlayerDisconnectEvent, PubSubMessageEvent, PlayerChangedServerNetworkEvent, PlayerLeftNetworkEvent, ServerConnectedEvent> implements Listener {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) {
|
||||
super.handleNetworkPlayerServerChange(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) {
|
||||
super.handleNetworkPlayerQuit(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void onNetworkPlayerJoin(PlayerJoinedNetworkEvent event) {
|
||||
super.handleNetworkPlayerJoin(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPubSubMessageEvent(PubSubMessageEvent event) {
|
||||
super.handlePubSubMessageEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void onServerConnectedEvent(ServerConnectedEvent event) {
|
||||
final String currentServer = event.getServer().getInfo().getName();
|
||||
@@ -61,33 +68,63 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, Po
|
||||
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);
|
||||
// check if online
|
||||
if (getLastOnline(event.getConnection().getUniqueId()) == 0) {
|
||||
// because something can go wrong and proxy somehow does not update player data correctly on shutdown
|
||||
// we have to check proxy if it has the player
|
||||
String proxyId = getProxyFor(event.getConnection().getUniqueId());
|
||||
if (proxyId == null || !plugin.proxyDataManager().isPlayerTrulyOnProxy(proxyId, event.getConnection().getUniqueId())) {
|
||||
event.completeIntent((Plugin) plugin);
|
||||
} else {
|
||||
if (plugin.configuration().kickWhenOnline()) {
|
||||
kickPlayer(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);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
event.completeIntent((Plugin) plugin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@EventHandler
|
||||
public void onLoginEvent(PostLoginEvent event) {
|
||||
super.addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getName(), event.getPlayer().getAddress().getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@EventHandler
|
||||
public void onDisconnectEvent(PlayerDisconnectEvent event) {
|
||||
super.removePlayer(event.getPlayer().getUniqueId());
|
||||
|
||||
@@ -15,18 +15,15 @@ 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;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPubSubMessageEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisPooledSummoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.InitialUtils;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.NameFetcher;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDFetcher;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDTranslator;
|
||||
import com.imaginarycode.minecraft.redisbungee.commands.CommandLoader;
|
||||
import com.imaginarycode.minecraft.redisbungee.commands.utils.CommandPlatformHelper;
|
||||
@@ -34,10 +31,9 @@ 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 com.squareup.okhttp.Dispatcher;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
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;
|
||||
@@ -50,8 +46,6 @@ import redis.clients.jedis.JedisPool;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetAddress;
|
||||
import java.sql.Date;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -59,7 +53,7 @@ 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;
|
||||
@@ -72,7 +66,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
private UUIDTranslator uuidTranslator;
|
||||
private RedisBungeeConfiguration configuration;
|
||||
private LangConfiguration langConfiguration;
|
||||
private OkHttpClient httpClient;
|
||||
private BungeeCommandManager commandManager;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger("RedisBungee");
|
||||
@@ -83,7 +76,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LangConfiguration langConfiguration() {
|
||||
return this.langConfiguration;
|
||||
}
|
||||
@@ -99,7 +91,7 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerDataManager<ProxiedPlayer, ?, ?, ?, ?, ?, ?> playerDataManager() {
|
||||
public PlayerDataManager<ProxiedPlayer> playerDataManager() {
|
||||
return this.playerDataManager;
|
||||
}
|
||||
|
||||
@@ -168,15 +160,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();
|
||||
@@ -241,11 +224,6 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
// cleanup
|
||||
this.cleanupTask = getProxy().getScheduler().schedule(this, () -> this.proxyDataManager.correctionTask(), 0, 60, TimeUnit.SECONDS);
|
||||
// init the http lib
|
||||
httpClient = new OkHttpClient();
|
||||
Dispatcher dispatcher = new Dispatcher(getExecutorService());
|
||||
httpClient.setDispatcher(dispatcher);
|
||||
NameFetcher.setHttpClient(httpClient);
|
||||
UUIDFetcher.setHttpClient(httpClient);
|
||||
InitialUtils.checkRedisVersion(this);
|
||||
uuidTranslator = new UUIDTranslator(this);
|
||||
|
||||
@@ -349,6 +327,21 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
this.summoner = summoner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLangConfigLoad(LangConfiguration langConfiguration) {
|
||||
this.langConfiguration = langConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String platformId() {
|
||||
return "bungeecord";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickPlayer(UUID player, Component message) {
|
||||
this.playerDataManager.kickPlayer(player, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns an instance of {@link RedisBungeeAPI}
|
||||
*
|
||||
@@ -362,12 +355,15 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
|
||||
|
||||
@Deprecated
|
||||
public JedisPool getPool() {
|
||||
return api.getJedisPool();
|
||||
if (api.getMode() == RedisBungeeMode.SINGLE) {
|
||||
JedisPool jedisPool = ((JedisPooledSummoner) getSummoner()).getCompatibilityJedisPool();
|
||||
if (jedisPool == null) {
|
||||
throw new IllegalStateException("JedisPool compatibility mode is disabled, Please enable it in the RedisBungee config.yml");
|
||||
}
|
||||
return jedisPool;
|
||||
} else {
|
||||
throw new IllegalStateException("Mode is not " + RedisBungeeMode.SINGLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLangConfigLoad(LangConfiguration langConfiguration) {
|
||||
this.langConfiguration = langConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder;
|
||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
@@ -29,6 +29,7 @@ import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.event.EventPriority;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -36,14 +37,37 @@ 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;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPing(ProxyPingEvent event) {
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPingFirst(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.FIRST) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPingNormal(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.NORMAL) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPingLast(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.LAST) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
private void onPing0(ProxyPingEvent event) {
|
||||
if (!plugin.configuration().handleMotd()) return;
|
||||
if (plugin.configuration().getExemptAddresses().contains(event.getConnection().getAddress().getAddress())) return;
|
||||
ServerInfo forced = AbstractReconnectHandler.getForcedHost(event.getConnection());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
java
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("xyz.jpenilla.run-velocity") version "2.0.0"
|
||||
alias(libs.plugins.shadow)
|
||||
alias(libs.plugins.run.velocity)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
annotationProcessor(libs.platform.velocity)
|
||||
implementation(project(":RedisBungee-Commands"))
|
||||
implementation(libs.acf.velocity)
|
||||
implementation(project(":RedisBungee-Lang"))
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +22,13 @@ java {
|
||||
|
||||
tasks {
|
||||
runVelocity {
|
||||
velocityVersion("3.3.0-SNAPSHOT")
|
||||
velocityVersion(libs.versions.velocity.get())
|
||||
environment["REDISBUNGEE_PROXY_ID"] = "velocity-1"
|
||||
environment["REDISBUNGEE_NETWORK_ID"] = "dev"
|
||||
}
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
options.release.set(21) // required by velocity
|
||||
}
|
||||
processResources {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
@@ -36,10 +37,10 @@ tasks {
|
||||
relocate("redis.clients.jedis", "com.imaginarycode.minecraft.redisbungee.internal.jedis")
|
||||
relocate("redis.clients.util", "com.imaginarycode.minecraft.redisbungee.internal.jedisutil")
|
||||
relocate("org.apache.commons.pool", "com.imaginarycode.minecraft.redisbungee.internal.commonspool")
|
||||
relocate("com.squareup.okhttp", "com.imaginarycode.minecraft.redisbungee.internal.okhttp")
|
||||
relocate("okhttp3", "com.imaginarycode.minecraft.redisbungee.internal.okhttp3")
|
||||
relocate("kotlin", "com.imaginarycode.minecraft.redisbungee.internal.kotlin")
|
||||
relocate("okio", "com.imaginarycode.minecraft.redisbungee.internal.okio")
|
||||
relocate("org.json", "com.imaginarycode.minecraft.redisbungee.internal.json")
|
||||
relocate("com.github.benmanes.caffeine", "com.imaginarycode.minecraft.redisbungee.internal.caffeine")
|
||||
// acf shade
|
||||
relocate("co.aikar.commands", "com.imaginarycode.minecraft.redisbungee.internal.acf.commands")
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
@@ -35,14 +36,37 @@ import static com.imaginarycode.minecraft.redisbungee.api.util.serialize.MultiMa
|
||||
|
||||
public class RedisBungeeListener {
|
||||
|
||||
private final RedisBungeePlugin<Player> plugin;
|
||||
private final RedisBungeeVelocityPlugin plugin;
|
||||
|
||||
public RedisBungeeListener(RedisBungeePlugin<Player> plugin) {
|
||||
public RedisBungeeListener(RedisBungeeVelocityPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LAST) // some plugins changes it online players so we need to be executed as last
|
||||
public void onPing(ProxyPingEvent event) {
|
||||
@Subscribe(order = PostOrder.FIRST)
|
||||
public void onPingFirst(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.FIRST) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.NORMAL)
|
||||
public void onPingNormal(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.NORMAL) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onPingLast(ProxyPingEvent event) {
|
||||
if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.LAST) {
|
||||
return;
|
||||
}
|
||||
onPing0(event);
|
||||
}
|
||||
|
||||
private void onPing0(ProxyPingEvent event) {
|
||||
if (!plugin.configuration().handleMotd()) return;
|
||||
if (plugin.configuration().getExemptAddresses().contains(event.getConnection().getRemoteAddress().getAddress())) return;
|
||||
|
||||
|
||||
@@ -18,25 +18,19 @@ import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.commands.CommandLoader;
|
||||
import com.imaginarycode.minecraft.redisbungee.commands.utils.CommandPlatformHelper;
|
||||
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;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.events.IPubSubMessageEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.InitialUtils;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.NameFetcher;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDFetcher;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDTranslator;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
|
||||
import com.squareup.okhttp.Dispatcher;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
@@ -50,6 +44,8 @@ import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.api.scheduler.ScheduledTask;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.limework.valiobungee.config.lang.LangConfiguration;
|
||||
import net.limework.valiobungee.config.lang.LangConfigLoader;
|
||||
import org.slf4j.Logger;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
|
||||
@@ -57,18 +53,15 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Date;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Plugin(id = "redisbungee", name = "RedisBungee", version = Constants.VERSION, url = "https://github.com/ProxioDev/RedisBungee", authors = {"astei", "ProxioDev"})
|
||||
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, ConfigLoader, LangConfigLoader, ServerObjectFetcher {
|
||||
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, ConfigLoader, LangConfigLoader, ApiPlatformSupport {
|
||||
private final ProxyServer server;
|
||||
private final Logger logger;
|
||||
private final Path dataFolder;
|
||||
@@ -78,7 +71,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
private final UUIDTranslator uuidTranslator;
|
||||
private RedisBungeeConfiguration configuration;
|
||||
private LangConfiguration langConfiguration;
|
||||
private final OkHttpClient httpClient;
|
||||
|
||||
private final ProxyDataManager proxyDataManager;
|
||||
|
||||
@@ -127,11 +119,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
};
|
||||
this.playerDataManager = new VelocityPlayerDataManager(this);
|
||||
uuidTranslator = new UUIDTranslator(this);
|
||||
this.httpClient = new OkHttpClient();
|
||||
Dispatcher dispatcher = new Dispatcher(Executors.newFixedThreadPool(6));
|
||||
this.httpClient.setDispatcher(dispatcher);
|
||||
NameFetcher.setHttpClient(httpClient);
|
||||
UUIDFetcher.setHttpClient(httpClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +138,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerDataManager<Player, ?, ?, ?, ?, ?, ?> playerDataManager() {
|
||||
public PlayerDataManager<Player> playerDataManager() {
|
||||
return this.playerDataManager;
|
||||
}
|
||||
|
||||
@@ -216,7 +203,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LangConfiguration langConfiguration() {
|
||||
return this.langConfiguration;
|
||||
}
|
||||
@@ -241,15 +227,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
return this.getProxy().getPlayer(player).map(Player::getUsername).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean handlePlatformKick(UUID uuid, Component message) {
|
||||
Player player = getPlayer(uuid);
|
||||
if (player == null) return false;
|
||||
player.disconnect(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerServerName(Player player) {
|
||||
return player.getCurrentServer().map(serverConnection -> serverConnection.getServerInfo().getName()).orElse(null);
|
||||
@@ -300,8 +277,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
if (heartbeatTask != null) {
|
||||
heartbeatTask.cancel();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
this.proxyDataManager.close();
|
||||
this.jedisSummoner.close();
|
||||
@@ -309,13 +284,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
this.httpClient.getDispatcher().getExecutorService().shutdown();
|
||||
try {
|
||||
logInfo("waiting for httpclient thread-pool termination.....");
|
||||
this.httpClient.getDispatcher().getExecutorService().awaitTermination(20, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (commandManager != null) commandManager.unregisterCommands();
|
||||
logInfo("RedisBungee shutdown complete");
|
||||
}
|
||||
@@ -373,6 +341,11 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
return server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickPlayer(UUID player, Component message) {
|
||||
this.playerDataManager.kickPlayer(player, message);
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
@@ -384,4 +357,9 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
return this.getClass().getClassLoader().getResourceAsStream(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String platformId() {
|
||||
return "velocity";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
package com.imaginarycode.minecraft.redisbungee;
|
||||
|
||||
import com.imaginarycode.minecraft.redisbungee.api.PlayerDataManager;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
|
||||
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
@@ -25,33 +24,41 @@ 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;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLoginEvent, DisconnectEvent, PubSubMessageEvent, PlayerChangedServerNetworkEvent, PlayerLeftNetworkEvent, ServerConnectedEvent> {
|
||||
public VelocityPlayerDataManager(RedisBungeePlugin<Player> plugin) {
|
||||
public class VelocityPlayerDataManager extends PlayerDataManager<Player> {
|
||||
|
||||
private final RedisBungeeVelocityPlugin vplugin;
|
||||
|
||||
public VelocityPlayerDataManager(RedisBungeeVelocityPlugin plugin) {
|
||||
super(plugin);
|
||||
this.vplugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) {
|
||||
handleNetworkPlayerServerChange(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) {
|
||||
handleNetworkPlayerQuit(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onNetworkPlayerJoin(PlayerJoinedNetworkEvent event) {
|
||||
handleNetworkPlayerJoin(event);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPubSubMessageEvent(PubSubMessageEvent event) {
|
||||
handlePubSubMessageEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onServerConnectedEvent(ServerConnectedEvent event) {
|
||||
final String currentServer = event.getServer().getServerInfo().getName();
|
||||
@@ -64,30 +71,56 @@ public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLog
|
||||
super.playerChangedServer(event.getPlayer().getUniqueId(), oldServer, currentServer);
|
||||
}
|
||||
|
||||
private final static MiniMessage MINI_MESSAGE_SERIALIZER = MiniMessage.miniMessage();
|
||||
@Override
|
||||
public boolean handleSerializedKick(UUID uuid, String serializedMiniMessage) {
|
||||
Player 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(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(message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void kickPlayer(UUID player, Component message) {
|
||||
serializedPlayerKick(player, MINI_MESSAGE_SERIALIZER.serialize(message));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoginEvent(LoginEvent event, Continuation continuation) {
|
||||
// check if online
|
||||
if (getLastOnline(event.getPlayer().getUniqueId()) == 0) {
|
||||
// because something can go wrong and proxy somehow does not update player data correctly on shutdown
|
||||
// we have to check proxy if it has the player
|
||||
String proxyId = getProxyFor(event.getPlayer().getUniqueId());
|
||||
if (proxyId == null || !plugin.proxyDataManager().isPlayerTrulyOnProxy(proxyId, event.getPlayer().getUniqueId())) {
|
||||
continuation.resume();
|
||||
} else {
|
||||
if (plugin.configuration().kickWhenOnline()) {
|
||||
kickPlayer(event.getPlayer().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
|
||||
kickPlayer(event.getPlayer().getUniqueId(), vplugin.langConfiguration().messages().loggedInFromOtherLocation());
|
||||
// wait 3 seconds before releasing the event
|
||||
plugin.executeAsyncAfter(continuation::resume, TimeUnit.SECONDS, 3);
|
||||
} else {
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(plugin.langConfiguration().messages().alreadyLoggedIn()));
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(vplugin.langConfiguration().messages().alreadyLoggedIn()));
|
||||
continuation.resume();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continuation.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onLoginEvent(PostLoginEvent event) {
|
||||
addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getUsername(), event.getPlayer().getRemoteAddress().getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Subscribe
|
||||
public void onDisconnectEvent(DisconnectEvent event) {
|
||||
if (event.getLoginStatus() == DisconnectEvent.LoginStatus.SUCCESSFUL_LOGIN || event.getLoginStatus() == DisconnectEvent.LoginStatus.PRE_SERVER_JOIN) {
|
||||
|
||||
@@ -5,19 +5,14 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
api(project(":RedisBungee-API")) {
|
||||
// Since velocity already includes guava / configurate exlude them
|
||||
// Since velocity already includes guava / configurate / guava exlude them
|
||||
exclude("com.google.guava", "guava")
|
||||
exclude("com.google.code.gson", "gson")
|
||||
exclude("org.spongepowered", "configurate-yaml")
|
||||
// exclude also adventure api
|
||||
exclude("net.kyori", "adventure-api")
|
||||
exclude("net.kyori", "adventure-text-serializer-gson")
|
||||
exclude("net.kyori", "adventure-text-serializer-legacy")
|
||||
exclude("net.kyori", "adventure-text-serializer-plain")
|
||||
exclude("net.kyori", "adventure-text-minimessage")
|
||||
exclude("com.github.ben-manes.caffeine", "caffeine")
|
||||
}
|
||||
implementation(project(":RedisBungee-Lang"))
|
||||
compileOnly(libs.platform.velocity)
|
||||
|
||||
}
|
||||
|
||||
description = "RedisBungee Velocity API"
|
||||
@@ -41,7 +36,7 @@ tasks {
|
||||
}
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
options.release.set(21) // required by velocity
|
||||
}
|
||||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 com.velocitypowered.api.proxy.ProxyServer;
|
||||
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 {
|
||||
|
||||
ProxyServer getProxy();
|
||||
|
||||
void kickPlayer(UUID player, Component message);
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ package com.imaginarycode.minecraft.redisbungee;
|
||||
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -49,9 +50,33 @@ public class RedisBungeeAPI extends AbstractRedisBungeeAPI {
|
||||
public final ServerInfo getServerFor(@NonNull UUID player) {
|
||||
String serverName = this.getServerNameFor(player);
|
||||
if (serverName == null) return null;
|
||||
return ((ServerObjectFetcher) this.plugin).getProxy().getServer(serverName).map((RegisteredServer::getServerInfo)).orElse(null);
|
||||
return ((ApiPlatformSupport) this.plugin).getProxy().getServer(serverName).map((RegisteredServer::getServerInfo)).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 playerUUID player name
|
||||
* @param message kick message that player will see on kick
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public void kickPlayer(UUID playerUUID, Component message) {
|
||||
((ApiPlatformSupport) this.plugin).kickPlayer(playerUUID, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Api instance
|
||||
*
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.imaginarycode.minecraft.redisbungee;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
|
||||
public interface ServerObjectFetcher {
|
||||
|
||||
ProxyServer getProxy();
|
||||
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
@@ -6,90 +7,28 @@ pluginManagement {
|
||||
|
||||
rootProject.name = "ValioBungee"
|
||||
|
||||
include(":RedisBungee-API")
|
||||
project(":RedisBungee-API").projectDir = file("api")
|
||||
|
||||
include(":RedisBungee-Commands")
|
||||
project(":RedisBungee-Commands").projectDir = file("commands")
|
||||
|
||||
include(":RedisBungee-Velocity")
|
||||
project(":RedisBungee-Velocity").projectDir = file("proxies/velocity")
|
||||
|
||||
include(":RedisBungee-Bungee")
|
||||
project(":RedisBungee-Bungee").projectDir = file("proxies/bungeecord/bungeecord-api")
|
||||
|
||||
include(":RedisBungee-Proxy-Bungee")
|
||||
project(":RedisBungee-Proxy-Bungee").projectDir = file("proxies/bungeecord")
|
||||
|
||||
include(":RedisBungee-Velocity")
|
||||
project(":RedisBungee-Velocity").projectDir = file("proxies/velocity/velocity-api")
|
||||
|
||||
include(":RedisBungee-Proxy-Velocity")
|
||||
project(":RedisBungee-Proxy-Velocity").projectDir = file("proxies/velocity")
|
||||
fun configureProject(name: String, path: String) {
|
||||
include(name)
|
||||
project(name).projectDir = file(path)
|
||||
}
|
||||
|
||||
configureProject(":RedisBungee-API", "api")
|
||||
configureProject(":RedisBungee-Lang", "lang")
|
||||
configureProject(":RedisBungee-Commands", "commands")
|
||||
|
||||
configureProject(":RedisBungee-Bungee", "proxies/bungeecord/bungeecord-api")
|
||||
configureProject(":RedisBungee-Proxy-Bungee", "proxies/bungeecord")
|
||||
|
||||
configureProject(":RedisBungee-Velocity", "proxies/velocity/velocity-api")
|
||||
configureProject(":RedisBungee-Proxy-Velocity", "proxies/velocity")
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "PaperMC"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://jitpack.io")
|
||||
}
|
||||
maven {
|
||||
// hosts the bungeecord apis
|
||||
name = "sonatype"
|
||||
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
maven {
|
||||
name = "aikar repo"
|
||||
url = uri("https://repo.aikar.co/content/groups/aikar/")
|
||||
}
|
||||
|
||||
}
|
||||
versionCatalogs {
|
||||
val jedisVersion = "5.1.2"
|
||||
val configurateVersion = "3.7.3"
|
||||
val guavaVersion = "31.1-jre"
|
||||
val okHttpVersion = "2.7.5"
|
||||
val caffeineVersion = "3.1.8"
|
||||
val adventureVersion = "4.16.0"
|
||||
val acf = "0.5.1-SNAPSHOT"
|
||||
val bungeecordApiVersion = "1.20-R0.1-SNAPSHOT"
|
||||
val velocityVersion = "3.3.0-SNAPSHOT";
|
||||
|
||||
|
||||
create("libs") {
|
||||
|
||||
library("guava", "com.google.guava:guava:$guavaVersion")
|
||||
library("jedis", "redis.clients:jedis:$jedisVersion")
|
||||
library("okhttp", "com.squareup.okhttp:okhttp:$okHttpVersion")
|
||||
library("configurate", "org.spongepowered:configurate-yaml:$configurateVersion")
|
||||
library("caffeine", "com.github.ben-manes.caffeine:caffeine:$caffeineVersion")
|
||||
|
||||
library("adventure-api", "net.kyori:adventure-api:$adventureVersion")
|
||||
library("adventure-gson", "net.kyori:adventure-text-serializer-gson:$adventureVersion")
|
||||
library("adventure-legacy", "net.kyori:adventure-text-serializer-legacy:$adventureVersion")
|
||||
library("adventure-plain", "net.kyori:adventure-text-serializer-plain:$adventureVersion")
|
||||
library("adventure-miniMessage", "net.kyori:adventure-text-minimessage:$adventureVersion")
|
||||
|
||||
library("acf-core", "co.aikar:acf-core:$acf")
|
||||
library("acf-bungeecord", "co.aikar:acf-bungee:$acf")
|
||||
library("acf-velocity", "co.aikar:acf-velocity:$acf")
|
||||
|
||||
library("platform-bungeecord","net.md-5:bungeecord-api:$bungeecordApiVersion")
|
||||
library("adventure-platforms-bungeecord", "net.kyori:adventure-platform-bungeecord:4.3.2")
|
||||
|
||||
library("platform-velocity", "com.velocitypowered:velocity-api:$velocityVersion")
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user