better map messaging
parent
c106cca6b1
commit
941aa58576
|
@ -6,7 +6,7 @@ import java.io.*;
|
|||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Client gameClient = new Client("localhost");
|
||||
new Client("localhost");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public class GameDisplay {
|
|||
Integer.toString(map.getTownHall().getGoldCapacity()),
|
||||
Integer.toString(map.getTownHall().getCurrentGold())));
|
||||
|
||||
Print.print(resourcesPrinter.createTable(true, false, true));
|
||||
ArrayList<String> total = new ArrayList<>(resourcesPrinter.createTable(true, false, true));
|
||||
|
||||
Print buildingPrinter = new Print("Village Buildings", 2, resourcesPrinter.getWidth());
|
||||
buildingPrinter.addColumn(new Print.Column("Name"));
|
||||
|
@ -65,7 +65,7 @@ public class GameDisplay {
|
|||
Integer.toString(b.getLevel() + 1),
|
||||
Integer.toString(b.getHealth())));
|
||||
|
||||
Print.print(buildingPrinter.createTable(true, false, true));
|
||||
total.addAll(buildingPrinter.createTable(true, false, true));
|
||||
|
||||
Print inhabs = new Print("Village Inhabitants", 2, buildingPrinter.getWidth());
|
||||
inhabs.addColumn(new Print.Column("Name"));
|
||||
|
@ -74,7 +74,11 @@ public class GameDisplay {
|
|||
for (Inhabitant i : map.inhabitants)
|
||||
inhabs.addRow(new Print.Row(i.getClass().getSimpleName(), Integer.toString(i.getLevel() + 1)));
|
||||
|
||||
return inhabs.createTable(true, true, true);
|
||||
total.addAll(inhabs.createTable(true, true, true));
|
||||
System.out.println(buildingPrinter.getWidth());
|
||||
System.out.println(resourcesPrinter.getWidth());
|
||||
System.out.println(inhabs.getWidth());
|
||||
return total;
|
||||
}
|
||||
|
||||
public void printVillageState(Map map, String displayName) {
|
||||
|
|
|
@ -22,6 +22,9 @@ public class Client implements Runnable {
|
|||
private final Map<Long, Message.Sent> sentMessages = Collections.synchronizedMap(new HashMap<>());
|
||||
private int lastMessageID = 0;
|
||||
private final InetAddress serverAddress;
|
||||
private String[] lineBuffer = new String[0];
|
||||
private int expectedLines = 0;
|
||||
private int currentLines = 0;
|
||||
|
||||
private long ourClientID = 0;
|
||||
|
||||
|
@ -120,7 +123,23 @@ public class Client implements Runnable {
|
|||
case PacketTable.MESSAGE:
|
||||
System.out.println(stream.readUTF());
|
||||
break;
|
||||
case PacketTable.BEGIN_MAP_DATA:
|
||||
expectedLines = stream.readInt();
|
||||
currentLines = 0;
|
||||
lineBuffer = new String[expectedLines];
|
||||
break;
|
||||
case PacketTable.MAP_LINE_DATA:
|
||||
int lineNumber = stream.readInt();
|
||||
lineBuffer[lineNumber] = stream.readUTF();
|
||||
currentLines++;
|
||||
if (currentLines >= expectedLines) {
|
||||
for (String line : lineBuffer){
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PacketTable.DISCONNECT:
|
||||
System.out.println("Disconnecting!");
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@ public class PacketTable {
|
|||
public static final byte TRAIN = 0x6;
|
||||
// messageHeader, upgrade
|
||||
public static final byte UPGRADE = 0x7;
|
||||
// messageHeader, serial packets with map info
|
||||
public static final byte PRINT_MAP_DATA = 0x8;
|
||||
|
||||
// messageHeader
|
||||
public static final byte PRINT_MAP_DATA = 0x8; // client -> server only!
|
||||
// messageHeader, line count
|
||||
public static final byte BEGIN_MAP_DATA = 0x9; // server -> client
|
||||
// messageHeader, line number (int), UTF8 String (the line)
|
||||
public static final byte MAP_LINE_DATA = 0xA; // server -> client
|
||||
}
|
||||
|
|
|
@ -143,6 +143,9 @@ public class Server implements Runnable {
|
|||
throw new RuntimeException("A message was acknowledged but does not exist!");
|
||||
message.acknowledged();
|
||||
sentMessages.remove(request.getMessageID());
|
||||
synchronized (sentMessages) {
|
||||
sentMessages.notifyAll();
|
||||
}
|
||||
break;
|
||||
case PacketTable.MESSAGE:
|
||||
System.out.println(request.getReader().readUTF());
|
||||
|
@ -165,7 +168,7 @@ public class Server implements Runnable {
|
|||
usingEngine.upgradeBuilding(clientMap, Integer.parseInt(request.getReader().readUTF()));
|
||||
break;
|
||||
case PacketTable.PRINT_MAP_DATA:
|
||||
usingEngine.view.getVillageStateTable(clientMap, "Home Village").forEach(this::sendMessageLn);
|
||||
sendMapData(usingEngine.view.getVillageStateTable(clientMap, "Home Village"));
|
||||
break;
|
||||
}
|
||||
if (request.getPacketID() != PacketTable.ACK)
|
||||
|
@ -187,35 +190,70 @@ public class Server implements Runnable {
|
|||
}
|
||||
requestLock.unlock();
|
||||
|
||||
ArrayList<Long> removes = new ArrayList<>();
|
||||
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
||||
Message.Sent sent = message.getValue();
|
||||
if (!sent.isAcknowledged() && sent.getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
||||
System.out.println("The client did not acknowledge our message, did they receive it?");
|
||||
sendMessage(sent);
|
||||
removes.add(message.getKey());
|
||||
// sentEntries needn't be in the synchronized block
|
||||
Set<HashMap.Entry<Long, Message.Sent>> sentEntries = sentMessages.entrySet();
|
||||
synchronized (sentMessages) {
|
||||
ArrayList<Long> removes = new ArrayList<>();
|
||||
for (HashMap.Entry<Long, Message.Sent> message : sentEntries) {
|
||||
Message.Sent sent = message.getValue();
|
||||
if (!sent.isAcknowledged() && sent.getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
||||
System.out.println("The client did not acknowledge our message, did they receive it?");
|
||||
sendMessage(sent);
|
||||
removes.add(message.getKey());
|
||||
}
|
||||
}
|
||||
for (Long l : removes)
|
||||
sentMessages.remove(l);
|
||||
}
|
||||
for (Long l : removes)
|
||||
sentMessages.remove(l);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessageLn(String str) {
|
||||
private void sendMapData(ArrayList<String> lines) {
|
||||
final long messageID = ++lastSentMessageID;
|
||||
Message.Sent beginMapInfoMessage = new Message.Sent(PacketTable.BEGIN_MAP_DATA, clientID, messageID);
|
||||
try {
|
||||
beginMapInfoMessage.getWriter().writeInt(lines.size());
|
||||
sendMessage(beginMapInfoMessage);
|
||||
} catch (IOException e) {
|
||||
sendAndLogLn("Unable to send map data: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
new Thread(() -> {
|
||||
while (sentMessages.containsKey(messageID)){
|
||||
try {
|
||||
synchronized (sentMessages) {
|
||||
sentMessages.wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// once we know that the client is waiting on our map data, we can send it in any order.
|
||||
for (int i = 0; i < lines.size(); i++){
|
||||
Message.Sent line = new Message.Sent(PacketTable.MAP_LINE_DATA, clientID, ++lastSentMessageID);
|
||||
try {
|
||||
// but we need the line index!
|
||||
line.getWriter().writeInt(i);
|
||||
line.getWriter().writeUTF(lines.get(i));
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
sendMessage(line);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sendAndLogLn(String str){
|
||||
Message.Sent mess = new Message.Sent(PacketTable.MESSAGE, clientID, ++lastSentMessageID);
|
||||
try {
|
||||
mess.getWriter().writeUTF(str + "\n");
|
||||
sendMessage(mess);
|
||||
System.out.println(str);
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendAndLogLn(String str){
|
||||
sendMessageLn(str);
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
|
||||
public void sendMessage(Message.Sent message){
|
||||
if (message.getPacketID() != PacketTable.ACK)
|
||||
|
|
Loading…
Reference in New Issue