private void PrintValues(System.Text.StringBuilder builder, UpdateFields values, ObjectTypeId type) { foreach (var pair in values) { var uf = UpdateFields.GetUpdateField(pair.Key, type); if (uf.Type == UpdateFieldType.Long && uf.Id.ToString().EndsWith("_HIPART")) { continue; } builder.Append(" "); builder.Append(uf.Id); builder.Append(" = "); if (uf.Type == UpdateFieldType.Long && values.ContainsKey(pair.Key + 1)) { builder.Append(uf.Print(((ulong)values[pair.Key + 1] << 32) | (ulong)pair.Value)); } else { builder.Append(uf.Print(pair.Value)); } builder.AppendLine(); } }
private static bool GetTransportMap(WoWObject @object, out int mapId) { mapId = -1; WoWObject transport; if (!Storage.Objects.TryGetValue(@object.Movement.TransportGuid, out transport)) { return(false); } UpdateField entry; if (!transport.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out entry)) { return(false); } if (SQLConnector.Enabled) { var transportTemplates = SQLDatabase.GetDict <uint, GameObjectTemplate>(new List <uint> { entry.UInt32Value }); if (transportTemplates.IsEmpty()) { return(false); } mapId = transportTemplates[entry.UInt32Value].Item1.Data[6]; } return(true); }
/// <summary> /// Grabs a value from a dictionary of UpdateFields /// </summary> /// <typeparam name="T">The type of UpdateField (ObjectField, UnitField, ...)</typeparam> /// <typeparam name="TK">The type of the value (int, uint or float and their nullable counterparts)</typeparam> /// <param name="dict">The dictionary</param> /// <param name="updateField">The update field we want</param> /// <returns></returns> public static TK GetValue <T, TK>(this Dictionary <int, UpdateField> dict, T updateField) { UpdateField uf; if (dict.TryGetValue(UpdateFields.GetUpdateField(updateField), out uf)) { var type = GetTypeCodeOfReturnValue <TK>(); switch (type) { case TypeCode.UInt32: return((TK)(object)uf.UInt32Value); case TypeCode.Int32: return((TK)(object)(int)uf.UInt32Value); case TypeCode.Single: return((TK)(object)uf.SingleValue); case TypeCode.Double: return((TK)(object)(double)uf.SingleValue); default: break; } } return(default(TK)); }
/// <summary> /// Grabs a value from a dictionary of UpdateFields /// </summary> /// <typeparam name="T">The type of UpdateField (ObjectField, UnitField, ...)</typeparam> /// <typeparam name="TK">The type of the value (int, uint or float and their nullable counterparts)</typeparam> /// <param name="dict">The dictionary</param> /// <param name="updateField">The update field we want</param> /// <returns></returns> public static TK GetValue <T, TK>(this Dictionary <int, UpdateField> dict, T updateField) { var isInt = false; var isUInt = false; var type = typeof(TK); switch (Type.GetTypeCode(type)) { case TypeCode.UInt32: isUInt = true; break; case TypeCode.Int32: isInt = true; break; case TypeCode.Single: case TypeCode.Double: break; default: { switch (Type.GetTypeCode(Nullable.GetUnderlyingType(type))) { case TypeCode.UInt32: isUInt = true; break; case TypeCode.Int32: isInt = true; break; case TypeCode.Single: case TypeCode.Double: break; default: return(default(TK)); } break; } } UpdateField uf; if (dict.TryGetValue(UpdateFields.GetUpdateField(updateField), out uf)) { if (isInt) { return((TK)(object)Convert.ToInt32(uf.UInt32Value)); } else if (isUInt) { return((TK)(object)uf.UInt32Value); } return((TK)(object)uf.SingleValue); } return(default(TK)); }
public static void HandleLootResponse(Packet packet) { var loot = new Loot(); var guid = packet.ReadGuid("GUID"); var lootType = packet.ReadEnum <LootType>("Loot Type", TypeCode.Byte); if (lootType == LootType.Unk0) { packet.ReadByte("Slot"); return; } loot.Gold = packet.ReadUInt32("Gold"); var count = packet.ReadByte("Drop Count"); if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_0_14333)) { packet.ReadByte("unk"); } loot.LootItems = new List <LootItem>(count); for (var i = 0; i < count; ++i) { var lootItem = new LootItem(); packet.ReadByte("Slot", i); lootItem.ItemId = (uint)packet.ReadEntryWithName <UInt32>(StoreNameType.Item, "Entry", i); lootItem.Count = packet.ReadUInt32("Count", i); packet.ReadUInt32("Display ID", i); packet.ReadInt32("Random Suffix", i); packet.ReadInt32("Random Property Id", i); packet.ReadEnum <LootSlotType>("Slot Type", TypeCode.Byte, i); loot.LootItems.Add(lootItem); } // Items do not have item id in its guid, we need to query the wowobject store go if (guid.GetObjectType() == ObjectType.Item) { WoWObject item; UpdateField itemEntry; if (Stuffing.Objects.TryGetValue(guid, out item)) { if (item.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out itemEntry)) { Stuffing.Loots.TryAdd(new Tuple <uint, ObjectType>((uint)itemEntry.Int32Value, guid.GetObjectType()), loot); return; } } } Stuffing.Loots.TryAdd(new Tuple <uint, ObjectType>(guid.GetEntry(), guid.GetObjectType()), loot); }
/// <summary> /// Grabs a value from a dictionary of UpdateFields and converts it to an enum val /// </summary> /// <typeparam name="T">The type of UpdateField (ObjectField, UnitField, ...)</typeparam> /// <typeparam name="TK">The type of the value (a NULLABLE enum)</typeparam> /// <param name="dict">The dictionary</param> /// <param name="updateField">The update field we want</param> /// <returns></returns> public static TK GetEnum <T, TK>(this Dictionary <int, UpdateField> dict, T updateField) { // typeof (TK) is a nullable type (ObjectField?) // typeof (TK).GetGenericArguments()[0] is the non nullable equivalent (ObjectField) // we need to convert our int from UpdateFields to the enum type try { UpdateField uf; if (dict.TryGetValue(UpdateFields.GetUpdateField(updateField), out uf)) { return((TK)Enum.Parse(typeof(TK).GetGenericArguments()[0], uf.UInt32Value.ToString(CultureInfo.InvariantCulture))); } } catch (OverflowException) // Data wrongly parsed can result in very wtfy values { return(default(TK)); } return(default(TK)); }
/// <summary> /// Grabs N (consecutive) values from a dictionary of UpdateFields /// </summary> /// <typeparam name="T">The type of UpdateField (ObjectField, UnitField, ...)</typeparam> /// <typeparam name="TK">The type of the value (int, uint or float and their nullable counterparts)</typeparam> /// <param name="dict">The dictionary</param> /// <param name="firstUpdateField">The first update field of the sequence</param> /// <param name="count">Number of values to retrieve</param> /// <returns></returns> public static TK[] GetArray <T, TK>(this Dictionary <int, UpdateField> dict, T firstUpdateField, int count) { var result = new TK[count]; var type = GetTypeCodeOfReturnValue <TK>(); for (var i = 0; i < count; i++) { UpdateField uf; if (dict.TryGetValue(UpdateFields.GetUpdateField(firstUpdateField) + i, out uf)) { switch (type) { case TypeCode.UInt32: result[i] = (TK)(object)uf.UInt32Value; break; case TypeCode.Int32: result[i] = (TK)(object)(int)uf.UInt32Value; break; case TypeCode.Single: result[i] = (TK)(object)uf.SingleValue; break; case TypeCode.Double: result[i] = (TK)(object)(double)uf.SingleValue; break; default: break; } } } return(result); }
private static Dictionary <int, List <UpdateField> > ReadDynamicValuesUpdateBlock(Packet packet, ObjectType type, object index, bool isCreating) { var dict = new Dictionary <int, List <UpdateField> >(); if (!ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_4_16016)) { return(dict); } int objectEnd = UpdateFields.GetUpdateField(ObjectDynamicField.OBJECT_DYNAMIC_END); var maskSize = packet.ReadByte(); var updateMask = new int[maskSize]; for (var i = 0; i < maskSize; i++) { updateMask[i] = packet.ReadInt32(); } var mask = new BitArray(updateMask); for (var i = 0; i < mask.Count; ++i) { if (!mask[i]) { continue; } string key = "Dynamic Block Value " + i; if (i < objectEnd) { key = UpdateFields.GetUpdateFieldName <ObjectDynamicField>(i); } else { switch (type) { case ObjectType.Container: { if (i < UpdateFields.GetUpdateField(ItemDynamicField.ITEM_DYNAMIC_END)) { goto case ObjectType.Item; } key = UpdateFields.GetUpdateFieldName <ContainerDynamicField>(i); break; } case ObjectType.Item: { key = UpdateFields.GetUpdateFieldName <ItemDynamicField>(i); break; } case ObjectType.Player: { if (i < UpdateFields.GetUpdateField(UnitDynamicField.UNIT_DYNAMIC_END)) { goto case ObjectType.Unit; } key = UpdateFields.GetUpdateFieldName <PlayerDynamicField>(i); break; } case ObjectType.Unit: { key = UpdateFields.GetUpdateFieldName <UnitDynamicField>(i); break; } case ObjectType.GameObject: { key = UpdateFields.GetUpdateFieldName <GameObjectDynamicField>(i); break; } case ObjectType.DynamicObject: { key = UpdateFields.GetUpdateFieldName <DynamicObjectDynamicField>(i); break; } case ObjectType.Corpse: { key = UpdateFields.GetUpdateFieldName <CorpseDynamicField>(i); break; } case ObjectType.AreaTrigger: { key = UpdateFields.GetUpdateFieldName <AreaTriggerDynamicField>(i); break; } case ObjectType.SceneObject: { key = UpdateFields.GetUpdateFieldName <SceneObjectDynamicField>(i); break; } case ObjectType.Conversation: { key = UpdateFields.GetUpdateFieldName <ConversationDynamicField>(i); break; } } } var flag = packet.ReadUInt16(); var cnt = flag & 0x7FFF; if ((flag & 0x8000) != 0) { packet.ReadUInt32(key + " Size", index); } var vals = new int[cnt]; for (var j = 0; j < cnt; ++j) { vals[j] = packet.ReadInt32(); } var values = new List <UpdateField>(); var fieldMask = new BitArray(vals); for (var j = 0; j < fieldMask.Count; ++j) { if (!fieldMask[j]) { continue; } var blockVal = packet.ReadUpdateField(); string value = blockVal.UInt32Value + "/" + blockVal.SingleValue; packet.AddValue(key, value, index, j); values.Add(blockVal); } dict.Add(i, values); } return(dict); }
public static string Creature(Dictionary <WowGuid, Unit> units) { if (units.Count == 0) { return(string.Empty); } if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature)) { return(string.Empty); } const string tableName = "creature"; const string addonTableName = "creature_addon"; uint count = 0; var rows = new List <QueryBuilder.SQLInsertRow>(); var addonRows = new List <QueryBuilder.SQLInsertRow>(); foreach (var unit in units) { var row = new QueryBuilder.SQLInsertRow(); var badTransport = false; var creature = unit.Value; if (Settings.AreaFilters.Length > 0) { if (!(creature.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } if (Settings.MapFilters.Length > 0) { if (!(creature.Map.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.MapFilters))) { continue; } } UpdateField uf; if (!creature.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out uf)) { continue; // broken entry, nothing to spawn } var entry = uf.UInt32Value; var movementType = 0; var spawnDist = 0; if (creature.Movement.HasWpsOrRandMov) { movementType = 1; spawnDist = 5; } row.AddValue("guid", "@CGUID+" + count, noQuotes: true); row.AddValue("id", entry); if (!creature.IsOnTransport()) { row.AddValue("map", creature.Map); } else { int mapId; badTransport = !GetTransportMap(creature, out mapId); row.AddValue("map", mapId); } row.AddValue("spawnMask", creature.GetDefaultSpawnMask()); row.AddValue("phaseMask", creature.PhaseMask); if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_4_15595) && creature.Phases != null) { row.AddValue("phaseId", string.Join(" - ", creature.Phases)); } if (!creature.IsOnTransport()) { row.AddValue("position_x", creature.Movement.Position.X); row.AddValue("position_y", creature.Movement.Position.Y); row.AddValue("position_z", creature.Movement.Position.Z); row.AddValue("orientation", creature.Movement.Orientation); } else { row.AddValue("position_x", creature.Movement.TransportOffset.X); row.AddValue("position_y", creature.Movement.TransportOffset.Y); row.AddValue("position_z", creature.Movement.TransportOffset.Z); row.AddValue("orientation", creature.Movement.TransportOffset.O); } row.AddValue("spawntimesecs", creature.GetDefaultSpawnTime()); row.AddValue("spawndist", spawnDist); row.AddValue("MovementType", movementType); row.Comment = StoreGetters.GetName(StoreNameType.Unit, (int)unit.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, creature.Area, false) + ")"; var auras = string.Empty; var commentAuras = string.Empty; if (creature.Auras != null && creature.Auras.Count() != 0) { foreach (var aura in creature.Auras) { if (aura == null) { continue; } // usually "template auras" do not have caster if (ClientVersion.AddedInVersion(ClientType.MistsOfPandaria) ? !aura.AuraFlags.HasAnyFlag(AuraFlagMoP.NoCaster) : !aura.AuraFlags.HasAnyFlag(AuraFlag.NotCaster)) { continue; } auras += aura.SpellId + " "; commentAuras += aura.SpellId.ToString() + " - " + StoreGetters.GetName(StoreNameType.Spell, (int)aura.SpellId, false) + ", "; } auras = auras.TrimEnd(' '); commentAuras = commentAuras.TrimEnd(',', ' '); row.Comment += " (Auras: " + commentAuras + ")"; } var addonRow = new QueryBuilder.SQLInsertRow(); if (Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_addon)) { addonRow.AddValue("guid", "@CGUID+" + count, noQuotes: true); addonRow.AddValue("mount", creature.Mount); addonRow.AddValue("bytes1", creature.Bytes1, true); addonRow.AddValue("bytes2", creature.Bytes2, true); addonRow.AddValue("auras", auras); addonRow.Comment += StoreGetters.GetName(StoreNameType.Unit, (int)unit.Key.GetEntry(), false); if (!String.IsNullOrWhiteSpace(auras)) { addonRow.Comment += " - " + commentAuras; } addonRows.Add(addonRow); } if (creature.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else if (creature.IsOnTransport() && badTransport) { row.CommentOut = true; row.Comment += " - !!! on transport - transport template not found !!!"; } else { ++count; } if (creature.Movement.HasWpsOrRandMov) { row.Comment += " (possible waypoints or random movement)"; } rows.Add(row); } var result = new StringBuilder(); if (count > 0) { // delete query for GUIDs var delete = new QueryBuilder.SQLDelete(Tuple.Create("@CGUID+0", "@CGUID+" + --count), "guid", tableName); result.Append(delete.Build()); var sql = new QueryBuilder.SQLInsert(tableName, rows, withDelete: false); result.Append(sql.Build()); if (Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_addon)) { var addonDelete = new QueryBuilder.SQLDelete(Tuple.Create("@CGUID+0", "@CGUID+" + count), "guid", addonTableName); result.Append(addonDelete.Build()); var addonSql = new QueryBuilder.SQLInsert(addonTableName, addonRows, withDelete: false); result.Append(addonSql.Build()); } } return(result.ToString()); }
private static Dictionary <int, UpdateField> ReadValuesUpdateBlock(Packet packet, ObjectType type, object index, bool isCreating) { var maskSize = packet.ReadByte(); var updateMask = new int[maskSize]; for (var i = 0; i < maskSize; i++) { updateMask[i] = packet.ReadInt32(); } var mask = new BitArray(updateMask); var dict = new Dictionary <int, UpdateField>(); int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END); for (var i = 0; i < mask.Count; ++i) { if (!mask[i]) { continue; } var blockVal = packet.ReadUpdateField(); // Don't spam 0 values at create if (isCreating && blockVal.UInt32Value == 0) { continue; } string key = "Block Value " + i; string value = blockVal.UInt32Value + "/" + blockVal.SingleValue; if (i < objectEnd) { key = UpdateFields.GetUpdateFieldName <ObjectField>(i); } else { switch (type) { case ObjectType.Container: { if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END)) { goto case ObjectType.Item; } key = UpdateFields.GetUpdateFieldName <ContainerField>(i); break; } case ObjectType.Item: { key = UpdateFields.GetUpdateFieldName <ItemField>(i); break; } case ObjectType.Player: { if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END) || i < UpdateFields.GetUpdateField(UnitField.UNIT_FIELD_END)) { goto case ObjectType.Unit; } key = UpdateFields.GetUpdateFieldName <PlayerField>(i); break; } case ObjectType.Unit: { key = UpdateFields.GetUpdateFieldName <UnitField>(i); break; } case ObjectType.GameObject: { key = UpdateFields.GetUpdateFieldName <GameObjectField>(i); break; } case ObjectType.DynamicObject: { key = UpdateFields.GetUpdateFieldName <DynamicObjectField>(i); break; } case ObjectType.Corpse: { key = UpdateFields.GetUpdateFieldName <CorpseField>(i); break; } case ObjectType.AreaTrigger: { key = UpdateFields.GetUpdateFieldName <AreaTriggerField>(i); break; } case ObjectType.SceneObject: { key = UpdateFields.GetUpdateFieldName <SceneObjectField>(i); break; } case ObjectType.Conversation: { key = UpdateFields.GetUpdateFieldName <ConversationField>(i); break; } } } // HACK... if (key == UnitField.UNIT_FIELD_SCALING_LEVEL_DELTA.ToString()) { value = (int)blockVal.UInt32Value + "/" + blockVal.SingleValue; } if (key == UnitField.UNIT_FIELD_FACTIONTEMPLATE.ToString()) { packet.AddValue(key, value + $" ({ StoreGetters.GetName(StoreNameType.Faction, (int)blockVal.UInt32Value, false) })", index); } else { packet.AddValue(key, value, index); } dict.Add(i, blockVal); } return(dict); }
public static Dictionary <int, UpdateField> ReadValuesUpdateBlock(ref Packet packet, ObjectType type, int index) { var maskSize = packet.ReadByte(); var updateMask = new int[maskSize]; for (var i = 0; i < maskSize; i++) { updateMask[i] = packet.ReadInt32(); } var mask = new BitArray(updateMask); var dict = new Dictionary <int, UpdateField>(); int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END); for (var i = 0; i < mask.Count; i++) { if (!mask[i]) { continue; } var blockVal = packet.ReadUpdateField(); string key = "Block Value " + i; string value = blockVal.Int32Value + "/" + blockVal.SingleValue; if (i < objectEnd) { key = UpdateFields.GetUpdateFieldName(i, "ObjectField"); } else { switch (type) { case ObjectType.Container: { if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END)) { goto case ObjectType.Item; } key = UpdateFields.GetUpdateFieldName(i, "ContainerField"); break; } case ObjectType.Item: { key = UpdateFields.GetUpdateFieldName(i, "ItemField"); break; } case ObjectType.Player: { if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END)) { goto case ObjectType.Unit; } key = UpdateFields.GetUpdateFieldName(i, "PlayerField"); break; } case ObjectType.Unit: { key = UpdateFields.GetUpdateFieldName(i, "UnitField"); break; } case ObjectType.GameObject: { key = UpdateFields.GetUpdateFieldName(i, "GameObjectField"); break; } case ObjectType.DynamicObject: { key = UpdateFields.GetUpdateFieldName(i, "DynamicObjectField"); break; } case ObjectType.Corpse: { key = UpdateFields.GetUpdateFieldName(i, "CorpseField"); break; } } } packet.Writer.WriteLine("[" + index + "] " + key + ": " + value); dict.Add(i, blockVal); } return(dict); }
public static string GameObject(Dictionary <WowGuid, GameObject> gameObjects) { if (gameObjects.Count == 0) { return(string.Empty); } if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.gameobject)) { return(string.Empty); } const string tableName = "gameobject"; uint count = 0; var rows = new List <QueryBuilder.SQLInsertRow>(); foreach (var gameobject in gameObjects) { var row = new QueryBuilder.SQLInsertRow(); var go = gameobject.Value; if (Settings.AreaFilters.Length > 0) { if (!(go.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } if (Settings.MapFilters.Length > 0) { if (!(go.Map.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.MapFilters))) { continue; } } uint animprogress = 0; uint state = 0; UpdateField uf; if (!go.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out uf)) { continue; // broken entry, nothing to spawn } var entry = uf.UInt32Value; var badTransport = false; if (go.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(GameObjectField.GAMEOBJECT_BYTES_1), out uf)) { var bytes = uf.UInt32Value; state = (bytes & 0x000000FF); animprogress = Convert.ToUInt32((bytes & 0xFF000000) >> 24); } row.AddValue("guid", "@OGUID+" + count, noQuotes: true); row.AddValue("id", entry); if (!go.IsOnTransport()) { row.AddValue("map", go.Map); } else { int mapId; badTransport = !GetTransportMap(go, out mapId); row.AddValue("map", mapId); } row.AddValue("spawnMask", go.GetDefaultSpawnMask()); row.AddValue("phaseMask", go.PhaseMask); if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_4_15595) && go.Phases != null) { row.AddValue("phaseId", string.Join(" - ", go.Phases)); } if (!go.IsOnTransport()) { row.AddValue("position_x", go.Movement.Position.X); row.AddValue("position_y", go.Movement.Position.Y); row.AddValue("position_z", go.Movement.Position.Z); row.AddValue("orientation", go.Movement.Orientation); } else { row.AddValue("position_x", go.Movement.TransportOffset.X); row.AddValue("position_y", go.Movement.TransportOffset.Y); row.AddValue("position_z", go.Movement.TransportOffset.Z); row.AddValue("orientation", go.Movement.TransportOffset.O); } var rotation = go.GetRotation(); if (rotation != null && rotation.Length == 4) { row.AddValue("rotation0", rotation[0]); row.AddValue("rotation1", rotation[1]); row.AddValue("rotation2", rotation[2]); row.AddValue("rotation3", rotation[3]); } else { row.AddValue("rotation0", 0); row.AddValue("rotation1", 0); row.AddValue("rotation2", 0); row.AddValue("rotation3", 0); } row.AddValue("spawntimesecs", go.GetDefaultSpawnTime()); row.AddValue("animprogress", animprogress); row.AddValue("state", state); row.Comment = StoreGetters.GetName(StoreNameType.GameObject, (int)gameobject.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, go.Area, false) + ")"; if (go.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else if (go.IsTransport()) { row.CommentOut = true; row.Comment += " - !!! transport !!!"; } else if (go.IsOnTransport() && badTransport) { row.CommentOut = true; row.Comment += " - !!! on transport - transport template not found !!!"; } else { ++count; } rows.Add(row); } var result = new StringBuilder(); if (count > 0) { // delete query for GUIDs var delete = new QueryBuilder.SQLDelete(Tuple.Create("@OGUID+0", "@OGUID+" + --count), "guid", tableName); result.Append(delete.Build()); } var sql = new QueryBuilder.SQLInsert(tableName, rows, withDelete: false); result.Append(sql.Build()); return(result.ToString()); }
/// <summary> /// Grabs N (consecutive) values from a dictionary of UpdateFields /// </summary> /// <typeparam name="T">The type of UpdateField (ObjectField, UnitField, ...)</typeparam> /// <typeparam name="TK">The type of the value (int, uint or float and their nullable counterparts)</typeparam> /// <param name="dict">The dictionary</param> /// <param name="firstUpdateField">The first update field of the sequence</param> /// <param name="count">Number of values to retrieve</param> /// <returns></returns> public static TK[] GetArray <T, TK>(this Dictionary <int, UpdateField> dict, T firstUpdateField, int count) { var isInt = false; var type = typeof(TK); switch (Type.GetTypeCode(type)) { case TypeCode.UInt32: case TypeCode.Int32: isInt = true; break; case TypeCode.Single: case TypeCode.Double: break; default: { switch (Type.GetTypeCode(Nullable.GetUnderlyingType(type))) { case TypeCode.UInt32: case TypeCode.Int32: isInt = true; break; case TypeCode.Single: case TypeCode.Double: break; default: return(null); } break; } } var result = new TK[count]; UpdateField uf; if (isInt) { for (var i = 0; i < count; i++) { if (dict.TryGetValue(UpdateFields.GetUpdateField(firstUpdateField) + i, out uf)) { result[i] = (TK)(object)uf.UInt32Value; } } } else { for (var i = 0; i < count; i++) { if (dict.TryGetValue(UpdateFields.GetUpdateField(firstUpdateField) + i, out uf)) { result[i] = (TK)(object)uf.SingleValue; } } } return(result); }
public static string GameObject(Dictionary <Guid, GameObject> gameObjects) { if (gameObjects.Count == 0) { return(string.Empty); } const string tableName = "gameobject"; uint count = 0; var rows = new List <QueryBuilder.SQLInsertRow>(); foreach (var gameobject in gameObjects) { var row = new QueryBuilder.SQLInsertRow(); var go = gameobject.Value; if (Settings.AreaFilters.Length > 0) { if (!(go.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } uint animprogress = 0; uint state = 0; UpdateField uf; if (go.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(GameObjectField.GAMEOBJECT_BYTES_1), out uf)) { var bytes = uf.UInt32Value; state = (bytes & 0x000000FF); animprogress = Convert.ToUInt32((bytes & 0xFF000000) >> 24); } var spawnTimeSecs = go.GetDefaultSpawnTime(); if (gameobject.Key.GetEntry() != 0) { row.AddValue("id", gameobject.Key.GetEntry()); row.AddValue("map", go.Map); row.AddValue("spawnMask", 1); row.AddValue("phaseMask", go.PhaseMask); row.AddValue("position_x", go.Movement.Position.X); row.AddValue("position_y", go.Movement.Position.Y); row.AddValue("position_z", go.Movement.Position.Z); row.AddValue("orientation", go.Movement.Orientation); row.AddValue("rotation0", go.Movement.Rotation.X); row.AddValue("rotation1", go.Movement.Rotation.Y); row.AddValue("rotation2", go.Movement.Rotation.Z); row.AddValue("rotation3", go.Movement.Rotation.W); row.AddValue("spawntimesecs", spawnTimeSecs); row.AddValue("animprogress", animprogress); row.AddValue("state", state); row.Comment = StoreGetters.GetName(StoreNameType.GameObject, (int)gameobject.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, go.Area, false) + ")"; if (go.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else { ++count; } rows.Add(row); } } var result = new StringBuilder(); var sql = new QueryBuilder.SQLInsert(tableName, rows, withDelete: false); result.Append(sql.Build()); return(result.ToString()); }
private static Dictionary <int, UpdateField> ReadValuesUpdateBlock(Packet packet, ObjectType type, object index, bool isCreating) { var maskSize = packet.ReadByte(); var updateMask = new int[maskSize]; for (var i = 0; i < maskSize; i++) { updateMask[i] = packet.ReadInt32(); } var mask = new BitArray(updateMask); var dict = new Dictionary <int, UpdateField>(); int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END); for (var i = 0; i < mask.Count; ++i) { if (!mask[i]) { continue; } var blockVal = packet.ReadUpdateField(); // Don't spam 0 values at create if (isCreating && blockVal.UInt32Value == 0) { continue; } string key = "Block Value " + i; string value = blockVal.UInt32Value + "/" + blockVal.SingleValue; if (i < objectEnd) { key = UpdateFields.GetUpdateFieldName <ObjectField>(i); } else { switch (type) { case ObjectType.Container: { if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END)) { goto case ObjectType.Item; } key = UpdateFields.GetUpdateFieldName <ContainerField>(i); break; } case ObjectType.Item: { key = UpdateFields.GetUpdateFieldName <ItemField>(i); break; } case ObjectType.Player: { if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END) || i < UpdateFields.GetUpdateField(UnitField.UNIT_FIELD_END)) { goto case ObjectType.Unit; } key = UpdateFields.GetUpdateFieldName <PlayerField>(i); break; } case ObjectType.Unit: { key = UpdateFields.GetUpdateFieldName <UnitField>(i); break; } case ObjectType.GameObject: { key = UpdateFields.GetUpdateFieldName <GameObjectField>(i); break; } case ObjectType.DynamicObject: { key = UpdateFields.GetUpdateFieldName <DynamicObjectField>(i); break; } case ObjectType.Corpse: { key = UpdateFields.GetUpdateFieldName <CorpseField>(i); break; } case ObjectType.AreaTrigger: { key = UpdateFields.GetUpdateFieldName <AreaTriggerField>(i); break; } case ObjectType.SceneObject: { key = UpdateFields.GetUpdateFieldName <SceneObjectField>(i); break; } case ObjectType.Conversation: { key = UpdateFields.GetUpdateFieldName <ConversationField>(i); break; } } } // HACK... if (key == UnitField.UNIT_FIELD_FACTIONTEMPLATE.ToString()) { packet.AddValue(key, value + $" ({ StoreGetters.GetName(StoreNameType.Faction, (int)blockVal.UInt32Value, false) })", index); } else { packet.AddValue(key, value, index); } dict.Add(i, blockVal); } objectEnd = UpdateFields.GetUpdateField(ObjectDynamicField.OBJECT_DYNAMIC_END); if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_4_16016)) { maskSize = packet.ReadByte(); updateMask = new int[maskSize]; for (var i = 0; i < maskSize; i++) { updateMask[i] = packet.ReadInt32(); } mask = new BitArray(updateMask); for (var i = 0; i < mask.Count; ++i) { if (!mask[i]) { continue; } string key = "Dynamic Block Value " + i; if (i < objectEnd) { key = UpdateFields.GetUpdateFieldName <ObjectDynamicField>(i); } else { switch (type) { case ObjectType.Container: { if (i < UpdateFields.GetUpdateField(ItemDynamicField.ITEM_DYNAMIC_END)) { goto case ObjectType.Item; } key = UpdateFields.GetUpdateFieldName <ContainerDynamicField>(i); break; } case ObjectType.Item: { key = UpdateFields.GetUpdateFieldName <ItemDynamicField>(i); break; } case ObjectType.Player: { if (i < UpdateFields.GetUpdateField(UnitDynamicField.UNIT_DYNAMIC_END)) { goto case ObjectType.Unit; } key = UpdateFields.GetUpdateFieldName <PlayerDynamicField>(i); break; } case ObjectType.Unit: { key = UpdateFields.GetUpdateFieldName <UnitDynamicField>(i); break; } case ObjectType.GameObject: { key = UpdateFields.GetUpdateFieldName <GameObjectDynamicField>(i); break; } case ObjectType.DynamicObject: { key = UpdateFields.GetUpdateFieldName <DynamicObjectDynamicField>(i); break; } case ObjectType.Corpse: { key = UpdateFields.GetUpdateFieldName <CorpseDynamicField>(i); break; } case ObjectType.AreaTrigger: { key = UpdateFields.GetUpdateFieldName <AreaTriggerDynamicField>(i); break; } case ObjectType.SceneObject: { key = UpdateFields.GetUpdateFieldName <SceneObjectDynamicField>(i); break; } case ObjectType.Conversation: { key = UpdateFields.GetUpdateFieldName <ConversationDynamicField>(i); break; } } } var flag = packet.ReadUInt16(); var cnt = flag & 0x7FFF; if ((flag & 0x8000) != 0) { packet.ReadUInt32(key + " Size", index); } var vals = new int[cnt]; for (var j = 0; j < cnt; ++j) { vals[j] = packet.ReadInt32(); } var fieldMask = new BitArray(vals); for (var j = 0; j < fieldMask.Count; ++j) { if (!fieldMask[j]) { continue; } var blockVal = packet.ReadUpdateField(); string value = blockVal.UInt32Value + "/" + blockVal.SingleValue; packet.AddValue(key, value, index, j); } } } return(dict); }
public static string Creature(Dictionary <Guid, Unit> units) { if (units.Count == 0) { return(string.Empty); } if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature)) { return(string.Empty); } const string tableName = "creature"; uint count = 0; var rows = new List <QueryBuilder.SQLInsertRow>(); foreach (var unit in units) { var row = new QueryBuilder.SQLInsertRow(); var creature = unit.Value; if (Settings.AreaFilters.Length > 0) { if (!(creature.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } UpdateField uf; if (!creature.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out uf)) { continue; // broken entry, nothing to spawn } var entry = uf.UInt32Value; var spawnTimeSecs = creature.GetDefaultSpawnTime(); var movementType = 0; // TODO: Find a way to check if our unit got random movement var spawnDist = (movementType == 1) ? 5 : 0; row.AddValue("guid", "@CGUID+" + count, noQuotes: true); row.AddValue("id", entry); row.AddValue("map", !creature.IsOnTransport() ? creature.Map : 0); // TODO: query transport template for map row.AddValue("spawnMask", 1); row.AddValue("phaseMask", creature.PhaseMask); if (!creature.IsOnTransport()) { row.AddValue("position_x", creature.Movement.Position.X); row.AddValue("position_y", creature.Movement.Position.Y); row.AddValue("position_z", creature.Movement.Position.Z); row.AddValue("orientation", creature.Movement.Orientation); } else { row.AddValue("position_x", creature.Movement.TransportOffset.X); row.AddValue("position_y", creature.Movement.TransportOffset.Y); row.AddValue("position_z", creature.Movement.TransportOffset.Z); row.AddValue("orientation", creature.Movement.TransportOffset.O); } row.AddValue("spawntimesecs", spawnTimeSecs); row.AddValue("spawndist", spawnDist); row.AddValue("MovementType", movementType); row.Comment = StoreGetters.GetName(StoreNameType.Unit, (int)unit.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, creature.Area, false) + ")"; if (creature.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else if (creature.IsOnTransport()) { row.CommentOut = true; row.Comment += " - !!! on transport (NYI) !!!"; } else { ++count; } if (creature.Movement.HasWpsOrRandMov) { row.Comment += " (possible waypoints or random movement)"; } rows.Add(row); } var result = new StringBuilder(); // delete query for GUIDs var delete = new QueryBuilder.SQLDelete(Tuple.Create("@CGUID+0", "@CGUID+" + --count), "guid", tableName); result.Append(delete.Build()); var sql = new QueryBuilder.SQLInsert(tableName, rows, withDelete: false); result.Append(sql.Build()); return(result.ToString()); }
private static bool GetTransportMap(WoWObject @object, out int mapId) { mapId = -1; WoWObject transport; if (!Storage.Objects.TryGetValue(@object.Movement.TransportGuid, out transport)) { return(false); } UpdateField entry; if (transport.UpdateFields == null || !transport.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out entry)) { return(false); } if (SQLConnector.Enabled) { var transportTemplates = SQLDatabase.Get(new RowList <GameObjectTemplate> { new GameObjectTemplate { Entry = entry.UInt32Value } }); if (transportTemplates.Count == 0) { return(false); } mapId = transportTemplates.First().Data.Data[6].GetValueOrDefault(); } return(true); }
public static void HandleLootResponse(Packet packet) { var loot = new Loot(); var guid = packet.ReadGuid("GUID"); var lootType = packet.ReadByteE <LootType>("Loot Type"); if (lootType == LootType.None) { packet.ReadByte("Slot"); return; } loot.Gold = packet.ReadUInt32("Gold"); var count = packet.ReadByte("Drop Count"); byte currencyCount = 0; if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_0_6a_13623)) { currencyCount = packet.ReadByte("Currency Count"); } loot.LootItems = new List <LootItem>(count); for (var i = 0; i < count; ++i) { var lootItem = new LootItem(); packet.ReadByte("Slot", i); lootItem.ItemId = packet.ReadUInt32 <ItemId>("Entry", i); lootItem.Count = packet.ReadUInt32("Count", i); packet.ReadUInt32("Display ID", i); packet.ReadInt32("Random Suffix", i); packet.ReadInt32("Random Property Id", i); packet.ReadByteE <LootSlotType>("Slot Type", i); loot.LootItems.Add(lootItem); } for (int i = 0; i < currencyCount; ++i) { packet.ReadByte("Slot", i); packet.ReadInt32("Currency Id", i); packet.ReadInt32("Count", i); // unconfirmed } // Items do not have item id in its guid, we need to query the wowobject store go if (guid.GetObjectType() == ObjectType.Item) { WoWObject item; UpdateField itemEntry; if (Storage.Objects.TryGetValue(guid, out item)) { if (item.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out itemEntry)) { Storage.Loots.Add(new Tuple <uint, ObjectType>(itemEntry.UInt32Value, guid.GetObjectType()), loot, packet.TimeSpan); return; } } } Storage.Loots.Add(new Tuple <uint, ObjectType>(guid.GetEntry(), guid.GetObjectType()), loot, packet.TimeSpan); }
public static string GameObject(Dictionary <WowGuid, GameObject> gameObjects) { if (gameObjects.Count == 0) { return(string.Empty); } if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.gameobject)) { return(string.Empty); } uint count = 0; var rows = new RowList <GameObjectModel>(); foreach (var gameobject in gameObjects) { Row <GameObjectModel> row = new Row <GameObjectModel>(); GameObject go = gameobject.Value; if (Settings.AreaFilters.Length > 0) { if (!(go.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } if (Settings.MapFilters.Length > 0) { if (!(go.Map.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.MapFilters))) { continue; } } uint animprogress = 0; uint state = 0; UpdateField uf; if (!go.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out uf)) { continue; // broken entry, nothing to spawn } uint entry = uf.UInt32Value; bool badTransport = false; if (go.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(GameObjectField.GAMEOBJECT_BYTES_1), out uf)) { uint bytes = uf.UInt32Value; state = (bytes & 0x000000FF); animprogress = Convert.ToUInt32((bytes & 0xFF000000) >> 24); } row.Data.GUID = "@OGUID+" + count; row.Data.ID = entry; if (!go.IsOnTransport()) { row.Data.Map = go.Map; } else { int mapId; badTransport = !GetTransportMap(go, out mapId); if (mapId != -1) { row.Data.Map = (uint)mapId; } } row.Data.SpawnMask = (uint)go.GetDefaultSpawnMask(); row.Data.PhaseMask = go.PhaseMask; if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_4_15595) && go.Phases != null) { row.Data.PhaseID = string.Join(" - ", go.Phases); } if (!go.IsOnTransport()) { row.Data.PositionX = go.Movement.Position.X; row.Data.PositionY = go.Movement.Position.Y; row.Data.PositionZ = go.Movement.Position.Z; row.Data.Orientation = go.Movement.Orientation; } else { row.Data.PositionX = go.Movement.TransportOffset.X; row.Data.PositionY = go.Movement.TransportOffset.Y; row.Data.PositionZ = go.Movement.TransportOffset.Z; row.Data.Orientation = go.Movement.TransportOffset.O; } var rotation = go.GetRotation(); if (rotation != null && rotation.Length == 4) { row.Data.Rotation = rotation.Cast <float?>().ToArray(); } else { row.Data.Rotation = new float?[] { 0, 0, 0, 0 } }; row.Data.SpawnTimeSecs = (int)go.GetDefaultSpawnTime(); row.Data.AnimProgress = animprogress; row.Data.State = state; // set some defaults row.Data.ZoneID = 0; row.Data.AreaID = 0; row.Data.PhaseGroup = 0; row.Comment = StoreGetters.GetName(StoreNameType.GameObject, (int)gameobject.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, go.Area, false) + ")"; if (go.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else if (go.IsTransport()) { row.CommentOut = true; row.Comment += " - !!! transport !!!"; } else if (go.IsOnTransport() && badTransport) { row.CommentOut = true; row.Comment += " - !!! on transport - transport template not found !!!"; } else { ++count; } rows.Add(row); } StringBuilder result = new StringBuilder(); if (count > 0) { // delete query for GUIDs var delete = new SQLDelete <GameObjectModel>(Tuple.Create("@OGUID+0", "@OGUID+" + --count)); result.Append(delete.Build()); } var sql = new SQLInsert <GameObjectModel>(rows, false); result.Append(sql.Build()); return(result.ToString()); } }
public static void HandleServerTrainerList(Packet packet) { Trainer trainer = new Trainer(); WowGuid guid = packet.ReadPackedGuid128("TrainerGUID"); bool hasFaction = false; float discount = 1.0f; if (Settings.UseDBC && Settings.RecalcDiscount) { if (Storage.Objects != null && Storage.Objects.ContainsKey(guid)) { WoWObject obj = Storage.Objects[guid].Item1; if (obj.Type == ObjectType.Unit) { int factionTemplateId = 0; int faction = 0; UpdateField uf; if (obj.UpdateFields != null && obj.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(UnitField.UNIT_FIELD_FACTIONTEMPLATE), out uf)) { factionTemplateId = (int)uf.UInt32Value; } if (factionTemplateId != 0 && DBC.FactionTemplate.ContainsKey(factionTemplateId)) { faction = DBC.FactionTemplate[factionTemplateId].Faction; } ulong reputation = 0; if (AchievementHandler.FactionReputationStore.ContainsKey(faction)) { reputation = AchievementHandler.FactionReputationStore[faction]; hasFaction = true; } uint multiplier = 0; if (reputation >= 3000) // Friendly { multiplier = 1; } if (reputation >= 9000) // Honored { multiplier = 2; } if (reputation >= 21000) // Revered { multiplier = 3; } if (reputation >= 42000) // Exalted { multiplier = 4; } if (multiplier != 0) { discount = 1.0f - 0.05f * multiplier; } packet.WriteLine("ReputationDiscount: {0}%", (int)((discount * 100) - 100)); } } } trainer.Type = packet.ReadInt32E <TrainerType>("TrainerType"); trainer.Id = packet.ReadUInt32("TrainerID"); var count = packet.ReadUInt32("Spells"); for (var i = 0u; i < count; ++i) { TrainerSpell trainerSpell = new TrainerSpell { TrainerId = trainer.Id, SpellId = packet.ReadUInt32 <SpellId>("SpellID", i) }; uint moneyCost = packet.ReadUInt32("MoneyCost", i); uint moneyCostOriginal = moneyCost; if (Settings.UseDBC && Settings.RecalcDiscount && hasFaction) { moneyCostOriginal = (uint)(Math.Round((moneyCost / discount) / 5)) * 5; packet.WriteLine("[{0}] MoneyCostOriginal: {1}", i, moneyCostOriginal); } if (Settings.UseDBC && Settings.RecalcDiscount && !hasFaction) { trainerSpell.FactionHelper = "No Faction found! MoneyCost not recalculated!"; } trainerSpell.MoneyCost = moneyCostOriginal; trainerSpell.ReqSkillLine = packet.ReadUInt32("ReqSkillLine", i); trainerSpell.ReqSkillRank = packet.ReadUInt32("ReqSkillRank", i); trainerSpell.ReqAbility = new uint[3]; for (var j = 0; j < 3; ++j) { trainerSpell.ReqAbility[j] = packet.ReadUInt32("ReqAbility", i, j); } packet.ReadByteE <TrainerSpellState>("Usable", i); trainerSpell.ReqLevel = packet.ReadByte("ReqLevel", i); Storage.TrainerSpells.Add(trainerSpell, packet.TimeSpan); } packet.ResetBitReader(); uint greetingLength = packet.ReadBits(11); trainer.Greeting = packet.ReadWoWString("Greeting", greetingLength); Storage.Trainers.Add(trainer, packet.TimeSpan); var lastGossipOption = CoreParsers.NpcHandler.LastGossipOption; if (lastGossipOption.HasSelection) { Storage.GossipMenuOptionTrainers.Add(new GossipMenuOptionTrainer { MenuId = lastGossipOption.MenuId, OptionIndex = lastGossipOption.OptionIndex, TrainerId = trainer.Id }, packet.TimeSpan); } else { Storage.CreatureDefaultTrainers.Add(new CreatureDefaultTrainer { CreatureId = lastGossipOption.Guid.GetEntry(), TrainerId = trainer.Id }, packet.TimeSpan); } }
public static string Creature(Dictionary <WowGuid, Unit> units) { if (units.Count == 0) { return(string.Empty); } if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature)) { return(string.Empty); } uint count = 0; var rows = new RowList <Creature>(); var addonRows = new RowList <CreatureAddon>(); foreach (var unit in units) { Row <Creature> row = new Row <Creature>(); bool badTransport = false; Unit creature = unit.Value; if (Settings.AreaFilters.Length > 0) { if (!(creature.Area.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.AreaFilters))) { continue; } } if (Settings.MapFilters.Length > 0) { if (!(creature.Map.ToString(CultureInfo.InvariantCulture).MatchesFilters(Settings.MapFilters))) { continue; } } UpdateField uf; if (!creature.UpdateFields.TryGetValue(UpdateFields.GetUpdateField(ObjectField.OBJECT_FIELD_ENTRY), out uf)) { continue; // broken entry, nothing to spawn } uint entry = uf.UInt32Value; uint movementType = 0; int spawnDist = 0; if (creature.Movement.HasWpsOrRandMov) { movementType = 1; spawnDist = 10; } row.Data.GUID = "@CGUID+" + count; row.Data.ID = entry; if (!creature.IsOnTransport()) { row.Data.Map = creature.Map; } else { int mapId; badTransport = !GetTransportMap(creature, out mapId); if (mapId != -1) { row.Data.Map = (uint)mapId; } } row.Data.SpawnMask = (uint)creature.GetDefaultSpawnMask(); row.Data.PhaseMask = creature.PhaseMask; if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_4_15595) && creature.Phases != null) { string data = string.Join(" - ", creature.Phases); if (string.IsNullOrEmpty(data)) { data = "0"; } row.Data.PhaseID = data; } if (!creature.IsOnTransport()) { row.Data.PositionX = creature.Movement.Position.X; row.Data.PositionY = creature.Movement.Position.Y; row.Data.PositionZ = creature.Movement.Position.Z; row.Data.Orientation = creature.Movement.Orientation; } else { row.Data.PositionX = creature.Movement.TransportOffset.X; row.Data.PositionY = creature.Movement.TransportOffset.Y; row.Data.PositionZ = creature.Movement.TransportOffset.Z; row.Data.Orientation = creature.Movement.TransportOffset.O; } row.Data.SpawnTimeSecs = creature.GetDefaultSpawnTime(); row.Data.SpawnDist = spawnDist; row.Data.MovementType = movementType; // set some defaults row.Data.ZoneID = 0; row.Data.AreaID = 0; row.Data.PhaseGroup = 0; row.Data.ModelID = 0; row.Data.CurrentWaypoint = 0; row.Data.CurHealth = 0; row.Data.CurMana = 0; row.Data.NpcFlag = 0; row.Data.UnitFlag = 0; row.Data.DynamicFlag = 0; row.Comment = StoreGetters.GetName(StoreNameType.Unit, (int)unit.Key.GetEntry(), false); row.Comment += " (Area: " + StoreGetters.GetName(StoreNameType.Area, creature.Area, false) + ")"; string auras = string.Empty; string commentAuras = string.Empty; if (creature.Auras != null && creature.Auras.Count != 0) { foreach (Aura aura in creature.Auras) { if (aura == null) { continue; } // usually "template auras" do not have caster if (ClientVersion.AddedInVersion(ClientType.MistsOfPandaria) ? !aura.AuraFlags.HasAnyFlag(AuraFlagMoP.NoCaster) : !aura.AuraFlags.HasAnyFlag(AuraFlag.NotCaster)) { continue; } auras += aura.SpellId + " "; commentAuras += aura.SpellId + " - " + StoreGetters.GetName(StoreNameType.Spell, (int)aura.SpellId, false) + ", "; } auras = auras.TrimEnd(' '); commentAuras = commentAuras.TrimEnd(',', ' '); row.Comment += " (Auras: " + commentAuras + ")"; } var addonRow = new Row <CreatureAddon>(); if (Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_addon)) { addonRow.Data.GUID = "@CGUID+" + count; addonRow.Data.PathID = 0; addonRow.Data.Mount = creature.Mount.GetValueOrDefault(0); addonRow.Data.Bytes1 = creature.Bytes1.GetValueOrDefault(0); addonRow.Data.Bytes2 = creature.Bytes2.GetValueOrDefault(0); addonRow.Data.Emote = 0; addonRow.Data.Auras = auras; addonRow.Comment += StoreGetters.GetName(StoreNameType.Unit, (int)unit.Key.GetEntry(), false); if (!string.IsNullOrWhiteSpace(auras)) { addonRow.Comment += " - " + commentAuras; } addonRows.Add(addonRow); } if (creature.IsTemporarySpawn()) { row.CommentOut = true; row.Comment += " - !!! might be temporary spawn !!!"; } else if (creature.IsOnTransport() && badTransport) { row.CommentOut = true; row.Comment += " - !!! on transport - transport template not found !!!"; } else { ++count; } if (creature.Movement.HasWpsOrRandMov) { row.Comment += " (possible waypoints or random movement)"; } rows.Add(row); } if (count == 0) { return(string.Empty); } StringBuilder result = new StringBuilder(); // delete query for GUIDs var delete = new SQLDelete <Creature>(Tuple.Create("@CGUID+0", "@CGUID+" + --count)); result.Append(delete.Build()); var sql = new SQLInsert <Creature>(rows, false); result.Append(sql.Build()); if (Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_addon)) { var addonDelete = new SQLDelete <CreatureAddon>(Tuple.Create("@CGUID+0", "@CGUID+" + count)); result.Append(addonDelete.Build()); var addonSql = new SQLInsert <CreatureAddon>(addonRows, false); result.Append(addonSql.Build()); } return(result.ToString()); }