private void updateAgression() {
   Player _player = World.getPlayer(agressor);
   if (_player != null) {
     if (agressors_pet != null
         && _player.getSummonList().getPet() != null
         && _player.getSummonList().getPet().getName().equalsIgnoreCase(agressors_pet))
       AddAgression(_player.getSummonList().getPet(), 10);
     AddAgression(_player, 2);
   }
   if (agressors_party != null)
     for (String _agressor : agressors_party) AddAgression(World.getPlayer(_agressor), 1);
 }
Ejemplo n.º 2
0
  /**
   * Do the obstruction check of a tile. So this means that all tiles are hidden in case there is a
   * tile above them and they are fully invisible anyway. Tiles below the level of the player are
   * removed, since they won't be displayed ever anyway. The tiles at or above the players location
   * are possibly shown in case the char steps into a building or something.
   *
   * @param tile the tile that is checked
   * @param key the location key of the checked tile
   * @return <code>true</code> in case the tile got removed
   */
  private boolean checkObstruction(final MapTile tile, final long key) {
    final Location playerLoc = World.getPlayer().getLocation();
    final Location tileLoc = tile.getLocation();

    final int topLimit = playerLoc.getScZ() + 2;

    int currX = tileLoc.getScX();
    int currY = tileLoc.getScY();
    int currZ = tileLoc.getScZ();

    while (currZ < topLimit) {
      currX -= MapDisplayManager.TILE_PERSPECTIVE_OFFSET;
      currY += MapDisplayManager.TILE_PERSPECTIVE_OFFSET;
      currZ++;

      final boolean remove = (currZ < (topLimit - 2));
      final MapTile foundTile = parent.getMapAt(currX, currY, currZ);

      if ((foundTile != null) && foundTile.isOpaque() && !foundTile.isHidden()) {
        if (remove) {
          parent.removeTile(key);
          return true;
        }
        tile.setObstructed(true);
        return false;
      }
    }
    if (tile.isObstructed()) {
      tile.setObstructed(false);
      addAllBelow(tileLoc, playerLoc.getScZ() - 2);
    }
    return false;
  }
Ejemplo n.º 3
0
 /** Check the visibility for all characters currently on the screen. */
 void checkVisibility() {
   charsLock.readLock().lock();
   try {
     for (final Char character : chars.values()) {
       character.setVisible(World.getPlayer().canSee(character));
     }
   } finally {
     charsLock.readLock().unlock();
   }
 }
Ejemplo n.º 4
0
  /**
   * Check all known characters if they are outside of the screen and hide them from the screen.
   * Save them still to the characters that are known to left the screen.
   */
  void clipCharacters() {
    charsLock.writeLock().lock();
    try {

      for (final Char character : chars.values()) {
        if (!World.getPlayer().isOnScreen(character.getLocation(), 0)) {
          addCharacterToRemoveList(character);
        }
      }
      cleanRemovalList();
    } finally {
      charsLock.writeLock().unlock();
    }
  }
Ejemplo n.º 5
0
  /**
   * Perform a check if the player character is inside a building. In case the inside status differs
   * for any level from the state before the check, all tiles are added to the list of tiles that
   * need to be checked once more.
   */
  private void performInsideCheck() {
    if (!checkInside) {
      return;
    }

    checkInside = false;

    final Location playerLoc = World.getPlayer().getLocation();
    final int currX = playerLoc.getScX();
    final int currY = playerLoc.getScY();
    int currZ = playerLoc.getScZ();
    boolean nowOutside = false;
    boolean isInside = false;

    for (int i = 0; i < 2; ++i) {
      currZ++;
      if (isInside || (parent.isMapAt(currX, currY, currZ))) {
        if (!insideStates[i]) {
          insideStates[i] = true;
          synchronized (unchecked) {
            unchecked.add(Location.getKey(currX, currY, currZ));
          }
        }
        isInside = true;
      } else {
        if (insideStates[i]) {
          insideStates[i] = false;
          nowOutside = true;
        }
      }
    }

    /*
     * If one of the values turned from inside to outside, all tiles are
     * added to the list to be checked again.
     */
    if (nowOutside) {
      synchronized (unchecked) {
        unchecked.clear();
        parent.processTiles(this);
      }
    }

    World.getWeather().setOutside(!isInside);
  }
Ejemplo n.º 6
0
  private void drawPlayer() {
    spriteBatch.draw(
        textureRegions.get("player"),
        world.getPlayer().getPosition().x * ppuX,
        world.getPlayer().getPosition().y * ppuY,
        Player.SIZE * ppuX,
        Player.SIZE * ppuY);

    /*renderer.setProjectionMatrix(cam.combined);
    Player player = world.getPlayer();
    renderer.begin(ShapeType.Rectangle);

    Rectangle rect = player.getBounds();
    float x1 = player.getPosition().x + rect.x;
    float y1 = player.getPosition().y + rect.y;
    renderer.setColor(new Color(1, 0, 0, 1));
    renderer.rect(x1, y1, rect.width, rect.height);
    renderer.end();*/
  }
Ejemplo n.º 7
0
 public boolean canBeAttacked(final Char character) {
   return !World.getPlayer().isPlayer(character.getCharId()) && !character.isNPC();
 }
Ejemplo n.º 8
0
  public void handlePacket(rscproject.gs.connection.Packet p, IoSession session) throws Exception {
    byte loginCode = p.readByte();
    if (world.getPlayer(player.getUsernameHash()) != null) {
      Exception e =
          new Exception(
              "Double log from " + player.getUsername() + " | " + player.getUsernameHash());
      e.printStackTrace();
      loginCode = 5;
      player.destroy(true);
      player.getSession().close();
      return;
    }
    boolean newchar = false;
    RSCPacketBuilder pb = new RSCPacketBuilder();
    pb.setBare(true);
    pb.addByte(loginCode);
    player.getSession().write(pb.toPacket());
    if (loginCode == 0 || loginCode == 1 || loginCode == 99) {
      player.setOwner(p.readInt());
      player.setGroupID(p.readInt());

      player.setSubscriptionExpires(p.readLong());

      player.setLastIP(DataConversions.IPToString(p.readLong()));
      player.setLastLogin(p.readLong());
      /** Check if account is a new account */
      if (player.getLastLogin() == 0L) {
        player.setLocation(Point.location(121, 647), true);
        int x = p.readShort();
        int y = p.readShort();
        newchar = true;
      } else {
        player.setLocation(Point.location(p.readShort(), p.readShort()), true);
      }
      player.setFatigue(p.readShort());
      player.setCombatStyle((int) p.readByte());

      player.setPrivacySetting(0, p.readByte() == 1);
      player.setPrivacySetting(1, p.readByte() == 1);
      player.setPrivacySetting(2, p.readByte() == 1);
      player.setPrivacySetting(3, p.readByte() == 1);

      player.setGameSetting(0, p.readByte() == 1);
      player.setGameSetting(2, p.readByte() == 1);
      player.setGameSetting(3, p.readByte() == 1);
      player.setGameSetting(4, p.readByte() == 1);
      player.setGameSetting(5, p.readByte() == 1);
      player.setGameSetting(6, p.readByte() == 1);

      PlayerAppearance appearance =
          new PlayerAppearance(
              p.readShort(),
              p.readShort(),
              p.readShort(),
              p.readShort(),
              p.readShort(),
              p.readShort());
      if (!appearance.isValid()) {
        loginCode = 7;
        player.destroy(true);
        player.getSession().close();
      }

      /*
       * if(World.isMembers() && !player.isMod()) { loginCode = 7;
       * player.destroy(true); player.getSession().close(); }
       */
      player.setAppearance(appearance);
      player.setWornItems(player.getPlayerAppearance().getSprites());

      player.setMale(p.readByte() == 1);
      long skull = p.readLong();
      if (skull > 0) player.addSkull(skull);

      for (int i = 0; i < 18; i++) {
        int exp = (int) p.readLong();
        player.setExp(i, exp);
        player.setMaxStat(i, Formulae.experienceToLevel(exp));
        player.setCurStat(i, p.readShort());
      }

      player.setCombatLevel(Formulae.getCombatlevel(player.getMaxStats()));

      Inventory inventory = new Inventory(player);
      int invCount = p.readShort();
      for (int i = 0; i < invCount; i++) {
        InvItem item = new InvItem(p.readShort(), p.readInt());
        if (p.readByte() == 1 && item.isWieldable()) {
          item.setWield(true);
          player.updateWornItems(
              item.getWieldableDef().getWieldPos(), item.getWieldableDef().getSprite());
        }
        inventory.add(item);
      }

      player.setInventory(inventory);

      Bank bank = new Bank();
      int bnkCount = p.readShort();
      for (int i = 0; i < bnkCount; i++) bank.add(new InvItem(p.readShort(), p.readInt()));

      player.setBank(bank);

      int friendCount = p.readShort();
      for (int i = 0; i < friendCount; i++) player.addFriend(p.readLong(), p.readShort());

      int ignoreCount = p.readShort();
      for (int i = 0; i < ignoreCount; i++) player.addIgnore(p.readLong());

      player.setQuestPoints(p.readShort(), false);
      int questCount = p.readShort();
      // System.out.println(questCount);
      for (int i = 0; i < questCount; i++)
        player.setQuestStage(p.readShort(), p.readShort(), false, false);

      /* Muted */

      player.setMuted(p.readLong());
      if (player.isMuted()) {
        player
            .getActionSender()
            .sendMessage("@red@You are muted for " + player.getDaysMuted() + " days!");
      }

      long eventcd = p.readLong();
      player.setEventCD(eventcd);

      /* End of loading methods */

      /* Send client data */
      world.registerPlayer(player);

      player.updateViewedPlayers();
      player.updateViewedObjects();

      rscproject.gs.builders.MiscPacketBuilder sender = player.getActionSender();
      sender.sendServerInfo();
      sender.sendFatigue();
      sender.sendWorldInfo(); // sends info for the client to load terrain
      sender.sendInventory();
      sender.sendEquipmentStats();
      sender.sendStats();
      sender.sendPrivacySettings();
      sender.sendGameSettings();
      sender.sendFriendList();
      sender.sendIgnoreList();
      sender.sendCombatStyle();
      sender.sendQuestData();
      sender.sendQuestInfo();

      for (InvItem i : player.getInventory().getItems()) {
        if (i.isWielded() && (i.getID() == 407 || i.getID() == 401)) {
          int count = 0;
          for (Quest q : World.getQuestManager().getQuests()) {
            if (player.getQuestStage(q.getUniqueID()) == Quest.COMPLETE) count++;
          }
          if (player.getCurStat(6) < 31
              || count <= World.getQuestManager().getQuests().size() - 1) {
            player
                .getActionSender()
                .sendMessage(
                    "You must have at least 31 magic & completed "
                        + (World.getQuestManager().getQuests().size() - 1)
                        + " quests");
            WieldHandler.unWieldItem(player, i, true);
            player.getActionSender().sendInventory();
          }
        }
        if (i.getID() == 1288 && i.isWielded()) {
          boolean found = false;
          for (int it = 0; it < 18; it++) {
            if (player.getMaxStat(it) == 99) {
              found = true;
              break;
            }
          }
          if (!found) {
            player
                .getActionSender()
                .sendMessage("Sorry, you need any skill of level 99 to wield this cape of legends");
            WieldHandler.unWieldItem(player, i, true);
          }
        }
      }
      if (player.getLocation().inWilderness()) player.p2pWildy();

      int timeTillShutdown = Instance.getServer().timeTillShutdown();
      if (timeTillShutdown > -1) sender.startShutdown((int) (timeTillShutdown / 1000));

      if (player.getLastLogin() == 0L) {
        player.getInventory().add(new InvItem(4));
        player.getInventory().add(new InvItem(70));
        player.getInventory().add(new InvItem(376));
        player.getInventory().add(new InvItem(156));
        player.getInventory().add(new InvItem(87));
        player.getInventory().add(new InvItem(1263));
        player.getActionSender().sendInventory();
        player.setChangingAppearance(true);
        sender.sendAppearanceScreen();
      }

      player.getActionSender().sendWakeUp(false);
      sender.sendLoginBox();
      sender.sendMessage(Constants.GameServer.MOTD);
      sender.sendOnlinePlayers();

      if (World.getCtf().isEventRunning) {
        sender.sendMessage(
            "%#adm#"
                + "@yel@Server@whi@"
                + ": @gre@"
                + "@gre@Capture the Flag@whi@ is running! (Levels "
                + CTF.getLevelString(CTF.currentLevelRank)
                + ")");
        sender.sendMessage("%#adm#" + "@yel@Server@whi@" + ": @gre@" + "Type ::ctf to join!");
      }
      if (newchar)
        player
            .getActionSender()
            .sendMessage(
                "@ran@Talk to the Community Instructor for information about "
                    + Constants.GameServer.SERVER_NAME);

      if (player.clientWarn()) {
        player
            .getActionSender()
            .sendAlert(
                "@red@Alert! @whi@You are using an old client, please download the new client from our website. This client WILL stop working @red@soon.",
                false);
        player
            .getActionSender()
            .sendMessage(
                "@red@Alert! @whi@You are using an old client, please download the new client from our website. This client WILL stop working on @red@soon.");
      }

      // player.getActionSender().sendAlert("Happy Birthday RSCAngel!!! XP rates are TIMES TWO for
      // today only. Check our website/twitter for more info.",
      // false);

      // sender.sendMessage("Subscriber?: " + player.isSubscriber());

      if (player.isAdmin() || player.isPMod()) {
        player.setnopk(true);
        player.setnonaggro(true);
      }

      player.setLoggedIn(true);
      player.setBusy(false);
      /** Call minigame login check */
      World.getWar().handlePlayerLogin(player);
      World.getCtf().handlePlayerLogin(player);
      World.getLoto().handlePlayerLogin(player);
    } else player.destroy(true);
  }
Ejemplo n.º 9
0
  /**
   * Check if the tile needs to be hidden because the player is inside a cave or a house or
   * something like this.
   *
   * @param tile the tile that is checked
   * @param key the location key of the checked tile
   * @return <code>true</code> in case the tile was handled
   */
  @SuppressWarnings("nls")
  private boolean checkHidden(final MapTile tile, final long key) {
    final Location playerLoc = World.getPlayer().getLocation();
    final Location tileLoc = tile.getLocation();

    if ((playerLoc == null) || (tileLoc == null)) {
      // something is very wrong. Put this entry back into the unchecked
      // list and try it again later.
      reportUnchecked(key);
      return true;
    }

    /*
     * And now we start with the inside check. In case the tile is below the
     * level of the player its never hidden for sure.
     */
    if (tileLoc.getScZ() <= playerLoc.getScZ()) {
      if (tile.isHidden()) {
        tile.setHidden(false);
        addAllBelow(tileLoc, playerLoc.getScZ() - 2);
        addAllNeighbours(tileLoc);
      }
      return true;
    }

    /*
     * Now generate the index in the list of inside states and check if the
     * tile is on a level that is hidden or not. If the tile is on such a
     * level it does not mean for sure that it really needs to be hidden.
     */
    final int insideIndex = tileLoc.getScZ() - playerLoc.getScZ() - 1;

    if ((insideIndex < 0) || (insideIndex > 1)) {
      LOGGER.warn("Invalid inside index: " + insideIndex);
      return true;
    }

    /*
     * Tile is not on a inside level. In case its hidden, show it again.
     */
    if (!insideStates[insideIndex]) {
      if (tile.isHidden()) {
        tile.setHidden(false);
        addAllBelow(tileLoc, playerLoc.getScZ() - 2);
        addAllAbove(tileLoc, playerLoc.getScZ() + 2);
        addAllNeighbours(tileLoc);
      }
      return true;
    }

    /*
     * Now check if the tile is directly above the player. In this case it
     * needs to be hidden.
     */
    if ((tileLoc.getScX() == playerLoc.getScX())
        && (tileLoc.getScY() == playerLoc.getScY())
        && (tileLoc.getScZ() > playerLoc.getScZ())
        && !tile.isHidden()) {
      tile.setHidden(true);
      addAllBelow(tileLoc, playerLoc.getScZ() - 2);
      addAllAbove(tileLoc, playerLoc.getScZ() + 2);
      addAllNeighbours(tileLoc);
      return true;
    }

    if (!tile.isHidden() && searchHiddenNeighbour(tileLoc)) {
      tile.setHidden(true);
      addAllBelow(tileLoc, playerLoc.getScZ() - 2);
      addAllAbove(tileLoc, playerLoc.getScZ() + 2);
      addAllNeighbours(tileLoc);
      return true;
    }

    return false;
  }
Ejemplo n.º 10
0
  /**
   * Do the clipping check of a tile.
   *
   * @param tile the tile that is checked
   * @param key the location key of the checked tile
   * @return <code>true</code> in case the tile was clipped away
   */
  private boolean checkClipping(final MapTile tile, final long key) {
    if (!World.getPlayer().hasValidLocation()) {
      return false;
    }

    final Location playerLoc = World.getPlayer().getLocation();
    final Location tileLoc = tile.getLocation();

    /*
     * Start checking the clipping of the tiles. In case a tile is found
     * outside the clipping range, its deleted.
     */
    if ((playerLoc.getScZ() + 2) < tileLoc.getScZ()) {
      parent.removeTile(key);
      LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (tile.x > player.z + 2)");
      return true;
    }

    if ((playerLoc.getScZ() - 2) > tileLoc.getScZ()) {
      parent.removeTile(key);
      LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (tile.x < player.z - 2)");
      return true;
    }

    final MapDimensions mapDim = MapDimensions.getInstance();

    if ((playerLoc.getCol() + mapDim.getClippingOffsetLeft()) > tileLoc.getCol()) {
      parent.removeTile(key);
      LOGGER.debug(
          "Removed tile at location " + tileLoc.toString() + " (outside of left clipping)");
      LOGGER.debug(
          "Ply Col: "
              + Integer.toString(playerLoc.getCol())
              + " Clipping Left: "
              + Integer.toString(mapDim.getClippingOffsetLeft())
              + " Tile Col: "
              + Integer.toString(tileLoc.getCol()));
      return true;
    }

    if ((playerLoc.getCol() + mapDim.getClippingOffsetRight()) < tileLoc.getCol()) {
      parent.removeTile(key);
      LOGGER.debug(
          "Removed tile at location " + tileLoc.toString() + " (outside of right clipping)");
      LOGGER.debug(
          "Ply Col: "
              + Integer.toString(playerLoc.getCol())
              + " Clipping Right: "
              + Integer.toString(mapDim.getClippingOffsetRight())
              + " Tile Col: "
              + Integer.toString(tileLoc.getCol()));
      return true;
    }

    final int level = Math.abs(tileLoc.getScZ() - playerLoc.getScZ()) * 6;

    if ((playerLoc.getRow() + mapDim.getClippingOffsetTop()) < (tileLoc.getRow() - level)) {
      parent.removeTile(key);
      LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (outside of top clipping)");
      LOGGER.debug(
          "Ply Row: "
              + Integer.toString(playerLoc.getRow())
              + " Clipping Top: "
              + Integer.toString(mapDim.getClippingOffsetTop())
              + " Tile Row: "
              + Integer.toString(tileLoc.getRow()));
      return true;
    }

    if ((playerLoc.getRow() + mapDim.getClippingOffsetBottom()) > (tileLoc.getRow() + level)) {
      parent.removeTile(key);
      LOGGER.debug(
          "Removed tile at location " + tileLoc.toString() + " (outside of bottom clipping)");
      LOGGER.debug(
          "Ply Row: "
              + Integer.toString(playerLoc.getRow())
              + " Clipping Bottom: "
              + Integer.toString(mapDim.getClippingOffsetBottom())
              + " Tile Row: "
              + Integer.toString(tileLoc.getRow()));
      return true;
    }

    return false;
  }
Ejemplo n.º 11
0
  public void handlePacket(Packet p, IoSession session) throws Exception {
    Player player = (Player) session.getAttachment();
    int pID = ((RSCPacket) p).getID();
    Player affectedPlayer;

    if (busy(player)) {
      affectedPlayer = player.getWishToTrade();
      unsetOptions(player);
      unsetOptions(affectedPlayer);
      return;
    }
    switch (pID) {
      case 166: // Sending trade request
        affectedPlayer = world.getPlayer(p.readShort());
        if (affectedPlayer == null) return;
        if (affectedPlayer.isTrading()) {
          player.getActionSender().sendMessage("That person is already trading");
          return;
        }
        if (affectedPlayer == null
            || affectedPlayer.isDueling()
            || !player.withinRange(affectedPlayer, 8)
            || player.isTrading()
            || player.tradeDuelThrottling()) {
          unsetOptions(player);
          return;
        }
        if (player == null) {
          Logger.println("Player is null affectedplayer is: " + affectedPlayer.getUsername());
        }
        if (affectedPlayer == player) {
          player.setSuspiciousPlayer(true);
          Logger.println("Warning: " + player.getUsername() + " tried to trade to himself.");
          unsetOptions(player);
          return;
        }
        if (!new PathGenerator(
                player.getX(), player.getY(), affectedPlayer.getX(), affectedPlayer.getY())
            .isValid()) {
          player.getActionSender().sendMessage("you can't reach this person");
          unsetOptions(player);
          return;
        }

        if ((affectedPlayer.getPrivacySetting(2)
                && !affectedPlayer.isFriendsWith(player.getUsernameHash()))
            || affectedPlayer.isIgnoring(player.getUsernameHash())) {
          player.getActionSender().sendMessage("This player has trade requests blocked.");
          return;
        }

        player.setWishToTrade(affectedPlayer);
        player
            .getActionSender()
            .sendMessage(
                affectedPlayer.isTrading()
                    ? affectedPlayer.getUsername() + " is already in a trade"
                    : "Sending trade request");
        affectedPlayer
            .getActionSender()
            .sendMessage(player.getUsername() + " wishes to trade with you");

        if (!player.isTrading()
            && affectedPlayer.getWishToTrade() != null
            && affectedPlayer.getWishToTrade().equals(player)
            && !affectedPlayer.isTrading()) {
          player.setTrading(true);
          player.resetPath();
          player.resetAllExceptTrading();
          affectedPlayer.setTrading(true);
          affectedPlayer.resetPath();
          affectedPlayer.resetAllExceptTrading();

          player.getActionSender().sendTradeWindowOpen();
          affectedPlayer.getActionSender().sendTradeWindowOpen();
          world.addEntryToSnapshots(
              new Activity(
                  player.getUsername(),
                  player.getUsername()
                      + " sent trade request "
                      + affectedPlayer.getUsername()
                      + " at: "
                      + player.getX()
                      + "/"
                      + player.getY()
                      + " | "
                      + affectedPlayer.getX()
                      + "/"
                      + affectedPlayer.getY()));
        }
        break;
      case 211: // Trade accepted
        affectedPlayer = player.getWishToTrade();
        if (affectedPlayer == null
            || busy(affectedPlayer)
            || !player.isTrading()
            || !affectedPlayer.isTrading()) { // This
          // shouldn't
          // happen
          player.setSuspiciousPlayer(true);
          unsetOptions(player);
          unsetOptions(affectedPlayer);
          return;
        }

        player.setTradeOfferAccepted(true);

        player.getActionSender().sendTradeAcceptUpdate();
        affectedPlayer.getActionSender().sendTradeAcceptUpdate();

        if (affectedPlayer.isTradeOfferAccepted()) {
          player.getActionSender().sendTradeAccept();
          affectedPlayer.getActionSender().sendTradeAccept();
        }
        world.addEntryToSnapshots(
            new Activity(
                player.getUsername(),
                player.getUsername()
                    + " accepted trade "
                    + affectedPlayer.getUsername()
                    + " at: "
                    + player.getX()
                    + "/"
                    + player.getY()
                    + " | "
                    + affectedPlayer.getX()
                    + "/"
                    + affectedPlayer.getY()));

        break;
      case 53: // Confirm accepted
        affectedPlayer = player.getWishToTrade();
        if (affectedPlayer == null
            || busy(affectedPlayer)
            || !player.isTrading()
            || !affectedPlayer.isTrading()
            || !player.isTradeOfferAccepted()
            || !affectedPlayer.isTradeOfferAccepted()) { // This
          // shouldn't
          // happen
          player.setSuspiciousPlayer(true);
          unsetOptions(player);
          unsetOptions(affectedPlayer);
          return;
        }
        player.setTradeConfirmAccepted(true);

        if (affectedPlayer.isTradeConfirmAccepted()) {
          world.addEntryToSnapshots(
              new Activity(
                  player.getUsername(),
                  player.getUsername()
                      + " finished trade "
                      + affectedPlayer.getUsername()
                      + " at: "
                      + player.getX()
                      + "/"
                      + player.getY()
                      + " | "
                      + affectedPlayer.getX()
                      + "/"
                      + affectedPlayer.getY()));

          ArrayList<InvItem> myOffer = player.getTradeOffer();
          ArrayList<InvItem> theirOffer = affectedPlayer.getTradeOffer();

          int myRequiredSlots = player.getInventory().getRequiredSlots(theirOffer);
          int myAvailableSlots =
              (30 - player.getInventory().size()) + player.getInventory().getFreedSlots(myOffer);

          int theirRequiredSlots = affectedPlayer.getInventory().getRequiredSlots(myOffer);
          int theirAvailableSlots =
              (30 - affectedPlayer.getInventory().size())
                  + affectedPlayer.getInventory().getFreedSlots(theirOffer);

          if (theirRequiredSlots > theirAvailableSlots) {
            player
                .getActionSender()
                .sendMessage("The other player does not have room to accept your items.");
            affectedPlayer
                .getActionSender()
                .sendMessage("You do not have room in your inventory to hold those items.");
            unsetOptions(player);
            unsetOptions(affectedPlayer);
            return;
          }
          if (myRequiredSlots > myAvailableSlots) {
            player
                .getActionSender()
                .sendMessage("You do not have room in your inventory to hold those items.");
            affectedPlayer
                .getActionSender()
                .sendMessage("The other player does not have room to accept your items.");
            unsetOptions(player);
            unsetOptions(affectedPlayer);
            return;
          }

          for (InvItem item : myOffer) {
            InvItem affectedItem = player.getInventory().get(item);
            if (affectedItem == null) {
              player.setSuspiciousPlayer(true);
              unsetOptions(player);
              unsetOptions(affectedPlayer);
              return;
            }
            if (item.getDef().isMembers() && !World.isMembers()) {
              player
                  .getActionSender()
                  .sendMessage("This feature is only avaliable on a members server");
              unsetOptions(player);
              unsetOptions(affectedPlayer);
              return;
            }
            if (affectedItem.isWielded()) {
              affectedItem.setWield(false);
              player.updateWornItems(
                  affectedItem.getWieldableDef().getWieldPos(),
                  player
                      .getPlayerAppearance()
                      .getSprite(affectedItem.getWieldableDef().getWieldPos()));
            }
            player.getInventory().remove(item);
          }
          for (InvItem item : theirOffer) {
            InvItem affectedItem = affectedPlayer.getInventory().get(item);
            if (affectedItem == null) {
              affectedPlayer.setSuspiciousPlayer(true);
              unsetOptions(player);
              unsetOptions(affectedPlayer);
              return;
            }
            if (item.getDef().isMembers() && !World.isMembers()) {
              player
                  .getActionSender()
                  .sendMessage("This feature is only avaliable on a members server");
              unsetOptions(player);
              unsetOptions(affectedPlayer);
              return;
            }
            if (affectedItem.isWielded()) {
              affectedItem.setWield(false);
              affectedPlayer.updateWornItems(
                  affectedItem.getWieldableDef().getWieldPos(),
                  affectedPlayer
                      .getPlayerAppearance()
                      .getSprite(affectedItem.getWieldableDef().getWieldPos()));
            }
            affectedPlayer.getInventory().remove(item);
          }
          MiscPacketBuilder loginServer =
              Instance.getServer().getLoginConnector().getActionSender();
          long playerhash = DataConversions.usernameToHash(player.getUsername());
          long affectedPlayerhash = DataConversions.usernameToHash(affectedPlayer.getUsername());
          for (InvItem item : myOffer) {
            affectedPlayer.getInventory().add(item);
          }
          for (InvItem item : theirOffer) {
            player.getInventory().add(item);
          }
          boolean senddata = false;
          for (InvItem item : myOffer) {
            loginServer.tradeLog(
                playerhash,
                affectedPlayerhash,
                item.getID(),
                item.getAmount(),
                player.getX(),
                player.getY(),
                1);
            if (item.getAmount() > 10000000 || Formulae.isRareItem(item.getID())) senddata = true;
          }
          if (senddata)
            DBConnection.getReport()
                .submitDupeData(DataConversions.hashToUsername(playerhash), playerhash);
          senddata = false;
          for (InvItem item : theirOffer) {
            loginServer.tradeLog(
                affectedPlayerhash,
                playerhash,
                item.getID(),
                item.getAmount(),
                player.getX(),
                player.getY(),
                1);
            if (item.getAmount() > 10000000 || Formulae.isRareItem(item.getID())) senddata = true;
          }
          if (senddata)
            DBConnection.getReport()
                .submitDupeData(
                    DataConversions.hashToUsername(affectedPlayerhash), affectedPlayerhash);

          player.getActionSender().sendInventory();
          player.getActionSender().sendEquipmentStats();
          Long now = System.currentTimeMillis();
          player.save();
          player.setLastSaveTime(now);
          affectedPlayer.save();
          affectedPlayer.setLastSaveTime(now);
          player.getActionSender().sendMessage("Trade completed.");

          affectedPlayer.getActionSender().sendInventory();
          affectedPlayer.getActionSender().sendEquipmentStats();
          affectedPlayer.getActionSender().sendMessage("Trade completed.");

          unsetOptions(player);
          unsetOptions(affectedPlayer);

          World.getWar().handleCapeWield(player);
          World.getWar().handleCapeWield(affectedPlayer);
        }
        break;
      case 216: // Trade declined
        affectedPlayer = player.getWishToTrade();
        if (affectedPlayer == null
            || busy(affectedPlayer)
            || !player.isTrading()
            || !affectedPlayer.isTrading()) { // This
          // shouldn't
          // happen
          player.setSuspiciousPlayer(true);
          unsetOptions(player);
          unsetOptions(affectedPlayer);
          return;
        }
        affectedPlayer
            .getActionSender()
            .sendMessage(player.getUsername() + " has declined the trade.");

        unsetOptions(player);
        unsetOptions(affectedPlayer);
        break;
      case 70: // Receive offered item data
        affectedPlayer = player.getWishToTrade();
        if (affectedPlayer == null
            || busy(affectedPlayer)
            || !player.isTrading()
            || !affectedPlayer.isTrading()
            || (player.isTradeOfferAccepted() && affectedPlayer.isTradeOfferAccepted())
            || player.isTradeConfirmAccepted()
            || affectedPlayer.isTradeConfirmAccepted()) { // This
          // shouldn't
          // happen
          player.setSuspiciousPlayer(true);
          unsetOptions(player);
          unsetOptions(affectedPlayer);
          return;
        }

        player.setTradeOfferAccepted(false);
        player.setTradeConfirmAccepted(false);
        affectedPlayer.setTradeOfferAccepted(false);
        affectedPlayer.setTradeConfirmAccepted(false);

        // player.getActionSender().sendTradeAcceptUpdate();
        // affectedPlayer.getActionSender().sendTradeAcceptUpdate();

        Inventory tradeOffer = new Inventory();
        player.resetTradeOffer();
        int count = (int) p.readByte();
        for (int slot = 0; slot < count; slot++) {
          InvItem tItem = new InvItem(p.readShort(), p.readInt());
          if (tItem.getAmount() < 1) {
            player.setSuspiciousPlayer(true);
            player.setRequiresOfferUpdate(true);
            continue;
          }
          ItemDef def = tItem.getDef();
          if (!def.canTrade() && !player.isMod()) {
            player
                .getActionSender()
                .sendMessage(def.getName() + " cannot be traded with other players");
            player.setRequiresOfferUpdate(true);
            continue;
          }
          tradeOffer.add(tItem);
        }
        for (InvItem item : tradeOffer.getItems()) {
          if (tradeOffer.countId(item.getID()) > player.getInventory().countId(item.getID())) {
            player.setSuspiciousPlayer(true);
            unsetOptions(player);
            unsetOptions(affectedPlayer);
            return;
          }
          player.addToTradeOffer(item);
        }
        player.setRequiresOfferUpdate(true);
        break;
    }
  }