Removed UDP stuff, upgrade to 2.0, chat improvements too.

This commit is contained in:
Andrew Lalis 2021-06-19 22:30:45 +02:00
parent 7ed19f3576
commit 95ba8c8746
21 changed files with 196 additions and 219 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ace-of-shades</artifactId>
<groupId>nl.andrewlalis</groupId>
<version>1.0</version>
<version>2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,18 +2,17 @@ package nl.andrewlalis.aos_client;
import nl.andrewlalis.aos_client.view.GameFrame;
import nl.andrewlalis.aos_client.view.GamePanel;
import nl.andrewlalis.aos_core.model.Player;
import nl.andrewlalis.aos_core.model.PlayerControlState;
import nl.andrewlalis.aos_core.model.World;
import nl.andrewlalis.aos_core.net.ChatMessage;
import nl.andrewlalis.aos_core.net.PlayerControlStateMessage;
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
import javax.swing.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
* The main class for the client, which connects to a server to join and play.
@ -21,15 +20,13 @@ import java.util.concurrent.ThreadLocalRandom;
public class Client {
public static final int MAX_CHAT_MESSAGES = 10;
private final int udpPort;
private DatagramReceiver datagramReceiver;
private MessageTransceiver messageTransceiver;
private int playerId;
private PlayerControlState playerControlState;
private World world;
private final List<String> chatMessages;
private final List<ChatMessage> chatMessages;
private boolean chatting = false;
private final StringBuilder chatBuffer;
@ -37,8 +34,7 @@ public class Client {
private final GamePanel gamePanel;
private final SoundManager soundManager;
public Client(int udpPort) {
this.udpPort = udpPort;
public Client() {
this.chatMessages = new LinkedList<>();
this.chatBuffer = new StringBuilder();
this.soundManager = new SoundManager();
@ -47,13 +43,11 @@ public class Client {
}
public void connect(String serverHost, int serverPort, String username) throws IOException, ClassNotFoundException {
this.datagramReceiver = new DatagramReceiver(this, this.udpPort);
this.datagramReceiver.start();
this.messageTransceiver = new MessageTransceiver(this);
this.messageTransceiver.connectToServer(serverHost, serverPort, username, this.udpPort);
this.messageTransceiver.connectToServer(serverHost, serverPort, username);
this.messageTransceiver.start();
while (this.playerControlState == null) {
while (this.playerControlState == null || this.world == null) {
try {
System.out.println("Waiting for server response and player registration...");
Thread.sleep(100);
@ -62,6 +56,7 @@ public class Client {
}
}
System.out.println("Player and world data initialized.");
GameFrame g = new GameFrame("Ace of Shades - " + serverHost + ":" + serverPort, this, this.gamePanel);
g.setVisible(true);
this.renderer.start();
@ -94,27 +89,24 @@ public class Client {
public void sendPlayerState() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this.playerControlState);
byte[] buffer = bos.toByteArray();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, this.messageTransceiver.getRemoteAddress(), this.messageTransceiver.getPort());
this.datagramReceiver.getDatagramSocket().send(packet);
this.messageTransceiver.send(new PlayerControlStateMessage(this.playerControlState));
} catch (IOException e) {
e.printStackTrace();
}
}
public synchronized void addChatMessage(String text) {
this.chatMessages.add(text);
public synchronized void addChatMessage(ChatMessage message) {
this.chatMessages.add(message);
if (message.getClass() == PlayerChatMessage.class) {
this.soundManager.play("chat.wav");
}
while (this.chatMessages.size() > MAX_CHAT_MESSAGES) {
this.chatMessages.remove(0);
}
}
public String[] getLatestChatMessages() {
return this.chatMessages.toArray(new String[0]);
public ChatMessage[] getLatestChatMessages() {
return this.chatMessages.toArray(new ChatMessage[0]);
}
public boolean isChatting() {
@ -140,7 +132,7 @@ public class Client {
public void sendChat() {
try {
this.messageTransceiver.send(new ChatMessage(this.chatBuffer.toString()));
this.messageTransceiver.send(new PlayerChatMessage(this.playerId, this.chatBuffer.toString()));
} catch (IOException e) {
e.printStackTrace();
}
@ -152,7 +144,6 @@ public class Client {
}
public void shutdown() {
this.datagramReceiver.shutdown();
this.messageTransceiver.shutdown();
this.renderer.shutdown();
}
@ -160,21 +151,18 @@ public class Client {
public static void main(String[] args) {
// Randomly choose a high-level UDP port that's probably open.
int udpPort = 20000 + ThreadLocalRandom.current().nextInt(0, 10000);
// String hostAndPort = JOptionPane.showInputDialog("Enter server host and port (host:port):");
// if (hostAndPort == null) throw new IllegalArgumentException("A host and port is required.");
// String[] parts = hostAndPort.split(":");
// if (parts.length != 2) throw new IllegalArgumentException("Invalid host:port.");
// String host = parts[0].trim();
// int port = Integer.parseInt(parts[1]);
// String username = JOptionPane.showInputDialog("Enter a username:");
// if (username == null || username.isBlank()) throw new IllegalArgumentException("Username is required.");
String hostAndPort = JOptionPane.showInputDialog("Enter server host and port (host:port):");
if (hostAndPort == null) throw new IllegalArgumentException("A host and port is required.");
String[] parts = hostAndPort.split(":");
if (parts.length != 2) throw new IllegalArgumentException("Invalid host:port.");
String host = parts[0].trim();
int port = Integer.parseInt(parts[1]);
String username = JOptionPane.showInputDialog("Enter a username:");
if (username == null || username.isBlank()) throw new IllegalArgumentException("Username is required.");
Client client = new Client(udpPort);
Client client = new Client();
try {
client.connect(host, port, username);
client.connect("localhost", 8035, "andrew");
} catch (IOException | ClassNotFoundException e) {
client.shutdown();
e.printStackTrace();

View File

@ -1,50 +0,0 @@
package nl.andrewlalis.aos_client;
import nl.andrewlalis.aos_core.model.World;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class DatagramReceiver extends Thread {
private final DatagramSocket datagramSocket;
private final Client client;
private volatile boolean running;
public DatagramReceiver(Client client, int port) throws SocketException {
this.datagramSocket = new DatagramSocket(port);
this.client = client;
}
public DatagramSocket getDatagramSocket() {
return datagramSocket;
}
public void shutdown() {
this.running = false;
this.datagramSocket.close();
}
@Override
public void run() {
this.running = true;
byte[] buffer = new byte[8192];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (this.running) {
try {
this.datagramSocket.receive(packet);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(packet.getData()));
Object obj = ois.readObject();
if (obj instanceof World) {
this.client.setWorld((World) obj);
}
} catch (IOException | ClassNotFoundException e) {
// Ignore any receive exception.d
}
}
}
}

View File

@ -1,12 +1,15 @@
package nl.andrewlalis.aos_client;
import nl.andrewlalis.aos_core.model.World;
import nl.andrewlalis.aos_core.net.*;
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.io.StreamCorruptedException;
import java.net.Socket;
import java.net.SocketException;
/**
* This thread is responsible for handling TCP message communication with the
@ -25,11 +28,12 @@ public class MessageTransceiver extends Thread {
this.client = client;
}
public void connectToServer(String serverHost, int serverPort, String username, int udpPort) throws IOException, ClassNotFoundException {
public void connectToServer(String serverHost, int serverPort, String username) throws IOException {
this.socket = new Socket(serverHost, serverPort);
this.out = new ObjectOutputStream(this.socket.getOutputStream());
this.in = new ObjectInputStream(this.socket.getInputStream());
this.send(new IdentMessage(username, udpPort));
this.send(new IdentMessage(username));
System.out.println("Sent identification packet.");
}
public void shutdown() {
@ -43,15 +47,8 @@ public class MessageTransceiver extends Thread {
}
}
public InetAddress getRemoteAddress() {
return this.socket != null ? this.socket.getInetAddress() : null;
}
public int getPort() {
return this.socket.getPort();
}
public void send(Message message) throws IOException {
public synchronized void send(Message message) throws IOException {
this.out.reset();
this.out.writeObject(message);
}
@ -64,10 +61,20 @@ public class MessageTransceiver extends Thread {
PlayerRegisteredMessage prm = (PlayerRegisteredMessage) msg;
this.client.initPlayerData(prm.getPlayerId());
} else if (msg.getType() == Type.CHAT) {
this.client.addChatMessage(((ChatMessage) msg).getText());
this.client.addChatMessage((ChatMessage) msg);
} else if (msg.getType() == Type.WORLD_UPDATE) {
World world = ((WorldUpdateMessage) msg).getWorld();
this.client.setWorld(world);
}
} catch (StreamCorruptedException e) {
e.printStackTrace();
this.running = false;
} catch (SocketException e) {
if (!e.getMessage().equalsIgnoreCase("Socket closed")) {
e.printStackTrace();
}
} catch (IOException | ClassNotFoundException e) {
// Ignore exceptions.
e.printStackTrace();
}
}
}

View File

@ -2,6 +2,9 @@ package nl.andrewlalis.aos_client.view;
import nl.andrewlalis.aos_client.Client;
import nl.andrewlalis.aos_core.model.*;
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
import nl.andrewlalis.aos_core.net.chat.SystemChatMessage;
import javax.swing.*;
import java.awt.*;
@ -44,7 +47,7 @@ public class GamePanel extends JPanel {
World world = client.getWorld();
if (world != null) drawWorld(g2, world);
drawChat(g2, client.getLatestChatMessages());
drawChat(g2, world);
}
private void drawWorld(Graphics2D g2, World world) {
@ -142,16 +145,35 @@ public class GamePanel extends JPanel {
}
}
private void drawChat(Graphics2D g2, String[] messages) {
private void drawChat(Graphics2D g2, World world) {
int height = g2.getFontMetrics().getHeight();
int y = height;
g2.setColor(Color.WHITE);
for (String message : messages) {
g2.drawString(message, 5, y);
for (ChatMessage message : this.client.getLatestChatMessages()) {
Color color = Color.WHITE;
String text = message.getText();
if (message instanceof SystemChatMessage sysMsg) {
if (sysMsg.getLevel() == SystemChatMessage.Level.INFO) {
color = Color.YELLOW;
} else if (sysMsg.getLevel() == SystemChatMessage.Level.WARNING) {
color = Color.ORANGE;
} else if (sysMsg.getLevel() == SystemChatMessage.Level.SEVERE) {
color = Color.RED;
}
} else if (message instanceof PlayerChatMessage pcm) {
String author = Integer.toString(pcm.getPlayerId());
if (world != null) {
Player p = world.getPlayers().get(pcm.getPlayerId());
if (p != null) author = p.getName();
}
text = author + ": " + text;
}
g2.setColor(color);
g2.drawString(text, 5, y);
y += height;
}
if (this.client.isChatting()) {
g2.setColor(Color.WHITE);
g2.drawString("> " + this.client.getCurrentChatBuffer(), 5, height * 11);
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ace-of-shades</artifactId>
<groupId>nl.andrewlalis</groupId>
<version>1.0</version>
<version>2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,4 +3,5 @@ module aos_core {
exports nl.andrewlalis.aos_core.net to aos_server, aos_client;
exports nl.andrewlalis.aos_core.model to aos_server, aos_client;
exports nl.andrewlalis.aos_core.geom to aos_server, aos_client;
exports nl.andrewlalis.aos_core.net.chat to aos_client, aos_server;
}

View File

@ -2,19 +2,13 @@ package nl.andrewlalis.aos_core.net;
public class IdentMessage extends Message {
private final String name;
private final int datagramPort;
public IdentMessage(String name, int datagramPort) {
public IdentMessage(String name) {
super(Type.IDENT);
this.name = name;
this.datagramPort = datagramPort;
}
public String getName() {
return name;
}
public int getDatagramPort() {
return datagramPort;
}
}

View File

@ -0,0 +1,16 @@
package nl.andrewlalis.aos_core.net;
import nl.andrewlalis.aos_core.model.PlayerControlState;
public class PlayerControlStateMessage extends Message {
private final PlayerControlState playerControlState;
public PlayerControlStateMessage(PlayerControlState pcs) {
super(Type.PLAYER_CONTROL_STATE);
this.playerControlState = pcs;
}
public PlayerControlState getPlayerControlState() {
return playerControlState;
}
}

View File

@ -4,5 +4,7 @@ public enum Type {
IDENT,
ACK,
PLAYER_REGISTERED,
CHAT
CHAT,
PLAYER_CONTROL_STATE,
WORLD_UPDATE
}

View File

@ -0,0 +1,15 @@
package nl.andrewlalis.aos_core.net;
import nl.andrewlalis.aos_core.model.World;
public class WorldUpdateMessage extends Message {
private final World world;
public WorldUpdateMessage(World world) {
super(Type.WORLD_UPDATE);
this.world = world;
}
public World getWorld() {
return world;
}
}

View File

@ -1,4 +1,7 @@
package nl.andrewlalis.aos_core.net;
package nl.andrewlalis.aos_core.net.chat;
import nl.andrewlalis.aos_core.net.Message;
import nl.andrewlalis.aos_core.net.Type;
public class ChatMessage extends Message {
private final String text;

View File

@ -0,0 +1,7 @@
package nl.andrewlalis.aos_core.net.chat;
public class CommandMessage extends PlayerChatMessage {
public CommandMessage(int id, String text) {
super(id, text);
}
}

View File

@ -0,0 +1,14 @@
package nl.andrewlalis.aos_core.net.chat;
public class PlayerChatMessage extends ChatMessage {
private final int playerId;
public PlayerChatMessage(int id, String text) {
super(text);
this.playerId = id;
}
public int getPlayerId() {
return playerId;
}
}

View File

@ -0,0 +1,16 @@
package nl.andrewlalis.aos_core.net.chat;
public class SystemChatMessage extends ChatMessage {
public enum Level {INFO, WARNING, SEVERE}
private final Level level;
public SystemChatMessage(Level level, String text) {
super(text);
this.level = level;
}
public Level getLevel() {
return level;
}
}

View File

@ -7,7 +7,7 @@
<groupId>nl.andrewlalis</groupId>
<artifactId>ace-of-shades</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<version>2.0</version>
<modules>
<module>server</module>
<module>client</module>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ace-of-shades</artifactId>
<groupId>nl.andrewlalis</groupId>
<version>1.0</version>
<version>2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,6 +1,7 @@
package nl.andrewlalis.aos_server;
import nl.andrewlalis.aos_core.net.*;
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
import java.io.IOException;
import java.io.ObjectInputStream;
@ -13,7 +14,6 @@ public class ClientHandler extends Thread {
private final ObjectOutputStream out;
private final ObjectInputStream in;
private int datagramPort = -1;
private int playerId;
private volatile boolean running = true;
@ -25,14 +25,6 @@ public class ClientHandler extends Thread {
this.in = new ObjectInputStream(socket.getInputStream());
}
public Socket getSocket() {
return socket;
}
public int getDatagramPort() {
return datagramPort;
}
public int getPlayerId() {
return playerId;
}
@ -41,7 +33,8 @@ public class ClientHandler extends Thread {
this.running = false;
}
public void send(Message message) throws IOException {
public synchronized void send(Message message) throws IOException {
this.out.reset();
this.out.writeObject(message);
}
@ -53,12 +46,11 @@ public class ClientHandler extends Thread {
Message msg = (Message) this.in.readObject();
if (msg.getType() == Type.IDENT) {
IdentMessage ident = (IdentMessage) msg;
int id = this.server.registerNewPlayer(ident.getName());
this.playerId = id;
this.datagramPort = ident.getDatagramPort();
this.send(new PlayerRegisteredMessage(id));
this.playerId = this.server.registerNewPlayer(ident.getName(), this);
} else if (msg.getType() == Type.CHAT) {
this.server.broadcastPlayerChat(this.playerId, (ChatMessage) msg);
} else if (msg.getType() == Type.PLAYER_CONTROL_STATE) {
this.server.updatePlayerState(((PlayerControlStateMessage) msg).getPlayerControlState());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
@ -67,7 +59,6 @@ public class ClientHandler extends Thread {
} catch (IOException e) {
// Ignore this exception, consider the client disconnected.
}
this.datagramPort = -1;
try {
this.socket.close();
} catch (IOException e) {

View File

@ -1,41 +0,0 @@
package nl.andrewlalis.aos_server;
import nl.andrewlalis.aos_core.model.PlayerControlState;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class DatagramCommunicationThread extends Thread {
private final Server server;
private final DatagramSocket socket;
public DatagramCommunicationThread(Server server, int port) throws SocketException {
this.server = server;
this.socket = new DatagramSocket(port);
}
public DatagramSocket getSocket() {
return socket;
}
@Override
public void run() {
byte[] buffer = new byte[8192];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
try {
this.socket.receive(packet);
Object obj = new ObjectInputStream(new ByteArrayInputStream(buffer)).readObject();
if (obj instanceof PlayerControlState) {
this.server.updatePlayerState((PlayerControlState) obj);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}

View File

@ -2,19 +2,20 @@ package nl.andrewlalis.aos_server;
import nl.andrewlalis.aos_core.geom.Vec2;
import nl.andrewlalis.aos_core.model.*;
import nl.andrewlalis.aos_core.net.ChatMessage;
import nl.andrewlalis.aos_core.net.Message;
import nl.andrewlalis.aos_core.net.PlayerRegisteredMessage;
import nl.andrewlalis.aos_core.net.WorldUpdateMessage;
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
import nl.andrewlalis.aos_core.net.chat.SystemChatMessage;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class Server {
@ -22,14 +23,12 @@ public class Server {
private final List<ClientHandler> clientHandlers;
private final ServerSocket serverSocket;
private final DatagramCommunicationThread datagramCommunicationThread;
private final World world;
private final WorldUpdater worldUpdater;
public Server(int port) throws IOException {
this.clientHandlers = new ArrayList<>();
this.clientHandlers = new CopyOnWriteArrayList<>();
this.serverSocket = new ServerSocket(port);
this.datagramCommunicationThread = new DatagramCommunicationThread(this, port);
this.world = new World(new Vec2(50, 70));
world.getBarricades().add(new Barricade(10, 10, 30, 5));
@ -42,19 +41,17 @@ public class Server {
world.getTeams().add(new Team("Blue", Color.BLUE, new Vec2(world.getSize().x() - 3, world.getSize().y() - 3), new Vec2(0, -1)));
this.worldUpdater = new WorldUpdater(this, this.world);
System.out.println("Started AOS-Server TCP/UDP on port " + port);
System.out.println("Started AOS-Server TCP on port " + port);
}
public void acceptClientConnection() throws IOException {
Socket socket = this.serverSocket.accept();
var t = new ClientHandler(this, socket);
t.start();
synchronized (this.clientHandlers) {
this.clientHandlers.add(t);
}
}
public int registerNewPlayer(String name) {
public int registerNewPlayer(String name, ClientHandler handler) {
int id = ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE);
Team team = null;
for (Team t : this.world.getTeams()) {
@ -65,50 +62,48 @@ public class Server {
}
}
Player p = new Player(id, name, team);
System.out.println("Client connected: " + p.getId() + ", " + p.getName());
this.broadcastMessage(new ChatMessage(name + " connected."));
this.world.getPlayers().put(p.getId(), p);
try {
handler.send(new PlayerRegisteredMessage(id));
} catch (IOException e) {
e.printStackTrace();
}
String message = p.getName() + " connected.";
this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, message));
System.out.println(message);
p.setPosition(new Vec2(this.world.getSize().x() / 2.0, this.world.getSize().y() / 2.0));
if (team != null) {
team.getPlayers().add(p);
p.setPosition(team.getSpawnPoint());
p.setOrientation(team.getOrientation());
this.broadcastMessage(new ChatMessage(name + " joined team " + team.getName()));
System.out.println("Player joined team " + team.getName());
message = name + " joined team " + team.getName() + ".";
this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, message));
}
return id;
}
public void clientDisconnected(ClientHandler clientHandler) {
Player player = this.world.getPlayers().get(clientHandler.getPlayerId());
synchronized (this.clientHandlers) {
this.clientHandlers.remove(clientHandler);
clientHandler.shutdown();
}
this.world.getPlayers().remove(player.getId());
if (player.getTeam() != null) {
player.getTeam().getPlayers().remove(player);
}
this.broadcastMessage(new ChatMessage(player.getName() + " disconnected."));
System.out.println("Client disconnected: " + player.getId() + ", " + player.getName());
String message = player.getName() + " disconnected.";
this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, message));
System.out.println(message);
}
public void sendWorldToClients() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
new ObjectOutputStream(bos).writeObject(this.world);
byte[] data = bos.toByteArray();
DatagramPacket packet = new DatagramPacket(data, data.length);
for (ClientHandler handler : this.clientHandlers) {
if (handler.getDatagramPort() == -1) continue;
packet.setAddress(handler.getSocket().getInetAddress());
packet.setPort(handler.getDatagramPort());
this.datagramCommunicationThread.getSocket().send(packet);
}
} catch (Exception e) {
try {
handler.send(new WorldUpdateMessage(this.world));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void updatePlayerState(PlayerControlState state) {
Player p = this.world.getPlayers().get(state.getPlayerId());
@ -130,7 +125,7 @@ public class Server {
public void broadcastPlayerChat(int playerId, ChatMessage msg) {
Player p = this.world.getPlayers().get(playerId);
if (p == null) return;
this.broadcastMessage(new ChatMessage(p.getName() + ": " + msg.getText()));
this.broadcastMessage(new PlayerChatMessage(p.getId(), msg.getText()));
}
@ -150,12 +145,9 @@ public class Server {
}
Server server = new Server(port);
server.datagramCommunicationThread.start();
server.worldUpdater.start();
while (true) {
server.acceptClientConnection();
}
}
}

View File

@ -5,7 +5,7 @@ import nl.andrewlalis.aos_core.model.Barricade;
import nl.andrewlalis.aos_core.model.Bullet;
import nl.andrewlalis.aos_core.model.Player;
import nl.andrewlalis.aos_core.model.World;
import nl.andrewlalis.aos_core.net.ChatMessage;
import nl.andrewlalis.aos_core.net.chat.SystemChatMessage;
import java.util.ArrayList;
import java.util.List;
@ -155,7 +155,7 @@ public class WorldUpdater extends Thread {
double dist = p.getPosition().dist(new Vec2(x1 + n * (x2 - x1), y1 + n * (y2 - y1)));
if (dist < Player.RADIUS) {
Player killer = this.world.getPlayers().get(b.getPlayerId());
this.server.broadcastMessage(new ChatMessage(p.getName() + " was shot by " + killer.getName() + "."));
this.server.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.SEVERE, p.getName() + " was shot by " + killer.getName() + "."));
world.getSoundsToPlay().add("death.wav");
if (p.getTeam() != null) {
p.setPosition(p.getTeam().getSpawnPoint());