Added ability to change teams, and removed teams from creative and spectator players.
This commit is contained in:
parent
352faff005
commit
20295596fa
|
@ -156,6 +156,14 @@ public class Client implements Runnable {
|
|||
});
|
||||
} else if (msg instanceof PlayerLeaveMessage leaveMessage) {
|
||||
runLater(() -> players.remove(leaveMessage.id()));
|
||||
} else if (msg instanceof PlayerTeamUpdateMessage teamUpdateMessage) {
|
||||
runLater(() -> {
|
||||
OtherPlayer op = players.get(teamUpdateMessage.playerId());
|
||||
Team team = teamUpdateMessage.teamId() == -1 ? null : teams.get(teamUpdateMessage.teamId());
|
||||
if (op != null) {
|
||||
op.setTeam(team);
|
||||
}
|
||||
});
|
||||
} else if (msg instanceof SoundMessage soundMessage) {
|
||||
if (soundManager != null) {
|
||||
soundManager.play(
|
||||
|
|
|
@ -26,29 +26,37 @@ public final class Net {
|
|||
|
||||
private static final Serializer serializer = new Serializer();
|
||||
static {
|
||||
serializer.registerType(1, ConnectRequestMessage.class);
|
||||
serializer.registerType(2, ConnectAcceptMessage.class);
|
||||
serializer.registerType(3, ConnectRejectMessage.class);
|
||||
serializer.registerType(4, DatagramInit.class);
|
||||
serializer.registerType(5, ChunkHashMessage.class);
|
||||
serializer.registerType(6, ChunkDataMessage.class);
|
||||
serializer.registerType(7, ChunkUpdateMessage.class);
|
||||
serializer.registerType(8, ClientInputState.class);
|
||||
serializer.registerType(9, ClientOrientationState.class);
|
||||
serializer.registerType(10, PlayerUpdateMessage.class);
|
||||
serializer.registerType(11, PlayerJoinMessage.class);
|
||||
serializer.registerType(12, PlayerLeaveMessage.class);
|
||||
int i = 1;
|
||||
// Basic protocol messages.
|
||||
serializer.registerType(i++, ConnectRequestMessage.class);
|
||||
serializer.registerType(i++, ConnectAcceptMessage.class);
|
||||
serializer.registerType(i++, ConnectRejectMessage.class);
|
||||
serializer.registerType(i++, DatagramInit.class);
|
||||
|
||||
// World messages.
|
||||
serializer.registerType(i++, ChunkHashMessage.class);
|
||||
serializer.registerType(i++, ChunkDataMessage.class);
|
||||
serializer.registerType(i++, ChunkUpdateMessage.class);
|
||||
serializer.registerType(i++, ProjectileMessage.class);
|
||||
|
||||
// Player/client messages.
|
||||
serializer.registerType(i++, ClientInputState.class);
|
||||
serializer.registerType(i++, ClientOrientationState.class);
|
||||
serializer.registerType(i++, ClientHealthMessage.class);
|
||||
serializer.registerType(i++, PlayerUpdateMessage.class);
|
||||
serializer.registerType(i++, PlayerJoinMessage.class);
|
||||
serializer.registerType(i++, PlayerLeaveMessage.class);
|
||||
serializer.registerType(i++, PlayerTeamUpdateMessage.class);
|
||||
serializer.registerType(i++, BlockColorMessage.class);
|
||||
serializer.registerType(i++, InventorySelectedStackMessage.class);
|
||||
serializer.registerType(i++, ChatMessage.class);
|
||||
serializer.registerType(i++, ChatWrittenMessage.class);
|
||||
serializer.registerType(i++, ClientRecoilMessage.class);
|
||||
// Separate serializers for client inventory messages.
|
||||
serializer.registerTypeSerializer(13, new InventorySerializer());
|
||||
serializer.registerTypeSerializer(14, new ItemStackSerializer());
|
||||
serializer.registerType(15, InventorySelectedStackMessage.class);
|
||||
serializer.registerType(16, SoundMessage.class);
|
||||
serializer.registerType(17, ProjectileMessage.class);
|
||||
serializer.registerType(18, ClientHealthMessage.class);
|
||||
serializer.registerType(19, BlockColorMessage.class);
|
||||
serializer.registerType(20, ChatMessage.class);
|
||||
serializer.registerType(21, ChatWrittenMessage.class);
|
||||
serializer.registerType(22, ClientRecoilMessage.class);
|
||||
serializer.registerTypeSerializer(i++, new InventorySerializer());
|
||||
serializer.registerTypeSerializer(i++, new ItemStackSerializer());
|
||||
|
||||
serializer.registerType(i++, SoundMessage.class);
|
||||
}
|
||||
|
||||
public static ExtendedDataInputStream getInputStream(InputStream in) {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package nl.andrewl.aos_core.net.client;
|
||||
|
||||
import nl.andrewl.record_net.Message;
|
||||
|
||||
/**
|
||||
* A message that's sent by the server to announce that a player has changed to
|
||||
* a specified team. Both the player and team should already be recognized by
|
||||
* all clients; otherwise they can ignore this.
|
||||
*/
|
||||
public record PlayerTeamUpdateMessage(
|
||||
int playerId,
|
||||
int teamId
|
||||
) implements Message {}
|
|
@ -30,21 +30,26 @@ public class PlayerManager {
|
|||
}
|
||||
|
||||
public synchronized ServerPlayer register(ClientCommunicationHandler handler, String username) {
|
||||
ServerPlayer player = new ServerPlayer(nextClientId++, username);
|
||||
Team team = findBestTeamForNewPlayer();
|
||||
ServerPlayer player = new ServerPlayer(nextClientId++, username, team, PlayerMode.NORMAL);
|
||||
var inv = player.getInventory();
|
||||
inv.getItemStacks().add(new GunItemStack(ItemTypes.RIFLE));
|
||||
inv.getItemStacks().add(new GunItemStack(ItemTypes.AK_47));
|
||||
inv.getItemStacks().add(new GunItemStack(ItemTypes.WINCHESTER));
|
||||
inv.getItemStacks().add(new BlockItemStack(ItemTypes.BLOCK, 50, (byte) 1));
|
||||
inv.setSelectedIndex(0);
|
||||
|
||||
System.out.printf("Registered player \"%s\" with id %d.%n", player.getUsername(), player.getId());
|
||||
players.put(player.getId(), player);
|
||||
clientHandlers.put(player.getId(), handler);
|
||||
String joinMessage;
|
||||
Team team = findBestTeamForNewPlayer();
|
||||
if (team != null) {
|
||||
player.setTeam(team);
|
||||
System.out.printf("Player \"%s\" joined the \"%s\" team.%n", player.getUsername(), team.getName());
|
||||
joinMessage = String.format("%s joined the %s team.", username, team.getName());
|
||||
if (player.getTeam() != null) {
|
||||
System.out.printf("Player \"%s\" joined the \"%s\" team.%n", player.getUsername(), player.getTeam().getName());
|
||||
joinMessage = String.format("%s joined the %s team.", username, player.getTeam().getName());
|
||||
} else {
|
||||
joinMessage = username + " joined the game.";
|
||||
}
|
||||
player.setPosition(getBestSpawnPoint(player));
|
||||
setMode(player, PlayerMode.NORMAL);
|
||||
// Tell all other players that this one has joined.
|
||||
broadcastTcpMessageToAllBut(new PlayerJoinMessage(
|
||||
player.getId(), player.getUsername(), player.getTeam() == null ? -1 : player.getTeam().getId(),
|
||||
|
@ -163,12 +168,9 @@ public class PlayerManager {
|
|||
*/
|
||||
public void playerKilled(ServerPlayer player, ServerPlayer killedBy) {
|
||||
Vector3f deathPosition = new Vector3f(player.getPosition());
|
||||
player.setPosition(getBestSpawnPoint(player));
|
||||
player.setVelocity(new Vector3f(0));
|
||||
player.incrementDeathCount();
|
||||
resupply(player);
|
||||
broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
||||
broadcastUdpMessage(new SoundMessage("death", 1, deathPosition));
|
||||
respawn(player);
|
||||
String deathMessage;
|
||||
if (killedBy != null) {
|
||||
killedBy.incrementKillCount();
|
||||
|
@ -198,8 +200,16 @@ public class PlayerManager {
|
|||
handler.sendTcpMessage(ChatMessage.privateMessage("You've been resupplied at your team base."));
|
||||
}
|
||||
|
||||
public void respawn(ServerPlayer player) {
|
||||
player.setPosition(getBestSpawnPoint(player));
|
||||
player.setVelocity(new Vector3f(0));
|
||||
broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
||||
resupply(player);
|
||||
}
|
||||
|
||||
public void setMode(ServerPlayer player, PlayerMode mode) {
|
||||
player.setMode(mode);
|
||||
var handler = getHandler(player);
|
||||
var inv = player.getInventory();
|
||||
inv.clear();
|
||||
if (mode == PlayerMode.NORMAL || mode == PlayerMode.CREATIVE) {
|
||||
|
@ -208,7 +218,31 @@ public class PlayerManager {
|
|||
inv.getItemStacks().add(new GunItemStack(ItemTypes.WINCHESTER));
|
||||
inv.getItemStacks().add(new BlockItemStack(ItemTypes.BLOCK, 50, (byte) 1));
|
||||
inv.setSelectedIndex(0);
|
||||
handler.sendTcpMessage(new ClientInventoryMessage(inv));
|
||||
broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
||||
}
|
||||
if (mode != PlayerMode.NORMAL) {
|
||||
player.setTeam(null);
|
||||
broadcastTcpMessage(new PlayerTeamUpdateMessage(player.getId(), -1));
|
||||
} else {
|
||||
player.setTeam(findBestTeamForNewPlayer());
|
||||
broadcastTcpMessage(new PlayerTeamUpdateMessage(player.getId(), player.getTeam() == null ? -1 : player.getTeam().getId()));
|
||||
}
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage("Your mode has been updated to " + mode.name() + "."));
|
||||
}
|
||||
|
||||
public void setTeam(ServerPlayer player, Team team) {
|
||||
if (Objects.equals(team, player.getTeam()) || player.getMode() != PlayerMode.NORMAL) return;
|
||||
player.setTeam(team);
|
||||
broadcastUdpMessage(new PlayerTeamUpdateMessage(player.getId(), team == null ? -1 : team.getId()));
|
||||
respawn(player);
|
||||
String chatMessage;
|
||||
if (team != null) {
|
||||
chatMessage = "%s has changed to the %s team.".formatted(player.getUsername(), team.getName());
|
||||
} else {
|
||||
chatMessage = "%s has changed to not be on a team.".formatted(player.getUsername());
|
||||
}
|
||||
broadcastTcpMessage(ChatMessage.announce(chatMessage));
|
||||
}
|
||||
|
||||
public void handleUdpInit(DatagramInit init, DatagramPacket packet) {
|
||||
|
|
|
@ -33,6 +33,9 @@ public class TeamManager {
|
|||
for (var team : teams.values()) {
|
||||
if (team.getName().equals(ident)) return Optional.of(team);
|
||||
}
|
||||
for (var team : teams.values()) {// Try again ignoring case.
|
||||
if (team.getName().equalsIgnoreCase(ident)) return Optional.of(team);
|
||||
}
|
||||
try {
|
||||
int id = Integer.parseInt(ident);
|
||||
for (var team : teams.values()) {
|
||||
|
|
|
@ -5,6 +5,7 @@ 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.cli.ingame.commands.PlayerModeCommand;
|
||||
import nl.andrewl.aos2_server.cli.ingame.commands.TeamsCommand;
|
||||
import nl.andrewl.aos2_server.model.ServerPlayer;
|
||||
import nl.andrewl.aos_core.net.client.ChatMessage;
|
||||
|
||||
|
@ -27,6 +28,7 @@ public class PlayerCommandHandler {
|
|||
commands.put("kd", new KillDeathRatioCommand());
|
||||
commands.put("kill", new KillCommand());
|
||||
commands.put("mode", new PlayerModeCommand());
|
||||
commands.put("teams", new TeamsCommand());
|
||||
}
|
||||
|
||||
public void handle(String rawCommand, ServerPlayer player, ClientCommunicationHandler handler) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import nl.andrewl.aos2_server.cli.ingame.PlayerCommand;
|
|||
import nl.andrewl.aos2_server.model.ServerPlayer;
|
||||
import nl.andrewl.aos_core.model.PlayerMode;
|
||||
import nl.andrewl.aos_core.net.client.ChatMessage;
|
||||
import nl.andrewl.aos_core.net.client.ClientInventoryMessage;
|
||||
|
||||
public class PlayerModeCommand implements PlayerCommand {
|
||||
@Override
|
||||
|
@ -19,9 +18,6 @@ public class PlayerModeCommand implements PlayerCommand {
|
|||
try {
|
||||
PlayerMode mode = PlayerMode.valueOf(modeText);
|
||||
server.getPlayerManager().setMode(player, mode);
|
||||
handler.sendTcpMessage(new ClientInventoryMessage(player.getInventory()));
|
||||
server.getPlayerManager().broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage("Your mode has been updated to " + mode.name() + "."));
|
||||
} catch (IllegalArgumentException e) {
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage("Invalid mode. Should be NORMAL, CREATIVE, or SPECTATOR."));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
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.model.Team;
|
||||
import nl.andrewl.aos_core.net.client.ChatMessage;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TeamsCommand implements PlayerCommand {
|
||||
@Override
|
||||
public void handle(String[] args, ServerPlayer player, ClientCommunicationHandler handler, Server server) {
|
||||
if (args.length == 0) {
|
||||
String teamsString = server.getTeamManager().getTeams().stream()
|
||||
.map(Team::getName).collect(Collectors.joining(", "));
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage(teamsString));
|
||||
} else {
|
||||
String cmd = args[0].trim().toLowerCase();
|
||||
if (cmd.equals("set")) {
|
||||
if (args.length >= 2) {
|
||||
String teamIdent = args[1].trim();
|
||||
server.getTeamManager().findByIdOrName(teamIdent)
|
||||
.ifPresentOrElse(
|
||||
team -> server.getPlayerManager().setTeam(player, team),
|
||||
() -> handler.sendTcpMessage(ChatMessage.privateMessage("Unknown team."))
|
||||
);
|
||||
} else {
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage("Missing required team identifier."));
|
||||
}
|
||||
} else {
|
||||
handler.sendTcpMessage(ChatMessage.privateMessage("Unknown subcommand."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ package nl.andrewl.aos2_server.model;
|
|||
|
||||
import nl.andrewl.aos2_server.logic.PlayerActionManager;
|
||||
import nl.andrewl.aos_core.model.Player;
|
||||
import nl.andrewl.aos_core.model.PlayerMode;
|
||||
import nl.andrewl.aos_core.model.Team;
|
||||
import nl.andrewl.aos_core.model.item.Inventory;
|
||||
import nl.andrewl.aos_core.net.client.PlayerUpdateMessage;
|
||||
|
||||
|
@ -24,8 +26,8 @@ public class ServerPlayer extends Player {
|
|||
private int deathCount;
|
||||
private int killCount;
|
||||
|
||||
public ServerPlayer(int id, String username) {
|
||||
super(id, username);
|
||||
public ServerPlayer(int id, String username, Team team, PlayerMode mode) {
|
||||
super(id, username, team, mode);
|
||||
this.inventory = new Inventory(new ArrayList<>(), 0);
|
||||
this.health = 1f;
|
||||
this.actionManager = new PlayerActionManager(this);
|
||||
|
|
Loading…
Reference in New Issue