/// <summary> /// Writes the log. /// </summary> /// <param name="context">The context.</param> /// <param name="stream">The stream.</param> /// <param name="callback">The callback for UI updates.</param> public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback) { int playerOid = -1; byte playerLevel = 0; string playerClassName = ""; Skills playerSkills = new Skills(); using (StreamWriter s = new StreamWriter(stream)) { foreach (PacketLog log in context.LogManager.Logs) { for (int i = 0; i < log.Count; i++) { if (callback != null && (i & 0xFFF) == 0) // update progress every 4096th packet { callback(i, log.Count - 1); } Packet pak = log[i]; if (pak is StoC_0x20_PlayerPositionAndObjectID) { StoC_0x20_PlayerPositionAndObjectID plr = (StoC_0x20_PlayerPositionAndObjectID)pak; playerOid = plr.PlayerOid; #if SHOW_PACKETS s.WriteLine("playerOid:0x{0:X4}", playerOid); #endif } else if (pak is StoC_0x16_VariousUpdate) { // Name, level, class StoC_0x16_VariousUpdate stat = (StoC_0x16_VariousUpdate)pak; if (stat.SubCode == 3) { StoC_0x16_VariousUpdate.PlayerUpdate subData = (StoC_0x16_VariousUpdate.PlayerUpdate)stat.SubData; playerLevel = subData.playerLevel; playerClassName = subData.className; #if SHOW_PACKETS s.WriteLine("{0, -16} 0x16:3 class:{1} level:{2}", pak.Time.ToString(), playerClassName, playerLevel); #endif } } else if (pak is StoC_0xAF_Message) { StoC_0xAF_Message msg = (StoC_0xAF_Message)pak; #if SHOW_PACKETS // s.WriteLine("{0, -16} 0xAF 0x{1:X2} {2}", pak.Time.ToString(), msg.Type, msg.Text); #endif } } } } }
/// <summary> /// Activates a log action. /// </summary> /// <param name="context">The context.</param> /// <param name="selectedPacket">The selected packet.</param> /// <returns><c>true</c> if log data tab should be updated.</returns> public override bool Activate(IExecutionContext context, PacketLocation selectedPacket) { PacketLog log = context.LogManager.GetPacketLog(selectedPacket.LogIndex); int selectedIndex = selectedPacket.PacketIndex; string serverName = "UNKNOWN"; int serverId = -1; int serverColorHandling = -1; int sessionId = -1; int objectId = -1; int petId = -1; int healthPercent = -1; int endurancePercent = -1; int manaPercent = -1; int concentrationPercent = -1; int speed = -1; int maxspeed = -1; int clientTargetOid = -1; int serverTargetOid = -1; int regionXOffset = 0; int regionYOffset = 0; int glocX = -1; int glocY = -1; int glocRegion = -1; string loc = "UNKNOWN"; string gloc = "UNKNOWN"; string state = ""; string charName = "UNKNOWN"; string lastName = ""; int playersInGroup = -1; int indexInGroup = -1; int mountId = -1; int mountSlot = -1; int level = -1; int mana = -1; int manaMax = -1; int health = -1; int healthMax = -1; int conc = -1; int concMax = -1; string className = "UNKNOWN"; string raceName = ""; int realm_level = -1; string realm_title = ""; int champ_level = -1; string champ_title = ""; int ml_level = -1; int houseLot = -1; string ml_title = ""; int guildID = -1; string guildName = "None"; string guildRank = ""; string enterRegionName = ""; string petInfo = ""; int insideHouseId = 0; Hashtable enterSubRegion = new Hashtable(); bool flagAwait0xA9 = false; for (int i = 0; i <= selectedIndex; i++) { Packet pak = log[i]; if (pak is CtoS_0xA9_PlayerPosition) { CtoS_0xA9_PlayerPosition pos = (CtoS_0xA9_PlayerPosition)pak; speed = pos.Status & 0x1FF; byte plrState = (byte)((pos.Status >> 10) & 7); state = plrState > 0 ? ((StoC_0xA9_PlayerPosition.PlrState)plrState).ToString() : ""; if ((pos.Status & 0x200) == 0x200) { state += ",Backward"; } if ((pos.Status & 0x8000) == 0x8000) { state += ",StrafeRight"; } if ((pos.Status & 0x4000) == 0x4000) { state += ",StrafeLeft"; } if ((pos.Status & 0x2000) == 0x2000) { state += "Move"; } if ((pos.Flag & 0x01) == 0x01) { state += ",CtoS_0xA9_Flagx01"; } if ((pos.Flag & 0x02) == 0x02) { state += ",Underwater"; } if ((pos.Flag & 0x04) == 0x04) { state += ",PetInView"; } if ((pos.Flag & 0x08) == 0x08) { state += ",GT"; } if ((pos.Flag & 0x10) == 0x10) { state += ",CheckTargetInView"; } if ((pos.Flag & 0x20) == 0x20) { state += ",TargetInView"; } if ((pos.Flag & 0x40) == 0x40) { state += ",MoveTo"; } if ((pos.Health & 0x80) == 0x80) { state += ",Combat"; } if ((pos.Speed & 0x8000) == 0x8000) { state += ",FallDown"; } loc = string.Format("({0,-3}): ({1,-6} {2,-6} {3,-5})", pos.CurrentZoneId, pos.CurrentZoneX, pos.CurrentZoneY, pos.CurrentZoneZ); if (flagAwait0xA9) { if (glocX != -1 && glocY != -1) { regionXOffset = glocX - pos.CurrentZoneX; regionYOffset = glocY - pos.CurrentZoneY; } flagAwait0xA9 = false; } gloc = string.Format("({0,-3}): ({1,-6} {2,-6} {3,-5})", glocRegion, regionXOffset + pos.CurrentZoneX, regionYOffset + pos.CurrentZoneY, pos.CurrentZoneZ); } else if (pak is StoC_0x16_VariousUpdate) { StoC_0x16_VariousUpdate stat = (StoC_0x16_VariousUpdate)pak; if (stat.SubCode == 3) { StoC_0x16_VariousUpdate.PlayerUpdate subData = (StoC_0x16_VariousUpdate.PlayerUpdate)stat.SubData; level = subData.playerLevel; className = subData.className; raceName = subData.raceName; healthMax = (ushort)(((subData.maxHealthHigh & 0xFF) << 8) | (subData.maxHealthLow & 0xFF)); realm_level = subData.realmLevel; realm_title = subData.realmTitle; ml_level = subData.mlLevel; ml_title = subData.mlTitle; houseLot = subData.personalHouse; guildName = subData.guildName; guildRank = subData.guildRank; lastName = subData.lastName; charName = subData.playerName; if (subData is StoC_0x16_VariousUpdate_179.PlayerUpdate_179) { champ_level = (subData as StoC_0x16_VariousUpdate_179.PlayerUpdate_179).championLevel; champ_title = (subData as StoC_0x16_VariousUpdate_179.PlayerUpdate_179).championTitle; } } else if (stat.SubCode == 6) { StoC_0x16_VariousUpdate.PlayerGroupUpdate subData = (StoC_0x16_VariousUpdate.PlayerGroupUpdate)stat.SubData; playersInGroup = stat.SubCount; for (int j = 0; j < stat.SubCount; j++) { StoC_0x16_VariousUpdate.GroupMember member = subData.groupMembers[j]; if (objectId >= 0 && objectId == member.oid) { indexInGroup = j; } } } } else if (pak is CtoS_0x10_CharacterSelectRequest) { CtoS_0x10_CharacterSelectRequest login = (CtoS_0x10_CharacterSelectRequest)pak; charName = login.CharName; } else if (pak is CtoS_0xB0_TargetChange) { CtoS_0xB0_TargetChange trg = (CtoS_0xB0_TargetChange)pak; clientTargetOid = trg.Oid; } else if (pak is StoC_0xAF_Message) { StoC_0xAF_Message msg = (StoC_0xAF_Message)pak; if (msg.Text.StartsWith("You have entered ")) { enterRegionName = regionNameFromMessage(msg.Text.Substring(17)); } else if (msg.Text.StartsWith("(Region) You have entered ")) { string enterSubRegionName = regionNameFromMessage(msg.Text.Substring(26)); if (!enterSubRegion.ContainsKey(enterSubRegionName)) { enterSubRegion.Add(enterSubRegionName, enterSubRegionName); } } else if (msg.Text.StartsWith("(Region) You have left ")) { string enterSubRegionName = regionNameFromMessage(msg.Text.Substring(23)); enterSubRegion.Remove(enterSubRegionName); } } else if (pak is StoC_0xF6_ChangeTarget) { StoC_0xF6_ChangeTarget trg = (StoC_0xF6_ChangeTarget)pak; serverTargetOid = trg.Oid; } else if (pak is StoC_0xB6_UpdateMaxSpeed) { StoC_0xB6_UpdateMaxSpeed spd = (StoC_0xB6_UpdateMaxSpeed)pak; maxspeed = spd.MaxSpeedPercent; } else if (pak is StoC_0xAD_StatusUpdate) { StoC_0xAD_StatusUpdate status = (StoC_0xAD_StatusUpdate)pak; healthPercent = status.HealthPercent; endurancePercent = status.EndurancePercent; manaPercent = status.ManaPercent; concentrationPercent = status.ConcentrationPercent; if (pak is StoC_0xAD_StatusUpdate_190) { health = (pak as StoC_0xAD_StatusUpdate_190).Health; healthMax = (pak as StoC_0xAD_StatusUpdate_190).MaxHealth; mana = (pak as StoC_0xAD_StatusUpdate_190).Power; manaMax = (pak as StoC_0xAD_StatusUpdate_190).MaxPower; conc = (pak as StoC_0xAD_StatusUpdate_190).Concentration; concMax = (pak as StoC_0xAD_StatusUpdate_190).MaxConcentration; } } else if (pak is StoC_0x28_SetSessionId) { StoC_0x28_SetSessionId session = (StoC_0x28_SetSessionId)pak; sessionId = session.SessionId; } else if (pak is StoC_0x20_PlayerPositionAndObjectID) { StoC_0x20_PlayerPositionAndObjectID posAndOid = (StoC_0x20_PlayerPositionAndObjectID)pak; objectId = posAndOid.PlayerOid; glocX = (int)posAndOid.X; glocY = (int)posAndOid.Y; if ((pak as StoC_0x20_PlayerPositionAndObjectID_171) != null) { glocRegion = (pak as StoC_0x20_PlayerPositionAndObjectID_171).Region; } loc = "UNKNOWN"; gloc = string.Format("({0,-3}): ({1,-6} {2,-6} {3,-5})", glocRegion, posAndOid.X, posAndOid.Y, posAndOid.Z); flagAwait0xA9 = true; enterSubRegion.Clear(); enterRegionName = ""; insideHouseId = 0; } else if (pak is StoC_0xDE_SetObjectGuildId) { StoC_0xDE_SetObjectGuildId guildId = (StoC_0xDE_SetObjectGuildId)pak; if (objectId == guildId.Oid) { guildID = guildId.GuildId; } if (guildId.ServerId == 0xFF) // set ObjectID for old logs (1.70-) { objectId = guildId.Oid; } } else if (pak is StoC_0x04_CharacterJump) { StoC_0x04_CharacterJump plrJump = (StoC_0x04_CharacterJump)pak; if (plrJump.X == 0 && plrJump.Y == 0 && plrJump.Z == 0) // skip /faceloc { continue; } objectId = plrJump.PlayerOid; glocX = (int)plrJump.X; glocY = (int)plrJump.Y; insideHouseId = plrJump.HouseId; loc = "UNKNOWN"; gloc = string.Format("({0,-3}): ({1,-6} {2,-6} {3,-5})", glocRegion, plrJump.X, plrJump.Y, plrJump.Z); flagAwait0xA9 = true; } else if (pak is StoC_0x88_PetWindowUpdate) { StoC_0x88_PetWindowUpdate pet = (StoC_0x88_PetWindowUpdate)pak; petId = pet.PetId; } else if (pak is StoC_0xDA_NpcCreate) { if (petId == -1) { continue; } StoC_0xDA_NpcCreate npc = (StoC_0xDA_NpcCreate)pak; if (npc.Oid != petId) { continue; } petInfo = string.Format(" \"{0}\" level:{1} model:0x{2:X4}", npc.Name, npc.Level, npc.Model); } else if (pak is StoC_0xC8_PlayerRide) { StoC_0xC8_PlayerRide ride = (StoC_0xC8_PlayerRide)pak; if (objectId >= 0 && objectId == ride.RiderOid) { if (ride.Flag == 0) { mountId = -1; mountSlot = -1; } else { mountId = ride.MountOid; mountSlot = ride.Slot; } } } else if (pak is StoC_0xFB_CharStatsUpdate_175) { if ((pak as StoC_0xFB_CharStatsUpdate_175).Flag != 0xFF) { healthMax = (pak as StoC_0xFB_CharStatsUpdate_175).MaxHealth; } } else if (pak is StoC_0xFB_CharStatsUpdate) { healthMax = (pak as StoC_0xFB_CharStatsUpdate).MaxHealth; } else if (pak is StoC_0x2A_LoginGranted) { StoC_0x2A_LoginGranted server = (StoC_0x2A_LoginGranted)pak; serverName = server.ServerName; serverId = server.ServerId; serverColorHandling = server.ColorHandling; } } int additionStrings = 0; StringBuilder str = new StringBuilder(); if (serverId > 0) { str.AppendFormat(" server: \"{0}\" id:0x{1:X2} color:{2}\n", serverName, serverId, serverColorHandling); additionStrings++; } str.AppendFormat("session id: 0x{0}\n", ValueToString(sessionId, "X4")); str.AppendFormat(" object id: 0x{0}\n", ValueToString(objectId, "X4")); str.AppendFormat(" pet id: 0x{0}{1}\n", ValueToString(petId, "X4"), petInfo); str.AppendFormat(" char name: {0}{1}\n", charName, lastName != "None" ? string.Format(" \"{0}\"", lastName) : ""); str.AppendFormat(" level: {0} {1}{2}\n", ValueToString(level), className, (raceName != "" ? " (" + raceName + ")" : "")); if (guildName != "None") { str.AppendFormat(" guild: {0}", guildName); str.AppendFormat(" rank:{0}", guildRank); if (guildID != -1) { str.AppendFormat(" guildId:0x{0:X4}", guildID); } str.AppendFormat("\n"); additionStrings++; } if (realm_level > 0) { str.AppendFormat("RealmLevel: {0} \"{1}\"\n", ValueToString(realm_level), realm_title); additionStrings++; } if (ml_level > 0) { str.AppendFormat(" ML level: {0} \"{1}\"\n", ValueToString(ml_level), ml_title); additionStrings++; } if (champ_level > 0) { str.AppendFormat("ChampLevel: {0} \"{1}\"\n", ValueToString(champ_level), champ_title); additionStrings++; } str.AppendFormat("\n"); if (houseLot > 0) { str.AppendFormat(" HouseLot: 0x{0}\n", ValueToString(houseLot, "X4")); additionStrings++; } if (mountId > 0) { str.AppendFormat(" mount id: 0x{0} (slot:{1})\n", ValueToString(mountId, "X4"), ValueToString(mountSlot)); additionStrings++; } if (playersInGroup > 0) { str.AppendFormat(" group: {0}[{1}]\n", ValueToString(indexInGroup), ValueToString(playersInGroup)); additionStrings++; } str.AppendFormat(" speed: {0,3}\n", ValueToString(speed)); str.AppendFormat(" maxSpeed: {0,3}%\n", ValueToString(maxspeed)); str.AppendFormat(" health: {0,3}%", ValueToString(healthPercent)); if (health != -1) { str.AppendFormat(" ({0}/{1})", health, healthMax); } else if (healthMax != -1) { str.AppendFormat(" (maxHealth:{0})", healthMax); } str.Append('\n'); str.AppendFormat(" mana: {0,3}%", ValueToString(manaPercent)); if (mana != -1) { str.AppendFormat(" ({0}/{1})", mana, manaMax); } str.Append('\n'); str.AppendFormat(" endurance: {0,3}%\n", ValueToString(endurancePercent)); str.AppendFormat("concentration: {0,3}%", ValueToString(concentrationPercent)); if (conc != -1) { str.AppendFormat(" ({0}/{1})", conc, concMax); } str.Append('\n'); str.AppendFormat(" clientTarget: 0x{0}\n", ValueToString(clientTargetOid, "X4")); str.AppendFormat(" checkTarget: 0x{0}\n", ValueToString(serverTargetOid, "X4")); str.AppendFormat(" current zone: {0}{1}\n", loc, enterRegionName == "" ? "" : " (" + enterRegionName + ")"); str.AppendFormat(" calced gloc: {0}\n", gloc); int subReg = 0; foreach (string subRegionName in enterSubRegion.Values) { str.AppendFormat(" subRegion[{0}]: {1}\n", subReg++, subRegionName); additionStrings++; } if (insideHouseId != 0) { str.AppendFormat(" inside House: {0}\n", insideHouseId); additionStrings++; } str.AppendFormat(" flags: {0}\n", state); InfoWindowForm infoWindow = new InfoWindowForm(); infoWindow.Text = "Player info (right click to close)"; infoWindow.Width = 500; infoWindow.Height = 310 + 15 * additionStrings; infoWindow.InfoRichTextBox.Text = str.ToString(); infoWindow.StartWindowThread(); return(false); }
/// <summary> /// Writes the log. /// </summary> /// <param name="context">The context.</param> /// <param name="stream">The stream.</param> /// <param name="callback">The callback for UI updates.</param> public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback) { StoC_0x16_VariousUpdate.CraftingSkillsUpdate lastCraftingSkill = null; StoC_0xF3_TimerWindow lastCraftBeginTimerPacket = null; StoC_0xF3_TimerWindow lastCloseTimerPacket = null; ushort lastReceipId = 0; SortedList recpToSkill = new SortedList(); //Alb receipts recpToSkill.Add(1, 4); // Alchemy recpToSkill.Add(701, 2); // Armorcraft recpToSkill.Add(1401, 8); // Clothworking recpToSkill.Add(1801, 15); // Basic Crafting recpToSkill.Add(2051, 12); // Fletching recpToSkill.Add(2751, 7); // Leatherworking recpToSkill.Add(3001, 11); // Tailoring recpToSkill.Add(3451, 6); // Metalworking recpToSkill.Add(4165, 3); // Siegecraft recpToSkill.Add(4201, 13); // Spellcraft recpToSkill.Add(4901, 11); // Tailoring recpToSkill.Add(5601, 1); // Weaponcrafting recpToSkill.Add(6501, 14); // Woodworking //Mid receipts recpToSkill.Add(7001, 4); // Alchemy recpToSkill.Add(7701, 2); // Armorcraft recpToSkill.Add(8401, 8); // Clothworking recpToSkill.Add(8801, 15); // Basic Crafting recpToSkill.Add(9051, 12); // Fletching recpToSkill.Add(9751, 7); // Leatherworking recpToSkill.Add(10001, 11); // Tailoring recpToSkill.Add(10451, 6); // Metalworking recpToSkill.Add(11165, 3); // Siegecraft recpToSkill.Add(11201, 13); // Spellcraft recpToSkill.Add(11901, 11); // Tailoring recpToSkill.Add(12601, 1); // Weaponcrafting recpToSkill.Add(13301, 14); // Woodworking //Hib receipts recpToSkill.Add(14001, 4); // Alchemy recpToSkill.Add(14701, 2); // Armorcraft recpToSkill.Add(15401, 8); // Clothworking recpToSkill.Add(15801, 15); // Basic Crafting recpToSkill.Add(16051, 12); // Fletching recpToSkill.Add(16751, 7); // Leatherworking recpToSkill.Add(17001, 11); // Tailoring recpToSkill.Add(17451, 6); // Metalworking recpToSkill.Add(18165, 3); // Siegecraft recpToSkill.Add(18201, 13); // Spellcraft recpToSkill.Add(18901, 11); // Tailoring recpToSkill.Add(19601, 1); // Weaponcrafting recpToSkill.Add(20301, 14); // Woodworking using (StreamWriter s = new StreamWriter(stream)) { foreach (PacketLog log in context.LogManager.Logs) { for (int i = 0; i < log.Count; i++) { if (callback != null && (i & 0xFFF) == 0) // update progress every 4096th packet { callback(i, log.Count - 1); } Packet pak = log[i]; if (pak is StoC_0x16_VariousUpdate) { StoC_0x16_VariousUpdate stat = pak as StoC_0x16_VariousUpdate; if (stat.SubCode == 8) { lastCraftingSkill = (StoC_0x16_VariousUpdate.CraftingSkillsUpdate)stat.SubData; } } else if (pak is CtoS_0xED_CraftItem) { CtoS_0xED_CraftItem craft = pak as CtoS_0xED_CraftItem; lastReceipId = craft.ReceptId; } else if (pak is StoC_0xF3_TimerWindow) { StoC_0xF3_TimerWindow timer = pak as StoC_0xF3_TimerWindow; if (timer.Flag == 1 && timer.Message.StartsWith("Making: ")) { lastCraftBeginTimerPacket = timer; } else if (timer.Flag == 0) { lastCloseTimerPacket = timer; } } else if (pak is StoC_0xAF_Message) { StoC_0xAF_Message message = pak as StoC_0xAF_Message; if (message.Text.StartsWith("You successfully make ")) { byte craftSkill = (byte)FindSkill(recpToSkill, lastReceipId); // StringBuilder str = new StringBuilder(); // lastCraftingSkill.MakeString(str, true); // s.WriteLine(str); bool found = false; foreach (StoC_0x16_VariousUpdate.CraftingSkill cs in lastCraftingSkill.skills) { if (cs.icon == craftSkill) { s.WriteLine(string.Format("{0}, crafting skill:{1}({3}:{4}) receptId:{2} (time:{5}, pakDiffTime:{6})", message.Text, craftSkill, lastReceipId, cs.name, cs.points, lastCraftBeginTimerPacket.Timer, lastCloseTimerPacket.Time - lastCraftBeginTimerPacket.Time)); found = true; break; } } if (!found) { s.WriteLine(string.Format("{0}, crafting skill:{1} receptId:{2}", message.Text, craftSkill, lastReceipId)); } } else if (message.Text.StartsWith("You gain skill in")) { s.WriteLine(message.Text); } } } // for (log.packets) } // foreach(context.logs) } }
/// <summary> /// Writes the log. /// </summary> /// <param name="context">The context.</param> /// <param name="stream">The stream.</param> /// <param name="callback">The callback for UI updates.</param> public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback) { SortedList oidInfo = new SortedList(); IList CombatWaitMessage = new ArrayList(); Hashtable styleIcons = new Hashtable(); Hashtable plrInfo = new Hashtable(); weapons = new StoC_0x02_InventoryUpdate.Item[4]; PlayerInfo playerInfo = null; // = new PlayerInfo(); int playerOid = -1; string nameKey = ""; string statKey = ""; string plrName = ""; string plrClass = ""; int plrLevel = 0; int countBC = 0; using (StreamWriter s = new StreamWriter(stream)) { foreach (PacketLog log in context.LogManager.Logs) { for (int i = 0; i < log.Count; i++) { if (callback != null && (i & 0xFFF) == 0) // update progress every 4096th packet { callback(i, log.Count - 1); } Packet pak = log[i]; // Enter region (get new self OID) if (pak is StoC_0x20_PlayerPositionAndObjectID) { StoC_0x20_PlayerPositionAndObjectID plr = (StoC_0x20_PlayerPositionAndObjectID)pak; playerOid = plr.PlayerOid; oidInfo.Clear(); oidInfo[plr.PlayerOid] = new ObjectInfo(eObjectType.player, "You", 0); s.WriteLine("{0, -16} playerOid:0x{1:X4}", pak.Time.ToString(), playerOid); } // Fill objects OID else if (pak is StoC_0xD4_PlayerCreate) { StoC_0xD4_PlayerCreate player = (StoC_0xD4_PlayerCreate)pak; oidInfo[player.Oid] = new ObjectInfo(eObjectType.player, player.Name, player.Level); } else if (pak is StoC_0x4B_PlayerCreate_172) { StoC_0x4B_PlayerCreate_172 player = (StoC_0x4B_PlayerCreate_172)pak; oidInfo[player.Oid] = new ObjectInfo(eObjectType.player, player.Name, player.Level); } else if (pak is StoC_0x12_CreateMovingObject) { StoC_0x12_CreateMovingObject obj = (StoC_0x12_CreateMovingObject)pak; oidInfo[obj.ObjectOid] = new ObjectInfo(eObjectType.movingObject, obj.Name, 0); } else if (pak is StoC_0x6C_KeepComponentOverview) { StoC_0x6C_KeepComponentOverview keep = (StoC_0x6C_KeepComponentOverview)pak; oidInfo[keep.Uid] = new ObjectInfo(eObjectType.keep, string.Format("keepId:0x{0:X4} componentId:{1}", keep.KeepId, keep.ComponentId), 0); } else if (pak is StoC_0xDA_NpcCreate) { StoC_0xDA_NpcCreate npc = (StoC_0xDA_NpcCreate)pak; oidInfo[npc.Oid] = new ObjectInfo(eObjectType.npc, npc.Name, npc.Level); } else if (pak is StoC_0xD9_ItemDoorCreate) { StoC_0xD9_ItemDoorCreate item = (StoC_0xD9_ItemDoorCreate)pak; eObjectType type = eObjectType.staticObject; if (item.ExtraBytes > 0) { type = eObjectType.door; } oidInfo[item.Oid] = new ObjectInfo(type, item.Name, 0); } // Fill current weapons else if (pak is StoC_0x02_InventoryUpdate) { StoC_0x02_InventoryUpdate invPack = (StoC_0x02_InventoryUpdate)pak; if (invPack.PreAction == 1 || invPack.PreAction == 0) { VisibleSlots = invPack.VisibleSlots; for (int j = 0; j < invPack.SlotsCount; j++) { StoC_0x02_InventoryUpdate.Item item = (StoC_0x02_InventoryUpdate.Item)invPack.Items[j]; switch (item.slot) { case 10: weapons[0] = item; break; case 11: weapons[1] = item; break; case 12: weapons[2] = item; break; case 13: weapons[3] = item; break; default: break; } } } } // Fill character stats else if (pak is StoC_0x16_VariousUpdate) { // name, level, class StoC_0x16_VariousUpdate stat = (StoC_0x16_VariousUpdate)pak; if (stat.SubCode == 3) { StoC_0x16_VariousUpdate.PlayerUpdate subData = (StoC_0x16_VariousUpdate.PlayerUpdate)stat.SubData; nameKey = "N:" + subData.playerName + "L:" + subData.playerLevel; statKey = ""; plrName = subData.playerName; plrLevel = subData.playerLevel; plrClass = subData.className; s.WriteLine("{0, -16} 0x16:3 nameKey:{1} plrName:{2} {3} {4}", pak.Time.ToString(), nameKey, plrName, plrLevel, plrClass); } // mainhand spec, mainhand DPS else if (stat.SubCode == 5) { StoC_0x16_VariousUpdate.PlayerStateUpdate subData = (StoC_0x16_VariousUpdate.PlayerStateUpdate)stat.SubData; string key = string.Format("WD:{0}.{1}WS:{2}", subData.weaponDamageHigh, subData.weaponDamageLow, (subData.weaponSkillHigh << 8) + subData.weaponSkillLow); if (nameKey != "") { if (plrInfo.ContainsKey(nameKey + key)) { playerInfo = (PlayerInfo)plrInfo[nameKey + key]; } else { playerInfo = new PlayerInfo(); playerInfo.name = plrName; playerInfo.level = plrLevel; playerInfo.className = plrClass; playerInfo.weaponDamage = string.Format("{0,2}.{1,-3}", subData.weaponDamageHigh, subData.weaponDamageLow); playerInfo.weaponSkill = (subData.weaponSkillHigh << 8) + subData.weaponSkillLow; plrInfo.Add(nameKey + key, playerInfo); } plrInfo[nameKey + key] = playerInfo; } statKey = key; s.WriteLine("{0, -16} 0x16:5 S:{1} {2} {3} {4} {5}", pak.Time.ToString(), statKey, playerInfo.name, playerInfo.level, playerInfo.weaponDamage, playerInfo.weaponSkill); } // Fill styles if (stat.SubCode == 1) { StoC_0x16_VariousUpdate.SkillsUpdate subData = (StoC_0x16_VariousUpdate.SkillsUpdate)stat.SubData; styleIcons.Clear(); if (log.Version < 186) { styleIcons.Add((ushort)0x01F4, "Bow prepare"); styleIcons.Add((ushort)0x01F5, "Lefthand hit"); styleIcons.Add((ushort)0x01F6, "Bothhands hit"); styleIcons.Add((ushort)0x01F7, "Bow shoot"); // styleIcons.Add((ushort)0x01F9, "Volley aim ?"); // styleIcons.Add((ushort)0x01FA, "Volley ready ?"); // styleIcons.Add((ushort)0x01FB, "Volley shoot ?"); } else { styleIcons.Add((ushort)0x3E80, "Bow prepare"); styleIcons.Add((ushort)0x3E81, "Lefthand hit"); styleIcons.Add((ushort)0x3E82, "Bothhands hit"); styleIcons.Add((ushort)0x3E83, "Bow shoot"); // styleIcons.Add((ushort)0x3E85, "Volley aim ?"); // styleIcons.Add((ushort)0x3E86, "Volley ready ?"); // styleIcons.Add((ushort)0x3E87, "Volley shoot ?"); } foreach (StoC_0x16_VariousUpdate.Skill skill in subData.data) { if (skill.page == StoC_0x16_VariousUpdate.eSkillPage.Styles) { styleIcons[skill.icon] = skill.name; // s.WriteLine("{0, -16} 0x16:1 icon:0x{1:X4} name:{2}", pak.Time.ToString(), skill.icon, styleIcons[skill.icon]); } } /* foreach (DictionaryEntry entry in styleIcons) * { * ushort icon = (ushort)entry.Key; * s.WriteLine("{0, -16} 0x16:1 icon:0x{1:X4} name:{2}", pak.Time.ToString(), icon, entry.Value); * }*/ } } // Combat animation else if (pak is StoC_0xBC_CombatAnimation && (playerInfo != null)) { StoC_0xBC_CombatAnimation combat = (StoC_0xBC_CombatAnimation)pak; CombatWaitMessage.Clear(); ObjectInfo targetObj = oidInfo[combat.DefenderOid] as ObjectInfo; string styleName = (combat.StyleId == 0 /* || (combat.Result & 0x7F) != 0x0B)*/) ? "" : (styleIcons[combat.StyleId] == null ? "not found " + combat.StyleId.ToString() : (styleIcons[combat.StyleId]).ToString()); string targetName = targetObj == null ? "" : " target:" + targetObj.name + " (" + targetObj.type + ")"; if (combat.Stance == 0 && combat.AttackerOid == playerOid /* && combat.DefenderOid != 0*/) { switch (combat.Result & 0x7F) { case 0: CombatWaitMessage.Add(new WaitMessage(0x11, "You miss!")); CombatWaitMessage.Add(new WaitMessage(0x11, "You were strafing in combat and miss!")); break; case 1: if (targetObj != null) { CombatWaitMessage.Add(new WaitMessage(0x11, targetObj.GetFirstFullName + " parries your attack!")); } break; case 2: // if (targetObj != null)//TODO // CombatWaitMessage.Add(new WaitMessage(0x11, targetObj.GetFirstFullName + " The Midgardian Assassin attacks you and you block the blow!")); break; case 3: if (targetObj != null) { CombatWaitMessage.Add(new WaitMessage(0x11, targetObj.GetFirstFullName + " evades your attack!")); } break; case 4: CombatWaitMessage.Add(new WaitMessage(0x11, "You fumble the attack and take time to recover!")); break; case 0xA: if (targetObj != null) { CombatWaitMessage.Add( new WaitMessage(0x11, "You attack " + targetObj.GetFullName + " with your % and hit for % damage!")); } break; case 0xB: CombatWaitMessage.Add(new WaitMessage(0x11, "You perform your " + styleName + " perfectly. %")); if (targetObj != null) { CombatWaitMessage.Add( new WaitMessage(0x11, "You attack " + targetObj.GetFullName + " with your % and hit for % damage!")); } break; case 0x14: if (targetObj != null) { CombatWaitMessage.Add(new WaitMessage(0x11, "You hit " + targetObj.GetFullName + " for % damage!")); } break; default: break; } } if (combat.AttackerOid == playerOid) { s.WriteLine("{0, -16} 0xBC attackerOid:0x{1:X4}(You) defenderOid:0x{2:X4} style:0x{4:X4} result:0x{3:X2}{5}{6}", pak.Time.ToString(), combat.AttackerOid, combat.DefenderOid, combat.Result, combat.StyleId, styleName == "" ? "" : " styleName:" + styleName, targetName); foreach (WaitMessage msg in CombatWaitMessage) { s.WriteLine(" WAITING 0xAF 0x{0:X2} {1}", msg.msgType, msg.message); } countBC++; } } // Messages else if (pak is StoC_0xAF_Message) { StoC_0xAF_Message msg = (StoC_0xAF_Message)pak; switch (msg.Type) { // case 0x10: // Your cast combat case 0x11: // Your Melee combat // case 0x1B: // resist // case 0x1D: // X hits you // case 0x1E: // X miss you s.WriteLine("{0, -16} 0xAF 0x{1:X2} {2} ", pak.Time.ToString(), msg.Type, msg.Text); break; default: break; } } } } if (nameKey != "" && statKey != "") { plrInfo[nameKey + statKey] = playerInfo; } } }
/// <summary> /// Writes the log. /// </summary> /// <param name="context">The context.</param> /// <param name="stream">The stream.</param> /// <param name="callback">The callback for UI updates.</param> public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback) { Packet prevpack = null; int playerOid = -1; ushort targetOid = 0xFFFF; using (StreamWriter s = new StreamWriter(stream)) { foreach (PacketLog log in context.LogManager.Logs) { for (int i = 0; i < log.Count; i++) { if (callback != null && (i & 0xFFF) == 0) // update progress every 4096th packet { callback(i, log.Count - 1); } Packet pak = log[i]; if (pak is StoC_0x20_PlayerPositionAndObjectID) { StoC_0x20_PlayerPositionAndObjectID plr = (StoC_0x20_PlayerPositionAndObjectID)pak; playerOid = plr.PlayerOid; #if SHOW_PACKETS s.WriteLine("playerOid:0x{0:X4}", playerOid); #endif } else if (pak is CtoS_0xB0_TargetChange) { CtoS_0xB0_TargetChange target = (CtoS_0xB0_TargetChange)pak; targetOid = target.Oid; } else if (pak is StoC_0xF9_EmoteAnimation) { #if SHOW_PACKETS StoC_0xF9_EmoteAnimation emote = (StoC_0xF9_EmoteAnimation)pak; if (emote.Oid == playerOid) { s.WriteLine("{0, -16} oid:0x{1:X4} target:0x{4:X4} emote:{2}({3})", pak.Time.ToString(), emote.Oid, emote.Emote, (StoC_0xF9_EmoteAnimation.eEmote)emote.Emote, targetOid); } else { s.WriteLine("{0, -16} oid:0x{1:X4} emote:{2}({3})", pak.Time.ToString(), emote.Oid, emote.Emote, (StoC_0xF9_EmoteAnimation.eEmote)emote.Emote); } #endif } else if (pak is StoC_0xAF_Message) { StoC_0xAF_Message msg = (StoC_0xAF_Message)pak; if (msg.Type == 6) // emote messages { #if SHOW_PACKETS s.WriteLine("{0, -16} 0xAF 0x{1:X2} {2}", pak.Time.ToString(), msg.Type, msg.Text); #endif if (prevpack != null && prevpack is StoC_0xF9_EmoteAnimation) { string targetStr = ""; ushort target = 0xFFFF; StoC_0xF9_EmoteAnimation emote = (StoC_0xF9_EmoteAnimation)prevpack; if (emote.Oid == playerOid) { target = targetOid; } if (target == 0xFFFF) { targetStr = "unknown"; } else if (target == 0) { targetStr = "none"; } else if (target == playerOid) { targetStr = "self"; } else { targetStr = string.Format("0x{0:X4}", target); } s.WriteLine("codeEmote:0x{0:X2}({1,-2}) emote:{2, -15} target:{4,-10} \"{3}\"", emote.Emote, emote.Emote, (StoC_0xF9_EmoteAnimation.eEmote)emote.Emote, msg.Text, targetStr); } } } prevpack = pak; } } } }