fix string message sending, added ack to all messages, fix sync issue
parent
fc0981852a
commit
24708a2fda
|
@ -150,6 +150,8 @@ public class GameEngine {
|
||||||
public synchronized boolean build (Map map, String buildingArg) {
|
public synchronized boolean build (Map map, String buildingArg) {
|
||||||
BuildingFactory bfactory = new BuildingFactory();
|
BuildingFactory bfactory = new BuildingFactory();
|
||||||
Building type = bfactory.getBuilding(buildingArg);
|
Building type = bfactory.getBuilding(buildingArg);
|
||||||
|
if (type == null)
|
||||||
|
return false;
|
||||||
return map.build(new Tile(), type);
|
return map.build(new Tile(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,35 +9,50 @@ import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Client implements Runnable {
|
public class Client implements Runnable {
|
||||||
private GameDisplay view = new GameDisplay();
|
private GameDisplay view = new GameDisplay();
|
||||||
|
|
||||||
private DatagramSocket clientSocket;
|
private DatagramSocket clientSocket;
|
||||||
private boolean running = true;
|
private volatile boolean running = true;
|
||||||
private Thread receiveThread;
|
private Thread receiveThread;
|
||||||
private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
|
private final Map<Long, Message.Sent> sentMessages = Collections.synchronizedMap(new HashMap<>());
|
||||||
private int lastMessageID = 0;
|
private int lastMessageID = 0;
|
||||||
private final InetAddress serverAddress;
|
private final InetAddress serverAddress;
|
||||||
|
|
||||||
|
private long ourClientID = 0;
|
||||||
|
|
||||||
public Client(String address) throws IOException {
|
public Client(String address) throws IOException {
|
||||||
serverAddress = InetAddress.getByName(address);
|
serverAddress = InetAddress.getByName(address);
|
||||||
clientSocket = new DatagramSocket();
|
clientSocket = new DatagramSocket();
|
||||||
receiveThread = new Thread(this);
|
receiveThread = new Thread(this);
|
||||||
receiveThread.start();
|
receiveThread.start();
|
||||||
|
|
||||||
sendMessage(new Message.Sent(PacketTable.CONNECT, 0, ++lastMessageID));
|
sendMessage(new Message.Sent(PacketTable.CONNECT, ourClientID, ++lastMessageID));
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
String prompt;
|
String prompt;
|
||||||
if ((prompt = view.nextInput()) != null) {
|
if ((prompt = view.nextInput()) != null) {
|
||||||
if (prompt.trim().isEmpty())
|
if (prompt.trim().isEmpty())
|
||||||
continue;
|
continue;
|
||||||
if (prompt.charAt(0) == '6')
|
if (prompt.charAt(0) == '6') {
|
||||||
|
running = false;
|
||||||
break;
|
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;
|
byte messageType;
|
||||||
switch (prompt.charAt(0)) {
|
switch (c) {
|
||||||
case '1':
|
case '1':
|
||||||
messageType = PacketTable.BUILD;
|
messageType = PacketTable.BUILD;
|
||||||
break;
|
break;
|
||||||
|
@ -47,15 +62,16 @@ public class Client implements Runnable {
|
||||||
case '3':
|
case '3':
|
||||||
messageType = PacketTable.UPGRADE;
|
messageType = PacketTable.UPGRADE;
|
||||||
break;
|
break;
|
||||||
|
case '5':
|
||||||
|
messageType = PacketTable.PRINT_MAP_DATA;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
System.err.println("> Invalid command input!");
|
System.err.println("> Invalid command input!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Message.Sent buildMessage = new Message.Sent(messageType,0,++lastMessageID);
|
Message.Sent buildMessage = new Message.Sent(messageType,ourClientID,++lastMessageID);
|
||||||
buildMessage.getData().write(prompt.substring(1).getBytes());
|
buildMessage.getWriter().writeUTF(prompt.substring(1));
|
||||||
sendMessage(buildMessage);
|
sendMessage(buildMessage);
|
||||||
|
|
||||||
view.printGameMenu();
|
|
||||||
}
|
}
|
||||||
ArrayList<Long> removes = new ArrayList<>();
|
ArrayList<Long> removes = new ArrayList<>();
|
||||||
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
||||||
|
@ -89,6 +105,8 @@ public class Client implements Runnable {
|
||||||
|
|
||||||
switch (packetID) {
|
switch (packetID) {
|
||||||
case PacketTable.ACK:
|
case PacketTable.ACK:
|
||||||
|
if (ourClientID == 0)
|
||||||
|
ourClientID = clientID;
|
||||||
Message.Sent message = sentMessages.get(messageID);
|
Message.Sent message = sentMessages.get(messageID);
|
||||||
if (message == null)
|
if (message == null)
|
||||||
throw new RuntimeException("Server acknowledged a message we never sent! (" + messageID + ")");
|
throw new RuntimeException("Server acknowledged a message we never sent! (" + messageID + ")");
|
||||||
|
@ -99,11 +117,16 @@ public class Client implements Runnable {
|
||||||
for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet())
|
for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet())
|
||||||
System.out.println("MessageID: " + ms.getKey());
|
System.out.println("MessageID: " + ms.getKey());
|
||||||
break;
|
break;
|
||||||
|
case PacketTable.MESSAGE:
|
||||||
|
System.out.println(stream.readUTF());
|
||||||
|
break;
|
||||||
case PacketTable.DISCONNECT:
|
case PacketTable.DISCONNECT:
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (packetID != PacketTable.ACK && packetID != PacketTable.DISCONNECT){
|
||||||
|
sendMessage(new Message.Sent(PacketTable.ACK, ourClientID, messageID));
|
||||||
|
}
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,6 @@ public class PacketTable {
|
||||||
// messageHeader, upgrade
|
// messageHeader, upgrade
|
||||||
public static final byte UPGRADE = 0x7;
|
public static final byte UPGRADE = 0x7;
|
||||||
// messageHeader, serial packets with map info
|
// messageHeader, serial packets with map info
|
||||||
public static final byte USER_MAP_DATA = 0x8;
|
public static final byte PRINT_MAP_DATA = 0x8;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,7 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.rmi.ServerException;
|
import java.rmi.ServerException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.PriorityQueue;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
@ -55,7 +52,7 @@ public class Server implements Runnable {
|
||||||
long clientID = stream.readLong();
|
long clientID = stream.readLong();
|
||||||
long messageID = 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);
|
ConnectedClient client = clients.get(clientID);
|
||||||
|
|
||||||
|
@ -67,7 +64,7 @@ public class Server implements Runnable {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (client == null)
|
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) {
|
if (packetID == PacketTable.DISCONNECT) {
|
||||||
client.halt();
|
client.halt();
|
||||||
clients.remove(clientID);
|
clients.remove(clientID);
|
||||||
|
@ -95,7 +92,7 @@ public class Server implements Runnable {
|
||||||
private final Queue<Message.Received> pendingRequests = new PriorityQueue<>();
|
private final Queue<Message.Received> pendingRequests = new PriorityQueue<>();
|
||||||
private final ReentrantLock requestLock = new ReentrantLock();
|
private final ReentrantLock requestLock = new ReentrantLock();
|
||||||
private final AtomicBoolean allowUpdate;
|
private final AtomicBoolean allowUpdate;
|
||||||
private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
|
private final java.util.Map<Long, Message.Sent> sentMessages = Collections.synchronizedMap(new HashMap<>());
|
||||||
private final DatagramSocket serverSocket;
|
private final DatagramSocket serverSocket;
|
||||||
private final long clientID;
|
private final long clientID;
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
|
@ -148,16 +145,20 @@ public class Server implements Runnable {
|
||||||
System.out.println(request.getReader().readUTF());
|
System.out.println(request.getReader().readUTF());
|
||||||
break;
|
break;
|
||||||
case PacketTable.BUILD:
|
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;
|
break;
|
||||||
case PacketTable.TRAIN:
|
case PacketTable.TRAIN:
|
||||||
usingEngine.train(clientMap,new String(request.getData(), StandardCharsets.UTF_8));
|
usingEngine.train(clientMap, request.getReader().readUTF());
|
||||||
break;
|
break;
|
||||||
case PacketTable.UPGRADE:
|
case PacketTable.UPGRADE:
|
||||||
usingEngine.upgradeBuilding(clientMap, ByteBuffer.wrap(request.getData()).getInt());
|
usingEngine.upgradeBuilding(clientMap, Integer.parseInt(request.getReader().readUTF()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
sendMessage(new Message.Sent(PacketTable.ACK, clientID, request.getMessageID()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue