Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions src/main/java/net/elytrium/limboreconnect/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@ public class Config extends YamlSerializable {
public long joinDelay = 2000;
@Comment(value = @CommentValue("Send to limbo or use current server's world"))
public boolean useLimbo = false;
@Comment(value = @CommentValue("Connects to Limbo instantly after connecting to the main server"))
public boolean testing = false;
@Comment(value = @CommentValue("Require permission to reconnect (limboreconnect.reconnect)"))
public boolean requirePermission = false;

public World world;
public Messages messages;
public Sounds sounds;
@Comment(value = @CommentValue("Allows you to transfer a player to the hub if the server is unavailable."))
public HubTeleport hubTeleport;
public boolean debug = false;


Expand All @@ -67,6 +71,7 @@ public Config() {
this.world = new World();
this.messages = new Messages();
this.sounds = new Sounds();
this.hubTeleport = new HubTeleport();
}


Expand Down Expand Up @@ -103,9 +108,9 @@ public WorldCoords() {

public static class PlayerCoords {

public int x = 0;
public int y = 100;
public int z = 0;
public double x = 0;
public double y = 100;
public double z = 0;
public float pitch = 0;
public float yaw = 90;

Expand Down Expand Up @@ -169,4 +174,38 @@ public Sound(String name) {
}
}
}

public static class HubTeleport {

public boolean enable = false;
@Comment(value = @CommentValue("sends the player to an available hub"), at = Comment.At.SAME_LINE)
public boolean instantly = false;
public List<String> servers = List.of("hub-1", "hub-2", "hub-3");
public Messages messages = new Messages();

public static class Messages {

public String teleport = """
>
<gray>━━━━━━━━━━━━━━━━━━━━</gray>
<newline>
<yellow><bold>The server you were on is currently unavailable</bold></yellow>
<newline>
<gray>You may wait here or teleport to the hub</gray>
<newline>
<click:run_command:/hub>
<hover:show_text:"<yellow>Click to teleport to the hub">
<gradient:#FFD700:#FF8C00><bold>▶ CLICK HERE TO GO TO HUB ◀</bold></gradient>
</hover>
</click>
<newline>
<gray>━━━━━━━━━━━━━━━━━━━━</gray>""";
public String fully = "<red>All hubs are currently full, please wait...";

public Messages() {}

}

}

}
23 changes: 14 additions & 9 deletions src/main/java/net/elytrium/limboreconnect/LimboReconnect.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import net.elytrium.limboapi.api.Limbo;
import net.elytrium.limboapi.api.LimboFactory;
import net.elytrium.limboapi.api.chunk.Dimension;
Expand All @@ -51,13 +43,23 @@
import net.elytrium.limboapi.api.protocol.packets.PacketMapping;
import net.elytrium.limboreconnect.commands.LimboReconnectCommand;
import net.elytrium.limboreconnect.handler.ReconnectHandler;
import net.elytrium.limboreconnect.listener.ConnectListener;
import net.elytrium.limboreconnect.listener.ReconnectListener;
import net.elytrium.limboreconnect.protocol.packets.PlaySound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import net.kyori.adventure.title.Title;
import org.slf4j.Logger;

import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

@Plugin(
id = "limboreconnect",
name = "LimboReconnect",
Expand Down Expand Up @@ -196,9 +198,11 @@ public void reload() {

this.server.getEventManager().unregisterListeners(this);
this.server.getEventManager().register(this, new ReconnectListener(this));
if(CONFIG.testing) this.server.getEventManager().register(this, new ConnectListener(server, this));
CommandManager commandManager = this.server.getCommandManager();
commandManager.unregister("limboreconnect");
commandManager.register(this.commandMeta, new LimboReconnectCommand(this));

}

public void addPlayer(Player player, RegisteredServer server) {
Expand All @@ -218,6 +222,7 @@ public void addPlayer(Player player, RegisteredServer server) {
}

connectedPlayer.getTabList().clearAll();
this.limbo.spawnPlayer(player, new ReconnectHandler(this, server));
this.limbo.spawnPlayer(player, new ReconnectHandler(this, server, this.server));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,40 @@

package net.elytrium.limboreconnect.handler;

import static net.elytrium.limboreconnect.LimboReconnect.CONFIG;

import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.PingOptions;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import net.elytrium.limboapi.api.Limbo;
import net.elytrium.limboapi.api.LimboSessionHandler;
import net.elytrium.limboapi.api.player.LimboPlayer;
import net.elytrium.limboreconnect.Config;
import net.elytrium.limboreconnect.LimboReconnect;
import net.elytrium.limboreconnect.protocol.packets.PlaySound;

import java.time.Duration;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import static net.elytrium.limboreconnect.LimboReconnect.CONFIG;

public class ReconnectHandler implements LimboSessionHandler {

private final PingOptions pingOptions = PingOptions.builder().timeout(Duration.ofMillis(CONFIG.pingTimeout)).build();
private final LimboReconnect plugin;
private final RegisteredServer server;
private final ProxyServer proxyServer;
private LimboPlayer player;
private boolean connected = true;
private boolean connecting = false;
private int titleIndex = -1;
private final PlaySound waitSound;
private final PlaySound connectSound;
private ScheduledFuture<?> hubRetryTask;

public ReconnectHandler(LimboReconnect plugin, RegisteredServer server) {
public ReconnectHandler(LimboReconnect plugin, RegisteredServer server, ProxyServer proxyServer) {
this.plugin = plugin;
this.server = server;
this.proxyServer = proxyServer;
Config.Sounds sounds = CONFIG.sounds;
double playerX = CONFIG.world.playerCoords.x;
double playerY = CONFIG.world.playerCoords.y;
Expand All @@ -60,6 +66,7 @@ public void onSpawn(Limbo server, LimboPlayer player) {
this.player.setGameMode(CONFIG.world.gamemode);
this.player.getScheduledExecutor().schedule(this::tick, CONFIG.checkInterval, TimeUnit.MILLISECONDS);
this.tickMessages();
this.hubTeleport();
}

@Override
Expand All @@ -73,10 +80,14 @@ public void onMove(double x, double y, double z) {
this.connectSound.setPosition(x, y, z);
}

@Override
public void onChat(String chat) {
if (!connected || connecting) return;
if ("/hub".equalsIgnoreCase(chat)) findAndSendHub();
}

private void tick() {
if (!this.connected) {
return;
}
if (!this.connected || CONFIG.testing) return;

this.server.ping(this.pingOptions).whenComplete((ping, exception) -> {
if (exception != null) {
Expand Down Expand Up @@ -115,4 +126,61 @@ private void tickMessages() {
this.player.writePacket(this.waitSound);
this.player.getScheduledExecutor().schedule(this::tickMessages, CONFIG.messages.titles.showDelay * 50, TimeUnit.MILLISECONDS);
}

private void hubTeleport() {
if (!connected || connecting || !CONFIG.hubTeleport.enable) return;

boolean fromHub = CONFIG.hubTeleport.servers
.contains(server.getServerInfo().getName());

if (fromHub && CONFIG.hubTeleport.servers.size() == 1) return;

if (CONFIG.hubTeleport.instantly) findAndSendHub();
else player.getProxyPlayer().sendMessage(LimboReconnect.getSerializer().deserialize(CONFIG.hubTeleport.messages.teleport));
}

private void findAndSendHub() {
if (!connected || connecting || !CONFIG.hubTeleport.enable) return;
if (hubRetryTask != null && !hubRetryTask.isDone()) return;

proxyServer.getAllServers().stream()
.filter(s -> CONFIG.hubTeleport.servers.contains(s.getServerInfo().getName()))
.forEach(s -> s.ping(pingOptions).whenComplete((ping, err) -> {
if (!connected || connecting) return;
if (err != null || ping == null) return;

ping.getPlayers().ifPresent(players -> {
if (players.getOnline() >= players.getMax()) return;
connect(s);
});
}));

hubRetryTask = player.getScheduledExecutor().schedule(
() -> {
if (!connected || connecting) return;
player.getProxyPlayer().sendMessage(LimboReconnect.getSerializer().deserialize(CONFIG.hubTeleport.messages.fully));
hubRetryTask = null;
findAndSendHub();
}, 2, TimeUnit.SECONDS
);
}

private void connect(RegisteredServer target) {
if (!connected || connecting) return;

connecting = true;
cancelHubRetry();

player.writePacket(connectSound);
player.getProxyPlayer().resetTitle();
player.disconnect(target);
}

private void cancelHubRetry() {
if (hubRetryTask != null) {
hubRetryTask.cancel(false);
hubRetryTask = null;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.elytrium.limboreconnect.listener;

import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.proxy.ProxyServer;
import net.elytrium.limboreconnect.LimboReconnect;

public class ConnectListener {

public ProxyServer server;
public LimboReconnect plugin;

public ConnectListener(ProxyServer server, LimboReconnect plugin) {
this.server = server;
this.plugin = plugin;
}

@Subscribe
public void onServerPreConnect(ServerPostConnectEvent event) {
event.getPlayer().getCurrentServer().ifPresent(serverConnection ->
plugin.addPlayer(event.getPlayer(), serverConnection.getServer()));
}

}