Пример #1
0
  /**
   * Constructor
   *
   * @param netMan the NetworkServerManager so that we can send message
   * @throws Exception in case of an unexpected error
   */
  public RPServerManager(INetworkServerManager netMan) throws Exception {
    super("RPServerManager");

    try {
      stats = Statistics.getStatistics();
      keepRunning = true;
      isfinished = false;

      scheduler = new RPScheduler();
      contentsToTransfer = new HashMap<RPObject, List<TransferContent>>();
      playerContainer = PlayerEntryContainer.getContainer();

      playersToRemove = new LinkedList<PlayerEntry>();
      this.netMan = netMan;

      Configuration conf = Configuration.getConfiguration();
      /*
       * This method loads the extensions that implement the game server
       * code.
       */
      initializeExtensions(conf);

      String duration = conf.get("turn_length");
      turnDuration = Long.parseLong(duration);
      turn = 0;
    } catch (Exception e) {
      logger.warn("ABORT: Unable to create RPZone, RPRuleProcessor or RPAIManager instances", e);
      throw e;
    }
  }
Пример #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
  @Override
  public void run() {
    try {
      long start = System.nanoTime();
      long stop;
      long delay;
      long timeStart = 0;
      long[] timeEnds = new long[12];

      while (keepRunning) {
        stop = System.nanoTime();

        logger.debug("Turn time elapsed: " + ((stop - start) / 1000) + " microsecs");
        delay = turnDuration - ((stop - start) / 1000000);
        if (delay < 0) {
          StringBuilder sb = new StringBuilder();
          for (long timeEnd : timeEnds) {
            sb.append(" " + (timeEnd - timeStart));
          }

          logger.warn("Turn duration overflow by " + (-delay) + " ms: " + sb.toString());
        } else if (delay > turnDuration) {
          logger.error(
              "Delay bigger than Turn duration. [delay: "
                  + delay
                  + "] [turnDuration:"
                  + turnDuration
                  + "]");
          delay = 0;
        }

        // only sleep when the turn delay is > 0
        if (delay > 0) {
          try {
            Thread.sleep(delay);
          } catch (InterruptedException e) {
            // ignore
          }
        }

        start = System.nanoTime();
        timeStart = System.currentTimeMillis();

        playerContainer.getLock().requestWriteLock();

        try {
          timeEnds[0] = System.currentTimeMillis();

          /* Get actions that players send */
          scheduler.nextTurn();
          timeEnds[1] = System.currentTimeMillis();

          /* Execute them all */
          scheduler.visit(ruleProcessor);
          timeEnds[2] = System.currentTimeMillis();

          /* Compute game RP rules to move to the next turn */
          ruleProcessor.endTurn();
          timeEnds[3] = System.currentTimeMillis();

          /* Send content that is waiting to players */
          deliverTransferContent();
          timeEnds[4] = System.currentTimeMillis();

          /* Tell player what happened */
          buildPerceptions();
          timeEnds[5] = System.currentTimeMillis();

          /* save players regularly to the db */
          savePlayersPeriodicly();
          timeEnds[6] = System.currentTimeMillis();

          /* Move zone to the next turn */
          world.nextTurn();
          timeEnds[7] = System.currentTimeMillis();

          turn++;

          ruleProcessor.beginTurn();
          timeEnds[8] = System.currentTimeMillis();
        } finally {
          playerContainer.getLock().releaseLock();
          timeEnds[9] = System.currentTimeMillis();
        }
        try {
          stats.set("Objects now", world.size());
        } catch (ConcurrentModificationException e) {
          // TODO: size is obviously not threadsafe as it asks the underlying zone.objects for its
          // sizes, which are not threadsafe.
        }
        timeEnds[10] = System.currentTimeMillis();
        TransactionPool.get().kickHangingTransactionsOfThisThread();
        timeEnds[11] = System.currentTimeMillis();
      }
    } catch (Throwable e) {
      logger.error("Unhandled exception, server will shut down.", e);
    } finally {
      isfinished = true;
    }
  }