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 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 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 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; }