mirror of
https://github.com/proxiodev/RedisBungee.git
synced 2024-11-22 20:28:00 +00:00
re-implement the commands, right usage of logger, general improvements to the listener (#39)
Co-authored-by: mohammed jasem alaajel <xrambad@gmail.com>
This commit is contained in:
parent
5f07ba6b66
commit
21f6cdeaeb
@ -12,8 +12,8 @@
|
|||||||
<artifactId>RedisBungee-Velocity</artifactId>
|
<artifactId>RedisBungee-Velocity</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
@ -48,8 +48,8 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>11</source>
|
||||||
<target>1.8</target>
|
<target>11</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -130,7 +130,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.velocitypowered</groupId>
|
<groupId>com.velocitypowered</groupId>
|
||||||
<artifactId>velocity-api</artifactId>
|
<artifactId>velocity-api</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.2-SNAPSHOT</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -4,13 +4,10 @@ package com.imaginarycode.minecraft.redisbungee;
|
|||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
import com.velocitypowered.api.permission.Tristate;
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import net.kyori.adventure.permission.PermissionChecker;
|
import net.kyori.adventure.permission.PermissionChecker;
|
||||||
import net.kyori.adventure.util.TriState;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class RedisBungeeCommandSource implements CommandSource {
|
public class RedisBungeeCommandSource implements CommandSource {
|
||||||
private static final RedisBungeeCommandSource singleton;
|
private static final RedisBungeeCommandSource singleton;
|
||||||
|
private final PermissionChecker permissionChecker = PermissionChecker.always(net.kyori.adventure.util.TriState.TRUE);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
singleton = new RedisBungeeCommandSource();
|
singleton = new RedisBungeeCommandSource();
|
||||||
@ -23,16 +20,16 @@ public class RedisBungeeCommandSource implements CommandSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(String permission) {
|
public boolean hasPermission(String permission) {
|
||||||
return true;
|
return this.permissionChecker.test(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tristate getPermissionValue(String s) {
|
public Tristate getPermissionValue(String s) {
|
||||||
return null;
|
return Tristate.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PermissionChecker getPermissionChecker() {
|
public PermissionChecker getPermissionChecker() {
|
||||||
return PermissionChecker.always(TriState.TRUE);
|
return this.permissionChecker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,21 +20,23 @@ import com.velocitypowered.api.event.connection.DisconnectEvent;
|
|||||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent.ForwardResult;
|
||||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ServerConnection;
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.Pipeline;
|
import redis.clients.jedis.Pipeline;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener<LoginEvent, PostLoginEvent, DisconnectEvent, ServerConnectedEvent, ProxyPingEvent, PluginMessageEvent, PubSubMessageEvent> {
|
public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener<LoginEvent, PostLoginEvent, DisconnectEvent, ServerConnectedEvent, ProxyPingEvent, PluginMessageEvent, PubSubMessageEvent> {
|
||||||
|
// Some messages are using legacy characters
|
||||||
|
private final LegacyComponentSerializer serializer = LegacyComponentSerializer.legacySection();
|
||||||
|
|
||||||
public RedisBungeeVelocityListener(RedisBungeePlugin<?> plugin, List<InetAddress> exemptAddresses) {
|
public RedisBungeeVelocityListener(RedisBungeePlugin<?> plugin, List<InetAddress> exemptAddresses) {
|
||||||
super(plugin, exemptAddresses);
|
super(plugin, exemptAddresses);
|
||||||
@ -56,14 +58,14 @@ public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener<Log
|
|||||||
Player player = (Player) plugin.getPlayer(event.getPlayer().getUsername());
|
Player player = (Player) plugin.getPlayer(event.getPlayer().getUsername());
|
||||||
|
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
event.setResult(ResultedEvent.ComponentResult.denied(Component.text(ONLINE_MODE_RECONNECT)));
|
event.setResult(ResultedEvent.ComponentResult.denied(serializer.deserialize(ONLINE_MODE_RECONNECT)));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String s : plugin.getServerIds()) {
|
for (String s : plugin.getServerIds()) {
|
||||||
if (jedis.sismember("proxy:" + s + ":usersOnline", event.getPlayer().getUniqueId().toString())) {
|
if (jedis.sismember("proxy:" + s + ":usersOnline", event.getPlayer().getUniqueId().toString())) {
|
||||||
event.setResult(ResultedEvent.ComponentResult.denied(Component.text(ALREADY_LOGGED_IN)));
|
event.setResult(ResultedEvent.ComponentResult.denied(serializer.deserialize(ALREADY_LOGGED_IN)));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,114 +138,115 @@ public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener<Log
|
|||||||
if (exemptAddresses.contains(event.getConnection().getRemoteAddress().getAddress())) {
|
if (exemptAddresses.contains(event.getConnection().getRemoteAddress().getAddress())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServerPing oldPing = event.getPing();
|
ServerPing.Builder ping = event.getPing().asBuilder();
|
||||||
int max = oldPing.getPlayers().map(ServerPing.Players::getMax).orElse(0);
|
ping.onlinePlayers(plugin.getCount());
|
||||||
List<ServerPing.SamplePlayer> list = oldPing.getPlayers().map(ServerPing.Players::getSample).orElse(Collections.emptyList());
|
event.setPing(ping.build());
|
||||||
event.setPing(new ServerPing(oldPing.getVersion(), new ServerPing.Players(plugin.getCount(), max, list), oldPing.getDescriptionComponent(), oldPing.getFavicon().orElse(null)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onPluginMessage(PluginMessageEvent event) {
|
public void onPluginMessage(PluginMessageEvent event) {
|
||||||
if ((event.getIdentifier().getId().equals("legacy:redisbungee") || event.getIdentifier().getId().equals("RedisBungee")) && event.getSource() instanceof ServerConnection) {
|
if(!(event.getSource() instanceof ServerConnection) || !RedisBungeeVelocityPlugin.IDENTIFIERS.contains(event.getIdentifier())) {
|
||||||
final String currentChannel = event.getIdentifier().getId();
|
return;
|
||||||
final byte[] data = Arrays.copyOf(event.getData(), event.getData().length);
|
|
||||||
plugin.executeAsync(() -> {
|
|
||||||
ByteArrayDataInput in = ByteStreams.newDataInput(data);
|
|
||||||
|
|
||||||
String subchannel = in.readUTF();
|
|
||||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
|
||||||
String type;
|
|
||||||
|
|
||||||
switch (subchannel) {
|
|
||||||
case "PlayerList":
|
|
||||||
out.writeUTF("PlayerList");
|
|
||||||
Set<UUID> original = Collections.emptySet();
|
|
||||||
type = in.readUTF();
|
|
||||||
if (type.equals("ALL")) {
|
|
||||||
out.writeUTF("ALL");
|
|
||||||
original = plugin.getPlayers();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
original = plugin.getApi().getPlayersOnServer(type);
|
|
||||||
} catch (IllegalArgumentException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Set<String> players = new HashSet<>();
|
|
||||||
for (UUID uuid : original)
|
|
||||||
players.add(plugin.getUuidTranslator().getNameFromUuid(uuid, false));
|
|
||||||
out.writeUTF(Joiner.on(',').join(players));
|
|
||||||
break;
|
|
||||||
case "PlayerCount":
|
|
||||||
out.writeUTF("PlayerCount");
|
|
||||||
type = in.readUTF();
|
|
||||||
if (type.equals("ALL")) {
|
|
||||||
out.writeUTF("ALL");
|
|
||||||
out.writeInt(plugin.getCount());
|
|
||||||
} else {
|
|
||||||
out.writeUTF(type);
|
|
||||||
try {
|
|
||||||
out.writeInt(plugin.getApi().getPlayersOnServer(type).size());
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
out.writeInt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "LastOnline":
|
|
||||||
String user = in.readUTF();
|
|
||||||
out.writeUTF("LastOnline");
|
|
||||||
out.writeUTF(user);
|
|
||||||
out.writeLong(plugin.getApi().getLastOnline(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(user, true))));
|
|
||||||
break;
|
|
||||||
case "ServerPlayers":
|
|
||||||
String type1 = in.readUTF();
|
|
||||||
out.writeUTF("ServerPlayers");
|
|
||||||
Multimap<String, UUID> multimap = plugin.getApi().getServerToPlayers();
|
|
||||||
|
|
||||||
boolean includesUsers;
|
|
||||||
|
|
||||||
switch (type1) {
|
|
||||||
case "COUNT":
|
|
||||||
includesUsers = false;
|
|
||||||
break;
|
|
||||||
case "PLAYERS":
|
|
||||||
includesUsers = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// TODO: Should I raise an error?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.writeUTF(type1);
|
|
||||||
|
|
||||||
if (includesUsers) {
|
|
||||||
Multimap<String, String> human = HashMultimap.create();
|
|
||||||
for (Map.Entry<String, UUID> entry : multimap.entries()) {
|
|
||||||
human.put(entry.getKey(), plugin.getUuidTranslator().getNameFromUuid(entry.getValue(), false));
|
|
||||||
}
|
|
||||||
serializeMultimap(human, true, out);
|
|
||||||
} else {
|
|
||||||
serializeMultiset(multimap.keys(), out);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Proxy":
|
|
||||||
out.writeUTF("Proxy");
|
|
||||||
out.writeUTF(plugin.getConfiguration().getServerId());
|
|
||||||
break;
|
|
||||||
case "PlayerProxy":
|
|
||||||
String username = in.readUTF();
|
|
||||||
out.writeUTF("PlayerProxy");
|
|
||||||
out.writeUTF(username);
|
|
||||||
out.writeUTF(plugin.getApi().getProxy(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(username, true))));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((ServerConnection) event.getSource()).sendPluginMessage(new LegacyChannelIdentifier(currentChannel), out.toByteArray());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.setResult(ForwardResult.handled());
|
||||||
|
|
||||||
|
plugin.executeAsync(() -> {
|
||||||
|
ByteArrayDataInput in = event.dataAsDataStream();
|
||||||
|
|
||||||
|
String subchannel = in.readUTF();
|
||||||
|
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||||
|
String type;
|
||||||
|
|
||||||
|
switch (subchannel) {
|
||||||
|
case "PlayerList":
|
||||||
|
out.writeUTF("PlayerList");
|
||||||
|
Set<UUID> original = Collections.emptySet();
|
||||||
|
type = in.readUTF();
|
||||||
|
if (type.equals("ALL")) {
|
||||||
|
out.writeUTF("ALL");
|
||||||
|
original = plugin.getPlayers();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
original = plugin.getApi().getPlayersOnServer(type);
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<String> players = original.stream()
|
||||||
|
.map(uuid -> plugin.getUuidTranslator().getNameFromUuid(uuid, false))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
out.writeUTF(Joiner.on(',').join(players));
|
||||||
|
break;
|
||||||
|
case "PlayerCount":
|
||||||
|
out.writeUTF("PlayerCount");
|
||||||
|
type = in.readUTF();
|
||||||
|
if (type.equals("ALL")) {
|
||||||
|
out.writeUTF("ALL");
|
||||||
|
out.writeInt(plugin.getCount());
|
||||||
|
} else {
|
||||||
|
out.writeUTF(type);
|
||||||
|
try {
|
||||||
|
out.writeInt(plugin.getApi().getPlayersOnServer(type).size());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
out.writeInt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "LastOnline":
|
||||||
|
String user = in.readUTF();
|
||||||
|
out.writeUTF("LastOnline");
|
||||||
|
out.writeUTF(user);
|
||||||
|
out.writeLong(plugin.getApi().getLastOnline(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(user, true))));
|
||||||
|
break;
|
||||||
|
case "ServerPlayers":
|
||||||
|
String type1 = in.readUTF();
|
||||||
|
out.writeUTF("ServerPlayers");
|
||||||
|
Multimap<String, UUID> multimap = plugin.getApi().getServerToPlayers();
|
||||||
|
|
||||||
|
boolean includesUsers;
|
||||||
|
|
||||||
|
switch (type1) {
|
||||||
|
case "COUNT":
|
||||||
|
includesUsers = false;
|
||||||
|
break;
|
||||||
|
case "PLAYERS":
|
||||||
|
includesUsers = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO: Should I raise an error?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.writeUTF(type1);
|
||||||
|
|
||||||
|
if (includesUsers) {
|
||||||
|
Multimap<String, String> human = HashMultimap.create();
|
||||||
|
for (Map.Entry<String, UUID> entry : multimap.entries()) {
|
||||||
|
human.put(entry.getKey(), plugin.getUuidTranslator().getNameFromUuid(entry.getValue(), false));
|
||||||
|
}
|
||||||
|
serializeMultimap(human, true, out);
|
||||||
|
} else {
|
||||||
|
serializeMultiset(multimap.keys(), out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Proxy":
|
||||||
|
out.writeUTF("Proxy");
|
||||||
|
out.writeUTF(plugin.getConfiguration().getServerId());
|
||||||
|
break;
|
||||||
|
case "PlayerProxy":
|
||||||
|
String username = in.readUTF();
|
||||||
|
out.writeUTF("PlayerProxy");
|
||||||
|
out.writeUTF(username);
|
||||||
|
out.writeUTF(plugin.getApi().getProxy(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(username, true))));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
((ServerConnection) event.getSource()).sendPluginMessage(event.getIdentifier(), out.toByteArray());
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,7 +258,7 @@ public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener<Log
|
|||||||
if (message.startsWith("/"))
|
if (message.startsWith("/"))
|
||||||
message = message.substring(1);
|
message = message.substring(1);
|
||||||
plugin.logInfo("Invoking command via PubSub: /" + message);
|
plugin.logInfo("Invoking command via PubSub: /" + message);
|
||||||
((RedisBungeeVelocityPlugin) plugin).getProxy().getCommandManager().executeAsync(RedisBungeeCommandSource.getSingleton(), message);//.dispatchCommand(RedisBungeeCommandSource.getSingleton(), message);
|
((RedisBungeeVelocityPlugin)plugin).getProxy().getCommandManager().executeAsync(RedisBungeeCommandSource.getSingleton(), message);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.common.reflect.TypeToken;
|
import com.google.common.reflect.TypeToken;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.imaginarycode.minecraft.redisbungee.commands.RedisBungeeCommands;
|
||||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
|
import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent;
|
||||||
import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
|
import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent;
|
||||||
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
|
import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent;
|
||||||
@ -29,6 +29,7 @@ import com.velocitypowered.api.plugin.Plugin;
|
|||||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import com.velocitypowered.api.scheduler.ScheduledTask;
|
import com.velocitypowered.api.scheduler.ScheduledTask;
|
||||||
@ -48,6 +49,7 @@ import java.io.*;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -56,7 +58,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
||||||
private final ProxyServer server;
|
private final ProxyServer server;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final File dataFolder;
|
private final Path dataFolder;
|
||||||
private final RedisBungeeAPI api;
|
private final RedisBungeeAPI api;
|
||||||
private final PubSubListener psl;
|
private final PubSubListener psl;
|
||||||
private JedisSummoner jedisSummoner;
|
private JedisSummoner jedisSummoner;
|
||||||
@ -73,6 +75,10 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
private LuaManager.Script getPlayerCountScript;
|
private LuaManager.Script getPlayerCountScript;
|
||||||
|
|
||||||
private static final Object SERVER_TO_PLAYERS_KEY = new Object();
|
private static final Object SERVER_TO_PLAYERS_KEY = new Object();
|
||||||
|
public static final List<ChannelIdentifier> IDENTIFIERS = List.of(
|
||||||
|
MinecraftChannelIdentifier.create("legacy", "redisbungee"),
|
||||||
|
new LegacyChannelIdentifier("RedisBungee")
|
||||||
|
);
|
||||||
private final Cache<Object, Multimap<String, UUID>> serverToPlayersCache = CacheBuilder.newBuilder()
|
private final Cache<Object, Multimap<String, UUID>> serverToPlayersCache = CacheBuilder.newBuilder()
|
||||||
.expireAfterWrite(5, TimeUnit.SECONDS)
|
.expireAfterWrite(5, TimeUnit.SECONDS)
|
||||||
.build();
|
.build();
|
||||||
@ -82,7 +88,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
public RedisBungeeVelocityPlugin(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
|
public RedisBungeeVelocityPlugin(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.dataFolder = dataDirectory.toFile();
|
this.dataFolder = dataDirectory;
|
||||||
try {
|
try {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -107,9 +113,9 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
for (String s : info.split("\r\n")) {
|
for (String s : info.split("\r\n")) {
|
||||||
if (s.startsWith("redis_version:")) {
|
if (s.startsWith("redis_version:")) {
|
||||||
String version = s.split(":")[1];
|
String version = s.split(":")[1];
|
||||||
getLogger().info(version + " <- redis version");
|
getLogger().info("{} <- redis version", version);
|
||||||
if (!RedisUtil.isRedisVersionRight(version)) {
|
if (!RedisUtil.isRedisVersionRight(version)) {
|
||||||
getLogger().error("Your version of Redis (" + version + ") is not at least version 6.0 RedisBungee requires a newer version of Redis.");
|
getLogger().error("Your version of Redis ({}) is not at least version 6.0 RedisBungee requires a newer version of Redis.", version);
|
||||||
throw new RuntimeException("Unsupported Redis version detected");
|
throw new RuntimeException("Unsupported Redis version detected");
|
||||||
} else {
|
} else {
|
||||||
LuaManager manager = new LuaManager(this);
|
LuaManager manager = new LuaManager(this);
|
||||||
@ -272,7 +278,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
if (lagged ? time >= stamp + 30 : time <= stamp + 30)
|
if (lagged ? time >= stamp + 30 : time <= stamp + 30)
|
||||||
servers.add(entry.getKey());
|
servers.add(entry.getKey());
|
||||||
else if (nag && nagTime <= 0) {
|
else if (nag && nagTime <= 0) {
|
||||||
getLogger().warn(entry.getKey() + " is " + (time - stamp) + " seconds behind! (Time not synchronized or server down?) and was removed from heartbeat.");
|
getLogger().warn("{} is {} seconds behind! (Time not synchronized or server down?) and was removed from heartbeat.", entry.getKey(), (time - stamp));
|
||||||
jedis.hdel("heartbeats", entry.getKey());
|
jedis.hdel("heartbeats", entry.getKey());
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
@ -308,12 +314,12 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeAsyncAfter(Runnable runnable, TimeUnit timeUnit, int time) {
|
public void executeAsyncAfter(Runnable runnable, TimeUnit timeUnit, int time) {
|
||||||
this.getProxy().getScheduler().buildTask(this, runnable).delay(time, timeUnit);
|
this.getProxy().getScheduler().buildTask(this, runnable).delay(time, timeUnit).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void callEvent(Object event) {
|
public void callEvent(Object event) {
|
||||||
this.getProxy().getEventManager().fire(event);
|
this.getProxy().getEventManager().fireAndForget(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -425,7 +431,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
Set<String> laggedPlayers = tmpRsc.smembers("proxy:" + s + ":usersOnline");
|
Set<String> laggedPlayers = tmpRsc.smembers("proxy:" + s + ":usersOnline");
|
||||||
tmpRsc.del("proxy:" + s + ":usersOnline");
|
tmpRsc.del("proxy:" + s + ":usersOnline");
|
||||||
if (!laggedPlayers.isEmpty()) {
|
if (!laggedPlayers.isEmpty()) {
|
||||||
getLogger().info("Cleaning up lagged proxy " + s + " (" + laggedPlayers.size() + " players)...");
|
getLogger().info("Cleaning up lagged proxy {} ({} players)...", s, laggedPlayers.size());
|
||||||
for (String laggedPlayer : laggedPlayers) {
|
for (String laggedPlayer : laggedPlayers) {
|
||||||
RedisUtil.cleanUpPlayer(laggedPlayer, tmpRsc);
|
RedisUtil.cleanUpPlayer(laggedPlayer, tmpRsc);
|
||||||
}
|
}
|
||||||
@ -449,10 +455,10 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
RedisUtil.cleanUpPlayer(member, tmpRsc);
|
RedisUtil.cleanUpPlayer(member, tmpRsc);
|
||||||
getLogger().warn("Player found in set that was not found locally and globally: " + member);
|
getLogger().warn("Player found in set that was not found locally and globally: {}", member);
|
||||||
} else {
|
} else {
|
||||||
tmpRsc.srem("proxy:" + configuration.getServerId() + ":usersOnline", member);
|
tmpRsc.srem("proxy:" + configuration.getServerId() + ":usersOnline", member);
|
||||||
getLogger().warn("Player found in set that was not found locally, but is on another proxy: " + member);
|
getLogger().warn("Player found in set that was not found locally, but is on another proxy: {}", member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +466,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
|
|
||||||
for (String player : absentInRedis) {
|
for (String player : absentInRedis) {
|
||||||
// Player not online according to Redis but not BungeeCord.
|
// Player not online according to Redis but not BungeeCord.
|
||||||
getLogger().warn("Player " + player + " is on the proxy but not in Redis.");
|
getLogger().warn("Player {} is on the proxy but not in Redis.", player);
|
||||||
|
|
||||||
Player playerProxied = getProxy().getPlayer(UUID.fromString(player)).orElse(null);
|
Player playerProxied = getProxy().getPlayer(UUID.fromString(player)).orElse(null);
|
||||||
if (playerProxied == null)
|
if (playerProxied == null)
|
||||||
@ -475,24 +481,23 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
}
|
}
|
||||||
}).repeat(1, TimeUnit.MINUTES).schedule();
|
}).repeat(1, TimeUnit.MINUTES).schedule();
|
||||||
|
|
||||||
|
// register plugin messages
|
||||||
|
IDENTIFIERS.forEach(getProxy().getChannelRegistrar()::register);
|
||||||
|
|
||||||
getProxy().getChannelRegistrar().register(new LegacyChannelIdentifier("RedisBungee"));
|
|
||||||
getProxy().getChannelRegistrar().register(new LegacyChannelIdentifier("legacy:redisbungee"));
|
|
||||||
getProxy().getChannelRegistrar().register(MinecraftChannelIdentifier.create("legacy", "redisbungee"));
|
|
||||||
// register commands
|
// register commands
|
||||||
// those still bungeecord commands will migrate them later.
|
// Override Velocity commands
|
||||||
// if (configuration.doOverrideBungeeCommands()) {
|
if (configuration.doOverrideBungeeCommands()) {
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.GlistCommand(this));
|
getProxy().getCommandManager().register("glist", new RedisBungeeCommands.GlistCommand(this), "redisbungee", "rglist");
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.FindCommand(this));
|
}
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.LastSeenCommand(this));
|
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.IpCommand(this));
|
getProxy().getCommandManager().register("sendtoall", new RedisBungeeCommands.SendToAll(this), "rsendtoall");
|
||||||
//
|
getProxy().getCommandManager().register("serverid", new RedisBungeeCommands.ServerId(this), "rserverid");
|
||||||
// }
|
getProxy().getCommandManager().register("serverids", new RedisBungeeCommands.ServerIds(this));
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.SendToAll(this));
|
getProxy().getCommandManager().register("pproxy", new RedisBungeeCommands.PlayerProxyCommand(this));
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.ServerId(this));
|
getProxy().getCommandManager().register("plist", new RedisBungeeCommands.PlistCommand(this), "rplist");
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.ServerIds(this));
|
getProxy().getCommandManager().register("lastseen", new RedisBungeeCommands.LastSeenCommand(this), "rlastseen");
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.PlayerProxyCommand(this));
|
getProxy().getCommandManager().register("ip", new RedisBungeeCommands.IpCommand(this), "playerip", "rip", "rplayerip");
|
||||||
// getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.PlistCommand(this));
|
getProxy().getCommandManager().register("find", new RedisBungeeCommands.FindCommand(this), "rfind");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -526,18 +531,26 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig() throws IOException {
|
public void loadConfig() throws IOException {
|
||||||
if (!getDataFolder().exists() && getDataFolder().mkdir()) {
|
if (Files.notExists(getDataFolder())) {
|
||||||
getLogger().info("data folder was created");
|
try {
|
||||||
|
Files.createDirectory(getDataFolder());
|
||||||
|
getLogger().info("data folder was created");
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().error("Cannot create data folder", e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
File file = new File(getDataFolder(), "config.yml");
|
Path file = getDataFolder().resolve("config.yml");
|
||||||
if (!file.exists() && file.createNewFile()) {
|
if (Files.notExists(file)) {
|
||||||
getLogger().info("config file was created");
|
try (InputStream in = getResourceAsStream("example_config.yml")) {
|
||||||
try (InputStream in = getResourceAsStream("example_config.yml");
|
Files.createFile(file);
|
||||||
OutputStream out = Files.newOutputStream(file.toPath())) {
|
Files.copy(in, file, StandardCopyOption.REPLACE_EXISTING);
|
||||||
ByteStreams.copy(in, out);
|
getLogger().info("config file was created");
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().error("Cannot create configuration", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final YAMLConfigurationLoader yamlConfiguration = YAMLConfigurationLoader.builder().setFile(file).build();
|
final YAMLConfigurationLoader yamlConfiguration = YAMLConfigurationLoader.builder().setPath(file).build();
|
||||||
ConfigurationNode node = yamlConfiguration.load();
|
ConfigurationNode node = yamlConfiguration.load();
|
||||||
final String redisServer = node.getNode("redis-server").getString();
|
final String redisServer = node.getNode("redis-server").getString();
|
||||||
final int redisPort = node.getNode("redis-port").getInt();
|
final int redisPort = node.getNode("redis-port").getInt();
|
||||||
@ -560,12 +573,12 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
* I think due snake yaml limitations so as todo: write our own yaml parser?
|
* I think due snake yaml limitations so as todo: write our own yaml parser?
|
||||||
*/
|
*/
|
||||||
String genId = UUID.randomUUID().toString();
|
String genId = UUID.randomUUID().toString();
|
||||||
getLogger().info("Generated server id " + genId + " and saving it to config.");
|
getLogger().info("Generated server id {} and saving it to config.", genId);
|
||||||
node.getNode("server-id").setValue(genId);
|
node.getNode("server-id").setValue(genId);
|
||||||
yamlConfiguration.save(node);
|
yamlConfiguration.save(node);
|
||||||
getLogger().info("Server id was generated: " + serverId);
|
getLogger().info("Server id was generated: {}", serverId);
|
||||||
} else {
|
} else {
|
||||||
getLogger().info("Loaded server id " + serverId + '.');
|
getLogger().info("Loaded server id {}.", serverId);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.configuration = new RedisBungeeConfiguration(serverId, node.getNode("exempt-ip-addresses").getList(TypeToken.of(String.class)), node.getNode("register-bungee-commands").getBoolean());
|
this.configuration = new RedisBungeeConfiguration(serverId, node.getNode("exempt-ip-addresses").getList(TypeToken.of(String.class)), node.getNode("register-bungee-commands").getBoolean());
|
||||||
@ -587,9 +600,15 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
try (Jedis rsc = requestJedis()) {
|
try (Jedis rsc = requestJedis()) {
|
||||||
rsc.ping();
|
rsc.ping();
|
||||||
// If that worked, now we can check for an existing, alive Bungee:
|
// If that worked, now we can check for an existing, alive Bungee:
|
||||||
File crashFile = new File(getDataFolder(), "restarted_from_crash.txt");
|
Path crashFile = getDataFolder().resolve("restarted_from_crash.txt");
|
||||||
if (crashFile.exists() && crashFile.delete()) {
|
if (Files.exists(crashFile)) {
|
||||||
getLogger().info("crash file was deleted");
|
try {
|
||||||
|
Files.delete(crashFile);
|
||||||
|
getLogger().info("crash file was deleted");
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().error("Cannot delete crash file", e);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (rsc.hexists("heartbeats", serverId)) {
|
} else if (rsc.hexists("heartbeats", serverId)) {
|
||||||
try {
|
try {
|
||||||
long value = Long.parseLong(rsc.hget("heartbeats", serverId));
|
long value = Long.parseLong(rsc.hget("heartbeats", serverId));
|
||||||
@ -653,7 +672,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin<Player> {
|
|||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getDataFolder() {
|
public Path getDataFolder() {
|
||||||
return this.dataFolder;
|
return this.dataFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
package com.imaginarycode.minecraft.redisbungee.commands;
|
package com.imaginarycode.minecraft.redisbungee.commands;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
|
import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
|
||||||
|
import com.imaginarycode.minecraft.redisbungee.RedisBungeeVelocityPlugin;
|
||||||
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.command.SimpleCommand;
|
||||||
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
|
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,316 +31,318 @@ import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
|
|||||||
* @since 0.2.3
|
* @since 0.2.3
|
||||||
*/
|
*/
|
||||||
public class RedisBungeeCommands {
|
public class RedisBungeeCommands {
|
||||||
/*
|
|
||||||
private static final BaseComponent[] NO_PLAYER_SPECIFIED =
|
private static final Component NO_PLAYER_SPECIFIED =
|
||||||
new ComponentBuilder("You must specify a player name.").color(ChatColor.RED).create();
|
Component.text("You must specify a player name.", NamedTextColor.RED);
|
||||||
private static final BaseComponent[] PLAYER_NOT_FOUND =
|
private static final Component PLAYER_NOT_FOUND =
|
||||||
new ComponentBuilder("No such player found.").color(ChatColor.RED).create();
|
Component.text("No such player found.", NamedTextColor.RED);
|
||||||
private static final BaseComponent[] NO_COMMAND_SPECIFIED =
|
private static final Component NO_COMMAND_SPECIFIED =
|
||||||
new ComponentBuilder("You must specify a command to be run.").color(ChatColor.RED).create();
|
Component.text("You must specify a command to be run.", NamedTextColor.RED);
|
||||||
|
|
||||||
private static String playerPlural(int num) {
|
private static String playerPlural(int num) {
|
||||||
return num == 1 ? num + " player is" : num + " players are";
|
return num == 1 ? num + " player is" : num + " players are";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GlistCommand extends Command {
|
public static class GlistCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public GlistCommand(RedisBungeeVelocityPlugin plugin) {
|
public GlistCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("glist", "bungeecord.command.list", "redisbungee", "rglist");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
@Override
|
int count = plugin.getApi().getPlayerCount();
|
||||||
public void run() {
|
Component playersOnline = Component.text(playerPlural(count) + " currently online.", NamedTextColor.YELLOW);
|
||||||
int count = plugin.getApi().getPlayerCount();
|
CommandSource sender = invocation.source();
|
||||||
BaseComponent[] playersOnline = new ComponentBuilder("").color(ChatColor.YELLOW)
|
if (invocation.arguments().length > 0 && invocation.arguments()[0].equals("showall")) {
|
||||||
.append(playerPlural(count) + " currently online.").create();
|
Multimap<String, UUID> serverToPlayers = plugin.getApi().getServerToPlayers();
|
||||||
if (args.length > 0 && args[0].equals("showall")) {
|
Multimap<String, String> human = HashMultimap.create();
|
||||||
Multimap<String, UUID> serverToPlayers = plugin.getApi().getServerToPlayers();
|
serverToPlayers.forEach((key, value) -> human.put(key, plugin.getUuidTranslator().getNameFromUuid(value, false)));
|
||||||
Multimap<String, String> human = HashMultimap.create();
|
for (String server : new TreeSet<>(serverToPlayers.keySet())) {
|
||||||
for (Map.Entry<String, UUID> entry : serverToPlayers.entries()) {
|
Component serverName = Component.text("[" + server + "] ", NamedTextColor.GREEN);
|
||||||
human.put(entry.getKey(), plugin.getUuidTranslator().getNameFromUuid(entry.getValue(), false));
|
Component serverCount = Component.text("(" + serverToPlayers.get(server).size() + "): ", NamedTextColor.YELLOW);
|
||||||
}
|
Component serverPlayers = Component.text(Joiner.on(", ").join(human.get(server)), NamedTextColor.WHITE);
|
||||||
for (String server : new TreeSet<>(serverToPlayers.keySet())) {
|
sender.sendMessage(Component.textOfChildren(serverName, serverCount, serverPlayers));
|
||||||
TextComponent serverName = new TextComponent();
|
|
||||||
serverName.setColor(ChatColor.GREEN);
|
|
||||||
serverName.setText("[" + server + "] ");
|
|
||||||
TextComponent serverCount = new TextComponent();
|
|
||||||
serverCount.setColor(ChatColor.YELLOW);
|
|
||||||
serverCount.setText("(" + serverToPlayers.get(server).size() + "): ");
|
|
||||||
TextComponent serverPlayers = new TextComponent();
|
|
||||||
serverPlayers.setColor(ChatColor.WHITE);
|
|
||||||
serverPlayers.setText(Joiner.on(", ").join(human.get(server)));
|
|
||||||
sender.sendMessage(serverName, serverCount, serverPlayers);
|
|
||||||
}
|
|
||||||
sender.sendMessage(playersOnline);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(playersOnline);
|
|
||||||
sender.sendMessage(new ComponentBuilder("To see all players online, use /glist showall.").color(ChatColor.YELLOW).create());
|
|
||||||
}
|
}
|
||||||
|
sender.sendMessage(playersOnline);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(playersOnline);
|
||||||
|
sender.sendMessage(Component.text("To see all players online, use /glist showall.", NamedTextColor.YELLOW));
|
||||||
}
|
}
|
||||||
});
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("velocity.command.server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FindCommand extends Command {
|
public static class FindCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public FindCommand(RedisBungeeVelocityPlugin plugin) {
|
public FindCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("find", "bungeecord.command.find", "rfind");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
@Override
|
String[] args = invocation.arguments();
|
||||||
public void run() {
|
CommandSource sender = invocation.source();
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
ServerInfo si = plugin.getProxy().getServerInfo(plugin.getApi().getServerFor(uuid));
|
|
||||||
if (si != null) {
|
|
||||||
TextComponent message = new TextComponent();
|
|
||||||
message.setColor(ChatColor.BLUE);
|
|
||||||
message.setText(args[0] + " is on " + si.getName() + ".");
|
|
||||||
sender.sendMessage(message);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
|
||||||
}
|
}
|
||||||
|
ServerInfo si = plugin.getProxy().getServer(plugin.getApi().getServerFor(uuid)).map(RegisteredServer::getServerInfo).orElse(null);
|
||||||
|
if (si != null) {
|
||||||
|
Component message = Component.text(args[0] + " is on " + si.getName() + ".", NamedTextColor.BLUE);
|
||||||
|
sender.sendMessage(message);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
||||||
}
|
}
|
||||||
});
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.find");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LastSeenCommand extends Command {
|
public static class LastSeenCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public LastSeenCommand(RedisBungeeVelocityPlugin plugin) {
|
public LastSeenCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("lastseen", "redisbungee.command.lastseen", "rlastseen");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
@Override
|
String[] args = invocation.arguments();
|
||||||
public void run() {
|
CommandSource sender = invocation.source();
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
long secs = plugin.getApi().getLastOnline(uuid);
|
|
||||||
TextComponent message = new TextComponent();
|
|
||||||
if (secs == 0) {
|
|
||||||
message.setColor(ChatColor.GREEN);
|
|
||||||
message.setText(args[0] + " is currently online.");
|
|
||||||
} else if (secs != -1) {
|
|
||||||
message.setColor(ChatColor.BLUE);
|
|
||||||
message.setText(args[0] + " was last online on " + new SimpleDateFormat().format(secs) + ".");
|
|
||||||
} else {
|
|
||||||
message.setColor(ChatColor.RED);
|
|
||||||
message.setText(args[0] + " has never been online.");
|
|
||||||
}
|
|
||||||
sender.sendMessage(message);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
|
||||||
}
|
}
|
||||||
|
long secs = plugin.getApi().getLastOnline(uuid);
|
||||||
|
TextComponent.Builder message = Component.text();
|
||||||
|
if (secs == 0) {
|
||||||
|
message.color(NamedTextColor.GREEN);
|
||||||
|
message.content(args[0] + " is currently online.");
|
||||||
|
} else if (secs != -1) {
|
||||||
|
message.color(NamedTextColor.BLUE);
|
||||||
|
message.content(args[0] + " was last online on " + new SimpleDateFormat().format(secs) + ".");
|
||||||
|
} else {
|
||||||
|
message.color(NamedTextColor.RED);
|
||||||
|
message.content(args[0] + " has never been online.");
|
||||||
|
}
|
||||||
|
sender.sendMessage(message.build());
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
||||||
}
|
}
|
||||||
});
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.lastseen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IpCommand extends Command {
|
public static class IpCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public IpCommand(RedisBungeeVelocityPlugin plugin) {
|
public IpCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("ip", "redisbungee.command.ip", "playerip", "rip", "rplayerip");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
CommandSource sender = invocation.source();
|
||||||
@Override
|
String[] args = invocation.arguments();
|
||||||
public void run() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
InetAddress ia = plugin.getApi().getPlayerIp(uuid);
|
|
||||||
if (ia != null) {
|
|
||||||
TextComponent message = new TextComponent();
|
|
||||||
message.setColor(ChatColor.GREEN);
|
|
||||||
message.setText(args[0] + " is connected from " + ia.toString() + ".");
|
|
||||||
sender.sendMessage(message);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
|
||||||
}
|
}
|
||||||
|
InetAddress ia = plugin.getApi().getPlayerIp(uuid);
|
||||||
|
if (ia != null) {
|
||||||
|
TextComponent message = Component.text(args[0] + " is connected from " + ia.toString() + ".", NamedTextColor.GREEN);
|
||||||
|
sender.sendMessage(message);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
||||||
}
|
}
|
||||||
});
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PlayerProxyCommand extends Command {
|
public static class PlayerProxyCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public PlayerProxyCommand(RedisBungeeVelocityPlugin plugin) {
|
public PlayerProxyCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("pproxy", "redisbungee.command.pproxy");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
CommandSource sender = invocation.source();
|
||||||
@Override
|
String[] args = invocation.arguments();
|
||||||
public void run() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
UUID uuid = plugin.getUuidTranslator().getTranslatedUuid(args[0], true);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
String proxy = plugin.getApi().getProxy(uuid);
|
|
||||||
if (proxy != null) {
|
|
||||||
TextComponent message = new TextComponent();
|
|
||||||
message.setColor(ChatColor.GREEN);
|
|
||||||
message.setText(args[0] + " is connected to " + proxy + ".");
|
|
||||||
sender.sendMessage(message);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(PLAYER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
|
||||||
}
|
}
|
||||||
|
String proxy = plugin.getApi().getProxy(uuid);
|
||||||
|
if (proxy != null) {
|
||||||
|
TextComponent message = Component.text(args[0] + " is connected to " + proxy + ".", NamedTextColor.GREEN);
|
||||||
|
sender.sendMessage(message);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(PLAYER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(NO_PLAYER_SPECIFIED);
|
||||||
}
|
}
|
||||||
});
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.pproxy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SendToAll extends Command {
|
public static class SendToAll implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public SendToAll(RedisBungeeVelocityPlugin plugin) {
|
public SendToAll(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("sendtoall", "redisbungee.command.sendtoall", "rsendtoall");
|
//super("sendtoall", "redisbungee.command.sendtoall", "rsendtoall");
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
public void execute(final Invocation invocation) {
|
||||||
|
String[] args = invocation.arguments();
|
||||||
|
CommandSource sender = invocation.source();
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
String command = Joiner.on(" ").skipNulls().join(args);
|
String command = Joiner.on(" ").skipNulls().join(args);
|
||||||
plugin.getApi().sendProxyCommand(command);
|
plugin.getApi().sendProxyCommand(command);
|
||||||
TextComponent message = new TextComponent();
|
TextComponent message = Component.text("Sent the command /" + command + " to all proxies.", NamedTextColor.GREEN);
|
||||||
message.setColor(ChatColor.GREEN);
|
|
||||||
message.setText("Sent the command /" + command + " to all proxies.");
|
|
||||||
sender.sendMessage(message);
|
sender.sendMessage(message);
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(NO_COMMAND_SPECIFIED);
|
sender.sendMessage(NO_COMMAND_SPECIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.sendtoall");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ServerId extends Command {
|
public static class ServerId implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public ServerId(RedisBungeeVelocityPlugin plugin) {
|
public ServerId(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("serverid", "redisbungee.command.serverid", "rserverid");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
public void execute(Invocation invocation) {
|
||||||
TextComponent textComponent = new TextComponent();
|
invocation.source().sendMessage(Component.text("You are on " + plugin.getApi().getServerId() + ".", NamedTextColor.YELLOW));
|
||||||
textComponent.setText("You are on " + plugin.getApi().getServerId() + ".");
|
}
|
||||||
textComponent.setColor(ChatColor.YELLOW);
|
|
||||||
sender.sendMessage(textComponent);
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.serverid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ServerIds extends Command {
|
public static class ServerIds implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
public ServerIds(RedisBungeeVelocityPlugin plugin) {
|
public ServerIds(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("serverids", "redisbungee.command.serverids");
|
|
||||||
this.plugin =plugin;
|
this.plugin =plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] strings) {
|
public void execute(Invocation invocation) {
|
||||||
TextComponent textComponent = new TextComponent();
|
invocation.source().sendMessage(
|
||||||
textComponent.setText("All server IDs: " + Joiner.on(", ").join(plugin.getApi().getAllServers()));
|
Component.text("All server IDs: " + Joiner.on(", ").join(plugin.getApi().getAllServers()), NamedTextColor.YELLOW));
|
||||||
textComponent.setColor(ChatColor.YELLOW);
|
}
|
||||||
sender.sendMessage(textComponent);
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.serverids");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PlistCommand extends Command {
|
public static class PlistCommand implements SimpleCommand {
|
||||||
private final RedisBungeeVelocityPlugin plugin;
|
private final RedisBungeeVelocityPlugin plugin;
|
||||||
|
|
||||||
public PlistCommand(RedisBungeeVelocityPlugin plugin) {
|
public PlistCommand(RedisBungeeVelocityPlugin plugin) {
|
||||||
super("plist", "redisbungee.command.plist", "rplist");
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final String[] args) {
|
public void execute(Invocation invocation) {
|
||||||
plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() {
|
CommandSource sender= invocation.source();
|
||||||
@Override
|
String[] args = invocation.arguments();
|
||||||
public void run() {
|
plugin.getProxy().getScheduler().buildTask(plugin, () -> {
|
||||||
String proxy = args.length >= 1 ? args[0] : plugin.getConfiguration().getServerId();
|
String proxy = args.length >= 1 ? args[0] : plugin.getConfiguration().getServerId();
|
||||||
if (!plugin.getServerIds().contains(proxy)) {
|
if (!plugin.getServerIds().contains(proxy)) {
|
||||||
sender.sendMessage(new ComponentBuilder(proxy + " is not a valid proxy. See /serverids for valid proxies.").color(ChatColor.RED).create());
|
sender.sendMessage(Component.text(proxy + " is not a valid proxy. See /serverids for valid proxies.", NamedTextColor.RED));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Set<UUID> players = plugin.getApi().getPlayersOnProxy(proxy);
|
|
||||||
BaseComponent[] playersOnline = new ComponentBuilder("").color(ChatColor.YELLOW)
|
|
||||||
.append(playerPlural(players.size()) + " currently on proxy " + proxy + ".").create();
|
|
||||||
if (args.length >= 2 && args[1].equals("showall")) {
|
|
||||||
Multimap<String, UUID> serverToPlayers = plugin.getApi().getServerToPlayers();
|
|
||||||
Multimap<String, String> human = HashMultimap.create();
|
|
||||||
for (Map.Entry<String, UUID> entry : serverToPlayers.entries()) {
|
|
||||||
if (players.contains(entry.getValue())) {
|
|
||||||
human.put(entry.getKey(), plugin.getUuidTranslator().getNameFromUuid(entry.getValue(), false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String server : new TreeSet<>(human.keySet())) {
|
|
||||||
TextComponent serverName = new TextComponent();
|
|
||||||
serverName.setColor(ChatColor.RED);
|
|
||||||
serverName.setText("[" + server + "] ");
|
|
||||||
TextComponent serverCount = new TextComponent();
|
|
||||||
serverCount.setColor(ChatColor.YELLOW);
|
|
||||||
serverCount.setText("(" + human.get(server).size() + "): ");
|
|
||||||
TextComponent serverPlayers = new TextComponent();
|
|
||||||
serverPlayers.setColor(ChatColor.WHITE);
|
|
||||||
serverPlayers.setText(Joiner.on(", ").join(human.get(server)));
|
|
||||||
sender.sendMessage(serverName, serverCount, serverPlayers);
|
|
||||||
}
|
|
||||||
sender.sendMessage(playersOnline);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(playersOnline);
|
|
||||||
sender.sendMessage(new ComponentBuilder("To see all players online, use /plist " + proxy + " showall.").color(ChatColor.YELLOW).create());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
Set<UUID> players = plugin.getApi().getPlayersOnProxy(proxy);
|
||||||
|
Component playersOnline = Component.text(playerPlural(players.size()) + " currently on proxy " + proxy + ".", NamedTextColor.YELLOW);
|
||||||
|
if (args.length >= 2 && args[1].equals("showall")) {
|
||||||
|
Multimap<String, UUID> serverToPlayers = plugin.getApi().getServerToPlayers();
|
||||||
|
Multimap<String, String> human = HashMultimap.create();
|
||||||
|
serverToPlayers.forEach((key, value) -> {
|
||||||
|
if (players.contains(value)) {
|
||||||
|
human.put(key, plugin.getUuidTranslator().getNameFromUuid(value, false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (String server : new TreeSet<>(human.keySet())) {
|
||||||
|
TextComponent serverName = Component.text("[" + server + "] ", NamedTextColor.RED);
|
||||||
|
TextComponent serverCount = Component.text("(" + human.get(server).size() + "): ", NamedTextColor.YELLOW);
|
||||||
|
TextComponent serverPlayers = Component.text(Joiner.on(", ").join(human.get(server)), NamedTextColor.WHITE);
|
||||||
|
sender.sendMessage(Component.textOfChildren(serverName, serverCount, serverPlayers));
|
||||||
|
}
|
||||||
|
sender.sendMessage(playersOnline);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(playersOnline);
|
||||||
|
sender.sendMessage(Component.text("To see all players online, use /plist " + proxy + " showall.", NamedTextColor.YELLOW));
|
||||||
|
}
|
||||||
|
}).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("redisbungee.command.plist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user