@Override
  public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    int cid = slea.readInt();
    MapleCharacter player = null;
    try {
      player = MapleCharacter.loadCharFromDB(cid, c, true);
      c.setPlayer(player);
    } catch (SQLException e) {
    }
    c.setAccID(player.getAccountID());
    int state = c.getLoginState();
    boolean allowLogin = true;
    ChannelServer cserv = c.getChannelServer();
    synchronized (this) {
      try {
        WorldChannelInterface worldInterface = cserv.getWorldInterface();
        if (state == MapleClient.LOGIN_SERVER_TRANSITION) {
          for (String charName : c.loadCharacterNames(c.getWorld())) {
            if (worldInterface.isConnected(charName)) {
              int chanNum = c.getChannelServer().getWorldInterface().getLocation(charName).channel;
              System.err.print(
                  charName
                      + " on channel "
                      + chanNum
                      + " has been unstuck, for bug-testing purposes.");
              MapleCharacter player_to_dc =
                  ChannelServer.getInstance(chanNum)
                      .getPlayerStorage()
                      .getCharacterByName(charName);
              if (player_to_dc.getEventInstance() != null)
                player_to_dc.getEventInstance().removePlayer(player_to_dc);
              player_to_dc.getMap().removePlayer(player_to_dc);
              ChannelServer.getInstance(chanNum).removePlayer(player_to_dc);
              player_to_dc.getClient().disconnect();
              player_to_dc.getClient().getSession().close();
              c.disconnect();
              allowLogin = false;
              break;
            }
          }
        }
      } catch (RemoteException e) {
        cserv.reconnectWorld();
        allowLogin = false;
      } catch (Exception e) {
        System.out.println("Error unsticking char:");
        e.printStackTrace();
      }
      if (state != MapleClient.LOGIN_SERVER_TRANSITION || !allowLogin) {
        c.setPlayer(null);
        c.getSession().close(true);
        return;
      }
      c.updateLoginState(MapleClient.LOGIN_LOGGEDIN);
    }
    cserv.addPlayer(player);
    try {
      List<PlayerBuffValueHolder> buffs = cserv.getWorldInterface().getBuffsFromStorage(cid);
      if (buffs != null) {
        c.getPlayer().silentGiveBuffs(buffs);
      }
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    Connection con = DatabaseConnection.getConnection();
    try {
      PreparedStatement ps =
          con.prepareStatement("SELECT SkillID,StartTime,length FROM cooldowns WHERE charid = ?");
      ps.setInt(1, c.getPlayer().getId());
      ResultSet rs = ps.executeQuery();
      while (rs.next()) {
        final long length = rs.getLong("length"), startTime = rs.getLong("StartTime");
        if (length + startTime > System.currentTimeMillis()) {
          c.getPlayer().giveCoolDowns(rs.getInt("SkillID"), startTime, length);
        }
      }
      rs.close();
      ps.close();
      ps = con.prepareStatement("DELETE FROM cooldowns WHERE charid = ?");
      ps.setInt(1, c.getPlayer().getId());
      ps.executeUpdate();
      ps.close();
      ps =
          con.prepareStatement(
              "SELECT Mesos FROM dueypackages WHERE RecieverId = ? and Checked = 1");
      ps.setInt(1, c.getPlayer().getId());
      rs = ps.executeQuery();
      if (rs.next()) {
        try {
          PreparedStatement pss =
              DatabaseConnection.getConnection()
                  .prepareStatement("UPDATE dueypackages SET Checked = 0 where RecieverId = ?");
          pss.setInt(1, c.getPlayer().getId());
          pss.executeUpdate();
          pss.close();
        } catch (SQLException e) {
        }
        c.getSession().write(MaplePacketCreator.sendDueyMSG((byte) 0x1B));
      }
      rs.close();
      ps.close();
      rs = null;
      ps = null;
    } catch (SQLException e) {
      e.printStackTrace();
    }
    c.getSession().write(MaplePacketCreator.getCharInfo(player));
    c.getPlayer().InitiateSaveEvent();
    if (player.isGM()) {
      SkillFactory.getSkill(GM.HIDE).getEffect(1).applyTo(player);
    }
    player.sendKeymap();
    player.sendMacros();
    player.getMap().addPlayer(player);
    try {
      int buddyIds[] = player.getBuddylist().getBuddyIds();
      cserv
          .getWorldInterface()
          .loggedOn(player.getName(), player.getId(), c.getChannel(), buddyIds);
      for (CharacterIdChannelPair onlineBuddy :
          cserv.getWorldInterface().multiBuddyFind(player.getId(), buddyIds)) {
        BuddylistEntry ble = player.getBuddylist().get(onlineBuddy.getCharacterId());
        ble.setChannel(onlineBuddy.getChannel());
        player.getBuddylist().put(ble);
      }
      c.getSession().write(MaplePacketCreator.updateBuddylist(player.getBuddylist().getBuddies()));
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    /*  c.getSession().write(MaplePacketCreator.loadFamily(player));
    if (player.getFamilyId() > 0) {
        c.getSession().write(MaplePacketCreator.getFamilyInfo(player));
    }*/
    if (player.getGuildId() > 0) {
      try {
        MapleGuild playerGuild =
            cserv.getWorldInterface().getGuild(player.getGuildId(), player.getMGC());
        if (playerGuild == null) {
          player.deleteGuild(player.getGuildId());
          player.resetMGC();
          player.setGuildId(0);
        } else {
          cserv.getWorldInterface().setGuildMemberOnline(player.getMGC(), true, c.getChannel());
          c.getSession().write(MaplePacketCreator.showGuildInfo(player));
          int allianceId = player.getGuild().getAllianceId();
          if (allianceId > 0) {
            MapleAlliance newAlliance = cserv.getWorldInterface().getAlliance(allianceId);
            if (newAlliance == null) {
              newAlliance = MapleAlliance.loadAlliance(allianceId);
              if (newAlliance != null) {
                cserv.getWorldInterface().addAlliance(allianceId, newAlliance);
              } else {
                player.getGuild().setAllianceId(0);
              }
            }
            if (newAlliance != null) {
              c.getSession().write(MaplePacketCreator.getAllianceInfo(newAlliance));
              c.getSession().write(MaplePacketCreator.getGuildAlliances(newAlliance, c));
              cserv
                  .getWorldInterface()
                  .allianceMessage(
                      allianceId,
                      MaplePacketCreator.allianceMemberOnline(player, true),
                      player.getId(),
                      -1);
            }
          }
        }
      } catch (RemoteException e) {
        cserv.reconnectWorld();
      }
    }
    try {
      //  c.getPlayer().showNote();
      if (player.getParty() != null) {
        cserv
            .getWorldInterface()
            .updateParty(
                player.getParty().getId(),
                PartyOperation.LOG_ONOFF,
                new MaplePartyCharacter(player));
      }
      player.updatePartyMemberHP();
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    for (MapleQuestStatus status : player.getStartedQuests()) {
      if (status.hasMobKills()) {
        c.getSession().write(MaplePacketCreator.updateQuestMobKills(status));
      }
    }
    CharacterNameAndId pendingBuddyRequest = player.getBuddylist().pollPendingRequest();
    if (pendingBuddyRequest != null) {
      player
          .getBuddylist()
          .put(
              new BuddylistEntry(
                  pendingBuddyRequest.getName(), "그룹 미지정", pendingBuddyRequest.getId(), -1, false));
      c.getSession()
          .write(
              MaplePacketCreator.requestBuddylistAdd(
                  pendingBuddyRequest.getId(),
                  c.getPlayer().getId(),
                  pendingBuddyRequest.getName(),
                  0,
                  0)); // todo: make actual levels / jobids appear
    }
    c.getSession().write(MaplePacketCreator.updateBuddylist(player.getBuddylist().getBuddies()));
    //    c.getSession().write(MaplePacketCreator.updateGender(player));
    player.checkMessenger();
    //  c.getSession().write(MaplePacketCreator.enableReport());
    /*     if (!player.isGM() && !player.hasWatchedCygnusIntro() && player.getLevel() > 19 && !player.isCygnus() && player.getCygnusLinkId() == 0) {
        player.startCygnusIntro();
        player.setWatchedCygnusIntro(true);
    }*/
    // unneeded in 83+ as cygnus is created at char select

    ISkill bof =
        SkillFactory.getSkill(
            10000000 * player.getJobType() + 12); // todo: find opcode and re-enable
    player.changeSkillLevel(bof, player.getLinkedLevel() / 10, bof.getMaxLevel());
    player.checkBerserk();
    player.expirationTask();
    player.setRates(false);
  }
Ejemplo n.º 2
0
  public static final void SummonPVP(final LittleEndianAccessor slea, final MapleClient c) {
    final MapleCharacter chr = c.getPlayer();
    if (chr == null
        || chr.isHidden()
        || !chr.isAlive()
        || chr.hasBlockedInventory()
        || chr.getMap() == null
        || !chr.inPVP()
        || !chr.getEventInstance().getProperty("started").equals("1")) {
      return;
    }
    final MapleMap map = chr.getMap();
    final MapleMapObject obj = map.getMapObject(slea.readInt(), MapleMapObjectType.SUMMON);
    if (obj == null || !(obj instanceof MapleSummon)) {
      chr.dropMessage(5, "The summon has disappeared.");
      return;
    }
    int tick = -1;
    if (slea.available() == 27) {
      slea.skip(23);
      tick = slea.readInt();
    }
    final MapleSummon summon = (MapleSummon) obj;
    if (summon.getOwnerId() != chr.getId() || summon.getSkillLevel() <= 0) {
      chr.dropMessage(5, "Error.");
      return;
    }
    final Skill skil = SkillFactory.getSkill(summon.getSkill());
    final MapleStatEffect effect = skil.getEffect(summon.getSkillLevel());
    final int lvl = Integer.parseInt(chr.getEventInstance().getProperty("lvl"));
    final int type = Integer.parseInt(chr.getEventInstance().getProperty("type"));
    final int ourScore =
        Integer.parseInt(chr.getEventInstance().getProperty(String.valueOf(chr.getId())));
    int addedScore = 0;
    final boolean magic = skil.isMagic();
    boolean killed = false, didAttack = false;
    double maxdamage =
        lvl == 3
            ? chr.getStat().getCurrentMaxBasePVPDamageL()
            : chr.getStat().getCurrentMaxBasePVPDamage();
    maxdamage *= (effect.getDamage() + chr.getStat().getDamageIncrease(summon.getSkill())) / 100.0;
    int mobCount = 1, attackCount = 1, ignoreDEF = chr.getStat().ignoreTargetDEF;

    final SummonSkillEntry sse = SkillFactory.getSummonData(summon.getSkill());
    if (summon.getSkill() / 1000000 != 35 && summon.getSkill() != 33101008 && sse == null) {
      chr.dropMessage(5, "Error in processing attack.");
      return;
    }
    Point lt, rb;
    if (sse != null) {
      if (sse.delay > 0) {
        if (tick != -1) {
          summon.CheckSummonAttackFrequency(chr, tick);
          chr.updateTick(tick);
        } else {
          summon.CheckPVPSummonAttackFrequency(chr);
        }
        chr.getCheatTracker().checkSummonAttack();
      }
      mobCount = sse.mobCount;
      attackCount = sse.attackCount;
      lt = sse.lt;
      rb = sse.rb;
    } else {
      lt = new Point(-100, -100);
      rb = new Point(100, 100);
    }
    final Rectangle box =
        MapleStatEffect.calculateBoundingBox(chr.getTruePosition(), chr.isFacingLeft(), lt, rb, 0);
    List<AttackPair> ourAttacks = new ArrayList<AttackPair>();
    List<Pair<Integer, Boolean>> attacks;
    maxdamage *= chr.getStat().dam_r / 100.0;
    for (MapleMapObject mo : chr.getMap().getCharactersIntersect(box)) {
      final MapleCharacter attacked = (MapleCharacter) mo;
      if (attacked.getId() != chr.getId()
          && attacked.isAlive()
          && !attacked.isHidden()
          && (type == 0 || attacked.getTeam() != chr.getTeam())) {
        double rawDamage =
            maxdamage
                / Math.max(
                    0,
                    ((magic ? attacked.getStat().mdef : attacked.getStat().wdef)
                            * Math.max(1.0, 100.0 - ignoreDEF)
                            / 100.0)
                        * (type == 3 ? 0.1 : 0.25));
        if (attacked.getBuffedValue(MapleBuffStat.INVINCIBILITY) != null
            || PlayersHandler.inArea(attacked)) {
          rawDamage = 0;
        }
        rawDamage += (rawDamage * chr.getDamageIncrease(attacked.getId()) / 100.0);
        rawDamage *= attacked.getStat().mesoGuard / 100.0;
        rawDamage = attacked.modifyDamageTaken(rawDamage, attacked).left;
        final double min = (rawDamage * chr.getStat().trueMastery / 100);
        attacks = new ArrayList<Pair<Integer, Boolean>>(attackCount);
        int totalMPLoss = 0, totalHPLoss = 0;
        for (int i = 0; i < attackCount; i++) {
          int mploss = 0;
          double ourDamage =
              Randomizer.nextInt((int) Math.abs(Math.round(rawDamage - min)) + 1) + min;
          if (attacked.getStat().dodgeChance > 0
              && Randomizer.nextInt(100) < attacked.getStat().dodgeChance) {
            ourDamage = 0;
            // i dont think level actually matters or it'd be too op
            // } else if (attacked.getLevel() > chr.getLevel() && Randomizer.nextInt(100) <
            // (attacked.getLevel() - chr.getLevel())) {
            //	ourDamage = 0;
          }
          if (attacked.getBuffedValue(MapleBuffStat.MAGIC_GUARD) != null) {
            mploss =
                (int)
                    Math.min(
                        attacked.getStat().getMp(),
                        (ourDamage
                            * attacked.getBuffedValue(MapleBuffStat.MAGIC_GUARD).doubleValue()
                            / 100.0));
          }
          ourDamage -= mploss;
          if (attacked.getBuffedValue(MapleBuffStat.INFINITY) != null) {
            mploss = 0;
          }
          attacks.add(new Pair<Integer, Boolean>((int) Math.floor(ourDamage), false));

          totalHPLoss += Math.floor(ourDamage);
          totalMPLoss += mploss;
        }
        attacked.addMPHP(-totalHPLoss, -totalMPLoss);
        ourAttacks.add(new AttackPair(attacked.getId(), attacked.getPosition(), attacks));
        attacked.getCheatTracker().setAttacksWithoutHit(false);
        if (totalHPLoss > 0) {
          didAttack = true;
        }
        if (attacked.getStat().getHPPercent() <= 20) {
          SkillFactory.getSkill(attacked.getStat().getSkillByJob(93, attacked.getJob()))
              .getEffect(1)
              .applyTo(attacked);
        }
        if (effect != null) {
          if (effect.getMonsterStati().size() > 0 && effect.makeChanceResult()) {
            for (Map.Entry<MonsterStatus, Integer> z : effect.getMonsterStati().entrySet()) {
              MapleDisease d = MonsterStatus.getLinkedDisease(z.getKey());
              if (d != null) {
                attacked.giveDebuff(d, z.getValue(), effect.getDuration(), d.getDisease(), 1);
              }
            }
          }
          effect.handleExtraPVP(chr, attacked);
        }
        chr.getClient()
            .getSession()
            .write(
                CField.getPVPHPBar(
                    attacked.getId(),
                    attacked.getStat().getHp(),
                    attacked.getStat().getCurrentMaxHp()));
        addedScore += (totalHPLoss / 100) + (totalMPLoss / 100); // ive NO idea
        if (!attacked.isAlive()) {
          killed = true;
        }

        if (ourAttacks.size() >= mobCount) {
          break;
        }
      }
    }
    if (killed || addedScore > 0) {
      chr.getEventInstance().addPVPScore(chr, addedScore);
      chr.getClient().getSession().write(CField.getPVPScore(ourScore + addedScore, killed));
    }
    if (didAttack) {
      chr.getMap()
          .broadcastMessage(
              SummonPacket.pvpSummonAttack(
                  chr.getId(),
                  chr.getLevel(),
                  summon.getObjectId(),
                  summon.isFacingLeft() ? 4 : 0x84,
                  summon.getTruePosition(),
                  ourAttacks));
      if (!summon.isMultiAttack()) {
        chr.getMap().broadcastMessage(SummonPacket.removeSummon(summon, true));
        chr.getMap().removeMapObject(summon);
        chr.removeVisibleMapObject(summon);
        chr.removeSummon(summon);
        if (summon.getSkill() != 35121011) {
          chr.cancelEffectFromBuffStat(MapleBuffStat.SUMMON);
        }
      }
    }
  }