using ProtoBuf; using System; namespace MohamedAyman.Network.GamePackets { public unsafe class Attack : Interfaces.IPacket { [ProtoContract] public class AttackProto { [ProtoMember(1, IsRequired = true)] public uint TimeSpam1 = 0; [ProtoMember(2, IsRequired = true)] public uint TimeSpam2 = 0; [ProtoMember(4, IsRequired = true)] public uint Attacker = 0; [ProtoMember(5, IsRequired = true)] public uint Attacked = 0; [ProtoMember(7, IsRequired = true)] public ushort X = 0; [ProtoMember(8, IsRequired = true)] public ushort Y = 0; [ProtoMember(13, IsRequired = true)] public uint AttackType = 0; [ProtoMember(15, IsRequired = true)] public uint SpellIDandDamage = 0; [ProtoMember(16, IsRequired = true)] public uint SpellLevel = 0; [ProtoMember(19, IsRequired = true)] public uint SkillID = 0; [ProtoMember(17, IsRequired = true)] public uint KOCount = 0; [ProtoMember(25, IsRequired = true)] public uint Effect1 = 0; [ProtoMember(26, IsRequired = true)] public uint Effect2 = 0; } public const uint Melee = 2, MarriageRequest = 8, MarriageAccept = 9, Kill = 14, Magic = 24, Reflect = 26, Dash = 27, Ranged = 28, MonkMelee = 34, CloudSaints = 36, ClaimCP = 37, Obtained = 39, MerchantAccept = 40, MerchantRefuse = 41, MerchantProgress = 42, Scapegoat = 43, CounterKillSwitch = 44, FatalStrike = 45, InteractionRequest = 46, InteractionAccept = 47, InteractionRefuse = 48, InteractionEffect = 49, InteractionStopEffect = 50, ShowUseSpell = 52, SkillMove = 53, BlueDamage = 55, BackFire = 57; AttackProto Buffer; ushort packetID = 1022; public Attack(bool Create) { if (Create) { Buffer = new AttackProto(); TimeStamp = (uint)Time32.Now.GetHashCode(); } } public uint TimeStamp { get { return (uint)Buffer.TimeSpam1; } set { Buffer.TimeSpam1 = value; } } public uint Attacker { get { return Buffer.Attacker; } set { Buffer.Attacker = value; } } public ushort MagicType { get { return (ushort)Damage; } set { Damage = (uint)((MagicLevel << 16) | value); } } public ushort MagicLevel { get { return (ushort)(Damage >> 16); } set { Damage = (uint)((value << 16) | MagicType); } } public uint Attacked { get { return Buffer.Attacked; } set { Buffer.Attacked = value; } } public ushort X { get { return (ushort)Buffer.X; } set { Buffer.X = value; } } public ushort Y { get { return (ushort)Buffer.Y; } set { Buffer.Y = value; } } public uint AttackType { get { return Buffer.AttackType; } set { Buffer.AttackType = value; } } public uint Damage { get { return Buffer.SpellIDandDamage; } set { Buffer.SpellIDandDamage = value; } } public ushort SpellID { get { return (ushort)Buffer.SkillID; } set { Buffer.SkillID = value; } } public uint MonsterSpellID { get { return Buffer.SpellIDandDamage; } set { Buffer.SpellIDandDamage = value; } } public ushort KOCount { get { return (ushort)Buffer.KOCount; } set { Buffer.KOCount = value; } } public uint ResponseDamage { get { return Buffer.SpellIDandDamage; } set { Buffer.SpellIDandDamage = value; } } public uint EncodingSpellID { get { return Buffer.SkillID; } } public bool weaponspell = false; public AttackEffects Effect { get { return (AttackEffects)Buffer.Effect1; } set { Buffer.Effect1 = (uint)value; } } public AttackEffects2 Effect2 { get { return (AttackEffects2)Buffer.Effect2; } set { Buffer.Effect2 = (uint)value; } } [Flags] public enum AttackEffects { None = 0, Block = 1 << 0, Penetration = 1 << 1, CriticalStrike = 1 << 2, Unknown = 1 << 3, MetalResist = 1 << 4, Immu = 8, Break = 10, WoodResist = 1 << 5, WaterResist = 1 << 6, FireResist = 1 << 7, EarthResist = 1 << 8, AddStudyPoint = 1 << 9, //Runes TortoiseBreaker = 1 << 12, Acalanatha = 1 << 13, Assassin = 1 << 14, BurningSky = 1 << 15, FireCurse = 1 << 16 } [Flags] public enum AttackEffects2 { None = 0, EarthResist = 1 << 0, StudyPoints = 1 << 1 } public bool Decoded = false; public bool CheckWeponSpell = false; public void Send(Client.GameState client) { client.Send(ToArray()); } public byte[] ToArray() { return Buffer.ToConquerPacket(packetID); } public void Deserialize(byte[] buffer) { this.Buffer = buffer.ConvertToProto<AttackProto>(); } public static void Process(byte[] packet, Client.GameState client) { if (client.Action != 2) return; client.LastAttack = Time32.Now; Attack attack = new Attack(false); attack.Deserialize(packet); Writer.WriteUInt32(0, 8, attack.ToArray()); HandleAttack(attack, client); switch (attack.AttackType) { case Attack.CloudSaints: { CloudSaintsJar.Calculate(client, attack); break; } case Attack.Obtained: { client.Entity.ConquerPoints += client.TQPoint; attack.ResponseDamage = client.TQPoint; client.TQPoint -= client.TQPoint; client.Send(packet); break; } case Attack.MerchantAccept: { client.Entity.Merchant = 255; client.Entity.Update((byte)FlagsUpdate.DataType.Merchant, 255, 0); client.Send(packet); break; } case Attack.MerchantRefuse: { client.Entity.Update((byte)FlagsUpdate.DataType.Merchant, 0, 0); Database.MerchantTable.Cancel(client); client.Send(packet); break; } //default: Console.WriteLine("[Attack] Unknown Type: " + attack.AttackType + ""); break; } } public static void HandleAttack(Attack attack, Client.GameState client) { #region Absolution if (client.Entity.ContainsFlag((ulong)FlagsUpdate.Flags.Absolution)) { client.Entity.RemoveFlag((ulong)FlagsUpdate.Flags.Absolution); FlagsUpdate upgrade2 = new FlagsUpdate(true); upgrade2.UID = client.Entity.UID; upgrade2.Append(106, 0, 0, 0, 0); client.Send(upgrade2.ToArray()); } #endregion client.Entity.SpiritFocus = false; client.Entity.OnCheckGuard = false; client.Entity.OnCheckSaqueo = false; DialyQuestsEffect.CheckCancelGuard(client); client.Entity.RemoveMagicDefender(); client.Entity.AttackPacket = attack; new Game.Attacking.Handle(attack, client.Entity, null); } } }