155 lines
6.0 KiB
Java
155 lines
6.0 KiB
Java
package ru.dragonestia.kubik.plugin;
|
||
|
||
import com.google.gson.Gson;
|
||
import com.google.inject.Inject;
|
||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
|
||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||
import com.velocitypowered.api.event.Subscribe;
|
||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||
import com.velocitypowered.api.plugin.Plugin;
|
||
import com.velocitypowered.api.proxy.Player;
|
||
import com.velocitypowered.api.proxy.ProxyServer;
|
||
import com.velocitypowered.api.proxy.ServerConnection;
|
||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||
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.format.NamedTextColor;
|
||
import org.slf4j.Logger;
|
||
import ru.dragonestia.kubik.client.Kubik;
|
||
import ru.dragonestia.kubik.client.proxy.ProxyControl;
|
||
import ru.dragonestia.kubik.client.proxy.ProxyServerRegistry;
|
||
import ru.dragonestia.kubik.client.util.EnvUtil;
|
||
|
||
import java.net.InetSocketAddress;
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.util.Map;
|
||
import java.util.concurrent.ConcurrentHashMap;
|
||
import java.util.function.Consumer;
|
||
|
||
@Plugin(
|
||
id = "kubik-velocity-plugin",
|
||
name = "KubikConnector",
|
||
version = "1.0.0",
|
||
description = "Kubik connector plugin",
|
||
authors = { "ScarletRedMan" }
|
||
)
|
||
public class KubikPlugin implements ProxyServerRegistry {
|
||
|
||
private final static MinecraftChannelIdentifier KUBIK_TRANSFER_CHANNEL_ID = MinecraftChannelIdentifier.from("kubik:transfer");
|
||
|
||
private final ProxyServer proxyServer;
|
||
private final Logger logger;
|
||
private final ProxyControl proxyControl;
|
||
|
||
private final Gson gson = new Gson();
|
||
private final Map<String, Consumer<PluginMessageEvent>> pluginChannelHandlers = new ConcurrentHashMap<>();
|
||
private final Map<String, RegisteredServer> registeredServers = new ConcurrentHashMap<>();
|
||
|
||
private Kubik kubik;
|
||
private String initialServerGroupId;
|
||
|
||
@Inject
|
||
public KubikPlugin(ProxyServer proxyServer, Logger logger) {
|
||
this.proxyServer = proxyServer;
|
||
this.logger = logger;
|
||
|
||
var kubikHttpUrl = EnvUtil.getString("KUBIK_DISCOVERY_HTTP_URL", "http://localhost:8080");
|
||
var kubikWsUrl = EnvUtil.getString("KUBIK_DISCOVERY_WS_URL", "ws://localhost:8080");
|
||
|
||
logger.info("Using kubik urls: {}, {}", kubikHttpUrl, kubikWsUrl);
|
||
|
||
kubik = new Kubik(kubikHttpUrl, kubikWsUrl);
|
||
proxyControl = kubik.initProxy(this);
|
||
|
||
initialServerGroupId = EnvUtil.getString("KUBIK_INITIAL_SERVER_GROUP_ID", "lobby");
|
||
}
|
||
|
||
@Subscribe
|
||
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||
registerPluginChannel(KUBIK_TRANSFER_CHANNEL_ID, e -> {
|
||
e.setResult(PluginMessageEvent.ForwardResult.handled());
|
||
|
||
if (!(e.getSource() instanceof ServerConnection backend)) return;
|
||
var serverId = new String(e.getData(), StandardCharsets.UTF_8);
|
||
var player = (Player) e.getTarget();
|
||
|
||
logger.info("Taken transfer request for player {} to {}", player.getUsername(), serverId);
|
||
var server = registeredServers.get(serverId);
|
||
if (server == null) {
|
||
logger.error("Could not find server with id '{}'", serverId);
|
||
player.disconnect(Component.text("Сервер '%s' недоступен".formatted(serverId), NamedTextColor.RED));
|
||
return;
|
||
}
|
||
|
||
player.createConnectionRequest(server).fireAndForget();
|
||
});
|
||
}
|
||
|
||
@Subscribe
|
||
public void onPreShutdown(ProxyShutdownEvent event) {
|
||
proxyControl.dispose();
|
||
}
|
||
|
||
@Subscribe
|
||
public void onChooseInitialServer(PlayerChooseInitialServerEvent event) {
|
||
var player = event.getPlayer();
|
||
|
||
if (initialServerGroupId == null) {
|
||
logger.error("Initial server group id is null");
|
||
player.disconnect(Component.text("Неправильно сконфигурировано лобби сервера"));
|
||
return;
|
||
}
|
||
|
||
var serverId = kubik.pickServer(initialServerGroupId);
|
||
if (serverId == null) {
|
||
logger.error("Could not find server with groupId '{}'", initialServerGroupId);
|
||
player.disconnect(Component.text("Нет доступных серверов для лобби"));
|
||
return;
|
||
}
|
||
|
||
var server = registeredServers.get(serverId);
|
||
if (server == null) {
|
||
logger.error("Server '{}' is not registered for groupId '{}'", serverId, initialServerGroupId);
|
||
player.disconnect(Component.text("Не зарегистрирован сервер для лобби"));
|
||
return;
|
||
}
|
||
|
||
event.setInitialServer(server);
|
||
}
|
||
|
||
@Subscribe
|
||
public void onTakenPluginMessage(PluginMessageEvent event) {
|
||
var handler = pluginChannelHandlers.get(event.getIdentifier().getId());
|
||
if (handler != null) handler.accept(event);
|
||
}
|
||
|
||
private void registerPluginChannel(MinecraftChannelIdentifier channelId, Consumer<PluginMessageEvent> handler) {
|
||
pluginChannelHandlers.put(channelId.getId(), handler);
|
||
proxyServer.getChannelRegistrar().register(KUBIK_TRANSFER_CHANNEL_ID);
|
||
logger.info("Registered plugin channel '{}'", channelId.getId());
|
||
}
|
||
|
||
@Override
|
||
public void register(String id, String address, int port) {
|
||
var server = registeredServers.computeIfAbsent(id, _ -> proxyServer.createRawRegisteredServer(new ServerInfo(
|
||
id,
|
||
InetSocketAddress.createUnresolved(address, port)
|
||
)));
|
||
|
||
logger.info("Registered server '{}'(address={} port={})", id, address, port);
|
||
}
|
||
|
||
@Override
|
||
public void unregister(String id) {
|
||
var server = registeredServers.remove(id);
|
||
|
||
logger.info("Unregistered server '{}'", id);
|
||
|
||
if (server == null) return;
|
||
|
||
//TODO
|
||
}
|
||
}
|