This commit is contained in:
kento2 2026-06-03 01:30:08 +02:00
parent e85228e717
commit 0cda14e3cc
34 changed files with 316 additions and 333 deletions

View file

@ -15,15 +15,14 @@ repositories {
}
dependencies {
implementation(project(":core-velocity-api"))
// https://docs.papermc.io/velocity/dev/creating-your-first-plugin/
annotationProcessor("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
compileOnly("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
// https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine
implementation("com.github.ben-manes.caffeine:caffeine:3.2.4")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-velocity
implementation("de.kentoj.scrow:kencommandapi-velocity")
implementation(project(":core-lib"))
}

View file

@ -1,64 +0,0 @@
package de.kentoj.scrow.corevelocity;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import de.kentoj.scrow.corevelocity.command.OnlineCommand;
import de.kentoj.scrow.corevelocity.privmsg.LastTargetCache;
import de.kentoj.scrow.corevelocity.privmsg.MsgCommand;
import de.kentoj.scrow.corevelocity.privmsg.ReplyCommand;
import de.kentoj.scrowlib.servermanager.ServerManager;
import de.kentoj.scrowlib.servermanager.ServerManagerImpl;
import io.nats.client.Connection;
import io.nats.client.Nats;
import io.nats.client.Options;
import lombok.extern.java.Log;
import java.io.IOException;
@Plugin(
id = "corevelocity",
name = "CoreVelocity",
version = "0.1"
)
@Log
public class CoreVelocity {
private final ProxyServer server;
private final Connection nats;
private final ServerManager serverManager;
private final ServerRegisterWatchdog registerWatchdog;
private final SendPlayerWatchdog sendPlayerWatchdog;
@Inject
public CoreVelocity(ProxyServer server) {
this.server = server;
var cmds = server.getCommandManager();
{
cmds.register(OnlineCommand.commandMeta(cmds), new OnlineCommand(server));
}
{
var lastTargetCache = new LastTargetCache();
cmds.register(MsgCommand.commandMeta(cmds), new MsgCommand(lastTargetCache, server));
cmds.register(ReplyCommand.commandMeta(cmds), new ReplyCommand(lastTargetCache, server));
}
try {
var natsHost = System.getenv("HOST_NATS");
nats = Nats.connect(Options.builder()
.pedantic()
.server(natsHost)
.build());
serverManager = new ServerManagerImpl(nats);
registerWatchdog = new ServerRegisterWatchdog(nats, serverManager, server);
sendPlayerWatchdog = new SendPlayerWatchdog(nats, server);
log.info("listening on " + natsHost + " for server registrations");
registerWatchdog.listen();
sendPlayerWatchdog.listen();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,36 @@
package de.kentoj.scrow.corevelocity;
import com.google.inject.Inject;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import de.kentoj.scrow.corevelocity.privmsg.LastTargetCache;
import de.kentoj.scrow.corevelocity.privmsg.MsgCommand;
import de.kentoj.scrow.corevelocity.privmsg.ReplyCommand;
import de.kentoj.scrow.velocity.ScrowAPI;
import lombok.extern.java.Log;
@Plugin(
id = "corevelocity",
name = "CoreVelocity",
version = "0.1"
)
@Log
public class CoreVelocityPlugin {
@Inject
public CoreVelocityPlugin(ProxyServer server) {
ScrowAPISurface.initScrowAPI(server, true);
var cmds = ScrowAPI.getCommandApi();
{
var lastTargetCache = new LastTargetCache();
cmds.register(new ReplyCommand(server, lastTargetCache).getRootNode());
cmds.register(new MsgCommand(server, lastTargetCache).getRootNode());
}
var registerWatchdog = new ServerRegisterWatchdog(ScrowAPI.getNats(), ScrowAPI.getServerManager(), server);
var sendPlayerWatchdog = new SendPlayerWatchdog(ScrowAPI.getNats(), server);
registerWatchdog.listen();
sendPlayerWatchdog.listen();
}
}

View file

@ -0,0 +1,66 @@
package de.kentoj.scrow.corevelocity;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import com.velocitypowered.api.proxy.ProxyServer;
import de.kentoj.kencommandapi.VelocityKenCommandApi;
import de.kentoj.scrow.velocity.ScrowAPI;
import de.kentoj.scrowlib.servermanager.ServerManagerImpl;
import io.nats.client.Nats;
import io.nats.client.Options;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.bson.UuidRepresentation;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
@NoArgsConstructor(access = AccessLevel.NONE)
public class ScrowAPISurface {
private static @Nullable MongoClient mongoClient;
public static void initScrowAPI(ProxyServer server, boolean enableDatabase) {
try {
String natsHost = System.getenv("HOST_NATS");
var options = Options.builder()
.server(natsHost)
.pedantic()
.build();
ScrowAPI.setNats(Nats.connect(options));
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
if (enableDatabase) {
var pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
var codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(pojoCodecProvider)
);
String mongoHost = System.getenv("HOST_MONGO");
var settings = MongoClientSettings.builder()
.codecRegistry(codecRegistry)
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyConnectionString(new ConnectionString(mongoHost))
.build();
mongoClient = MongoClients.create(settings);
ScrowAPI.setDatabase(mongoClient.getDatabase("scrow"));
}
ScrowAPI.setServerManager(new ServerManagerImpl(ScrowAPI.getNats()));
ScrowAPI.setCommandApi(new VelocityKenCommandApi(server));
}
public static void destroyScrowAPI() {
if (mongoClient != null) {
mongoClient.close();
}
}
}

View file

@ -1,59 +1,48 @@
package de.kentoj.scrow.corevelocity.privmsg;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.SimpleCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import de.kentoj.kencommandapi.VelocityCommandContext;
import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.nodes.CommandNode;
import de.kentoj.kencommandapi.api.processing.CommandException;
import de.kentoj.kencommandapi.api.processing.CommandExecutor;
import de.kentoj.kencommandapi.api.types.StringArgumentType;
import de.kentoj.kencommandapi.type.PlayerArgumentType;
import de.kentoj.scrow.velocity.ScrowAPI;
import lombok.Getter;
import java.util.Arrays;
import java.util.stream.Collectors;
public class MsgCommand implements CommandExecutor<CommandSource, VelocityCommandContext> {
@RequiredArgsConstructor
public class MsgCommand implements SimpleCommand {
@Getter
private final CommandNode<CommandSource, VelocityCommandContext> rootNode;
private final CommandArgument<CommandSource, VelocityCommandContext, Player> targetArg;
private final CommandArgument<CommandSource, VelocityCommandContext, String> msgArg;
private final LastTargetCache cache;
private final ProxyServer server;
@Override
public void execute(Invocation invocation) {
if (!(invocation.source() instanceof Player player)) return;
public MsgCommand(ProxyServer server, LastTargetCache cache) {
this.cache = cache;
var targetName = invocation.arguments()[0];
if (invocation.arguments().length < 2) {
player.sendMessage(Component.text("usage: ./msg <name> <msg>"));
return;
NamedTextColor
}
var target = server.getPlayer(targetName).orElse(null);
if (target == null) {
player.sendMessage(Component.text("The player you last messaged is now offline."));
return;
}
if (target.getUniqueId().equals(player.getUniqueId())) {
player.sendMessage(Component.text("You can't message yourself."));
return;
}
var msg = Arrays.stream(invocation.arguments())
.skip(1)
.collect(Collectors.joining(" "));
cache.setLastTarget(player.getUniqueId(), target.getUniqueId());
PrivmsgHelper.handle(player, target, msg);
var cmds = ScrowAPI.getCommandApi();
targetArg = cmds.createArgument("target", new PlayerArgumentType(server));
msgArg = cmds.createArgument("msg", new StringArgumentType<>(true));
rootNode = cmds.createNode("msg", "w");
rootNode.setExecutor(this);
rootNode.addArgument(targetArg);
rootNode.addArgument(msgArg);
}
@Override
public boolean hasPermission(Invocation invocation) {
return invocation.source().hasPermission("corevelocity.cmd.msg");
}
public void execute(VelocityCommandContext ctx) {
var target = ctx.getArg(targetArg);
var msg = ctx.getArg(msgArg);
public static CommandMeta commandMeta(CommandManager cmds) {
return cmds.metaBuilder("msg").aliases("w").build();
var isMessagingSelf = target.getUniqueId().equals(ctx.getPlayerSender().getUniqueId());
if (isMessagingSelf) throw new CommandException("You can't message yourself.");
cache.setLastTarget(ctx.getPlayerSender().getUniqueId(), target.getUniqueId());
PrivmsgHelper.handle(ctx.getPlayerSender(), target, msg);
}
}

View file

@ -1,44 +1,44 @@
package de.kentoj.scrow.corevelocity.privmsg;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.RawCommand;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import de.kentoj.kencommandapi.VelocityCommandContext;
import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.nodes.CommandNode;
import de.kentoj.kencommandapi.api.processing.CommandException;
import de.kentoj.kencommandapi.api.processing.CommandExecutor;
import de.kentoj.kencommandapi.api.types.StringArgumentType;
import de.kentoj.scrow.velocity.ScrowAPI;
import lombok.Getter;
@RequiredArgsConstructor
public class ReplyCommand implements RawCommand {
public class ReplyCommand implements CommandExecutor<CommandSource, VelocityCommandContext> {
@Getter
private final CommandNode<CommandSource, VelocityCommandContext> rootNode;
private final CommandArgument<CommandSource, VelocityCommandContext, String> msgArg;
private final LastTargetCache cache;
private final ProxyServer server;
@Override
public void execute(Invocation invocation) {
if (!(invocation.source() instanceof Player player)) return;
var targetId = cache.getLastTarget(player.getUniqueId());
if (targetId == null) {
player.sendMessage(Component.text("You haven't msg'd anyone recently. Use '/msg <name>' first."));
return;
}
public ReplyCommand(ProxyServer server, LastTargetCache cache) {
this.cache = cache;
this.server = server;
var cmds = ScrowAPI.getCommandApi();
msgArg = cmds.createArgument("msg", new StringArgumentType<>(true));
rootNode = cmds.createNode("reply", "r");
rootNode.setExecutor(this);
rootNode.addArgument(msgArg);
}
@Override
public void execute(VelocityCommandContext ctx) {
var targetId = cache.getLastTarget(ctx.getPlayerSender().getUniqueId());
var target = server.getPlayer(targetId).orElse(null);
if (target == null) {
player.sendMessage(Component.text("The player you last messaged is now offline."));
return;
}
if (target == null) throw new CommandException("The player you last messaged is no longer online");
cache.setLastTarget(player.getUniqueId(), target.getUniqueId());
PrivmsgHelper.handle(player, target, invocation.arguments());
}
@Override
public boolean hasPermission(Invocation invocation) {
return invocation.source().hasPermission("corevelocity.cmd.msg");
}
public static CommandMeta commandMeta(CommandManager cmds) {
return cmds.metaBuilder("reply").aliases("r").build();
var msg = ctx.getArg(msgArg);
cache.setLastTarget(ctx.getPlayerSender().getUniqueId(), target.getUniqueId());
PrivmsgHelper.handle(ctx.getPlayerSender(), target, msg);
}
}

View file

@ -1,10 +0,0 @@
package de.kentoj.scrow.corevelocity.privmsg;
import com.velocitypowered.api.proxy.ProxyServer;
public class ReplyKenCommand {
public ReplyKenCommand(ProxyServer server) {
}
}