public Message onExceptionThrown(Message message, InetSocketAddress destinationAddress) { boolean gsAvailable = checkBFFailures(destinationAddress); MessageRequest request = (MessageRequest) message.get("request"); switch (request) { case disconnectedBF: if (gsAvailable) return message; break; case disconnectedUnit: if (gsAvailable) return message; break; case gameState: Unit u; synchronized (this) { u = units.remove(destinationAddress); map[u.getX()][u.getY()] = null; } Integer[] tempClock = vClock.incrementClock(id); LogEntry entry = new LogEntry(tempClock, LogEntryType.DISCONNECTED_UNIT, destinationAddress); logger.writeAsText(entry, true); Message replyMessage = new Message(); replyMessage.put("request", MessageRequest.disconnectedUnit); replyMessage.put("unitAddress", destinationAddress); replyMessage.put("vclock", tempClock); synchronizeWithAllBF(replyMessage); break; default: break; } return null; }
private void sendSyncMessage(Message message) { SynchronizedClientSocket clientSocket; message.put("sync", (Boolean) true); message.put("serverAddress", new InetSocketAddress(url, port)); message.put("serverMessageID", localMessageCounter); for (InetSocketAddress address : battlefields.keySet()) { if (address.equals(new InetSocketAddress(url, port))) continue; clientSocket = new SynchronizedClientSocket(message, address, this); clientSocket.sendMessage(); } }
private void sendActionAck( Message message, boolean valid, Integer messageID, InetSocketAddress address) { Message toSend = new Message(); toSend = message.clone(); toSend.put("request", MessageRequest.SyncActionResponse); toSend.put("serverAddress", (InetSocketAddress) new InetSocketAddress(url, port)); toSend.put("ack", (Boolean) valid); SynchronizedClientSocket socket = new SynchronizedClientSocket(toSend, address, this); socket.sendMessage(); }
BattleField(int id, String url, int port, String otherUrl, int otherPort, boolean restart) { battlefields = new HashMap<InetSocketAddress, Integer>(); this.url = url; this.port = port; this.id = id; this.restart = restart; battlefields.put(new InetSocketAddress(url, port), 0); initBattleField(restart); Message message = new Message(); message.put("request", MessageRequest.requestBFList); message.put("bfAddress", new InetSocketAddress(url, port)); SynchronizedClientSocket clientSocket; clientSocket = new SynchronizedClientSocket(message, new InetSocketAddress(otherUrl, otherPort), this); clientSocket.sendMessageWithResponse(); }
private synchronized Message processConfirmMessage(Message msg) { // Write to log; Integer messageID = (Integer) msg.get("serverMessageID"); // System.out.println("[S"+port+"] MessageID "+messageID+" Address // "+(InetSocketAddress)msg.get("serverAddress")+"\nOutsideSize // "+pendingOutsideActions.size()+"\n[S"+port+"]"+pendingOutsideActions); ActionInfo removeAction = pendingOutsideActions.remove( new ActionID(messageID, (InetSocketAddress) msg.get("serverAddress"))); if (removeAction != null) { removeAction.timer.cancel(); // System.out.println("[S"+port+"] OutsideSize "+pendingOutsideActions.size()+" Confirm = // "+(Boolean)msg.get("confirm")+" RemoveAction Request: // "+removeAction.message.get("request")); if ((Boolean) msg.get("confirm")) processEvent(msg, removeAction); } return null; }
/** * @param message * @return true if message is already a sync message, or false if the if it was not a sync message * and it was propagated. */ private boolean syncBF(Message message) { for (InetSocketAddress address : battlefields.keySet()) { if (address.equals(new InetSocketAddress(url, port))) continue; message.put("sync", (Boolean) true); String s = "[S" + port + "] SENDING SYNC MESSAGE\nBefore change: " + message.get("address") + "\nAfter Change: "; message.put("address", new InetSocketAddress(url, port)); s += message.get("address"); // System.out.println(s); // System.out.println("####################"); SynchronizedClientSocket clientSocket; clientSocket = new SynchronizedClientSocket(message, address, this); clientSocket.sendMessage(); // messageList.put(message, 0); } return false; }
private synchronized boolean checkBFFailures(InetSocketAddress destinationAddress) { Integer failures = battlefields.get(destinationAddress); if (failures != null) { if (failures > 1) { battlefields.remove(destinationAddress); // Remove all Units connected to this battleField for (Map.Entry<InetSocketAddress, Unit> entry : units.entrySet()) { if (entry.getValue().getBattlefieldAddress().equals(destinationAddress)) { removeUnit(entry.getValue().getX(), entry.getValue().getY()); } } Message message = new Message(); message.put("request", MessageRequest.disconnectedBF); message.put("serverAddress", new InetSocketAddress(url, port)); message.put("vclock", vClock.incrementClock(id)); synchronizeWithAllBF(message); return false; } else { battlefields.put(destinationAddress, failures + 1); } } return false; }
private synchronized void processSyncMessage(Message msg) { MessageRequest request = (MessageRequest) msg.get("request"); Integer messageID = (Integer) msg.get("serverMessageID"); // InetSocketAddress originAddress = (InetSocketAddress)msg.get("address"); InetSocketAddress serverAddress = (InetSocketAddress) msg.get("serverAddress"); Integer x = (Integer) msg.get("x"); Integer y = (Integer) msg.get("y"); msg.put("sync", (Boolean) false); // System.out.println("[S"+port+"] Process Sync Message from "+serverAddress.getPort()+"\n // Message "+request.name()+" with X="+x+"|Y="+y); boolean conflictFound = false; Set<InetSocketAddress> toRemoveTemp = new HashSet<InetSocketAddress>(); switch (request) { case spawnUnit: if (getUnit(x, y) == null) { for (ActionInfo info : pendingOwnActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit || actionType == MessageRequest.spawnUnit) { if (x.equals((Integer) info.message.get("x")) && y.equals((Integer) info.message.get("y"))) { // sendActionAck(msg, false, messageID, originAddress); conflictFound = true; break; } } } for (ActionInfo info : pendingOutsideActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit || actionType == MessageRequest.spawnUnit) { if (x.equals((Integer) info.message.get("x")) && y.equals((Integer) info.message.get("y"))) { // sendActionAck(msg, false, messageID, originAddress); conflictFound = true; break; } } } } else { conflictFound = true; } if (conflictFound) { sendActionAck(msg, false, messageID, serverAddress); } else { addPendingOutsideAction(msg, messageID, serverAddress); sendActionAck(msg, true, messageID, serverAddress); } break; case moveUnit: if (getUnit(x, y) == null) { Unit unit = units.get((InetSocketAddress) msg.get("address")); if (unit == null) break; if (!((Math.abs(unit.getX() - x) <= 1 && Math.abs(unit.getY() - y) == 0) || (Math.abs(unit.getY() - y) <= 1 && Math.abs(unit.getX() - x) == 0))) { conflictFound = true; } for (ActionInfo info : pendingOwnActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit || actionType == MessageRequest.spawnUnit) { if (x.equals((Integer) info.message.get("x")) && y.equals((Integer) info.message.get("y"))) { conflictFound = true; break; } } else if (actionType == MessageRequest.healDamage || actionType == MessageRequest.dealDamage) { if (unit.getX().equals((Integer) info.message.get("x")) && unit.getY().equals((Integer) info.message.get("y"))) { toRemoveTemp.add((InetSocketAddress) info.message.get("serverAddress")); } } } for (ActionInfo info : pendingOutsideActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit || actionType == MessageRequest.spawnUnit) { if (x.equals((Integer) info.message.get("x")) && y.equals((Integer) info.message.get("y"))) { conflictFound = true; break; } } } } else { conflictFound = true; } if (conflictFound) { sendActionAck(msg, false, messageID, serverAddress); } else { for (InetSocketAddress addressToRemove : toRemoveTemp) { ActionInfo info = pendingOwnActions.remove(addressToRemove); if (info != null) info.timer.cancel(); } addPendingOutsideAction(msg, messageID, serverAddress); sendActionAck(msg, true, messageID, serverAddress); } break; case dealDamage: case healDamage: if (getUnit(x, y) != null) { for (ActionInfo info : pendingOwnActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit) { Unit infoUnit = units.get((InetSocketAddress) info.message.get("address")); if (x.equals(infoUnit.getX()) && y.equals(infoUnit.getY())) { conflictFound = true; break; } } } for (ActionInfo info : pendingOutsideActions.values()) { MessageRequest actionType = (MessageRequest) info.message.get("request"); if (actionType == MessageRequest.moveUnit) { Unit infoUnit = units.get((InetSocketAddress) info.message.get("address")); if (x.equals(infoUnit.getX()) && y.equals(infoUnit.getY())) { conflictFound = true; break; } } } } else { conflictFound = true; } if (conflictFound) { sendActionAck(msg, false, messageID, serverAddress); } else { for (InetSocketAddress addressToRemove : toRemoveTemp) { pendingOwnActions.remove(addressToRemove).timer.cancel(); } addPendingOutsideAction(msg, messageID, serverAddress); sendActionAck(msg, true, messageID, serverAddress); } break; } }
private synchronized Message processResponseMessage(Message msg) { Integer messageID = (Integer) msg.get("serverMessageID"); ActionInfo actionInfo = pendingOwnActions.get(messageID); InetSocketAddress serverAddress = (InetSocketAddress) msg.get("serverAddress"); Message message = msg.clone(); message.put("request", MessageRequest.SyncActionConfirm); message.put("serverAddress", new InetSocketAddress(url, port)); message.put("serverMessageID", messageID); if (actionInfo != null) { if ((Boolean) msg.get("ack")) { // System.out.println("[S"+port+"] "+actionInfo.message.get("address")+" ACK TRUE from // "+serverAddress.getHostName()+":"+serverAddress.getPort()+" Adding info to queue."); actionInfo.ackReceived.add((InetSocketAddress) msg.get("serverAddress")); if (actionInfo.ackReceived.size() == battlefields.size() - 1) { message.put("confirm", true); Integer[] tempClock = vClock.incrementClock(id); // System.out.println("<"+url+":"+port+"> Clock added when action is ready to ship --> // "+toStringArray(tempClock)); message.put("vclock", tempClock); for (InetSocketAddress address : actionInfo.ackReceived) { SynchronizedClientSocket clientSocket = new SynchronizedClientSocket(message, address, this); clientSocket.sendMessage(); } ActionInfo removeAction = pendingOwnActions.remove(messageID); removeAction.timer.cancel(); msg.put("vclock", tempClock); Message toPlayer = processEvent(message, removeAction); if (toPlayer != null) { SynchronizedClientSocket clientSocket = new SynchronizedClientSocket( toPlayer, (InetSocketAddress) msg.get("address"), this); clientSocket.sendMessage(); } } } else { pendingOwnActions.remove(messageID).timer.cancel(); message.put("confirm", false); SynchronizedClientSocket clientSocket = new SynchronizedClientSocket(message, serverAddress, this); clientSocket.sendMessage(); } } else { message.put("confirm", false); SynchronizedClientSocket clientSocket = new SynchronizedClientSocket(message, serverAddress, this); clientSocket.sendMessage(); } return null; }
private Message processEvent(Message msg, ActionInfo removeAction) { Unit unit = null; LogEntry entry; Integer[] tempClock; switch ((MessageRequest) removeAction.message.get("request")) { case spawnUnit: { // System.out.println("BATTLE FIELD:Spawn" + port); // System.out.println(battlefields.toString()); Boolean succeded = this.spawnUnit( (Unit) msg.get("unit"), (InetSocketAddress) msg.get("address"), (Integer) msg.get("x"), (Integer) msg.get("y")); if (succeded) { units.put((InetSocketAddress) msg.get("address"), (Unit) msg.get("unit")); } Message reply = new Message(); reply.put("request", MessageRequest.spawnAck); reply.put("succeded", succeded); reply.put("gamestate", map); // Puts position of the unit we are sending to in the map we are sending Unit u = units.get((InetSocketAddress) msg.get("address")); reply.put("unit", u); tempClock = ((Integer[]) msg.get("vclock")).clone(); entry = new LogEntry( tempClock, LogEntryType.SPAWN, (InetSocketAddress) msg.get("address"), new Position((Integer) msg.get("x"), (Integer) msg.get("y"))); logger.writeAsText(entry, true); if (!((InetSocketAddress) msg.get("serverAddress")) .equals(new InetSocketAddress(url, port))) { // System.out.println("<"+url+":"+port+"> Spawn will be processed --> // "+toStringArray(tempClock)); vClock.updateClock(tempClock); } return reply; } case dealDamage: { int x = (Integer) msg.get("x"); int y = (Integer) msg.get("y"); unit = this.getUnit(x, y); if (unit != null) { unit.adjustHitPoints(-(Integer) msg.get("damage")); Unit attackingUnit = (Unit) msg.get("unit"); // System.out.println(attackingUnit); entry = new LogEntry( (Integer[]) msg.get("vclock"), LogEntryType.ATACK, (InetSocketAddress) msg.get("address"), new Position(attackingUnit.getX(), attackingUnit.getY()), new Position(x, y), (Integer) msg.get("damage")); logger.writeAsText(entry, true); if (!((InetSocketAddress) msg.get("serverAddress")) .equals(new InetSocketAddress(url, port))) { vClock.updateClock((Integer[]) msg.get("vclock")); } if (unit.getHitPoints() <= 0) { removeUnit(x, y); // Log remove unit // Should we log with same clock as deal damage that cause it? entry = new LogEntry( vClock.getClock(), LogEntryType.REMOVE, (InetSocketAddress) msg.get("address"), new Position((Integer) msg.get("x"), (Integer) msg.get("y"))); logger.writeAsText(entry, true); } } break; } case healDamage: { int x = (Integer) msg.get("x"); int y = (Integer) msg.get("y"); unit = this.getUnit(x, y); if (unit != null) unit.adjustHitPoints((Integer) msg.get("healed")); /* Copy the id of the message so that the unit knows * what message the battlefield responded to. */ Unit attackingUnit = (Unit) msg.get("unit"); entry = new LogEntry( (Integer[]) msg.get("vclock"), LogEntryType.HEAL, (InetSocketAddress) msg.get("address"), new Position(attackingUnit.getX(), attackingUnit.getY()), new Position((Integer) msg.get("x"), (Integer) msg.get("y")), (Integer) msg.get("healed")); logger.writeAsText(entry, true); if (!((InetSocketAddress) msg.get("serverAddress")) .equals(new InetSocketAddress(url, port))) { vClock.updateClock((Integer[]) msg.get("vclock")); } break; } case moveUnit: { // System.out.println("BATTLEFIELD: MOVEUNIT"); Unit tempUnit = units.get((InetSocketAddress) msg.get("address")); int x = tempUnit.getX(); int y = tempUnit.getY(); /* if(temptUnit == null) { System.out.println("NULL"); }*/ boolean move = this.moveUnit(tempUnit, (Integer) msg.get("x"), (Integer) msg.get("y")); if (!move) System.out.println("MOVE CANCELED"); entry = new LogEntry( (Integer[]) msg.get("vclock"), LogEntryType.MOVE, (InetSocketAddress) msg.get("address"), new Position(x, y), new Position((Integer) msg.get("x"), (Integer) msg.get("y"))); logger.writeAsText(entry, true); if (!((InetSocketAddress) msg.get("serverAddress")) .equals(new InetSocketAddress(url, port))) { vClock.updateClock((Integer[]) msg.get("vclock")); } /* Copy the id of the message so that the unit knows * what message the battlefield responded to. */ break; } default: break; } return null; }
public Message onMessageReceived(Message msg) { // System.out.println("MESSAGE RECEIVED:" + msg.get("request")); // System.out.println("MESSAGE RECEIVED " + (MessageRequest)msg.get("request")); if ((Boolean) msg.get("sync") != null && (Boolean) msg.get("sync") == true) { // System.out.println("SYNC MESSAGE RECEIVED " + (MessageRequest)msg.get("request")); processSyncMessage(msg); } else { MessageRequest request = (MessageRequest) msg.get("request"); Message reply = null; String origin = (String) msg.get("origin"); Unit unit; Integer[] tempClock; Message replyMessage; LogEntry entry; switch (request) { case disconnectedUnit: Unit u; synchronized (this) { u = units.remove((InetSocketAddress) msg.get("unitAddress")); if (u != null) map[u.getX()][u.getY()] = null; } tempClock = ((Integer[]) msg.get("vclock")).clone(); entry = new LogEntry( tempClock, LogEntryType.DISCONNECTED_UNIT, (InetSocketAddress) msg.get("serverAddress")); logger.writeAsText(entry, true); replyMessage = new Message(); replyMessage.put("request", MessageRequest.disconnectedUnitAck); replyMessage.put("serverAddress", new InetSocketAddress(url, port)); SynchronizedClientSocket client = new SynchronizedClientSocket( replyMessage, (InetSocketAddress) msg.get("serverAddress"), this); client.sendMessage(); break; case disconnectedBF: tempClock = ((Integer[]) msg.get("vclock")).clone(); entry = new LogEntry( tempClock, LogEntryType.DISCONNECTED_BF, (InetSocketAddress) msg.get("serverAddress")); logger.writeAsText(entry, true); replyMessage = new Message(); replyMessage.put("request", MessageRequest.disconnectedBFAck); replyMessage.put("serverAddress", new InetSocketAddress(url, port)); SynchronizedClientSocket syncClient = new SynchronizedClientSocket( replyMessage, (InetSocketAddress) msg.get("serverAddress"), this); syncClient.sendMessage(); break; case spawnUnit: case moveUnit: case dealDamage: case healDamage: syncActionWithBattlefields(msg); break; case requestBFList: { reply = new Message(); reply.put("request", MessageRequest.replyBFList); battlefields.put((InetSocketAddress) msg.get("bfAddress"), 0); reply.put("bfList", battlefields); return reply; } case replyBFList: { HashMap<InetSocketAddress, Integer> bfList = (HashMap<InetSocketAddress, Integer>) msg.get("bfList"); for (InetSocketAddress address : bfList.keySet()) { battlefields.put(address, 0); } for (InetSocketAddress address : battlefields.keySet()) { SynchronizedClientSocket clientSocket; Message message = new Message(); message.put("request", MessageRequest.addBF); message.put("bfAddress", new InetSocketAddress(url, port)); clientSocket = new SynchronizedClientSocket(message, address, this); clientSocket.sendMessage(); } // System.out.println("BATTLEFIELDS:"+ bfList.toString()); // reply = new Message(); // HashSet bfList = (HashSet<InetSocketAddress>)msg.get("bfList"); // int y = (Integer)msg.get("y"); // reply.put("id", msg.get("id")); return null; } case addBF: { battlefields.put((InetSocketAddress) msg.get("bfAddress"), 0); // System.out.println("ADD BF:"+ battlefields.toString()); return null; } // break; // case removeUnit: // this.removeUnit((Integer)msg.get("x"), (Integer)msg.get("y")); // if(syncBF(msg)) return null; case SyncActionResponse: processResponseMessage(msg); break; case SyncActionConfirm: return processConfirmMessage(msg); } } return null; // serverSocket.sendMessage(reply, origin); /* try { if (reply != null) serverSocket.sendMessage(reply, origin); } /*catch(IDNotAssignedException idnae) { // Could happen if the target already logged out }*/ }