Added improved client command system.

This commit is contained in:
Andrew Lalis 2022-07-29 13:15:11 +02:00
parent e065be9b35
commit 35fcc43ccc
8 changed files with 108 additions and 18 deletions

Binary file not shown.

Binary file not shown.

View File

@ -80,24 +80,8 @@ public class ClientCommunicationHandler {
sendTcpMessage(new ChunkDataMessage(chunk)); sendTcpMessage(new ChunkDataMessage(chunk));
} }
} else if (msg instanceof ChatWrittenMessage chatWrittenMessage) { } else if (msg instanceof ChatWrittenMessage chatWrittenMessage) {
if (chatWrittenMessage.message().startsWith("/t ")) { if (chatWrittenMessage.message().startsWith("/")) {
if (player.getTeam() != null) { server.handleCommand(chatWrittenMessage.message(), player, this);
var chat = new ChatMessage(
System.currentTimeMillis(),
player.getUsername(),
chatWrittenMessage.message().substring(3)
);
for (var teamPlayer : server.getTeamManager().getPlayers(player.getTeam())) {
server.getPlayerManager().getHandler(teamPlayer).sendTcpMessage(chat);
}
}
} else if (chatWrittenMessage.message().equalsIgnoreCase("/kd")) {
int k = player.getKillCount();
int d = player.getDeathCount();
float kd = d <= 0 ? 0 : (float) k / (float) d;
sendTcpMessage(ChatMessage.privateMessage("Your kill/death ratio is %.2f.".formatted(kd)));
} else if (chatWrittenMessage.message().equalsIgnoreCase("/kill")) {
server.getPlayerManager().playerKilled(player, null);
} else { } else {
server.getPlayerManager().broadcastTcpMessage(new ChatMessage( server.getPlayerManager().broadcastTcpMessage(new ChatMessage(
System.currentTimeMillis(), System.currentTimeMillis(),

View File

@ -1,6 +1,7 @@
package nl.andrewl.aos2_server; package nl.andrewl.aos2_server;
import nl.andrewl.aos2_server.cli.ServerCli; import nl.andrewl.aos2_server.cli.ServerCli;
import nl.andrewl.aos2_server.cli.ingame.PlayerCommandHandler;
import nl.andrewl.aos2_server.config.ServerConfig; import nl.andrewl.aos2_server.config.ServerConfig;
import nl.andrewl.aos2_server.logic.WorldUpdater; import nl.andrewl.aos2_server.logic.WorldUpdater;
import nl.andrewl.aos2_server.model.ServerPlayer; import nl.andrewl.aos2_server.model.ServerPlayer;
@ -37,6 +38,7 @@ public class Server implements Runnable {
private final PlayerManager playerManager; private final PlayerManager playerManager;
private final TeamManager teamManager; private final TeamManager teamManager;
private final ProjectileManager projectileManager; private final ProjectileManager projectileManager;
private final PlayerCommandHandler commandHandler;
private final World world; private final World world;
private final WorldUpdater worldUpdater; private final WorldUpdater worldUpdater;
@ -49,6 +51,7 @@ public class Server implements Runnable {
this.playerManager = new PlayerManager(this); this.playerManager = new PlayerManager(this);
this.teamManager = new TeamManager(this); this.teamManager = new TeamManager(this);
this.projectileManager = new ProjectileManager(this); this.projectileManager = new ProjectileManager(this);
this.commandHandler = new PlayerCommandHandler(this);
this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond); this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond);
if (config.world.startsWith("worlds.")) { if (config.world.startsWith("worlds.")) {
@ -175,6 +178,10 @@ public class Server implements Runnable {
return projectileManager; return projectileManager;
} }
public void handleCommand(String cmd, ServerPlayer player, ClientCommunicationHandler handler) {
commandHandler.handle(cmd, player, handler);
}
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
List<Path> configPaths = Config.getCommonConfigPaths(); List<Path> configPaths = Config.getCommonConfigPaths();
configPaths.add(0, Path.of("server.yaml")); configPaths.add(0, Path.of("server.yaml"));

View File

@ -0,0 +1,12 @@
package nl.andrewl.aos2_server.cli.ingame;
import nl.andrewl.aos2_server.ClientCommunicationHandler;
import nl.andrewl.aos2_server.Server;
import nl.andrewl.aos2_server.model.ServerPlayer;
/**
* Represents a component for handling a certain type of command.
*/
public interface PlayerCommand {
void handle(String[] args, ServerPlayer player, ClientCommunicationHandler handler, Server server);
}

View File

@ -0,0 +1,56 @@
package nl.andrewl.aos2_server.cli.ingame;
import nl.andrewl.aos2_server.ClientCommunicationHandler;
import nl.andrewl.aos2_server.Server;
import nl.andrewl.aos2_server.cli.ingame.commands.KillCommand;
import nl.andrewl.aos2_server.cli.ingame.commands.KillDeathRatioCommand;
import nl.andrewl.aos2_server.model.ServerPlayer;
import nl.andrewl.aos_core.net.client.ChatMessage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PlayerCommandHandler {
private static final Pattern commandSplitter = Pattern.compile("\"(.*)\"|'(.*)'|(\\S+)");
private final Server server;
private final Map<String, PlayerCommand> commands;
public PlayerCommandHandler(Server server) {
this.server = server;
commands = new HashMap<>();
commands.put("kd", new KillDeathRatioCommand());
commands.put("kill", new KillCommand());
}
public void handle(String rawCommand, ServerPlayer player, ClientCommunicationHandler handler) {
Matcher matcher = commandSplitter.matcher(rawCommand);
List<String> matches = new ArrayList<>();
while (matcher.find()) {
for (int i = matcher.groupCount() - 1; i >= 0; i--) {
String group = matcher.group(i);
if (group != null) {
matches.add(group);
break;
}
}
}
String mainCommandString = matches.get(0).substring(1).trim().toLowerCase();
if (!mainCommandString.isBlank()) {
PlayerCommand command = commands.get(mainCommandString);
if (command != null) {
String[] args = new String[matches.size() - 1];
matches.subList(1, matches.size()).toArray(args);
command.handle(args, player, handler, server);
} else {
handler.sendTcpMessage(ChatMessage.privateMessage("Unknown command: \"%s\".".formatted(mainCommandString)));
}
} else {
handler.sendTcpMessage(ChatMessage.privateMessage("Invalid or missing command."));
}
}
}

View File

@ -0,0 +1,13 @@
package nl.andrewl.aos2_server.cli.ingame.commands;
import nl.andrewl.aos2_server.ClientCommunicationHandler;
import nl.andrewl.aos2_server.Server;
import nl.andrewl.aos2_server.cli.ingame.PlayerCommand;
import nl.andrewl.aos2_server.model.ServerPlayer;
public class KillCommand implements PlayerCommand {
@Override
public void handle(String[] args, ServerPlayer player, ClientCommunicationHandler handler, Server server) {
server.getPlayerManager().playerKilled(player, null);
}
}

View File

@ -0,0 +1,18 @@
package nl.andrewl.aos2_server.cli.ingame.commands;
import nl.andrewl.aos2_server.ClientCommunicationHandler;
import nl.andrewl.aos2_server.Server;
import nl.andrewl.aos2_server.cli.ingame.PlayerCommand;
import nl.andrewl.aos2_server.model.ServerPlayer;
import nl.andrewl.aos_core.net.client.ChatMessage;
public class KillDeathRatioCommand implements PlayerCommand {
@Override
public void handle(String[] args, ServerPlayer player, ClientCommunicationHandler handler, Server server) {
float killCount = player.getKillCount();
float deathCount = player.getDeathCount();
float kd = 0;
if (deathCount > 0) kd = killCount / deathCount;
handler.sendTcpMessage(ChatMessage.privateMessage("Your kill/death ratio is %.2f.".formatted(kd)));
}
}