소스 검색

Attack packet performance fix, thanks FBIagent.
Also added durty hack to rid off lags on the olympiad if players using shields. Hope we will later solve it in normal way.

_DS_ 15 년 전
부모
커밋
1d55abc461

+ 7 - 11
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/L2Character.java

@@ -919,12 +919,8 @@ public abstract class L2Character extends L2Object
         int ssGrade = 0;
 
         if (weaponItem != null)
-        {
-        	ssGrade = weaponItem.getCrystalType();
-        	if (ssGrade == 6 || ssGrade == 7)
-        		ssGrade = 5;
-        }
-            
+        	ssGrade = weaponItem.getItemGradeSPlus();
+
         // Create a Server->Client packet Attack
 		Attack attack = new Attack(this, target, wasSSCharged, ssGrade);
 
@@ -1070,7 +1066,7 @@ public abstract class L2Character extends L2Object
 		_disableBowAttackEndTime = (sAtk+reuse)/GameTimeController.MILLIS_IN_TICK + GameTimeController.getGameTicks();
 
 		// Add this hit to the Server-Client packet Attack
-		attack.addHit(target, damage1, miss1, crit1, shld1);
+		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
 
 		// Return true if hit isn't missed
 		return !miss1;
@@ -1142,7 +1138,7 @@ public abstract class L2Character extends L2Object
         _disableCrossBowAttackEndTime = (sAtk+reuse)/GameTimeController.MILLIS_IN_TICK + GameTimeController.getGameTicks();
 
         // Add this hit to the Server-Client packet Attack
-        attack.addHit(target, damage1, miss1, crit1, shld1);
+        attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
 
         // Return true if hit isn't missed
         return !miss1;
@@ -1213,8 +1209,8 @@ public abstract class L2Character extends L2Object
 		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage2, crit2, miss2, attack.soulshot, shld2), sAtk);
 
 		// Add those hits to the Server-Client packet Attack
-		attack.addHit(target, damage1, miss1, crit1, shld1);
-		attack.addHit(target, damage2, miss2, crit2, shld2);
+		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1),
+				attack.createHit(target, damage2, miss2, crit2, shld2));
 
 		// Return true if hit 1 or hit 2 isn't missed
 		return (!miss1 || !miss2);
@@ -1379,7 +1375,7 @@ public abstract class L2Character extends L2Object
 		ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
 
 		// Add this hit to the Server-Client packet Attack
-		attack.addHit(target, damage1, miss1, crit1, shld1);
+		attack.hit(attack.createHit(target, damage1, miss1, crit1, shld1));
 
 		// Return true if hit isn't missed
 		return !miss1;

+ 75 - 58
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/Attack.java

@@ -16,6 +16,7 @@ package net.sf.l2j.gameserver.network.serverpackets;
 
 import net.sf.l2j.gameserver.model.L2Object;
 import net.sf.l2j.gameserver.model.actor.L2Character;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 
 
 /**
@@ -30,82 +31,97 @@ import net.sf.l2j.gameserver.model.actor.L2Character;
  */
 public class Attack extends L2GameServerPacket
 {
-    private class Hit
-    {
-    	protected int _targetId;
-    	protected int _damage;
-    	protected int _flags;
-
-        Hit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
-        {
-            _targetId = target.getObjectId();
-            _damage = damage;
-            if (soulshot)  _flags |= 0x10 | _grade;
-            if (crit)      _flags |= 0x20;
-            if (shld > 0)  _flags |= 0x40;
-            if (miss)      _flags |= 0x80;
-
-        }
-    }
-
-	// dh
+	public static final int HITFLAG_USESS = 0x10;
+	public static final int HITFLAG_CRIT = 0x20;
+	public static final int HITFLAG_SHLD = 0x40;
+	public static final int HITFLAG_MISS = 0x80;
+
+	public class Hit
+	{
+		protected final int _targetId;
+		protected final int _damage;
+		protected int _flags;
+
+		Hit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
+		{
+			_targetId = target.getObjectId();
+			_damage = damage;
+			if (miss)
+			{
+				_flags = HITFLAG_MISS;
+				return;
+			}
+			if (soulshot)
+				_flags = HITFLAG_USESS | Attack.this._ssGrade;
+			if (crit)
+				_flags |= HITFLAG_CRIT;
+			// dirty fix for lags on olympiad
+			if (shld > 0 && !(target instanceof L2PcInstance && ((L2PcInstance)target).isInOlympiadMode()))
+				_flags |= HITFLAG_SHLD;
+//			if (shld > 0)
+//				_flags |= HITFLAG_SHLD;
+		}
+	}
 
 	private static final String _S__06_ATTACK = "[S] 33 Attack";
-	protected final int _attackerObjId;
+	private final int _attackerObjId;
+	private final int _targetObjId;
 	public final boolean soulshot;
-    protected int _grade;
-	private int _x;
-	private int _y;
-	private int _z;
-	private int _tx;
-	private int _ty;
-	private int _tz;
-	L2Object _defender;
+	public final int _ssGrade;
+	private final int _x;
+	private final int _y;
+	private final int _z;
+	private final int _tx;
+	private final int _ty;
+	private final int _tz;
 	private Hit[] _hits;
 
 	/**
-	 * @param attacker the attacker L2Character
-	 * @param ss true if useing SoulShots
+	 * @param attacker: the attacking L2Character<br>
+	 * @param target: the target L2Object<br>
+	 * @param useShots: true if soulshots used
+	 * @param ssGrade: the grade of the soulshots
 	 */
-	public Attack(L2Character attacker, L2Object target, boolean ss, int grade)
+	public Attack(L2Character attacker, L2Object target, boolean useShots, int ssGrade)
 	{
 		_attackerObjId = attacker.getObjectId();
-		soulshot = ss;
-        _grade = grade;
+		_targetObjId = target.getObjectId();
+		soulshot = useShots;
+		_ssGrade = ssGrade;
 		_x = attacker.getX();
 		_y = attacker.getY();
 		_z = attacker.getZ();
 		_tx = target.getX();
 		_ty = target.getY();
 		_tz = target.getZ();
-		_defender = target;
-		_hits = new Hit[0];
 	}
 
-	/**
-	 * Add this hit (target, damage, miss, critical, shield) to the Server-Client packet Attack.<BR><BR>
-	 */
-	public void addHit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
+	public Hit createHit(L2Object target, int damage, boolean miss, boolean crit, byte shld)
 	{
-		// Get the last position in the hits table
-		int pos = _hits.length;
+		return new Hit( target, damage, miss, crit, shld );
+	}
 
-		// Create a new Hit object
-		Hit[] tmp = new Hit[pos+1];
+	public void hit(Hit... hits)
+	{
+		if (_hits == null)
+		{
+			_hits = hits;
+			return;
+		}
 
-		// Add the new Hit object to hits table
-		for (int i=0; i < _hits.length; i++)
-			tmp[i] = _hits[i];
-		tmp[pos] = new Hit(target, damage, miss, crit, shld);
+		// this will only happen with pole attacks
+		Hit[] tmp = new Hit[hits.length + _hits.length];
+		System.arraycopy(_hits, 0, tmp, 0, _hits.length);
+		System.arraycopy(hits, 0, tmp, _hits.length, hits.length);
 		_hits = tmp;
 	}
 
 	/**
-	 * Return True if the Server-Client packet Attack conatins at least 1 hit.<BR><BR>
+	 * Return True if the Server-Client packet Attack contains at least 1 hit.<BR><BR>
 	 */
 	public boolean hasHits()
 	{
-		return _hits.length > 0;
+		return _hits != null;
 	}
 
 	@Override
@@ -114,24 +130,25 @@ public class Attack extends L2GameServerPacket
 		writeC(0x33);
 
 		writeD(_attackerObjId);
-		writeD(_defender.getObjectId());
+		writeD(_targetObjId);
 		writeD(_hits[0]._damage);
 		writeC(_hits[0]._flags);
 		writeD(_x);
 		writeD(_y);
 		writeD(_z);
-		writeH(_hits.length-1);
-		
-		if(_hits.length > 1) // prevent sending useless packet while there is only one target.
+
+		writeH(_hits.length - 1);
+		// prevent sending useless packet while there is only one target.
+		if (_hits.length > 1)
 		{
-			for (Hit temp: _hits)
+			for (int i = 1; i < _hits.length; i++)
 			{
-				writeD(temp._targetId);
-				writeD(temp._damage);
-				writeC(temp._flags);
+				writeD(_hits[i]._targetId);
+				writeD(_hits[i]._damage);
+				writeC(_hits[i]._flags);
 			}
 		}
-		
+
 		writeD(_tx);
 		writeD(_ty);
 		writeD(_tz);