예제 #1
0
  private void buildPerceptions() {
    playersToRemove.clear();

    /** We reset the cache at Perceptions */
    MessageS2CPerception.clearPrecomputedPerception();

    for (PlayerEntry entry : playerContainer) {
      try {
        // Before creating the perception we check the player is still there.
        if (entry.isTimeout()) {
          logger.info("Request (TIMEOUT) disconnection of Player " + entry.getAddress());
          playersToRemove.add(entry);
          continue;
        }

        if (entry.state == ClientState.GAME_BEGIN) {
          Perception perception = getPlayerPerception(entry);
          sendPlayerPerception(entry, perception, entry.object);
        }
      } catch (Exception e) {
        logger.error(
            "Removing player("
                + entry.clientid
                + ") because it caused a Exception while contacting it",
            e);
        playersToRemove.add(entry);
      }
    }

    for (PlayerEntry entry : playersToRemove) {
      logger.warn("RP Disconnecting entry: " + entry);
      netMan.disconnectClient(entry.channel);
    }
  }
예제 #2
0
  private void sendPlayerPerception(
      PlayerEntry entry, Perception perception, RPObject playerObject) {
    if (perception == null) {
      /** Until player enters game perception is null */
      return;
    }

    MessageS2CPerception messages2cPerception = new MessageS2CPerception(entry.channel, perception);

    stats.add("Perceptions " + (perception.type == 0 ? "DELTA" : "SYNC"), 1);

    /*
     * The perception is build of two parts: the general information and the
     * private information about our object. This private information
     * consists only of attributes that are not visible to every player but
     * the owner, because visible attributes are already stored in the
     * perception.
     */

    if (perception.type == Perception.SYNC) {
      RPObject copy = new RPObject();
      copy.fill(playerObject);
      if (!playerObject.isHidden()) {
        copy.clearVisible(true);
      }
      messages2cPerception.setMyRPObject(copy, null);
    } else {
      RPObject added = new RPObject();
      RPObject deleted = new RPObject();

      try {
        playerObject.getDifferences(added, deleted);
        if (!playerObject.isHidden()) {
          added.clearVisible(false);
          deleted.clearVisible(false);
        }

        if (added.size() == 0) {
          added = null;
        }

        if (deleted.size() == 0) {
          deleted = null;
        }
      } catch (Exception e) {
        logger.error("Error getting object differences", e);
        logger.error(playerObject);
        added = null;
        deleted = null;
      }
      messages2cPerception.setMyRPObject(added, deleted);
    }

    messages2cPerception.setClientID(entry.clientid);
    messages2cPerception.setPerceptionTimestamp(entry.getPerceptionTimestamp());
    messages2cPerception.setProtocolVersion(entry.getProtocolVersion());

    netMan.sendMessage(messages2cPerception);
  }
예제 #3
0
  /**
   * This method disconnects a player from the server.
   *
   * @param object the player object that we want to disconnect from world
   */
  public void disconnectPlayer(RPObject object) {
    PlayerEntry entry = playerContainer.get(object);
    if (entry == null) {
      /*
       * There is no player entry for such channel This is not necesaryly
       * an error, as the connection could be anything else but an arianne
       * client or we are just disconnecting a player that logout
       * correctly.
       */
      logger.warn("There is no PlayerEntry associated to this RPObject.");
      return;
    }

    netMan.disconnectClient(entry.channel);
  }
예제 #4
0
  private void deliverTransferContent() {
    synchronized (contentsToTransfer) {
      for (Map.Entry<RPObject, List<TransferContent>> val : contentsToTransfer.entrySet()) {
        RPObject target = val.getKey();
        List<TransferContent> content = val.getValue();

        PlayerEntry entry = playerContainer.get(target);
        if (entry == null) {
          logger.warn(
              "Entry for player (" + target + ") does not exist: " + playerContainer,
              new Throwable());
          continue;
        }

        if (content == null) {
          logger.warn("content is null");
        }
        if (!entry.contentToTransfer.isEmpty()) {
          // prevent DoS if the client never confirms the Transfer offer
          if (entry.contentToTransfer.size() > 30) {
            synchronized (entry.contentToTransfer) {
              for (int i = 0; i < 10; i++) {
                entry.contentToTransfer.remove(0);
              }
            }
          }
          logger.warn(
              "Adding to existing contentToTransfer for player "
                  + entry.character
                  + " old: "
                  + entry.contentToTransfer
                  + " added "
                  + content);
        }
        entry.contentToTransfer.addAll(content);

        MessageS2CTransferREQ mes = new MessageS2CTransferREQ(entry.channel, content);
        mes.setClientID(entry.clientid);
        mes.setProtocolVersion(entry.getProtocolVersion());

        netMan.sendMessage(mes);
      }

      contentsToTransfer.clear();
    }
  }
예제 #5
0
 /**
  * This method exposes network layer connection validator so game logic can handle it.
  *
  * @return the connection validator
  */
 public ConnectionValidator getValidator() {
   return netMan.getValidator();
 }