예제 #1
0
  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;
  }
예제 #2
0
 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();
   }
 }
예제 #3
0
  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();
  }
예제 #4
0
  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();
  }
예제 #5
0
  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;
  }
예제 #6
0
 /**
  * @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;
 }
예제 #7
0
 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;
 }
예제 #8
0
  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;
    }
  }
예제 #9
0
  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;
  }
예제 #10
0
  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;
  }
예제 #11
0
  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
    }*/
  }