/// <summary> /// Gets the list to be displayed in the Minion category /// </summary> /// <remarks> /// The model data for the minion is held separately in modelchara_0.exd /// The data within companion_0 exd contains a reference to the index for lookup in modelchara /// </remarks> /// <returns>A list containing XivMinion data</returns> public List <XivMinion> GetMinionList() { var minionList = new List <XivMinion>(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int dataLength = 48; const int nameDataOffset = 6; const int modelCharaIndexOffset = 16; var ex = new Ex(_gameDirectory, _xivLanguage); var minionEx = ex.ReadExData(XivEx.companion); // Loops through all available minions in the companion exd files // At present only one file exists (companion_0) foreach (var minion in minionEx.Values) { var xivMinion = new XivMinion { Category = XivStrings.Companions, ItemCategory = XivStrings.Minions }; int modelCharaIndex; // Big Endian Byte Order using (var br = new BinaryReaderBE(new MemoryStream(minion))) { br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin); var nameOffset = br.ReadInt16(); br.BaseStream.Seek(modelCharaIndexOffset, SeekOrigin.Begin); modelCharaIndex = br.ReadInt16(); br.BaseStream.Seek(dataLength, SeekOrigin.Begin); var nameString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Encoding.UTF8.GetString(br.ReadBytes(nameOffset)).Replace("\0", "")); xivMinion.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray()); } if (modelCharaIndex == 0) { continue; } // This will get the model data using the index obtained for the current minion xivMinion.PrimaryModelInfo = XivModelChara.GetModelInfo(_gameDirectory, modelCharaIndex); minionList.Add(xivMinion); } minionList.Sort(); return(minionList); }
/// <summary> /// Get the minions entries list, optionally with a substring filter. /// </summary> /// <param name="substring"></param> /// <returns></returns> public async Task <List <XivMinion> > GetCachedMinionsList(string substring = null) { var where = new WhereClause(); var minionClause = new WhereClause(); minionClause.Column = "category"; minionClause.Value = XivStrings.Minions; minionClause.Join = WhereClause.JoinType.And; minionClause.Comparer = WhereClause.ComparisonType.Equal; where.Inner.Add(minionClause); if (substring != null) { var w = new WhereClause(); w.Comparer = WhereClause.ComparisonType.Like; w.Join = WhereClause.JoinType.And; w.Column = "name"; w.Value = "%" + substring + "%"; where.Inner.Add(w); } try { return(await BuildListFromTable("monsters", where, async (reader) => { var item = new XivMinion { PrimaryCategory = XivStrings.Companions, SecondaryCategory = reader.GetString("category"), Name = reader.GetString("name"), ModelInfo = new XivMonsterModelInfo { ModelType = (XivItemType)Enum.Parse(typeof(XivItemType), reader.GetString("model_type")), PrimaryID = reader.GetInt32("primary_id"), SecondaryID = reader.GetInt32("secondary_id"), ImcSubsetID = reader.GetInt32("imc_variant"), } }; return item; })); } catch (Exception ex) { throw ex; } }
/// <summary> /// Gets the list to be displayed in the Minion category /// </summary> /// <remarks> /// The model data for the minion is held separately in modelchara_0.exd /// The data within companion_0 exd contains a reference to the index for lookup in modelchara /// </remarks> /// <returns>A list containing XivMinion data</returns> public async Task <List <XivMinion> > GetUncachedMinionList() { var minionLock = new object(); var minionList = new List <XivMinion>(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int dataLength = 48; const int nameDataOffset = 6; const int modelCharaIndexOffset = 16; var minionEx = await _ex.ReadExData(XivEx.companion); var modelCharaEx = await XivModelChara.GetModelCharaData(_gameDirectory); // Loops through all available minions in the companion exd files // At present only one file exists (companion_0) await Task.Run(() => Parallel.ForEach(minionEx.Values, (minion) => { var xivMinion = new XivMinion { PrimaryCategory = XivStrings.Companions, SecondaryCategory = XivStrings.Minions }; int modelCharaIndex; // Big Endian Byte Order using (var br = new BinaryReaderBE(new MemoryStream(minion))) { br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin); var nameOffset = br.ReadInt16(); br.BaseStream.Seek(modelCharaIndexOffset, SeekOrigin.Begin); modelCharaIndex = br.ReadInt16(); br.BaseStream.Seek(dataLength, SeekOrigin.Begin); var nameString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Encoding.UTF8 .GetString(br.ReadBytes(nameOffset)).Replace("\0", "")); xivMinion.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray()); } if (modelCharaIndex == 0) { return; } // This will get the model data using the index obtained for the current minion xivMinion.ModelInfo = XivModelChara.GetModelInfo(modelCharaEx, modelCharaIndex); lock (minionLock) { minionList.Add(xivMinion); } })); minionList.Sort(); return(minionList); }