public void CheckWriting1Packet() { m_PacketReader.RegisterType(typeof(WrapperPacket)); WrapperPacket writtenPacket = new WrapperPacket("Test1", 100); m_PacketWriter.Write(writtenPacket); Assert.AreEqual(108, m_MemoryStream.Position); m_MemoryStream.Position = 0; IPacket readPacket = m_PacketReader.Read(); Assert.AreEqual(writtenPacket, readPacket); }
public void Read_Packet_With_Complex_Content() { PacketOutput output = _packetReader.Read("inv 1 0.5.4.1.0 1.2.9.7.0"); Check.That(output.Header).Is("inv"); Check.That(output.Content).IsNotNullOrEmpty(); string[] contentSplit = output.Content.Split(' '); Check.That(contentSplit).CountIs(3); Check.That(contentSplit).HasElementAt(0).WhichIs("1"); Check.That(contentSplit).HasElementAt(1).WhichIs("0.5.4.1.0"); Check.That(contentSplit).HasElementAt(2).WhichIs("1.2.9.7.0"); }
public void ReadFromPacket(IPacketReader reader) { _ = reader.ReadByte(); // FieldKey _ = reader.ReadInt(); // dr0 _ = reader.ReadInt(); // dr1 var attackInfo = reader.ReadByte(); DamagePerMob = attackInfo >> 0 & 0xF; MobCount = attackInfo >> 4 & 0xF; _ = reader.ReadInt(); // dr2 _ = reader.ReadInt(); // dr3 SkillID = reader.ReadInt(); _ = reader.ReadBool(); // unk _ = reader.ReadInt(); // dr rand _ = reader.ReadInt(); // crc _ = reader.ReadInt(); // skillLevel crc _ = reader.ReadInt(); // skillLevel crc Keydown = 0; // TODO keydownskill check - int keydown var skillFlags = reader.ReadByte(); IsFinalAfterSlashBlast = (skillFlags & 0x0) > 0; IsShadowPartner = (skillFlags & 8) > 0; IsSerialAttack = (skillFlags & 32) > 0; var actionInfo = reader.ReadShort(); Action = actionInfo & 0x7FFF; IsFacingLeft = (actionInfo >> 15 & 1) > 0; _ = reader.ReadInt(); // action crc? ActionType = reader.ReadByte(); ActionSpeed = reader.ReadByte(); ActionTime = reader.ReadInt(); Phase = reader.ReadInt(); // BattleMage? for (var i = 0; i < MobCount; i++) { Mobs.Add(reader.Read(new ClientAttackMobInfo(DamagePerMob))); } _ = reader.ReadPoint2D(); // unk // TODO grenade readpoint2d }
public IPacket Deserialize(string packet) { PacketOutput output = _packetReader.Read(packet); CachedType cachedType = _reflectionCache.GetCachedType(output.Header); if (string.IsNullOrEmpty(output.Header)) { throw new InvalidOperationException("Failed to deserialize packet"); } char firstChar = output.Header[0]; if (firstChar == '$' || firstChar == '%') { string name = output.Header.Remove(0); string[] args = output.Content.Split(' '); _logger.Debug($"[DESERIALIZER] Deserialized Command packet [Header: {firstChar} / Name {name}]"); return(new CommandPacket { Header = $"{firstChar}", Content = output.Content, Name = name, Arguments = args }); } if (cachedType == null) { _logger.Debug($"[DESERIALIZER] No type found in cache for header {output.Header}"); return(new UnknownPacket { Header = output.Header, Content = packet }); } var deserialized = (IPacket)_conversionFactory.ToObject(output.Content, cachedType.PacketType); deserialized.Header = output.Header; deserialized.Content = output.Content; _logger.Debug($"[DESERIALIZER] {output.Header} successfully deserialized to {deserialized.GetType()}"); return(deserialized); }
protected override async Task Handle( GameStageUser stageUser, IFieldObjUser user, IPacketReader packet ) { _ = packet.ReadLong(); _ = packet.ReadByte(); _ = packet.ReadLong(); _ = packet.ReadInt(); _ = packet.ReadInt(); _ = packet.ReadInt(); var path = packet.Read(new MovePath()); var movement = new UnstructuredOutgoingPacket(PacketSendOperations.UserMove); movement.WriteInt(user.ID); movement.Write(path); await user.Move(path); await user.FieldSplit.Dispatch(user, movement); }
protected override async Task Handle( GameStageUser stageUser, IFieldObjUser controller, IFieldObjNPC controlled, IPacketReader packet ) { var movement = new UnstructuredOutgoingPacket(PacketSendOperations.NpcMove); movement.WriteInt(controlled.ID); movement.WriteByte(packet.ReadByte()); // TODO: actions movement.WriteByte(packet.ReadByte()); if (controlled.Info.Move) { var path = packet.Read(new MovePath()); movement.Write(path); await controlled.Move(path); } await controlled.FieldSplit.Dispatch(movement); }
protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet) { var clientAttackInfo = packet.Read(new ClientAttackInfo()); var skill = (Skill)clientAttackInfo.SkillID; var skillLevel = clientAttackInfo.SkillID > 0 ? user.Character.GetSkillLevel(clientAttackInfo.SkillID) : 0; var damageType = Type == AttackType.Magic ? DamageType.Magic : DamageType.Physical; var damageApply = new List <Tuple <IFieldObjMob, int> >(); if (Type == AttackType.Melee) { // TODO bmage blows } if (Type == AttackType.Body) { // TODO teleport mastery } var operation = (PacketSendOperations)((int)PacketSendOperations.UserMeleeAttack + (int)Type); var response = new UnstructuredOutgoingPacket(operation); response.WriteInt(user.ID); response.WriteByte((byte)(clientAttackInfo.DamagePerMob | 16 * clientAttackInfo.MobCount)); response.WriteByte(user.Character.Level); response.WriteByte((byte)skillLevel); if (skillLevel > 0) { response.WriteInt(clientAttackInfo.SkillID); } response.WriteByte((byte)( 1 * Convert.ToByte(clientAttackInfo.IsFinalAfterSlashBlast) | 8 * Convert.ToByte(clientAttackInfo.IsShadowPartner) | 16 * 0 | 32 * Convert.ToByte(clientAttackInfo.IsSerialAttack) )); response.WriteShort((short)( clientAttackInfo.Action & 0x7FFF | Convert.ToByte(clientAttackInfo.IsFacingLeft) << 15) ); if (clientAttackInfo.Action <= 0x110) { response.WriteByte(0); // nMastery response.WriteByte(0); // v82 response.WriteInt(0); // bMovingShoot clientAttackInfo.Mobs.ForEach(m => { var critical = new bool[clientAttackInfo.DamagePerMob]; var damage = new int[clientAttackInfo.DamagePerMob]; var totalDamage = m.Damage.Sum(); var mob = user.Field.GetObject <IFieldObjMob>(m.MobID); response.WriteInt(m.MobID); response.WriteByte(m.HitAction); if (mob != null) { var equipInventory = user.Character.Inventories[ItemInventoryType.Equip]; var serverAttackInfo = new AttackInfo(user, mob) { WeaponID = equipInventory.Items.ContainsKey((short)BodyPart.Weapon) ? equipInventory.Items[(short)BodyPart.Weapon].TemplateID : 0, BulletID = 0, SkillID = clientAttackInfo.SkillID, SkillLevel = skillLevel }; var calculatedDamage = damageType == DamageType.Physical ? user.Damage.CalculateCharacterPDamage(serverAttackInfo) : user.Damage.CalculateCharacterMDamage(serverAttackInfo); var calculatedTotalDamage = calculatedDamage.Select(d => d.Damage).Sum(); // TODO cheatdetector? if (clientAttackInfo.DamagePerMob != calculatedDamage.Length) { user.Message($"Attack count mismatch: {clientAttackInfo.DamagePerMob} : {calculatedDamage.Length}"); return; } if (totalDamage != calculatedTotalDamage) { user.Message($"Client damage: {string.Join(" + ", m.Damage.Select(m => $"{m}"))} = {totalDamage}"); user.Message($"Server damage: {string.Join(" + ", calculatedDamage.Select(m => $"{m.Damage}"))} = {calculatedTotalDamage}"); } damageApply.Add(Tuple.Create(mob, calculatedTotalDamage)); for (var i = 0; i < clientAttackInfo.DamagePerMob; i++) { critical[i] = calculatedDamage[i].IsCritical; damage[i] = calculatedDamage[i].Damage; } } else { user.Damage.SkipCalculationForCharacterDamage(); } for (var i = 0; i < clientAttackInfo.DamagePerMob; i++) { response.WriteBool(critical[i]); response.WriteInt(damage[i]); } }); } // TODO Keydown await user.FieldSplit.Dispatch(user, response); await Task.WhenAll(damageApply.Select(async a => { var(mob, damage) = a; mob.Controller = user; await mob.Damage(user, damage); })); }
protected override async Task Handle( GameStageUser stageUser, IFieldObjUser controller, IFieldObjMob controlled, IPacketReader packet ) { if (controlled.HP <= 0) { return; } var mobCtrlSN = packet.ReadShort(); var v7 = packet.ReadByte(); //v85 = nDistance | 4 * (v184 | 2 * ((unsigned __int8)retaddr | 2 * v72)); [ CONFIRMED ] var oldSplit = (v7 & 0xF0) != 0; //this is a type of CFieldSplit var mobMoveStartResult = (v7 & 0xF) != 0; var curSplit = packet.ReadByte(); var illegalVelocity = packet.ReadInt(); var v8 = packet.ReadByte(); var cheatedRandom = (v8 & 0xF0) != 0; var cheatedCtrlMove = (v8 & 0xF) != 0; var multiTargetForBall = packet.ReadInt(); for (var i = 0; i < multiTargetForBall; i++) { packet.ReadLong(); // int, int } var randTimeForAreaAttack = packet.ReadInt(); for (var i = 0; i < randTimeForAreaAttack; i++) { packet.ReadInt(); } packet.ReadInt(); // HackedCode packet.ReadInt(); // idk packet.ReadInt(); // HackedCodeCrc packet.ReadInt(); // idk var path = packet.Read(new MovePath()); await controlled.Move(path); var response = new UnstructuredOutgoingPacket(PacketSendOperations.MobCtrlAck); response.WriteInt(controlled.ID); response.WriteShort(mobCtrlSN); response.WriteBool(mobMoveStartResult); response.WriteShort((short)controlled.MP); // nMP response.WriteByte(0); // SkillCommand response.WriteByte(0); // SLV await controller.Dispatch(response); var movement = new UnstructuredOutgoingPacket(PacketSendOperations.MobMove); movement.WriteInt(controlled.ID); movement.WriteBool(false); // NotForceLandingWhenDiscard movement.WriteBool(false); // NotChangeAction movement.WriteBool(false); // NextAttackPossible movement.WriteBool(false); // Left movement.WriteInt(illegalVelocity); movement.WriteInt(0); // MultiTargetForBall movement.WriteInt(0); // RandTimeForAreaAttack movement.Write(path); await controlled.Field.Dispatch(controller, movement); }