2
0
mirror of https://github.com/proxiodev/RedisBungee.git synced 2026-05-03 11:40:29 +00:00

69 Commits

Author SHA1 Message Date
d0ae5d5342 fix 2024-04-26 21:17:38 +04:00
b88202ae38 fix color 2024-04-26 20:36:00 +04:00
3c4e45dfe2 remove debug 2024-04-26 20:10:18 +04:00
abd19c1c3a pageable show command 2024-04-26 20:09:15 +04:00
b406c89406 remove yourkit 2024-04-24 12:17:28 +04:00
91c3845b2e add network id 2024-04-22 16:44:35 +04:00
97e6b5c944 update config / readme 2024-04-21 16:00:03 +04:00
65ac465915 add default values to commands config 2024-04-18 14:23:17 +04:00
32826d843c finsh up command system 2024-04-18 12:48:00 +04:00
78561fa467 improve rb ocmmand 2024-04-15 05:36:52 +04:00
ab441503c7 correctly remove heartbeat on cleanup 2024-04-15 05:23:38 +04:00
51719f13e2 show command 2024-04-15 05:06:36 +04:00
2015d1d0fd remove debug message 2024-04-15 03:36:44 +04:00
70aacc99c0 use continue instead of break 2024-04-15 03:32:30 +04:00
72025bc22c fix wrong use method of inetaddres in player data manager 2024-04-14 13:19:08 +04:00
de65b163e2 finish up the commands 2024-04-14 11:58:04 +04:00
1e7f474a09 adding first batch of commands 2024-04-14 08:40:16 +04:00
19064e0a60 impl: redis clean up task, taken from brains impl. 2024-04-14 08:04:08 +04:00
e76f0d0a00 finish up the version command etc 2024-04-14 07:09:05 +04:00
40c542a50a new command infrastructure 2024-04-14 05:54:08 +04:00
86f64ab019 move all depeneds management into settings.gradle.kts and include acf lib 2024-04-13 23:57:00 +04:00
41b5bde55c insert todo into langauge system 2024-04-13 22:27:26 +04:00
e5b1f9d76e update adventure 2024-04-13 22:22:19 +04:00
ThiagoROX
0b8dc4bde6 provide pt-br translation
Signed-off-by: mohammed jasem alaajel <xrambad@gmail.com>
2024-04-12 22:37:33 +04:00
782f0994c2 [skip ci] Update readme about the transfer packets x3 2024-04-12 22:37:33 +04:00
ca8377ad4c [skip ci] Update readme about the transfer packets 2024-04-12 22:37:33 +04:00
69c3e30344 [skip ci] Update readme about the transfer packets 2024-04-12 22:37:33 +04:00
b3eacbd1c4 typo in redis minimal version 2024-04-12 22:37:33 +04:00
72b2d46dcd update redis wrong version message 2024-04-12 22:37:33 +04:00
44175e8a68 fix redis version detection 2024-04-12 22:37:33 +04:00
6c27228920 fix for lang too 2024-04-12 22:37:33 +04:00
2eb7f3cf9d Fix wrong config version 2024-04-12 22:37:33 +04:00
1c36aa5418 remove lang system for commands
commands will be included in seperate plugins for each platforms.
NOTE: because of this commands `Modules` will be used as example to access
the API
2024-04-12 22:37:33 +04:00
c56a64bbc2 update depends & Gradle 2024-04-12 22:37:33 +04:00
2429cc63d5 load common command messages 2024-04-12 22:37:33 +04:00
46d53fc018 config changes 2024-04-12 22:37:33 +04:00
d70a5de829 Only allow 6.2 or above of redis versions 2024-04-12 22:37:33 +04:00
a6c6916103 remove arabic for now, and finish up the lang file 2024-04-12 22:37:33 +04:00
fa7ca2dacb checkstyle 2024-04-12 22:37:33 +04:00
da255860bd remove debug message 2024-04-12 22:37:33 +04:00
983693b929 Language system implementation, commands still not translatable yet, finish up configs system 2024-04-12 22:37:33 +04:00
32b5e829ba gradle update 2024-04-12 22:37:33 +04:00
383e647c87 split some functions from config loader to be common 2024-04-12 22:37:33 +04:00
9b54ca93db remove old commands system, rename register leagacy command to register commands. 2024-04-12 22:37:33 +04:00
eed91dd73d fix some issues on lang file 2024-04-12 22:37:33 +04:00
b76709c291 change %s to it placeholders 2024-04-12 22:37:33 +04:00
4f6529b295 provide arabic translation 2024-04-12 22:37:33 +04:00
97cdf31cfc provide better info from the wiki 2024-04-12 22:37:33 +04:00
5ea8932ac4 lang file changes 2024-04-12 22:37:33 +04:00
20932d894b addtional stuff for lang config file 2024-04-12 22:37:33 +04:00
6bcba06f7a ignore bungeecord commands override on velocity 2024-04-12 22:37:33 +04:00
76c362cf66 log version / build date 2024-04-12 22:37:33 +04:00
b7433bc9a3 Remove unnecessary public in some methods in plugin interface 2024-04-12 22:37:33 +04:00
7ba54ebfe2 include build date 2024-04-12 22:37:33 +04:00
dd38532501 config log changes, introduction of new env REDISBUNGEE_PROXY_ID 2024-04-12 22:37:33 +04:00
7183e809d0 bungeecord version 2024-04-12 22:37:33 +04:00
d1d848fa8c remove tests as its no longer used 2024-04-12 22:37:33 +04:00
e70a6e305c implement last server connect on join, closes #84 2024-04-12 22:37:33 +04:00
e897a60976 remove all old messages code, new lang file 2024-04-12 22:37:33 +04:00
f6e1ca65bf make varable for depeneds, remove javadocs for adventure from implementations javadocs 2024-04-12 22:37:33 +04:00
11a0d84368 remove weird javadocs 2024-04-12 22:37:33 +04:00
a0fdd6d997 welcome adventure api
MiniMessage is now used for Messages.yml

fix bug when from is null when server change
2024-04-12 22:37:33 +04:00
3c4f0d8c93 oops forgotten to change something for kick when online 2024-04-12 22:37:33 +04:00
6d40c1902a change false to true as default for kick-when-online option 2024-04-12 22:37:33 +04:00
a2f1ec22c6 remove autoclosable interface from proxy data manager 2024-04-12 22:37:33 +04:00
16576ab4c2 new config options: handle-motd, reconnect to last server 2024-04-12 22:37:33 +04:00
f96c5759a2 config changes
jedispool is now disabled by default, some minor config changes
2024-04-12 22:37:33 +04:00
8aaae6702e new data system 2024-04-12 22:37:02 +04:00
006066f66c prepare for 0.12.0 2024-04-12 22:36:07 +04:00
97 changed files with 195 additions and 314 deletions

View File

@@ -5,9 +5,9 @@ name: RedisBungee Build
on: on:
push: push:
branches: [ stable, develop ] branches: [ develop ]
pull_request: pull_request:
branches: [ stable, develop ] branches: [ develop ]
jobs: jobs:
build: build:
@@ -24,19 +24,19 @@ jobs:
- name: Build with gradle - name: Build with gradle
run: ./gradlew shadowJar run: ./gradlew shadowJar
- name: Upload Bungee - name: Upload Bungee
uses: actions/upload-artifact@v4.4.0 uses: actions/upload-artifact@v2.2.3
with: with:
# Artifact name # Artifact name
name: RedisBungee-Bungee name: RedisBungee-Bungee
# Destination path # Destination path
path: proxies/bungeecord/build/libs/* path: RedisBungee-Bungee/build/libs/*
- name: Upload Velocity - name: Upload Velocity
uses: actions/upload-artifact@v4.4.0 uses: actions/upload-artifact@v2.2.3
with: with:
name: RedisBungee-Velocity name: RedisBungee-Velocity
path: proxies/velocity/build/libs/* path: RedisBungee-Velocity/build/libs/*
- name: Upload API - name: Upload API
uses: actions/upload-artifact@v4.4.0 uses: actions/upload-artifact@v2.2.3
with: with:
name: RedisBungee-API name: RedisBungee-API
path: api/build/libs/* path: RedisBungee-API/build/libs/*

2
.gitignore vendored
View File

@@ -46,4 +46,4 @@ manifest.mf
javadoc javadoc
# run-server folders # run-server folders
proxies/*/run */run

View File

@@ -9,10 +9,6 @@ or [Velocity*](https://github.com/PaperMC/Velocity) proxies
[![](https://raw.githubusercontent.com/Prospector/badges/master/modrinth-badge-72h-padded.png)](https://modrinth.com/plugin/redisbungee) [![](https://raw.githubusercontent.com/Prospector/badges/master/modrinth-badge-72h-padded.png)](https://modrinth.com/plugin/redisbungee)
## Wiki
https://github.com/ProxioDev/RedisBungee/wiki
## Support ## Support
open an issue with question button open an issue with question button

View File

@@ -35,6 +35,7 @@ blossom {
commit = "$commitStdout".replace("\n", "") // for some reason it adds new line so remove it. commit = "$commitStdout".replace("\n", "") // for some reason it adds new line so remove it.
commitStdout.close() commitStdout.close()
replaceToken("@git_commit@", commit) replaceToken("@git_commit@", commit)
replaceToken("@build_date@", "${Instant.now().epochSecond}")
} }
@@ -52,7 +53,7 @@ tasks {
val jedisVersion = libs.jedis.get().version val jedisVersion = libs.jedis.get().version
val configurateVersion = libs.configurate.get().version val configurateVersion = libs.configurate.get().version
val guavaVersion = libs.guava.get().version val guavaVersion = libs.guava.get().version
val adventureVersion = libs.adventure.plain.get().version val adventureVersion = libs.guava.get().version
options.links( options.links(
"https://configurate.aoeu.xyz/$configurateVersion/apidocs/", // configurate "https://configurate.aoeu.xyz/$configurateVersion/apidocs/", // configurate
"https://javadoc.io/doc/redis.clients/jedis/$jedisVersion/", // jedis "https://javadoc.io/doc/redis.clients/jedis/$jedisVersion/", // jedis

View File

@@ -224,7 +224,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.2.5 * @since 0.2.5
* @deprecated to avoid confusion between A server and A proxy see #getProxyId() * @deprecated to avoid confusion between A server and A proxy see #getProxyId()
*/ */
@Deprecated(forRemoval = true) @Deprecated
public final String getServerId() { public final String getServerId() {
return getProxyId(); return getProxyId();
} }
@@ -248,7 +248,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.2.5 * @since 0.2.5
* @deprecated to avoid confusion between A server and A proxy see see {@link #getAllProxies()} * @deprecated to avoid confusion between A server and A proxy see see {@link #getAllProxies()}
*/ */
@Deprecated(forRemoval = true) @Deprecated
public final List<String> getAllServers() { public final List<String> getAllServers() {
return getAllProxies(); return getAllProxies();
} }
@@ -260,7 +260,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.3 * @since 0.3
* @deprecated No longer required * @deprecated No longer required
*/ */
@Deprecated(forRemoval = true) @Deprecated
public final void registerPubSubChannels(String... channels) { public final void registerPubSubChannels(String... channels) {
} }
@@ -271,7 +271,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.3 * @since 0.3
* @deprecated No longer required * @deprecated No longer required
*/ */
@Deprecated(forRemoval = true) @Deprecated
public final void unregisterPubSubChannels(String... channels) { public final void unregisterPubSubChannels(String... channels) {
} }
@@ -352,7 +352,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.8.0 * @since 0.8.0
* @deprecated * @deprecated
*/ */
@Deprecated(forRemoval = true) @Deprecated
public void kickPlayer(String playerName, String message) { public void kickPlayer(String playerName, String message) {
kickPlayer(getUuidFromName(playerName), message); kickPlayer(getUuidFromName(playerName), message);
} }
@@ -365,7 +365,7 @@ public abstract class AbstractRedisBungeeAPI {
* @since 0.8.0 * @since 0.8.0
* @deprecated * @deprecated
*/ */
@Deprecated(forRemoval = true) @Deprecated
public void kickPlayer(UUID playerUUID, String message) { public void kickPlayer(UUID playerUUID, String message) {
kickPlayer(playerUUID, Component.text(message)); kickPlayer(playerUUID, Component.text(message));
} }
@@ -402,9 +402,7 @@ public abstract class AbstractRedisBungeeAPI {
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE} * @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE}
* @see #getJedisPool() * @see #getJedisPool()
* @since 0.7.0 * @since 0.7.0
* @deprecated use {@link #getSummoner() }
*/ */
@Deprecated(forRemoval = true)
public Jedis requestJedis() { public Jedis requestJedis() {
if (getMode() == RedisBungeeMode.SINGLE) { if (getMode() == RedisBungeeMode.SINGLE) {
return getJedisPool().getResource(); return getJedisPool().getResource();
@@ -425,7 +423,7 @@ public abstract class AbstractRedisBungeeAPI {
if (getMode() == RedisBungeeMode.SINGLE) { if (getMode() == RedisBungeeMode.SINGLE) {
JedisPool jedisPool = ((JedisPooledSummoner) this.plugin.getSummoner()).getCompatibilityJedisPool(); JedisPool jedisPool = ((JedisPooledSummoner) this.plugin.getSummoner()).getCompatibilityJedisPool();
if (jedisPool == null) { if (jedisPool == null) {
throw new IllegalStateException("JedisPool compatibility mode is disabled, Please enable it in the RedisBungee config.yml"); throw new IllegalStateException("JedisPool compatibility mode is disabled");
} }
return jedisPool; return jedisPool;
} else { } else {
@@ -440,9 +438,7 @@ public abstract class AbstractRedisBungeeAPI {
* @return {@link redis.clients.jedis.JedisCluster} * @return {@link redis.clients.jedis.JedisCluster}
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#CLUSTER} * @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#CLUSTER}
* @since 0.8.0 * @since 0.8.0
* @deprecated use {@link #getSummoner()}
*/ */
@Deprecated(forRemoval = true)
public JedisCluster requestClusterJedis() { public JedisCluster requestClusterJedis() {
if (getMode() == RedisBungeeMode.CLUSTER) { if (getMode() == RedisBungeeMode.CLUSTER) {
return ((JedisClusterSummoner) this.plugin.getSummoner()).obtainResource(); return ((JedisClusterSummoner) this.plugin.getSummoner()).obtainResource();
@@ -458,9 +454,7 @@ public abstract class AbstractRedisBungeeAPI {
* @return {@link redis.clients.jedis.JedisPooled} * @return {@link redis.clients.jedis.JedisPooled}
* @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE} * @throws IllegalStateException if the {@link #getMode()} is not equal to {@link RedisBungeeMode#SINGLE}
* @since 0.8.0 * @since 0.8.0
* @deprecated use {@link #getSummoner()}
*/ */
@Deprecated(forRemoval = true)
public JedisPooled requestJedisPooled() { public JedisPooled requestJedisPooled() {
if (getMode() == RedisBungeeMode.SINGLE) { if (getMode() == RedisBungeeMode.SINGLE) {
return ((JedisPooledSummoner) this.plugin.getSummoner()).obtainResource(); return ((JedisPooledSummoner) this.plugin.getSummoner()).obtainResource();

View File

@@ -15,6 +15,7 @@ public class Constants {
public final static String VERSION = "@version@"; public final static String VERSION = "@version@";
public final static String GIT_COMMIT = "@git_commit@"; public final static String GIT_COMMIT = "@git_commit@";
public final static long BUILD_DATE = Long.parseLong("@build_date@");
public static String getGithubCommitLink() { public static String getGithubCommitLink() {
return "https://github.com/ProxioDev/RedisBungee/commit/" + GIT_COMMIT; return "https://github.com/ProxioDev/RedisBungee/commit/" + GIT_COMMIT;

View File

@@ -28,22 +28,25 @@ import redis.clients.jedis.Response;
import redis.clients.jedis.UnifiedJedis; import redis.clients.jedis.UnifiedJedis;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.*; import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit; 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, LE, DE, PS extends IPubSubMessageEvent, SC extends IPlayerChangedServerNetworkEvent, NJE extends IPlayerLeftNetworkEvent, CE> {
protected final RedisBungeePlugin<P> plugin; protected final RedisBungeePlugin<P> plugin;
private final Object SERVERS_TO_PLAYERS_KEY = new Object();
private final UnifiedJedis unifiedJedis;
private final String proxyId;
private final String networkId;
private final LoadingCache<UUID, String> serverCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getServerFromRedis); private final LoadingCache<UUID, String> serverCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getServerFromRedis);
private final LoadingCache<UUID, String> lastServerCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(this::getLastServerFromRedis); 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, 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, 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 Object SERVERS_TO_PLAYERS_KEY = new Object();
private final LoadingCache<Object, Multimap<String, UUID>> serverToPlayersCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build(this::serversToPlayersBuilder); private final LoadingCache<Object, Multimap<String, UUID>> serverToPlayersCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build(this::serversToPlayersBuilder);
private final JSONComponentSerializer COMPONENT_SERIALIZER = JSONComponentSerializer.json(); private final UnifiedJedis unifiedJedis;
private final String proxyId;
private final String networkId;
public PlayerDataManager(RedisBungeePlugin<P> plugin) { public PlayerDataManager(RedisBungeePlugin<P> plugin) {
this.plugin = plugin; this.plugin = plugin;
@@ -54,34 +57,30 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
// handle network wide // handle network wide
// server change // server change
//l public abstract void onPlayerChangedServerNetworkEvent(SC event); public abstract void onPlayerChangedServerNetworkEvent(SC event);
// public abstract void onNetworkPlayerQuit(NJE event); public abstract void onNetworkPlayerQuit(NJE event);
// local events // local events
//public abstract void onPubSubMessageEvent(PS event); public abstract void onPubSubMessageEvent(PS event);
//public abstract void onServerConnectedEvent(CE event); public abstract void onServerConnectedEvent(CE event);
//public abstract void onLoginEvent(LE event); public abstract void onLoginEvent(LE event);
public abstract void onDisconnectEvent(DE event);
//public abstract void onDisconnectEvent(DE event);
protected void handleNetworkPlayerServerChange(IPlayerChangedServerNetworkEvent event) { protected void handleNetworkPlayerServerChange(IPlayerChangedServerNetworkEvent event) {
this.serverCache.invalidate(event.getUuid()); this.serverCache.invalidate(event.getUuid());
this.lastServerCache.invalidate(event.getUuid()); this.lastServerCache.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 handleNetworkPlayerQuit(IPlayerLeftNetworkEvent event) { protected void handleNetworkPlayerQuit(IPlayerLeftNetworkEvent event) {
this.proxyCache.invalidate(event.getUuid()); this.proxyCache.invalidate(event.getUuid());
this.serverCache.invalidate(event.getUuid()); this.serverCache.invalidate(event.getUuid());
this.ipCache.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) { protected void handlePubSubMessageEvent(IPubSubMessageEvent event) {
@@ -143,6 +142,8 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
handleServerChangeRedis(uuid, to); handleServerChangeRedis(uuid, to);
} }
private final JSONComponentSerializer COMPONENT_SERIALIZER =JSONComponentSerializer.json();
public void kickPlayer(UUID uuid, Component message) { public void kickPlayer(UUID uuid, Component message) {
if (!plugin.handlePlatformKick(uuid, message)) { // handle locally before SENDING a message if (!plugin.handlePlatformKick(uuid, message)) { // handle locally before SENDING a message
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
@@ -160,13 +161,13 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", data); unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", data);
} }
protected void addPlayer(final UUID uuid, final String name, final InetAddress inetAddress) { protected void addPlayer(final UUID uuid, final InetAddress inetAddress) {
Map<String, String> redisData = new HashMap<>(); Map<String, String> redisData = new HashMap<>();
redisData.put("last-online", String.valueOf(0)); redisData.put("last-online", String.valueOf(0));
redisData.put("proxy", this.proxyId); redisData.put("proxy", this.proxyId);
redisData.put("ip", inetAddress.getHostAddress()); redisData.put("ip", inetAddress.getHostAddress());
unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", redisData); unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", redisData);
plugin.getUuidTranslator().persistInfo(name, uuid, this.unifiedJedis);
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("proxy", this.proxyId); data.put("proxy", this.proxyId);
data.put("uuid", uuid); data.put("uuid", uuid);
@@ -214,7 +215,6 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
public String getLastServerFor(UUID uuid) { public String getLastServerFor(UUID uuid) {
return this.lastServerCache.get(uuid); return this.lastServerCache.get(uuid);
} }
public String getServerFor(UUID uuid) { public String getServerFor(UUID uuid) {
return this.serverCache.get(uuid); return this.serverCache.get(uuid);
} }
@@ -228,7 +228,7 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
} }
public long getLastOnline(UUID uuid) { public long getLastOnline(UUID uuid) {
return getLastOnlineFromRedis(uuid); return this.lastOnlineCache.get(uuid);
} }
public Multimap<String, UUID> serversToPlayers() { public Multimap<String, UUID> serversToPlayers() {
@@ -245,17 +245,10 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
public Multimap<String, UUID> doPooledPipeline(Pipeline pipeline) { public Multimap<String, UUID> doPooledPipeline(Pipeline pipeline) {
HashMap<UUID, Response<String>> responses = new HashMap<>(); HashMap<UUID, Response<String>> responses = new HashMap<>();
for (UUID uuid : uuids) { for (UUID uuid : uuids) {
Optional.ofNullable(pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server")).ifPresent(stringResponse -> { responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server"));
responses.put(uuid, stringResponse);
});
} }
pipeline.sync(); pipeline.sync();
responses.forEach((uuid, response) -> { responses.forEach((uuid, response) -> builder.put(response.get(), uuid));
String key = response.get();
if (key == null) return;
builder.put(key, uuid);
});
return builder.build(); return builder.build();
} }
@@ -263,16 +256,10 @@ public abstract class PlayerDataManager<P, LE, DE, PS extends IPubSubMessageEven
public Multimap<String, UUID> clusterPipeline(ClusterPipeline pipeline) { public Multimap<String, UUID> clusterPipeline(ClusterPipeline pipeline) {
HashMap<UUID, Response<String>> responses = new HashMap<>(); HashMap<UUID, Response<String>> responses = new HashMap<>();
for (UUID uuid : uuids) { for (UUID uuid : uuids) {
Optional.ofNullable(pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server")).ifPresent(stringResponse -> { responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server"));
responses.put(uuid, stringResponse);
});
} }
pipeline.sync(); pipeline.sync();
responses.forEach((uuid, response) -> { responses.forEach((uuid, response) -> builder.put(response.get(), uuid));
String key = response.get();
if (key == null) return;
builder.put(key, uuid);
});
return builder.build(); return builder.build();
} }
}.call(); }.call();

View File

@@ -66,9 +66,9 @@ public abstract class ProxyDataManager implements Runnable {
this.plugin = plugin; this.plugin = plugin;
this.proxyId = this.plugin.configuration().getProxyId(); this.proxyId = this.plugin.configuration().getProxyId();
this.unifiedJedis = plugin.getSummoner().obtainResource(); this.unifiedJedis = plugin.getSummoner().obtainResource();
this.destroyProxyMembers();
this.networkId = plugin.configuration().networkId(); this.networkId = plugin.configuration().networkId();
this.STREAM_ID = "network-" + this.networkId + "-redisbungee-stream"; this.STREAM_ID = "network-" + this.networkId + "-redisbungee-stream";
this.destroyProxyMembers();
} }
public abstract Set<UUID> getLocalOnlineUUIDs(); public abstract Set<UUID> getLocalOnlineUUIDs();
@@ -82,22 +82,12 @@ public abstract class ProxyDataManager implements Runnable {
return getProxyMembers(proxyId); 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() { public List<String> proxiesIds() {
return Collections.list(this.heartbeats.keys()); return Collections.list(this.heartbeats.keys());
} }
public synchronized void sendCommandTo(String proxyToRun, String command) { public synchronized void sendCommandTo(String proxyToRun, String command) {
if (isClosed()) return; if (isClosed()) return;
if (proxyToRun.equals("allservers") || proxyToRun.equals(this.proxyId())) {
handlePlatformCommandExecution(command);
}
publishPayload(new RunCommandPayload(this.proxyId, proxyToRun, command)); publishPayload(new RunCommandPayload(this.proxyId, proxyToRun, command));
} }

View File

@@ -12,6 +12,7 @@ package com.imaginarycode.minecraft.redisbungee.api.config.loaders;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;

View File

@@ -34,7 +34,7 @@ public class InitialUtils {
} }
long uuidCacheSize = unifiedJedis.hlen("uuid-cache"); long uuidCacheSize = unifiedJedis.hlen("uuid-cache");
if (uuidCacheSize > 750000) { if (uuidCacheSize > 750000) {
plugin.logInfo("Looks like you have a really big UUID cache! Run '/rb clean' to remove expired cache entries"); plugin.logInfo("Looks like you have a really big UUID cache! Run https://github.com/ProxioDev/Brains");
} }
break; break;
} }

View File

@@ -56,7 +56,7 @@ network-id: "main"
# You can set Environment variable 'REDISBUNGEE_PROXY_ID' to override # You can set Environment variable 'REDISBUNGEE_PROXY_ID' to override
proxy-id: "proxy-1" proxy-id: "proxy-1"
# since RedisBungee Internally now uses UnifiedJedis instead of Jedis, JedisPool. # since RedisBungee Internally now uses JedisPooled instead of Jedis, JedisPool.
# which will break compatibility with old plugins that uses RedisBungee JedisPool # which will break compatibility with old plugins that uses RedisBungee JedisPool
# so to mitigate this issue, RedisBungee will create an JedisPool for compatibility reasons. # so to mitigate this issue, RedisBungee will create an JedisPool for compatibility reasons.
# disabled by default # disabled by default

View File

@@ -1,11 +1,12 @@
plugins { plugins {
java `java-library`
`maven-publish`
id("com.github.johnrengelman.shadow") version "8.1.1" id("com.github.johnrengelman.shadow") version "8.1.1"
id("xyz.jpenilla.run-waterfall") version "2.0.0" id("xyz.jpenilla.run-waterfall") version "2.0.0"
} }
dependencies { dependencies {
implementation(project(":RedisBungee-Bungee")) api(project(":RedisBungee-API"))
compileOnly(libs.platform.bungeecord) { compileOnly(libs.platform.bungeecord) {
exclude("com.google.guava", "guava") exclude("com.google.guava", "guava")
exclude("com.google.code.gson", "gson") exclude("com.google.code.gson", "gson")
@@ -20,10 +21,23 @@ dependencies {
description = "RedisBungee Bungeecord implementation" description = "RedisBungee Bungeecord implementation"
java { java {
withJavadocJar()
withSourcesJar() withSourcesJar()
} }
tasks { tasks {
withType<Javadoc> {
dependsOn(project(":RedisBungee-API").getTasksByName("javadoc", false))
val options = options as StandardJavadocDocletOptions
options.use()
options.isDocFilesSubDirs = true
options.links(
"https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/", // bungeecord api
)
val apiDocs = File(rootProject.projectDir, "RedisBungee-API/build/docs/javadoc")
options.linksOffline("https://ci.limework.net/RedisBungee/RedisBungee-API/build/docs/javadoc", apiDocs.path)
}
runWaterfall { runWaterfall {
waterfallVersion("1.20") waterfallVersion("1.20")
environment["REDISBUNGEE_PROXY_ID"] = "bungeecord-1" environment["REDISBUNGEE_PROXY_ID"] = "bungeecord-1"
@@ -33,6 +47,9 @@ tasks {
options.encoding = Charsets.UTF_8.name() options.encoding = Charsets.UTF_8.name()
options.release.set(17) options.release.set(17)
} }
javadoc {
options.encoding = Charsets.UTF_8.name()
}
processResources { processResources {
filteringCharset = Charsets.UTF_8.name() filteringCharset = Charsets.UTF_8.name()
filesMatching("plugin.yml") { filesMatching("plugin.yml") {
@@ -64,3 +81,11 @@ tasks {
} }
} }
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}

View File

@@ -15,6 +15,7 @@ import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent; import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent; import com.imaginarycode.minecraft.redisbungee.events.PlayerLeftNetworkEvent;
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent; import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.LoginEvent; import net.md_5.bungee.api.event.LoginEvent;
@@ -34,21 +35,25 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, Po
super(plugin); super(plugin);
} }
@Override
@EventHandler @EventHandler
public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) { public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) {
super.handleNetworkPlayerServerChange(event); super.handleNetworkPlayerServerChange(event);
} }
@Override
@EventHandler @EventHandler
public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) { public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) {
super.handleNetworkPlayerQuit(event); super.handleNetworkPlayerQuit(event);
} }
@Override
@EventHandler @EventHandler
public void onPubSubMessageEvent(PubSubMessageEvent event) { public void onPubSubMessageEvent(PubSubMessageEvent event) {
super.handlePubSubMessageEvent(event); super.handlePubSubMessageEvent(event);
} }
@Override
@EventHandler @EventHandler
public void onServerConnectedEvent(ServerConnectedEvent event) { public void onServerConnectedEvent(ServerConnectedEvent event) {
final String currentServer = event.getServer().getInfo().getName(); final String currentServer = event.getServer().getInfo().getName();
@@ -61,21 +66,14 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, Po
event.registerIntent((Plugin) plugin); event.registerIntent((Plugin) plugin);
// check if online // check if online
if (getLastOnline(event.getConnection().getUniqueId()) == 0) { if (getLastOnline(event.getConnection().getUniqueId()) == 0) {
// because something can go wrong and proxy somehow does not update player data correctly on shutdown if (plugin.configuration().kickWhenOnline()) {
// we have to check proxy if it has the player kickPlayer(event.getConnection().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
String proxyId = getProxyFor(event.getConnection().getUniqueId()); // wait 3 seconds before releasing the event
if (proxyId == null || !plugin.proxyDataManager().isPlayerTrulyOnProxy(proxyId, event.getConnection().getUniqueId())) { plugin.executeAsyncAfter(() -> event.completeIntent((Plugin) plugin), TimeUnit.SECONDS, 3);
event.completeIntent((Plugin) plugin);
} else { } else {
if (plugin.configuration().kickWhenOnline()) { event.setCancelled(true);
kickPlayer(event.getConnection().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation()); event.setCancelReason(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().alreadyLoggedIn()));
// wait 3 seconds before releasing the event event.completeIntent((Plugin) plugin);
plugin.executeAsyncAfter(() -> event.completeIntent((Plugin) plugin), TimeUnit.SECONDS, 3);
} else {
event.setCancelled(true);
event.setCancelReason(BungeeComponentSerializer.get().serialize(plugin.langConfiguration().messages().alreadyLoggedIn()));
event.completeIntent((Plugin) plugin);
}
} }
} else { } else {
event.completeIntent((Plugin) plugin); event.completeIntent((Plugin) plugin);
@@ -83,11 +81,13 @@ public class BungeePlayerDataManager extends PlayerDataManager<ProxiedPlayer, Po
} }
@Override
@EventHandler @EventHandler
public void onLoginEvent(PostLoginEvent event) { public void onLoginEvent(PostLoginEvent event) {
super.addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getName(), event.getPlayer().getAddress().getAddress()); super.addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getAddress().getAddress());
} }
@Override
@EventHandler @EventHandler
public void onDisconnectEvent(PlayerDisconnectEvent event) { public void onDisconnectEvent(PlayerDisconnectEvent event) {
super.removePlayer(event.getPlayer().getUniqueId()); super.removePlayer(event.getPlayer().getUniqueId());

View File

@@ -197,6 +197,7 @@ public class RedisBungee extends Plugin implements RedisBungeePlugin<ProxiedPlay
public void initialize() { public void initialize() {
logInfo("Initializing RedisBungee....."); logInfo("Initializing RedisBungee.....");
logInfo("Version: {}", Constants.VERSION); logInfo("Version: {}", Constants.VERSION);
logInfo("Build date: {}", Date.from(Instant.ofEpochSecond(Constants.BUILD_DATE)));
ThreadFactory factory = ((ThreadPoolExecutor) getExecutorService()).getThreadFactory(); ThreadFactory factory = ((ThreadPoolExecutor) getExecutorService()).getThreadFactory();
ScheduledExecutorService service = Executors.newScheduledThreadPool(24, factory); ScheduledExecutorService service = Executors.newScheduledThreadPool(24, factory);
try { try {

View File

@@ -11,7 +11,6 @@
package com.imaginarycode.minecraft.redisbungee.commands; package com.imaginarycode.minecraft.redisbungee.commands;
import co.aikar.commands.CommandIssuer; import co.aikar.commands.CommandIssuer;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.annotation.*; import co.aikar.commands.annotation.*;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.imaginarycode.minecraft.redisbungee.Constants; import com.imaginarycode.minecraft.redisbungee.Constants;
@@ -27,12 +26,12 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@CommandAlias("rb|redisbungee") @CommandAlias("rb|redisbungee")
@CommandPermission("redisbungee.command.use") @CommandPermission("redisbungee.command.use")
@Description("Main command")
public class CommandRedisBungee extends AdventureBaseCommand { public class CommandRedisBungee extends AdventureBaseCommand {
private final RedisBungeePlugin<?> plugin; private final RedisBungeePlugin<?> plugin;
@@ -43,12 +42,12 @@ public class CommandRedisBungee extends AdventureBaseCommand {
@Default @Default
@Subcommand("info|version|git") @Subcommand("info|version|git")
@Description("information about current redisbungee build")
public void info(CommandIssuer issuer) { public void info(CommandIssuer issuer) {
final String message = """ final String message = """
<color:aqua>This proxy is running RedisBungee Limework's fork <color:aqua>This proxy is running RedisBungee Limework's fork
<color:gold>======================================== <color:gold>========================================
<color:aqua>RedisBungee version: <color:green><version> <color:aqua>RedisBungee version: <color:green><version>
<color:aqua>Build date: <color:green><build-date>
<color:aqua>Commit: <color:green><commit> <color:aqua>Commit: <color:green><commit>
<color:gold>======================================== <color:gold>========================================
<color:gold>run /rb help for more commands"""; <color:gold>run /rb help for more commands""";
@@ -58,6 +57,7 @@ public class CommandRedisBungee extends AdventureBaseCommand {
.deserialize( .deserialize(
message, message,
Placeholder.component("version", Component.text(Constants.VERSION)), Placeholder.component("version", Component.text(Constants.VERSION)),
Placeholder.component("build-date", Component.text( new Date(Constants.BUILD_DATE * 1000).toString() )),
Placeholder.component( Placeholder.component(
"commit", "commit",
Component.text(Constants.GIT_COMMIT.substring(0, 8)) Component.text(Constants.GIT_COMMIT.substring(0, 8))
@@ -67,29 +67,19 @@ public class CommandRedisBungee extends AdventureBaseCommand {
} }
// <color:aqua>......: <color:green>...... // <color:aqua>......: <color:green>......
@HelpCommand @HelpCommand
@Description("shows the help page")
public void help(CommandIssuer issuer) { public void help(CommandIssuer issuer) {
final String barFormat = "<color:gold>========================================"; final String message = """
final String commandFormat = "<color:aqua>/rb <sub-command>: <color:green><description>"; <color:gold>========================================
<color:aqua>/rb info: <color:green>shows info of this version.
TextComponent.Builder message = Component.text(); <color:aqua>/rb help: <color:green>shows this page.
message.append(MiniMessage.miniMessage().deserialize(barFormat)); <color:aqua>/rb clean: <color:green>cleans up the uuid cache
<color:red><bold>WARNING...</bold> <color:white>command above could cause performance issues
getSubCommands().forEach((subCommand, registeredCommand) -> { <color:aqua>/rb show: <color:green>shows list of proxies with player count
String[] split = registeredCommand.getCommand().split(" "); <color:gold>========================================
if (split.length > 1 && subCommand.equalsIgnoreCase(split[1])) { <color:gold>run /rb help for more commands""";
message.appendNewline().append(MiniMessage.miniMessage().deserialize(commandFormat, Placeholder.component("sub-command", Component.text(subCommand)), sendMessage(issuer, MiniMessage.miniMessage().deserialize(message));
Placeholder.component("description", MiniMessage.miniMessage().deserialize(registeredCommand.getHelpText()))
));
}
});
message.appendNewline().append(MiniMessage.miniMessage().deserialize(barFormat));
sendMessage(issuer, message.build());
} }
@Subcommand("clean") @Subcommand("clean")
@Description("cleans up the uuid cache<color:red> <bold>WARNING...</bold> <color:white>command above could cause performance issues")
@Private @Private
public void cleanUp(CommandIssuer issuer) { public void cleanUp(CommandIssuer issuer) {
if (StopperUUIDCleanupTask.isRunning) { if (StopperUUIDCleanupTask.isRunning) {
@@ -109,7 +99,6 @@ public class CommandRedisBungee extends AdventureBaseCommand {
} }
@Subcommand("show") @Subcommand("show")
@Description("Shows proxies in this network")
public void showProxies(CommandIssuer issuer, String[] args) { public void showProxies(CommandIssuer issuer, String[] args) {
final String closer = "<color:gold>========================================"; final String closer = "<color:gold>========================================";
final String pageTop = "<color:yellow>Page: <color:green><current>/<max> <color:yellow>Network ID: <color:green><network> <color:yellow>Proxies online: <color:green><proxies>"; final String pageTop = "<color:yellow>Page: <color:green><current>/<max> <color:yellow>Network ID: <color:green><network> <color:yellow>Proxies online: <color:green><proxies>";
@@ -134,6 +123,15 @@ public class CommandRedisBungee extends AdventureBaseCommand {
} else currentPage = 1; } else currentPage = 1;
var data = new ArrayList<>(plugin.proxyDataManager().eachProxyCount().entrySet()); var data = new ArrayList<>(plugin.proxyDataManager().eachProxyCount().entrySet());
data.addAll(data);
data.addAll(data);
data.addAll(data);
data.addAll(data);
data.addAll(data);
data.addAll(data);
data.addAll(data);
data.addAll(data);
// there is no way this runs because there is always an heartbeat. // there is no way this runs because there is always an heartbeat.
// if not could be some shenanigans done by devs :P // if not could be some shenanigans done by devs :P
if (data.isEmpty()) { if (data.isEmpty()) {
@@ -141,7 +139,7 @@ public class CommandRedisBungee extends AdventureBaseCommand {
return; return;
} }
// compute the total pages // compute the total pages
int maxPages = (int) Math.ceil(data.size() / (double) pageSize); int maxPages = data.size() < pageSize ? 1 : data.size() / pageSize ;
if (currentPage > maxPages) currentPage = maxPages; if (currentPage > maxPages) currentPage = maxPages;
var subList = subListProxies(data, currentPage, pageSize); var subList = subListProxies(data, currentPage, pageSize);
TextComponent.Builder builder = Component.text(); TextComponent.Builder builder = Component.text();
@@ -171,19 +169,17 @@ public class CommandRedisBungee extends AdventureBaseCommand {
} }
if (currentPage > 1) { if (currentPage > 1) {
builder.append(MiniMessage.miniMessage().deserialize(previousPage) builder.append(MiniMessage.miniMessage().deserialize(previousPage)
.color(NamedTextColor.WHITE).clickEvent(ClickEvent.runCommand("/rb show " + (currentPage - 1)))); .clickEvent(ClickEvent.runCommand("/rb show " + (currentPage - 1))));
} else {
builder.append(MiniMessage.miniMessage().deserialize(previousPage).color(NamedTextColor.GRAY));
} }
if (subList.size() == pageSize && !subListProxies(data, currentPage + 1, pageSize).isEmpty()) { if (subList.size() == pageSize && !subListProxies(data, currentPage + 1, pageSize).isEmpty()) {
builder.append(MiniMessage.miniMessage().deserialize(nextPage) builder.append(MiniMessage.miniMessage().deserialize(nextPage)
.color(NamedTextColor.WHITE).clickEvent(ClickEvent.runCommand("/rb show " + (currentPage + 1)))); .clickEvent(ClickEvent.runCommand("/rb show " + (currentPage + 1))));
} else {
builder.append(MiniMessage.miniMessage().deserialize(nextPage).color(NamedTextColor.GRAY));
} }
builder.appendNewline(); builder.appendNewline();
builder.append(MiniMessage.miniMessage().deserialize(closer)); builder.append(MiniMessage.miniMessage().deserialize(closer));
sendMessage(issuer, builder.build()); sendMessage(issuer, builder.build());
} }
} }

View File

@@ -1,11 +1,25 @@
plugins { plugins {
java `java-library`
`maven-publish`
id("com.github.johnrengelman.shadow") version "8.1.1" id("com.github.johnrengelman.shadow") version "8.1.1"
id("xyz.jpenilla.run-velocity") version "2.0.0" id("xyz.jpenilla.run-velocity") version "2.0.0"
} }
dependencies { dependencies {
implementation(project(":RedisBungee-Velocity")) api(project(":RedisBungee-API")) {
// Since velocity already includes guava / configurate 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")
}
compileOnly(libs.platform.velocity) compileOnly(libs.platform.velocity)
annotationProcessor(libs.platform.velocity) annotationProcessor(libs.platform.velocity)
implementation(project(":RedisBungee-Commands")) implementation(project(":RedisBungee-Commands"))
@@ -16,10 +30,22 @@ dependencies {
description = "RedisBungee Velocity implementation" description = "RedisBungee Velocity implementation"
java { java {
withJavadocJar()
withSourcesJar() withSourcesJar()
} }
tasks { tasks {
withType<Javadoc> {
dependsOn(project(":RedisBungee-API").getTasksByName("javadoc", false))
val options = options as StandardJavadocDocletOptions
options.use()
options.isDocFilesSubDirs = true
options.links(
"https://jd.papermc.io/velocity/3.0.0/", // velocity api
)
val apiDocs = File(rootProject.projectDir, "RedisBungee-API/build/docs/javadoc")
options.linksOffline("https://ci.limework.net/RedisBungee/RedisBungee-API/build/docs/javadoc", apiDocs.path)
}
runVelocity { runVelocity {
velocityVersion("3.3.0-SNAPSHOT") velocityVersion("3.3.0-SNAPSHOT")
environment["REDISBUNGEE_PROXY_ID"] = "velocity-1" environment["REDISBUNGEE_PROXY_ID"] = "velocity-1"
@@ -29,6 +55,9 @@ tasks {
options.encoding = Charsets.UTF_8.name() options.encoding = Charsets.UTF_8.name()
options.release.set(17) options.release.set(17)
} }
javadoc {
options.encoding = Charsets.UTF_8.name()
}
processResources { processResources {
filteringCharset = Charsets.UTF_8.name() filteringCharset = Charsets.UTF_8.name()
} }
@@ -46,3 +75,10 @@ tasks {
} }
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}

View File

@@ -49,7 +49,7 @@ public class RedisBungeeAPI extends AbstractRedisBungeeAPI {
public final ServerInfo getServerFor(@NonNull UUID player) { public final ServerInfo getServerFor(@NonNull UUID player) {
String serverName = this.getServerNameFor(player); String serverName = this.getServerNameFor(player);
if (serverName == null) return null; if (serverName == null) return null;
return ((ServerObjectFetcher) this.plugin).getProxy().getServer(serverName).map((RegisteredServer::getServerInfo)).orElse(null); return ((RedisBungeeVelocityPlugin) this.plugin).getProxy().getServer(serverName).map((RegisteredServer::getServerInfo)).orElse(null);
} }
/** /**

View File

@@ -26,6 +26,7 @@ import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
import net.kyori.adventure.text.Component;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -145,11 +146,8 @@ public class RedisBungeeListener {
return; return;
} }
} }
try {
// ServerConnection throws IllegalStateException when connection dies somehow so just ignore :/ ((ServerConnection) event.getSource()).sendPluginMessage(event.getIdentifier(), out.toByteArray());
((ServerConnection) event.getSource()).sendPluginMessage(event.getIdentifier(), out.toByteArray());
} catch (IllegalStateException ignored) {
}
}); });
} }

View File

@@ -68,7 +68,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Plugin(id = "redisbungee", name = "RedisBungee", version = Constants.VERSION, url = "https://github.com/ProxioDev/RedisBungee", authors = {"astei", "ProxioDev"}) @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 {
private final ProxyServer server; private final ProxyServer server;
private final Logger logger; private final Logger logger;
private final Path dataFolder; private final Path dataFolder;
@@ -102,6 +102,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player>, Con
this.logger = logger; this.logger = logger;
this.dataFolder = dataDirectory; this.dataFolder = dataDirectory;
logInfo("Version: {}", Constants.VERSION); logInfo("Version: {}", Constants.VERSION);
logInfo("Build date: {}", Date.from(Instant.ofEpochSecond(Constants.BUILD_DATE)));
try { try {
loadConfig(this, dataDirectory); loadConfig(this, dataDirectory);
loadLangConfig(this, dataDirectory); loadLangConfig(this, dataDirectory);

View File

@@ -33,21 +33,25 @@ public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLog
super(plugin); super(plugin);
} }
@Override
@Subscribe @Subscribe
public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) { public void onPlayerChangedServerNetworkEvent(PlayerChangedServerNetworkEvent event) {
handleNetworkPlayerServerChange(event); handleNetworkPlayerServerChange(event);
} }
@Override
@Subscribe @Subscribe
public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) { public void onNetworkPlayerQuit(PlayerLeftNetworkEvent event) {
handleNetworkPlayerQuit(event); handleNetworkPlayerQuit(event);
} }
@Override
@Subscribe @Subscribe
public void onPubSubMessageEvent(PubSubMessageEvent event) { public void onPubSubMessageEvent(PubSubMessageEvent event) {
handlePubSubMessageEvent(event); handlePubSubMessageEvent(event);
} }
@Override
@Subscribe @Subscribe
public void onServerConnectedEvent(ServerConnectedEvent event) { public void onServerConnectedEvent(ServerConnectedEvent event) {
final String currentServer = event.getServer().getServerInfo().getName(); final String currentServer = event.getServer().getServerInfo().getName();
@@ -64,31 +68,26 @@ public class VelocityPlayerDataManager extends PlayerDataManager<Player, PostLog
public void onLoginEvent(LoginEvent event, Continuation continuation) { public void onLoginEvent(LoginEvent event, Continuation continuation) {
// check if online // check if online
if (getLastOnline(event.getPlayer().getUniqueId()) == 0) { if (getLastOnline(event.getPlayer().getUniqueId()) == 0) {
// because something can go wrong and proxy somehow does not update player data correctly on shutdown if (plugin.configuration().kickWhenOnline()) {
// we have to check proxy if it has the player kickPlayer(event.getPlayer().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation());
String proxyId = getProxyFor(event.getPlayer().getUniqueId()); // wait 3 seconds before releasing the event
if (proxyId == null || !plugin.proxyDataManager().isPlayerTrulyOnProxy(proxyId, event.getPlayer().getUniqueId())) { plugin.executeAsyncAfter(continuation::resume, TimeUnit.SECONDS, 3);
continuation.resume();
} else { } else {
if (plugin.configuration().kickWhenOnline()) { event.setResult(ResultedEvent.ComponentResult.denied(plugin.langConfiguration().messages().alreadyLoggedIn()));
kickPlayer(event.getPlayer().getUniqueId(), plugin.langConfiguration().messages().loggedInFromOtherLocation()); continuation.resume();
// wait 3 seconds before releasing the event
plugin.executeAsyncAfter(continuation::resume, TimeUnit.SECONDS, 3);
} else {
event.setResult(ResultedEvent.ComponentResult.denied(plugin.langConfiguration().messages().alreadyLoggedIn()));
continuation.resume();
}
} }
} else { } else {
continuation.resume(); continuation.resume();
} }
} }
@Override
@Subscribe @Subscribe
public void onLoginEvent(PostLoginEvent event) { public void onLoginEvent(PostLoginEvent event) {
addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getUsername(), event.getPlayer().getRemoteAddress().getAddress()); addPlayer(event.getPlayer().getUniqueId(), event.getPlayer().getRemoteAddress().getAddress());
} }
@Override
@Subscribe @Subscribe
public void onDisconnectEvent(DisconnectEvent event) { public void onDisconnectEvent(DisconnectEvent event) {
if (event.getLoginStatus() == DisconnectEvent.LoginStatus.SUCCESSFUL_LOGIN || event.getLoginStatus() == DisconnectEvent.LoginStatus.PRE_SERVER_JOIN) { if (event.getLoginStatus() == DisconnectEvent.LoginStatus.SUCCESSFUL_LOGIN || event.getLoginStatus() == DisconnectEvent.LoginStatus.PRE_SERVER_JOIN) {

View File

@@ -1,2 +1,2 @@
group=com.imaginarycode.minecraft group=com.imaginarycode.minecraft
version=0.12.5 version=0.12.0-SNAPSHOT

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

7
gradlew vendored
View File

@@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -86,8 +84,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum

22
gradlew.bat vendored
View File

@@ -13,8 +13,6 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail
@@ -59,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail

View File

@@ -1,50 +0,0 @@
plugins {
`java-library`
`maven-publish`
}
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")
}
}
description = "RedisBungee Bungeecord API"
java {
withJavadocJar()
withSourcesJar()
}
tasks {
withType<Javadoc> {
dependsOn(project(":RedisBungee-API").getTasksByName("javadoc", false))
val options = options as StandardJavadocDocletOptions
options.use()
options.isDocFilesSubDirs = true
options.links(
"https://ci.md-5.net/job/BungeeCord/ws/api/target/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)
}
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
javadoc {
options.encoding = Charsets.UTF_8.name()
}
}
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}

View File

@@ -1,61 +0,0 @@
plugins {
`java-library`
`maven-publish`
}
dependencies {
api(project(":RedisBungee-API")) {
// Since velocity already includes guava / configurate 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")
}
compileOnly(libs.platform.velocity)
}
description = "RedisBungee Velocity API"
java {
withJavadocJar()
withSourcesJar()
}
tasks {
withType<Javadoc> {
dependsOn(project(":RedisBungee-API").getTasksByName("javadoc", false))
val options = options as StandardJavadocDocletOptions
options.use()
options.isDocFilesSubDirs = true
options.links(
"https://jd.papermc.io/velocity/3.0.0/", // velocity api
)
val apiDocs = File(rootProject.projectDir, "api/build/docs/javadoc")
options.linksOffline("https://ci.limework.net/ValioBungee/api/build/docs/javadoc", apiDocs.path)
}
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"])
}
}
}

View File

@@ -1,10 +0,0 @@
package com.imaginarycode.minecraft.redisbungee;
import com.velocitypowered.api.proxy.ProxyServer;
public interface ServerObjectFetcher {
ProxyServer getProxy();
}

View File

@@ -4,31 +4,12 @@ pluginManagement {
} }
} }
rootProject.name = "ValioBungee" rootProject.name = "RedisBungee-Parent"
include(":RedisBungee-API")
project(":RedisBungee-API").projectDir = file("api")
include(":RedisBungee-Velocity")
include(":RedisBungee-Commands") include(":RedisBungee-Commands")
project(":RedisBungee-Commands").projectDir = file("commands")
include(":RedisBungee-Velocity")
project(":RedisBungee-Velocity").projectDir = file("proxies/velocity")
include(":RedisBungee-Bungee") include(":RedisBungee-Bungee")
project(":RedisBungee-Bungee").projectDir = file("proxies/bungeecord/bungeecord-api") include(":RedisBungee-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")
dependencyResolutionManagement { dependencyResolutionManagement {
repositories { repositories {
@@ -56,7 +37,7 @@ dependencyResolutionManagement {
val caffeineVersion = "3.1.8" val caffeineVersion = "3.1.8"
val adventureVersion = "4.16.0" val adventureVersion = "4.16.0"
val acf = "0.5.1-SNAPSHOT" val acf = "0.5.1-SNAPSHOT"
val bungeecordApiVersion = "1.21-R0.1-SNAPSHOT" val bungeecordApiVersion = "1.20-R0.1-SNAPSHOT"
val velocityVersion = "3.3.0-SNAPSHOT"; val velocityVersion = "3.3.0-SNAPSHOT";
@@ -92,4 +73,4 @@ dependencyResolutionManagement {
} }
} }