155 lines
6.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}