public Flame createTransformedFlame(DancingFlame pFlame, short pFFTData[], long pTime, int pFPS) { Flame res = pFlame.getFlame().makeCopy(); Flame refFlame = pFlame.getFlame().makeCopy(); for (Motion motion : pFlame.getMotions()) { if (motion.getParent() == null && motion.isActive(pTime, pFPS)) { double value = 0.0; int iter = 0; Motion currMotion = motion; while (currMotion != null) { value += currMotion.computeValue(pFFTData, pTime, pFPS); Motion refMotion = currMotion; currMotion = null; for (Motion nextMotion : pFlame.getMotions()) { if (nextMotion.isActive(pTime, pFPS) && nextMotion.getParent() == refMotion) { currMotion = nextMotion; break; } } iter++; if (iter > 100) { throw new RuntimeException("Probably endless loop detected"); } } for (MotionLink link : motion.getMotionLinks()) { if (link.getProperyPath().getFlame().isEqual(refFlame)) { AnimationModelService.setFlameProperty(res, link.getProperyPath(), value); } } } } return res; }
private boolean checkAnimationTime() { if (!(effector instanceof Player) || skillMethod != SkillMethod.CAST) // TODO item skills? return true; Player player = (Player) effector; // if player is without weapon, dont check animation time if (player.getEquipment().getMainHandWeaponType() == null) return true; /** exceptions for certain skills -herb and mana treatment -traps */ // dont check herb , mana treatment and concentration enhancement switch (this.getSkillId()) { case 1803: // bandage heal case 1804: // herb treatment case 1805: case 1825: case 1827: case 2672: case 1823: // mana treatment case 1824: case 1826: case 1828: case 2673: case 1078: // concentration enhancement case 1125: case 1468: case 11580: return true; } if (this.getSkillTemplate().getSubType() == SkillSubType.SUMMONTRAP) return true; Motion motion = this.getSkillTemplate().getMotion(); if (motion == null || motion.getName() == null) { log.warn("missing motion for skillId: " + this.getSkillId()); return true; } if (motion.getInstantSkill() && hitTime != 0) { log.warn( "Instant and hitTime not 0! modified client_skills? player objectid: " + player.getObjectId()); return false; } else if (!motion.getInstantSkill() && hitTime == 0) { log.warn("modified client_skills! player objectid: " + player.getObjectId()); return false; } MotionTime motionTime = DataManager.MOTION_DATA.getMotionTime(motion.getName()); if (motionTime == null) { log.warn( "missing motiontime for motionName: " + motion.getName() + " skillId: " + this.getSkillId()); return true; } WeaponTypeWrapper weapons = new WeaponTypeWrapper( player.getEquipment().getMainHandWeaponType(), player.getEquipment().getOffHandWeaponType()); float serverTime = motionTime.getTimeForWeapon(player.getRace(), player.getGender(), weapons); int clientTime = hitTime; if (serverTime == 0) { log.warn( "missing weapon time for motionName: " + motion.getName() + " weapons: " + weapons.toString() + " skillId: " + this.getSkillId()); return true; } // adjust client time with ammotime long ammoTime = 0; double distance = MathUtil.getDistance(effector, firstTarget); if (getSkillTemplate().getAmmoSpeed() != 0) ammoTime = Math.round(distance / getSkillTemplate().getAmmoSpeed() * 1000); // checked with client clientTime -= ammoTime; // adjust servertime with motion play speed if (motion.getSpeed() != 100) { serverTime /= 100f; serverTime *= (float) motion.getSpeed(); } Stat2 attackSpeed = player.getGameStats().getAttackSpeed(); // adjust serverTime with attackSpeed if (attackSpeed.getBase() != attackSpeed.getCurrent()) serverTime *= ((float) attackSpeed.getCurrent() / (float) attackSpeed.getBase()); // tolerance if (duration == 0) serverTime *= 0.9f; else serverTime *= 0.5f; int finalTime = Math.round(serverTime); if (motion.getInstantSkill() && hitTime == 0) { this.serverTime = (int) ammoTime; } else { if (clientTime < finalTime) { // check for no animation Hacks if (SecurityConfig.NO_ANIMATION) { float clientTme = clientTime; float serverTme = serverTime; float checkTme = clientTme / serverTme; // check if values are too low if (clientTime < 0 || checkTme < SecurityConfig.NO_ANIMATION_VALUE) { if (SecurityConfig.NO_ANIMATION_KICK) { player.getClientConnection().close(new SM_QUIT_RESPONSE(), false); AuditLogger.info( player, "Modified client_skills:" + this.getSkillId() + " (clientTime<finalTime:" + clientTime + "/" + finalTime + ") Kicking Player: " + player.getName()); } else { AuditLogger.info( player, "Modified client_skills:" + this.getSkillId() + " (clientTime<finalTime:" + clientTime + "/" + finalTime + ")"); } return false; } } log.warn( "Possible modified client_skills:" + this.getSkillId() + " (clientTime<finalTime:" + clientTime + "/" + finalTime + ") player Name: " + player.getName()); } this.serverTime = hitTime; } player.setNextSkillUse(System.currentTimeMillis() + duration + finalTime); return true; }