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);
    }
  }
  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);
  }
 private void savePlayersPeriodicly() {
   for (PlayerEntry entry : playerContainer) {
     try {
       // do not use = 0 because we need a little time until the
       // player object is fully initialized (e. g. has a charname)
       if (entry.getThisPerceptionTimestamp() % 2000 == 1999) {
         entry.storeRPObject(entry.object);
       }
     } catch (Exception e) {
       String name = "null";
       if (entry != null) {
         name = entry.character;
       }
       logger.error("Error while storing player " + name, e);
     }
   }
 }
  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();
    }
  }
  private Perception getPlayerPerception(PlayerEntry entry) {
    Perception perception = null;

    IRPZone.ID id = new IRPZone.ID(entry.object.get("zoneid"));
    IRPZone zone = world.getRPZone(id);

    if (!(entry.requestedSync)) {
      perception = zone.getPerception(entry.object, Perception.DELTA);
    } else {
      entry.requestedSync = false;
      perception = zone.getPerception(entry.object, Perception.SYNC);
    }

    return perception;
  }