From 24708a2fdafbe28877889153ad8273de6ef00c76 Mon Sep 17 00:00:00 2001 From: Brett Date: Thu, 20 Apr 2023 14:56:13 -0400 Subject: [PATCH] fix string message sending, added ack to all messages, fix sync issue --- .../src/ca/cosc3p91/a4/game/GameEngine.java | 2 + .../ca/cosc3p91/a4/util/network/Client.java | 43 ++++++++++++++----- .../cosc3p91/a4/util/network/PacketTable.java | 2 +- .../ca/cosc3p91/a4/util/network/Server.java | 23 +++++----- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java index b5240df..ae9ea89 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java +++ b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java @@ -150,6 +150,8 @@ public class GameEngine { public synchronized boolean build (Map map, String buildingArg) { BuildingFactory bfactory = new BuildingFactory(); Building type = bfactory.getBuilding(buildingArg); + if (type == null) + return false; return map.build(new Tile(), type); } diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java index 558018e..5b63458 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java @@ -9,35 +9,50 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; public class Client implements Runnable { private GameDisplay view = new GameDisplay(); private DatagramSocket clientSocket; - private boolean running = true; + private volatile boolean running = true; private Thread receiveThread; - private final HashMap sentMessages = new HashMap<>(); + private final Map sentMessages = Collections.synchronizedMap(new HashMap<>()); private int lastMessageID = 0; private final InetAddress serverAddress; + private long ourClientID = 0; + public Client(String address) throws IOException { serverAddress = InetAddress.getByName(address); clientSocket = new DatagramSocket(); receiveThread = new Thread(this); receiveThread.start(); - sendMessage(new Message.Sent(PacketTable.CONNECT, 0, ++lastMessageID)); + sendMessage(new Message.Sent(PacketTable.CONNECT, ourClientID, ++lastMessageID)); while (running) { String prompt; if ((prompt = view.nextInput()) != null) { if (prompt.trim().isEmpty()) continue; - if (prompt.charAt(0) == '6') + if (prompt.charAt(0) == '6') { + running = false; break; + } + view.printGameMenu(); + String[] args = prompt.split(" "); + char c = prompt.charAt(0); + if (c > '0' && c < '4') { + if (args.length < 2) { + System.err.println("Args must include type!"); + continue; + } + } byte messageType; - switch (prompt.charAt(0)) { + switch (c) { case '1': messageType = PacketTable.BUILD; break; @@ -47,15 +62,16 @@ public class Client implements Runnable { case '3': messageType = PacketTable.UPGRADE; break; + case '5': + messageType = PacketTable.PRINT_MAP_DATA; + break; default: System.err.println("> Invalid command input!"); return; } - Message.Sent buildMessage = new Message.Sent(messageType,0,++lastMessageID); - buildMessage.getData().write(prompt.substring(1).getBytes()); + Message.Sent buildMessage = new Message.Sent(messageType,ourClientID,++lastMessageID); + buildMessage.getWriter().writeUTF(prompt.substring(1)); sendMessage(buildMessage); - - view.printGameMenu(); } ArrayList removes = new ArrayList<>(); for (HashMap.Entry message : sentMessages.entrySet()){ @@ -89,6 +105,8 @@ public class Client implements Runnable { switch (packetID) { case PacketTable.ACK: + if (ourClientID == 0) + ourClientID = clientID; Message.Sent message = sentMessages.get(messageID); if (message == null) throw new RuntimeException("Server acknowledged a message we never sent! (" + messageID + ")"); @@ -99,11 +117,16 @@ public class Client implements Runnable { for (HashMap.Entry ms : sentMessages.entrySet()) System.out.println("MessageID: " + ms.getKey()); break; + case PacketTable.MESSAGE: + System.out.println(stream.readUTF()); + break; case PacketTable.DISCONNECT: running = false; break; } - + if (packetID != PacketTable.ACK && packetID != PacketTable.DISCONNECT){ + sendMessage(new Message.Sent(PacketTable.ACK, ourClientID, messageID)); + } } catch (Exception e){ e.printStackTrace(); } diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java index eab7859..ca3d279 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java @@ -23,6 +23,6 @@ public class PacketTable { // messageHeader, upgrade public static final byte UPGRADE = 0x7; // messageHeader, serial packets with map info - public static final byte USER_MAP_DATA = 0x8; + public static final byte PRINT_MAP_DATA = 0x8; } diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java index 52cb271..ed18178 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java @@ -9,10 +9,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.rmi.ServerException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.PriorityQueue; -import java.util.Queue; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; @@ -55,7 +52,7 @@ public class Server implements Runnable { long clientID = stream.readLong(); long messageID = stream.readLong(); - System.out.println("Receiving message with ID " + messageID + " to client: " + clientID + " of type " + packetID); + System.out.println("Receiving message with ID " + messageID + " from client: " + clientID + " of type " + packetID); ConnectedClient client = clients.get(clientID); @@ -67,7 +64,7 @@ public class Server implements Runnable { continue; } if (client == null) - throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")"); + throw new ServerException("Client sent message invalid client id! (" + clientID + ")"); if (packetID == PacketTable.DISCONNECT) { client.halt(); clients.remove(clientID); @@ -95,7 +92,7 @@ public class Server implements Runnable { private final Queue pendingRequests = new PriorityQueue<>(); private final ReentrantLock requestLock = new ReentrantLock(); private final AtomicBoolean allowUpdate; - private final HashMap sentMessages = new HashMap<>(); + private final java.util.Map sentMessages = Collections.synchronizedMap(new HashMap<>()); private final DatagramSocket serverSocket; private final long clientID; private volatile boolean running = true; @@ -148,16 +145,20 @@ public class Server implements Runnable { System.out.println(request.getReader().readUTF()); break; case PacketTable.BUILD: - usingEngine.build(clientMap,new String(request.getData(), StandardCharsets.UTF_8)); + if (usingEngine.build(clientMap, request.getReader().readUTF())){ + System.out.println("Client " + clientID + " has built something!"); + } else { + System.out.println("Client " + clientID + " failed to build!"); + } break; case PacketTable.TRAIN: - usingEngine.train(clientMap,new String(request.getData(), StandardCharsets.UTF_8)); + usingEngine.train(clientMap, request.getReader().readUTF()); break; case PacketTable.UPGRADE: - usingEngine.upgradeBuilding(clientMap, ByteBuffer.wrap(request.getData()).getInt()); + usingEngine.upgradeBuilding(clientMap, Integer.parseInt(request.getReader().readUTF())); break; - } + sendMessage(new Message.Sent(PacketTable.ACK, clientID, request.getMessageID())); } catch (Exception e) { throw new RuntimeException(e); }