public SHA256Hasher() { _hashGenerator = new SHA256HashGenerator(); }
/// <summary> /// Gets the skeleton sklb file /// </summary> /// <param name="modelName">The name of the model</param> /// <param name="category">The items category</param> private async Task GetSkeleton(string modelName, string category) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var skelFolder = ""; var skelFile = ""; var slotAbr = ""; if (modelName[0].Equals('w')) { skelFolder = string.Format(XivStrings.WeapSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.WeapSkelFile, modelName.Substring(1, 4), "0001"); } else if (modelName[0].Equals('m')) { skelFolder = string.Format(XivStrings.MonsterSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.MonsterSkelFile, modelName.Substring(1, 4), "0001"); } else if (modelName[0].Equals('d')) { skelFolder = string.Format(XivStrings.DemiSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.DemiSkelFile, modelName.Substring(1, 4), "0001"); } else { slotAbr = SlotAbbreviationDictionary[category]; var id = modelName.Substring(6, 4); if (_item.ItemCategory.Equals(XivStrings.Hair)) { id = _hairSklbName.Substring(1); } if (slotAbr.Equals("base")) { id = "0001"; } skelFolder = string.Format(XivStrings.EquipSkelFolder, modelName.Substring(1, 4), slotAbr, slotAbr[0], id); skelFile = string.Format(XivStrings.EquipSkelFile, modelName.Substring(1, 4), slotAbr[0], id); } // Continue only if the skeleton file exists if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), _dataFile)) { // Sometimes for face skeletons id 0001 does not exist but 0002 does if (_item.ItemCategory.Equals(XivStrings.Face)) { skelFolder = string.Format(XivStrings.EquipSkelFolder, modelName.Substring(1, 4), slotAbr, slotAbr[0], "0002"); skelFile = string.Format(XivStrings.EquipSkelFile, modelName.Substring(1, 4), slotAbr[0], "0002"); if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), _dataFile)) { return; } } else { return; } } var offset = await index.GetDataOffset(HashGenerator.GetHash(skelFolder), HashGenerator.GetHash(skelFile), _dataFile); if (offset == 0) { throw new Exception($"Could not find offest for {skelFolder}/{skelFile}"); } var sklbData = await dat.GetType2Data(offset, _dataFile); using (var br = new BinaryReader(new MemoryStream(sklbData))) { br.BaseStream.Seek(0, SeekOrigin.Begin); var magic = br.ReadInt32(); var format = br.ReadInt32(); br.ReadBytes(2); if (magic != 0x736B6C62) { throw new FormatException(); } var dataOffset = 0; switch (format) { case 0x31323030: dataOffset = br.ReadInt16(); break; case 0x31333030: case 0x31333031: br.ReadBytes(2); dataOffset = br.ReadInt16(); break; default: throw new Exception($"Unkown Data Format ({format})"); } br.BaseStream.Seek(dataOffset, SeekOrigin.Begin); var havokData = br.ReadBytes(sklbData.Length - dataOffset); var mName = modelName.Substring(0, 5); if (category.Equals(XivStrings.Head)) { mName = modelName.Substring(5, 5); } else if (category.Equals(XivStrings.Hair)) { mName = _hairSklbName; } File.WriteAllBytes(Directory.GetCurrentDirectory() + "/Skeletons/" + mName + ".sklb", havokData); } }
/// <summary> /// Gets the assets for furniture /// </summary> /// <param name="modelID">The model id to get the assets for</param> /// <returns>A HousingAssets object containing the asset info</returns> private async Task <HousingAssets> GetFurnitureAssets(int modelID, string category) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var id = modelID.ToString().PadLeft(4, '0'); var assetFolder = ""; var assetFile = ""; if (category.Equals(XivStrings.Furniture_Indoor)) { assetFolder = $"bgcommon/hou/indoor/general/{id}/asset"; assetFile = $"fun_b0_m{id}.sgb"; } else if (category.Equals(XivStrings.Furniture_Outdoor)) { assetFolder = $"bgcommon/hou/outdoor/general/{id}/asset"; assetFile = $"gar_b0_m{id}.sgb"; } var assetOffset = await index.GetDataOffset(HashGenerator.GetHash(assetFolder), HashGenerator.GetHash(assetFile), XivDataFile._01_Bgcommon); var assetData = await dat.GetType2Data(assetOffset, XivDataFile._01_Bgcommon); var housingAssets = new HousingAssets(); await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(assetData))) { br.BaseStream.Seek(20, SeekOrigin.Begin); var skip = br.ReadInt32() + 20; br.BaseStream.Seek(skip + 4, SeekOrigin.Begin); var stringsOffset = br.ReadInt32(); br.BaseStream.Seek(skip + stringsOffset, SeekOrigin.Begin); var pathCounts = 0; while (true) { // Because we don't know the length of the string, we read the data until we reach a 0 value // That 0 value is the space between strings byte a; var pathName = new List <byte>(); while ((a = br.ReadByte()) != 0) { if (a == 0xFF) { break; } pathName.Add(a); } if (a == 0xFF) { break; } // Read the string from the byte array and remove null terminators var path = Encoding.ASCII.GetString(pathName.ToArray()).Replace("\0", ""); if (path.Equals(string.Empty)) { continue; } // Add the attribute to the list if (pathCounts == 0) { housingAssets.Shared = path; } else if (pathCounts == 1) { housingAssets.BaseFileName = path; } else { if (path.Contains(".mdl")) { housingAssets.MdlList.Add(path); } else if (path.Contains(".sgb")) { housingAssets.AdditionalAssetList.Add(path); } else if (!path.Contains(".")) { housingAssets.BaseFolder = path; } else { housingAssets.OthersList.Add(path); } } pathCounts++; } } }); if (housingAssets.AdditionalAssetList.Count > 0) { await GetAdditionalAssets(housingAssets); } return(housingAssets); }
/// <summary> /// Gets the relevant IMC information for a given item /// </summary> /// <param name="item">The item to get the version for</param> /// <param name="modelInfo">The model info of the item</param> /// <returns>The XivImc Data</returns> public XivImc GetImcInfo(IItemModel item, XivModelInfo modelInfo) { var xivImc = new XivImc(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int headerLength = 4; const int variantLength = 6; const int variantSetLength = 30; var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(item); var imcPath = GetImcPath(modelInfo, itemType); var imcOffset = index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile); if (imcOffset == 0) { throw new Exception($"Could not find offest for {imcPath.Folder}/{imcPath.File}"); } var imcData = dat.GetType2Data(imcOffset, _dataFile); using (var br = new BinaryReader(new MemoryStream(imcData))) { int variantOffset; if (itemType == XivItemType.weapon || itemType == XivItemType.monster) { // weapons and monsters do not have variant sets variantOffset = (modelInfo.Variant * variantLength) + headerLength; // use default if offset is out of range if (variantOffset >= imcData.Length) { variantOffset = headerLength; } } else { // Variant Sets contain 5 variants for each slot // These can be Head, Body, Hands, Legs, Feet or Ears, Neck, Wrists, LRing, RRing // This skips to the correct variant set, then to the correct slot within that set for the item variantOffset = (modelInfo.Variant * variantSetLength) + (_slotOffsetDictionary[item.ItemCategory] * variantLength) + headerLength; // use defalut if offset is out of range if (variantOffset >= imcData.Length) { variantOffset = (_slotOffsetDictionary[item.ItemCategory] * variantLength) + headerLength; } } br.BaseStream.Seek(variantOffset, SeekOrigin.Begin); // if(variantOffset) xivImc.Version = br.ReadByte(); var unknown = br.ReadByte(); xivImc.Mask = br.ReadUInt16(); xivImc.Vfx = br.ReadByte(); var unknown1 = br.ReadByte(); } return(xivImc); }
private async Task <Result> CheckIdentityIsUnique(string identity) { return(await _context.Agents.AnyAsync(a => a.IdentityHash == HashGenerator.ComputeSha256(identity)) ? Result.Failure("User is already registered") : Result.Success()); }
public OperationResult <Model.BusinessEntities.PetitionEmailVote> CreateEmailVoteRequest(EmailVote vote) { OperationResult <Model.BusinessEntities.PetitionEmailVote> emailVoteRequestResult; Func <EDEntities, OperationResult <Model.BusinessEntities.PetitionEmailVote> > procedure = (db) => { OperationResult <Model.BusinessEntities.PetitionEmailVote> result; var emailVote = db.PetitionEmailVotes.SingleOrDefault(v => v.PetitionID == vote.ID && v.Email == vote.Email); if (emailVote != null) { var votedPetition = db.Petitions.SingleOrDefault(p => p.ID == vote.ID); result = emailVote.IsConfirmed ? OperationResult <Model.BusinessEntities.PetitionEmailVote> .Fail( int.Parse(PetitionVoteOperationResult.AlreadyVotedCode), PetitionVoteOperationResult.AlreadyVotedMessage) : OperationResult <Model.BusinessEntities.PetitionEmailVote> .Success( int.Parse(PetitionVoteOperationResult.WaitingConfirmationCode), string.Format(PetitionVoteOperationResult.WaitingConfirmationMessage, emailVote.Email), new Model.BusinessEntities.PetitionEmailVote(emailVote, votedPetition)); return(result); } emailVote = new PetitionEmailVote { PetitionID = vote.ID, Email = vote.Email, CreatedDate = DateTime.Now, IsConfirmed = false, Hash = HashGenerator.Generate() }; db.PetitionEmailVotes.Add(emailVote); db.SaveChanges(); var petition = new Model.BusinessEntities.Petition(db.Petitions.SingleOrDefault(p => p.ID == emailVote.PetitionID)); var clientEmailVote = new Model.BusinessEntities.PetitionEmailVote() { ID = emailVote.ID, Petition = petition, Hash = emailVote.Hash, Email = emailVote.Email, CreatedDate = emailVote.CreatedDate, IsConfirmed = emailVote.IsConfirmed }; result = OperationResult <Model.BusinessEntities.PetitionEmailVote> .Success( int.Parse(PetitionVoteOperationResult.EmailVoteRequestCreatedCode), string.Format(PetitionVoteOperationResult.EmailVoteRequestCreatedMessage, emailVote.Email), clientEmailVote); return(result); }; emailVoteRequestResult = DbExecuter.Execute(procedure); return(emailVoteRequestResult); }
/// <summary> /// Searches for items given a model ID and item type /// </summary> /// <param name="modelID"> The model id used for searching</param> /// <param name="type">The type of item</param> /// <returns>A list of SearchResults objects</returns> public async Task <List <SearchResults> > SearchGearByModelID(int modelID, string type) { var searchLock = new object(); var searchLock1 = new object(); var searchResultsList = new List <SearchResults>(); var resultCheckList = new List <string>(); var equipmentSlots = new string[] { "met", "glv", "dwn", "sho", "top", }; var accessorySlots = new string[] { "ear", "nek", "rir", "ril", "wrs" }; var parts = new string[] { "a", "b", "c", "d", "e", "f" }; var id = modelID.ToString().PadLeft(4, '0'); var folder = ""; if (type.Equals("Equipment")) { folder = $"chara/equipment/e{id}/material/v"; } else if (type.Equals("Accessory")) { folder = $"chara/accessory/a{id}/material/v"; } else if (type.Equals("Weapon")) { folder = $"chara/weapon/w{id}/obj/body/b"; } var bodyVariantDictionary = new Dictionary <int, List <int> >(); List <int> variantList = null; if (type.Equals("Weapon")) { await Task.Run(() => Parallel.For(1, 200, (i) => { var folderHashDictionary = new Dictionary <int, int>(); var wFolder = $"{folder}{i.ToString().PadLeft(4, '0')}/material/v"; Parallel.For(1, 200, (j) => { lock (searchLock) { folderHashDictionary.Add(HashGenerator.GetHash($"{wFolder}{j.ToString().PadLeft(4, '0')}"), j); } }); variantList = _index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara).Result; if (variantList.Count > 0) { variantList.Sort(); lock (searchLock1) { bodyVariantDictionary.Add(i, variantList); } } })); } else { var folderHashDictionary = new Dictionary <int, int>(); await Task.Run(() => Parallel.For(1, 200, (i) => { lock (searchLock) { folderHashDictionary.Add(HashGenerator.GetHash($"{folder}{i.ToString().PadLeft(4, '0')}"), i); } })); variantList = _index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara).Result; } if (!type.Equals("Weapon")) { foreach (var variant in variantList) { var mtrlFolder = $"{folder}{variant.ToString().PadLeft(4, '0')}"; var mtrlFile = ""; var mtrlFolderHashes = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), XivDataFile._04_Chara); foreach (var race in IDRaceDictionary.Keys) { string[] slots = null; if (type.Equals("Equipment")) { slots = equipmentSlots; } else if (type.Equals("Accessory")) { slots = accessorySlots; } foreach (var slot in slots) { foreach (var part in parts) { if (type.Equals("Equipment")) { mtrlFile = $"mt_c{race}e{id}_{slot}_{part}.mtrl"; } else if (type.Equals("Accessory")) { mtrlFile = $"mt_c{race}a{id}_{slot}_{part}.mtrl"; } if (mtrlFolderHashes.Contains(HashGenerator.GetHash(mtrlFile))) { var abbrSlot = AbbreviationSlotDictionary[slot]; if (!resultCheckList.Contains($"{abbrSlot}{variant.ToString()}")) { searchResultsList.Add(new SearchResults { Body = "-", Slot = abbrSlot, Variant = variant }); resultCheckList.Add($"{abbrSlot}{variant.ToString()}"); } } } } } } } else { foreach (var bodyVariant in bodyVariantDictionary) { foreach (var variant in bodyVariant.Value) { searchResultsList.Add(new SearchResults { Body = bodyVariant.Key.ToString(), Slot = XivStrings.Main_Hand, Variant = variant }); } } } searchResultsList.Sort(); return(searchResultsList); }
public static IHtmlContent Identicon(this IHtmlHelper helper, object?value, int size, string?alt = null, ExportImageFormat format = ExportImageFormat.Png, IdenticonStyle?style = null) { var hash = HashGenerator.ComputeHash(value, "SHA1"); return(helper.Identicon(hash, size, alt, format, style)); }
public static void SetPath(this CharacterCustomizationAppearances.HashValueEntry entry, string value) { entry.Hash = HashGenerator.CalcFNV1A64(value); }
/// <summary> /// Adds a new file descriptor/stub into the Index files. /// </summary> /// <param name="fullPath">Full path to the new file.</param> /// <param name="dataOffset">Raw DAT file offset to use for the new file.</param> /// <param name="dataFile">Which data file set to use.</param> /// <returns></returns> public bool AddFileDescriptor(string fullPath, int dataOffset, XivDataFile dataFile) { fullPath = fullPath.Replace("\\", "/"); var pathHash = HashGenerator.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/", StringComparison.Ordinal))); var fileHash = HashGenerator.GetHash(Path.GetFileName(fullPath)); var uPathHash = BitConverter.ToUInt32(BitConverter.GetBytes(pathHash), 0); var uFileHash = BitConverter.ToUInt32(BitConverter.GetBytes(fileHash), 0); var fullPathHash = HashGenerator.GetHash(fullPath); var uFullPathHash = BitConverter.ToUInt32(BitConverter.GetBytes(fullPathHash), 0); var SegmentHeaders = new int[4]; var SegmentOffsets = new int[4]; var SegmentSizes = new int[4]; // Segment header offsets SegmentHeaders[0] = 1028; // Files SegmentHeaders[1] = 1028 + (72 * 1) + 4; // Unknown SegmentHeaders[2] = 1028 + (72 * 2) + 4; // Unknown SegmentHeaders[3] = 1028 + (72 * 3) + 4; // Folders // Index 1 Closure { var indexPath = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{IndexExtension}"); // Dump the index into memory, since we're going to have to inject data. byte[] originalIndex = File.ReadAllBytes(indexPath); byte[] modifiedIndex = new byte[originalIndex.Length + 16]; // Get all the segment header data for (int i = 0; i < SegmentHeaders.Length; i++) { SegmentOffsets[i] = BitConverter.ToInt32(originalIndex, SegmentHeaders[i] + 4); SegmentSizes[i] = BitConverter.ToInt32(originalIndex, SegmentHeaders[i] + 8); } int fileCount = SegmentSizes[0] / 16; // Search for appropriate location to inject data. bool foundFolder = false; var injectLocation = SegmentOffsets[0] + SegmentSizes[0]; for (int i = 0; i < fileCount; i++) { int position = SegmentOffsets[0] + (i * 16); uint iHash = BitConverter.ToUInt32(originalIndex, position); uint iPathHash = BitConverter.ToUInt32(originalIndex, position + 4); uint iOffset = BitConverter.ToUInt32(originalIndex, position + 8); if (iPathHash == uPathHash) { foundFolder = true; if (iHash == uFileHash) { // File already exists return(false); } else if (iHash > uFileHash) { injectLocation = position; break; } } else { // End of folder - inject file here if we haven't yet. if (foundFolder == true) { injectLocation = position; break; } } } // Cancel if we failed to find the path. if (foundFolder == false) { return(false); } // Split the file at the injection point. int remainder = originalIndex.Length - injectLocation; Array.Copy(originalIndex, 0, modifiedIndex, 0, injectLocation); Array.Copy(originalIndex, injectLocation, modifiedIndex, injectLocation + 16, remainder); // Update the segment headers. for (int i = 0; i < SegmentHeaders.Length; i++) { // Update Segment 0 Size. if (i == 0) { SegmentSizes[i] += 16; Array.Copy(BitConverter.GetBytes(SegmentSizes[i]), 0, modifiedIndex, SegmentHeaders[i] + 8, 4); } // Update other segments' offsets. else { SegmentOffsets[i] += 16; Array.Copy(BitConverter.GetBytes(SegmentOffsets[i]), 0, modifiedIndex, SegmentHeaders[i] + 4, 4); } } // Set the actual Injected Data Array.Copy(BitConverter.GetBytes(fileHash), 0, modifiedIndex, injectLocation, 4); Array.Copy(BitConverter.GetBytes(pathHash), 0, modifiedIndex, injectLocation + 4, 4); Array.Copy(BitConverter.GetBytes(dataOffset), 0, modifiedIndex, injectLocation + 8, 4); // Update the folder structure var folderCount = SegmentSizes[3] / 16; foundFolder = false; for (int i = 0; i < folderCount; i++) { int position = SegmentOffsets[3] + (i * 16); uint iHash = BitConverter.ToUInt32(modifiedIndex, position); uint iOffset = BitConverter.ToUInt32(modifiedIndex, position + 4); uint iFolderSize = BitConverter.ToUInt32(modifiedIndex, position + 8); // Update folder offset if (iOffset > injectLocation) { Array.Copy(BitConverter.GetBytes(iOffset + 16), 0, modifiedIndex, position + 4, 4); } // Update folder size if (iHash == uPathHash) { foundFolder = true; Array.Copy(BitConverter.GetBytes(iFolderSize + 16), 0, modifiedIndex, position + 8, 4); } } if (!foundFolder) { return(false); } // Update SHA-1 Hashes. SHA1 sha = new SHA1CryptoServiceProvider(); byte[] shaHash; for (int i = 0; i < SegmentHeaders.Length; i++) { //Segment shaHash = sha.ComputeHash(modifiedIndex, SegmentOffsets[i], SegmentSizes[i]); Array.Copy(shaHash, 0, modifiedIndex, SegmentHeaders[i] + 12, 20); } // Compute Hash of the header segment shaHash = sha.ComputeHash(modifiedIndex, 0, 960); Array.Copy(shaHash, 0, modifiedIndex, 960, 20); // Write file File.WriteAllBytes(indexPath, modifiedIndex); } // Index 2 Closure { var index2Path = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{Index2Extension}"); // Dump the index into memory, since we're going to have to inject data. byte[] originalIndex = File.ReadAllBytes(index2Path); byte[] modifiedIndex = new byte[originalIndex.Length + 16]; // Get all the segment header data for (int i = 0; i < SegmentHeaders.Length; i++) { SegmentOffsets[i] = BitConverter.ToInt32(originalIndex, SegmentHeaders[i] + 4); SegmentSizes[i] = BitConverter.ToInt32(originalIndex, SegmentHeaders[i] + 8); } int fileCount = SegmentSizes[0] / 8; // Search for appropriate location to inject data. var injectLocation = SegmentOffsets[0] + SegmentSizes[0]; for (int i = 0; i < fileCount; i++) { int position = SegmentOffsets[0] + (i * 8); uint iFullPathHash = BitConverter.ToUInt32(originalIndex, position); uint iOffset = BitConverter.ToUInt32(originalIndex, position + 4); // Index 2 is just in hash order, so find the spot where we fit in. if (iFullPathHash > uFullPathHash) { injectLocation = position; break; } } // Split the file at the injection point. int remainder = originalIndex.Length - injectLocation; Array.Copy(originalIndex, 0, modifiedIndex, 0, injectLocation); Array.Copy(originalIndex, injectLocation, modifiedIndex, injectLocation + 8, remainder); // Update the segment headers. for (int i = 0; i < SegmentHeaders.Length; i++) { // Update Segment 0 Size. if (i == 0) { SegmentSizes[i] += 8; Array.Copy(BitConverter.GetBytes(SegmentSizes[i]), 0, modifiedIndex, SegmentHeaders[i] + 8, 4); } // Update other segments' offsets. else { // Index 2 doesn't have all 4 segments. if (SegmentOffsets[i] != 0) { SegmentOffsets[i] += 8; Array.Copy(BitConverter.GetBytes(SegmentOffsets[i]), 0, modifiedIndex, SegmentHeaders[i] + 4, 4); } } } // Set the actual Injected Data Array.Copy(BitConverter.GetBytes(uFullPathHash), 0, modifiedIndex, injectLocation, 4); Array.Copy(BitConverter.GetBytes(dataOffset), 0, modifiedIndex, injectLocation + 4, 4); // Update SHA-1 Hashes. SHA1 sha = new SHA1CryptoServiceProvider(); byte[] shaHash; for (int i = 0; i < SegmentHeaders.Length; i++) { if (SegmentSizes[i] > 0) { //Segment shaHash = sha.ComputeHash(modifiedIndex, SegmentOffsets[i], SegmentSizes[i]); Array.Copy(shaHash, 0, modifiedIndex, SegmentHeaders[i] + 12, 20); } } // Compute Hash of the header segment shaHash = sha.ComputeHash(modifiedIndex, 0, 960); Array.Copy(shaHash, 0, modifiedIndex, 960, 20); // Write file File.WriteAllBytes(index2Path, modifiedIndex); } return(true); }
protected Int32 GenerateConfigId(EndpointConfiguration config) { Int64 result = config.RootDeviceDescriptionPathsToRootDevices.Values.Select( rootDevice => rootDevice.BuildRootDeviceDescription( _serverData, config, CultureInfo.InvariantCulture)).Aggregate <string, long>( 0, (current, description) => current + HashGenerator.CalculateHash(0, description)); result = config.SCPDPathsToServices.Values.Select(service => service.BuildSCPDDocument( config, _serverData)).Aggregate(result, (current, description) => current + HashGenerator.CalculateHash(0, description)); result += HashGenerator.CalculateHash(0, NetworkHelper.IPAddrToString(config.EndPointIPAddress)); //result += HashGenerator.CalculateHash(0, config.ServicePrefix); result += HashGenerator.CalculateHash(0, config.ControlPathBase + config.DescriptionPathBase + config.EventSubPathBase); return((int)result); }
/// <summary> /// Gets the list of available mtrl parts for a given item /// </summary> /// <param name="itemModel">An item that contains model data</param> /// <param name="xivRace">The race for the requested data</param> /// <returns>A list of part characters</returns> public async Task <List <string> > GetTexturePartList(IItemModel itemModel, XivRace xivRace, XivDataFile dataFile) { var itemType = ItemType.GetPrimaryItemType(itemModel); var version = "0001"; var id = itemModel.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); var itemCategory = itemModel.SecondaryCategory; if (itemType != XivItemType.human && itemType != XivItemType.furniture) { // Get the mtrl version for the given item from the imc file var imc = new Imc(_gameDirectory); version = (await imc.GetImcInfo(itemModel)).MaterialSet.ToString().PadLeft(4, '0'); } var parts = Constants.Alphabet; var race = xivRace.GetRaceCode(); string mtrlFolder = "", mtrlFile = ""; switch (itemType) { case XivItemType.equipment: mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}"; mtrlFile = $"mt_c{race}e{id}_{itemModel.GetItemSlotAbbreviation()}_"; break; case XivItemType.accessory: mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}"; mtrlFile = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemCategory]}_"; break; case XivItemType.weapon: mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}"; mtrlFile = $"mt_w{id}b{bodyVer}_"; break; case XivItemType.monster: mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}"; mtrlFile = $"mt_m{id}b{bodyVer}_"; break; case XivItemType.demihuman: mtrlFolder = $"chara/{itemType}/d{id}/obj/body/e{bodyVer}/material/v{version}"; mtrlFile = $"mt_d{id}e{bodyVer}_"; break; case XivItemType.human: if (itemCategory.Equals(XivStrings.Body)) { mtrlFolder = $"chara/{itemType}/c{id}/obj/body/b{bodyVer}/material/v{version}"; mtrlFile = $"mt_c{id}b{bodyVer}_"; } else if (itemCategory.Equals(XivStrings.Hair)) { mtrlFolder = $"chara/{itemType}/c{id}/obj/body/h{bodyVer}/material/v{version}"; mtrlFile = $"mt_c{id}h{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_"; } else if (itemCategory.Equals(XivStrings.Face)) { mtrlFolder = $"chara/{itemType}/c{id}/obj/body/f{bodyVer}/material/v{version}"; mtrlFile = $"mt_c{id}f{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_"; } else if (itemCategory.Equals(XivStrings.Tail)) { mtrlFolder = $"chara/{itemType}/c{id}/obj/body/t{bodyVer}/material/v{version}"; mtrlFile = $"mt_c{id}t{bodyVer}_"; } break; case XivItemType.furniture: if (itemCategory.Equals(XivStrings.Furniture_Indoor)) { mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material"; mtrlFile = $"fun_b0_m{id}_0"; } else if (itemCategory.Equals(XivStrings.Furniture_Outdoor)) { mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material"; mtrlFile = $"gar_b0_m{id}_0"; } break; default: mtrlFolder = ""; break; } // Get a list of hashed mtrl files that are in the given folder var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile); // append the part char to the mtrl file and see if its hashed value is within the files list var partList = (from part in parts let mtrlCheck = mtrlFile + part + ".mtrl" where files.Contains(HashGenerator.GetHash(mtrlCheck)) select part.ToString()).ToList(); if (partList.Count < 1 && itemType == XivItemType.furniture) { if (itemCategory.Equals(XivStrings.Furniture_Indoor)) { mtrlFile = $"fun_b0_m{id}_1"; } else if (itemCategory.Equals(XivStrings.Furniture_Outdoor)) { mtrlFile = $"gar_b0_m{id}_1"; } // Get a list of hashed mtrl files that are in the given folder files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile); // append the part char to the mtrl file and see if its hashed value is within the files list partList = (from part in parts let mtrlCheck = mtrlFile + part + ".mtrl" where files.Contains(HashGenerator.GetHash(mtrlCheck)) select part.ToString()).ToList(); } // returns the list of parts that exist within the mtrl folder return(partList); }
/// <summary> /// Gets the MTRL data for the given item /// </summary> /// <remarks> /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>) /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a') /// </remarks> /// <param name="itemModel">Item that contains model data</param> /// <param name="race">The race for the requested data</param> /// <param name="part">The Mtrl part </param> /// <returns></returns> public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, char part) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(itemModel); // Get mtrl path var mtrlPath = GetMtrlPath(itemModel, race, part, itemType); // Get mtrl offset var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File), _dataFile); if (mtrlOffset == 0) { throw new Exception($"Could not find offest for {mtrlPath.Folder}/{mtrlPath.File}"); } // Get uncompressed mtrl data var mtrlData = dat.GetType2Data(mtrlOffset, _dataFile); XivMtrl xivMtrl; using (var br = new BinaryReader(new MemoryStream(mtrlData))) { xivMtrl = new XivMtrl { Signature = br.ReadInt32(), FileSize = br.ReadInt16(), ColorSetDataSize = br.ReadInt16(), MaterialDataSize = br.ReadInt16(), TexturePathsDataSize = br.ReadByte(), Unknown = br.ReadByte(), TextureCount = br.ReadByte(), MapCount = br.ReadByte(), ColorSetCount = br.ReadByte(), Unknown1 = br.ReadByte(), TextureTypePathList = new List <TexTypePath>(), MTRLPath = $"{mtrlPath.Folder}/{mtrlPath.File}" }; var pathSizeList = new List <int>(); // get the texture path offsets xivMtrl.TexturePathOffsetList = new List <int>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.TexturePathOffsetList[i] - xivMtrl.TexturePathOffsetList[i - 1]); } } // get the map path offsets xivMtrl.MapPathOffsetList = new List <int>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.MapPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.TexturePathOffsetList[xivMtrl.TextureCount - 1]); } } // get the color set offsets xivMtrl.ColorSetPathOffsetList = new List <int>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.ColorSetPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.MapPathOffsetList[xivMtrl.MapCount - 1]); } } pathSizeList.Add(xivMtrl.TexturePathsDataSize - xivMtrl.ColorSetPathOffsetList[xivMtrl.ColorSetCount - 1]); var count = 0; // get the texture path strings xivMtrl.TexturePathList = new List <string>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // add the textures to the TextureTypePathList xivMtrl.TextureTypePathList.AddRange(GetTexNames(xivMtrl.TexturePathList, _dataFile)); // get the map path strings xivMtrl.MapPathList = new List <string>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // get the color set path strings xivMtrl.ColorSetPathList = new List <string>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // If the mtrl file contains a color set, add it to the TextureTypePathList if (xivMtrl.ColorSetDataSize > 0) { var ttp = new TexTypePath { Path = mtrlPath.Folder + "/" + mtrlPath.File, Type = XivTexType.ColorSet, DataFile = _dataFile }; xivMtrl.TextureTypePathList.Add(ttp); } var shaderPathSize = xivMtrl.MaterialDataSize - xivMtrl.TexturePathsDataSize; xivMtrl.Shader = Encoding.UTF8.GetString(br.ReadBytes(shaderPathSize)).Replace("\0", ""); xivMtrl.Unknown2 = br.ReadInt32(); xivMtrl.ColorSetData = new List <Half>(); for (var i = 0; i < xivMtrl.ColorSetDataSize / 2; i++) { xivMtrl.ColorSetData.Add(new Half(br.ReadUInt16())); } xivMtrl.AdditionalDataSize = br.ReadInt16(); xivMtrl.DataStruct1Count = br.ReadInt16(); xivMtrl.DataStruct2Count = br.ReadInt16(); xivMtrl.ParameterStructCount = br.ReadInt16(); xivMtrl.ShaderNumber = br.ReadInt16(); xivMtrl.Unknown3 = br.ReadInt16(); xivMtrl.DataStruct1List = new List <DataStruct1>(xivMtrl.DataStruct1Count); for (var i = 0; i < xivMtrl.DataStruct1Count; i++) { xivMtrl.DataStruct1List.Add(new DataStruct1 { ID = br.ReadUInt32(), Unknown1 = br.ReadUInt32() }); } xivMtrl.DataStruct2List = new List <DataStruct2>(xivMtrl.DataStruct2Count); for (var i = 0; i < xivMtrl.DataStruct2Count; i++) { xivMtrl.DataStruct2List.Add(new DataStruct2 { ID = br.ReadUInt32(), Offset = br.ReadInt16(), Size = br.ReadInt16() }); } xivMtrl.ParameterStructList = new List <ParameterStruct>(xivMtrl.ParameterStructCount); for (var i = 0; i < xivMtrl.ParameterStructCount; i++) { xivMtrl.ParameterStructList.Add(new ParameterStruct { ID = br.ReadUInt32(), Unknown1 = br.ReadInt16(), Unknown2 = br.ReadInt16(), TextureIndex = br.ReadUInt32() }); } xivMtrl.AdditionalData = br.ReadBytes(xivMtrl.AdditionalDataSize); } return(xivMtrl); }
public MD5Hasher() { _hashGenerator = new Md5HashGenerator(); }
public Murmur3Hasher() { _hashGenerator = new Murmur3AUnsafe(); }
public static void Create(TrinityItem actor) { if (actor.ActorType != ActorType.Item) { return; } if (!actor.IsAcdBased) // || !actor.IsAcdValid) { return; } var commonData = actor.CommonData; var attributes = actor.Attributes; actor.InventorySlot = ZetaDia.Memory.Read <InventorySlot>(commonData.BaseAddress + 0x114); //actor.AcdItemTemp.InventorySlot; actor.InventoryColumn = ZetaDia.Memory.Read <int>(commonData.BaseAddress + 0x118); //actor.AcdItemTemp.InventoryColumn; actor.InventoryRow = ZetaDia.Memory.Read <int>(commonData.BaseAddress + 0x11c); //actor.AcdItemTemp.InventoryRow; actor.IsUnidentified = attributes.IsUnidentified; actor.IsAncient = attributes.IsAncient; actor.IsPrimalAncient = attributes.IsPrimalAncient; actor.ItemQualityLevel = attributes.ItemQualityLevel; actor.RequiredLevel = Math.Max(actor.Attributes.RequiredLevel, actor.Attributes.ItemLegendaryItemLevelOverride); actor.IsCrafted = attributes.IsCrafted; actor.IsVendorBought = attributes.IsVendorBought; actor.IsAccountBound = attributes.ItemBoundToACDId > 0; #region Trading int gameTick = ZetaDia.Globals.GameTick; int tradeEndTime = attributes.ItemTradeEndTime <= gameTick ? 0 : attributes.ItemTradeEndTime - gameTick; actor.ItemTradeEndTime = TimeSpan.FromSeconds(tradeEndTime / 60); actor.TradablePlayers = new List <int>(); for (int i = 0; i < 8; i++) { int playerTradeHigh = attributes.GetTradePlayerHigh(i); int playerTradeLow = attributes.GetTradePlayerLow(i); int playerTrade = (int)((long)playerTradeHigh << 32 | (uint)playerTradeLow); if (playerTrade != 0) { actor.TradablePlayers.Add(playerTrade); } } int playerId = ZetaDia.Storage.PlayerDataManager.ActivePlayerData.PlayerId; actor.IsTradeable = attributes.ItemTradeEndTime != 0 && actor.TradablePlayers.Contains(playerId); #endregion var realname = GetName(actor.GameBalanceId); actor.Name = string.IsNullOrEmpty(realname) ? actor.InternalName : realname; var gbi = GameBalanceHelper.GetRecord <SnoGameBalanceItem>(SnoGameBalanceType.Items, actor.GameBalanceId); actor.ItemLevel = actor.RequiredLevel; //gbi.ItemLevel; actor.InternalName = gbi.InternalName; actor.MaxStackCount = gbi.StackSize; actor.GemType = gbi.GemType; actor.RawItemType = (RawItemType)gbi.ItemTypesGameBalanceId; actor.GemQuality = attributes.GemQuality; actor.ItemType = TypeConversions.GetItemType(actor.RawItemType); actor.ItemBaseType = TypeConversions.GetItemBaseType(actor.ItemType); actor.TrinityItemType = TypeConversions.GetTrinityItemType(actor.RawItemType, actor.GemType); actor.TrinityItemBaseType = TypeConversions.GetTrinityItemBaseType(actor.TrinityItemType); actor.IsGem = actor.RawItemType == RawItemType.Gem || actor.RawItemType == RawItemType.UpgradeableJewel; actor.IsCraftingReagent = actor.RawItemType == RawItemType.CraftingReagent || actor.RawItemType == RawItemType.CraftingReagent_Bound; actor.IsGold = actor.RawItemType == RawItemType.Gold; actor.IsEquipment = TypeConversions.GetIsEquipment(actor.TrinityItemBaseType); actor.IsClassItem = TypeConversions.GetIsClassItem(actor.ItemType); actor.IsOffHand = TypeConversions.GetIsOffhand(actor.ItemType); actor.IsPotion = actor.RawItemType == RawItemType.HealthPotion; actor.IsSalvageable = actor.IsEquipment && !actor.IsVendorBought && actor.RequiredLevel > 1 || actor.IsPotion; actor.IsLegendaryGem = actor.RawItemType == RawItemType.UpgradeableJewel; actor.IsMiscItem = actor.ItemBaseType == ItemBaseType.Misc; actor.IsTwoSquareItem = TypeConversions.GetIsTwoSlot(actor.ItemBaseType, actor.ItemType); actor.FollowerType = GetFollowerType(actor.ActorSnoId); actor.ItemStackQuantity = attributes.ItemStackQuantity; actor.TrinityItemQuality = TypeConversions.GetTrinityItemQuality(actor.ItemQualityLevel); actor.IsCosmeticItem = actor.RawItemType == RawItemType.CosmeticPet || actor.RawItemType == RawItemType.CosmeticPennant || actor.RawItemType == RawItemType.CosmeticPortraitFrame || actor.RawItemType == RawItemType.CosmeticWings; actor.IsLowQuality = actor.TrinityItemQuality == TrinityItemQuality.Common || actor.TrinityItemQuality == TrinityItemQuality.Inferior || actor.TrinityItemQuality == TrinityItemQuality.Magic || actor.TrinityItemQuality == TrinityItemQuality.Rare; actor.GlobeType = GetGlobeType(actor); actor.IsWeapon = TypeConversions.IsWeapon(actor); actor.IsArmor = TypeConversions.IsArmor(actor); actor.ObjectHash = HashGenerator.GenerateItemHash( actor.Position, actor.ActorSnoId, actor.InternalName, actor.WorldDynamicId, actor.ItemQualityLevel, actor.ItemLevel); if (actor.IsGroundItem) { actor.IsPickupNoClick = GameData.NoPickupClickItemTypes.Contains(actor.TrinityItemType) || GameData.NoPickupClickTypes.Contains(actor.Type); actor.IsMyDroppedItem = DropItems.DroppedItemAnnIds.Contains(actor.AnnId); actor.CanPickupItem = CanPickupItem(actor); actor.IsItemAssigned = actor.Attributes.ItemBoundToACDId == 0 && actor.Attributes.ItemAssignedHero == ZetaDia.Service.Hero.HeroId; } if (actor.Type == TrinityObjectType.Gold) { actor.GoldAmount = attributes.Gold; } if (!_seenActorAnnIds.Contains(actor.PositionHash)) { _seenActorAnnIds.Add(actor.PositionHash); if (actor.InventorySlot == InventorySlot.None) { actor.OnDropped(); } } }
private static string GetFileHash(string filePath) { return(HashGenerator.GetFileHash(filePath, HashGenerator.HashType.SHA512)); }
/// <summary> /// Resolves the original skeleton path in the FFXIV file system and raw extracts it. /// </summary> /// <param name="fullMdlPath">Full path to the MDL.</param> /// <param name="internalSkelName">Internal skeleton name (for hair). This can be resolved if missing, though it is slightly expensive to do so.</param> private async Task <string> ExtractSkelb(string fullMdlPath, string internalSkelName = null) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var dataFile = IOUtil.GetDataFileFromPath(fullMdlPath); var fileName = Path.GetFileNameWithoutExtension(fullMdlPath); var skelFolder = ""; var skelFile = ""; var slotAbr = ""; if (IsNonhuman(fullMdlPath)) { // Weapons / Monsters / Demihumans are simple enough cases, we just have to use different formatting strings. if (IsWeapon(fullMdlPath)) { skelFolder = string.Format(XivStrings.WeapSkelFolder, fileName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.WeapSkelFile, fileName.Substring(1, 4), "0001"); } else if (IsMonster(fullMdlPath)) { skelFolder = string.Format(XivStrings.MonsterSkelFolder, fileName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.MonsterSkelFile, fileName.Substring(1, 4), "0001"); } else if (IsDemihuman(fullMdlPath)) { skelFolder = string.Format(XivStrings.DemiSkelFolder, fileName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.DemiSkelFile, fileName.Substring(1, 4), "0001"); } } else if (IsHair(fullMdlPath)) { // Hair we have to potentially scrape the MDL file to check for EX bones to scrape those EX bones for their skeleton name. // Pretty ugly, but you do what you gotta do. if (internalSkelName == null) { internalSkelName = await GetInternalSkelName(fullMdlPath); } // First arg is the constant string to format based on. Second arg is Race #. skelFolder = string.Format(XivStrings.EquipSkelFolder, fileName.Substring(1, 4), "hair", internalSkelName, ""); skelFile = string.Format(XivStrings.EquipSkelFile, fileName.Substring(1, 4), internalSkelName, ""); } else { // This is some jank in order to determine what id/slotAbr to use. var slotRegex = new Regex("_([a-z]{3})$"); var match = slotRegex.Match(fileName); var normalSlotAbr = match.Groups[1].Value; var category = Mdl.SlotAbbreviationDictionary.First(x => x.Value == normalSlotAbr).Key; slotAbr = SlotAbbreviationDictionary[category]; var id = fileName.Substring(6, 4); // Most subtypes just use body 0001 always, but not *all* of them. // This weird construct is to check for those exceptions. if (slotAbr.Equals("base")) { id = "0001"; } skelFolder = string.Format(XivStrings.EquipSkelFolder, fileName.Substring(1, 4), slotAbr, slotAbr[0], id); skelFile = string.Format(XivStrings.EquipSkelFile, fileName.Substring(1, 4), slotAbr[0], id); } // Continue only if the skeleton file exists if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), dataFile)) { // Sometimes for face skeletons id 0001 does not exist but 0002 does if (IsFace(fullMdlPath)) { skelFolder = string.Format(XivStrings.EquipSkelFolder, fileName.Substring(1, 4), slotAbr, slotAbr[0], "0002"); skelFile = string.Format(XivStrings.EquipSkelFile, fileName.Substring(1, 4), slotAbr[0], "0002"); if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), dataFile)) { return(null); } } else { return(null); } } var offset = await index.GetDataOffset(HashGenerator.GetHash(skelFolder), HashGenerator.GetHash(skelFile), dataFile); if (offset == 0) { throw new Exception($"Could not find offset for {skelFolder}/{skelFile}"); } var sklbData = await dat.GetType2Data(offset, dataFile); using (var br = new BinaryReader(new MemoryStream(sklbData))) { br.BaseStream.Seek(0, SeekOrigin.Begin); var magic = br.ReadInt32(); var format = br.ReadInt32(); br.ReadBytes(2); if (magic != 0x736B6C62) { throw new FormatException(); } var dataOffset = 0; switch (format) { case 0x31323030: dataOffset = br.ReadInt16(); break; case 0x31333030: case 0x31333031: br.ReadBytes(2); dataOffset = br.ReadInt16(); break; default: throw new Exception($"Unkown Data Format ({format})"); } br.BaseStream.Seek(dataOffset, SeekOrigin.Begin); var havokData = br.ReadBytes(sklbData.Length - dataOffset); var cwd = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); var outputPath = cwd + "/Skeletons/" + internalSkelName + ".sklb"; File.WriteAllBytes(outputPath, havokData); return(outputPath); } }
/// <summary> /// Gets the available races that contain model data for the given gear /// </summary> /// <remarks> /// This checks to see if the mdl file for each race exists in the mdl folder /// It creates a list of the races which do have an available mdl file /// </remarks> /// <param name="xivGear">A gear item</param> /// <returns>A list of XivRace data</returns> public async Task <List <XivRace> > GetRacesForModels(XivGear xivGear, XivDataFile dataFile) { var itemType = ItemType.GetItemType(xivGear); var modelID = xivGear.ModelInfo.ModelID.ToString().PadLeft(4, '0'); var raceList = new List <XivRace>(); if (itemType == XivItemType.weapon) { return(new List <XivRace> { XivRace.All_Races }); } string mdlFolder; var id = xivGear.ModelInfo.ModelID.ToString().PadLeft(4, '0'); switch (itemType) { case XivItemType.equipment: mdlFolder = $"chara/{itemType}/e{id}/model"; break; case XivItemType.accessory: mdlFolder = $"chara/{itemType}/a{id}/model"; break; default: mdlFolder = ""; break; } var testFilesDictionary = new Dictionary <int, string>(); // loop through each race ID to create a dictionary containing [Hashed file name, race ID] foreach (var ID in IDRaceDictionary.Keys) { string mdlFile; switch (itemType) { case XivItemType.equipment: mdlFile = $"c{ID}e{modelID}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}.mdl"; break; case XivItemType.accessory: mdlFile = $"c{ID}a{modelID}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}.mdl"; break; default: mdlFile = ""; break; } testFilesDictionary.Add(HashGenerator.GetHash(mdlFile), ID); } // get the list of hashed file names from the mtrl folder var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mdlFolder), dataFile); // Loop through each entry in the dictionary foreach (var testFile in testFilesDictionary) { // if the file in the dictionary entry is contained in the list of files from the folder // add that race to the race list if (files.Contains(testFile.Key)) { raceList.Add(IDRaceDictionary[testFile.Value]); } } return(raceList); }
partial void OnModelCreatingPartial(ModelBuilder modelBuilder) { modelBuilder.Entity <Role>().HasData(new Role() { RoleId = 1, RoleName = "Administrator" }); modelBuilder.Entity <Role>().HasData(new Role() { RoleId = 2, RoleName = "Visitor" }); modelBuilder.Entity <City>().HasData(new City() { CityId = 1, CityName = "Bugojno" }); modelBuilder.Entity <City>().HasData(new City() { CityId = 2, CityName = "Mostar" }); modelBuilder.Entity <City>().HasData(new City() { CityId = 3, CityName = "Sarajevo" }); modelBuilder.Entity <City>().HasData(new City() { CityId = 4, CityName = "Donji Vakuf" }); modelBuilder.Entity <City>().HasData(new City() { CityId = 5, CityName = "Tuzla" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 1, Description = "Popust na svu hranu" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 2, Description = "Popust na sva pića" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 3, Description = "Popust na predjela" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 4, Description = "Popust na glavna jela" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 5, Description = "Popust na mesne plate" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 6, Description = "Popust na salate" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 7, Description = "Popust na deserte" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 8, Description = "Popust na negazirane sokove" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 9, Description = "Popust na gazirane sokove" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 10, Description = "Popust na cijeđene sokove" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 11, Description = "Popust na vodu" }); modelBuilder.Entity <DiscountType>().HasData(new DiscountType() { DiscountTypeId = 12, Description = "Popust na pojedinačnu stavku" }); modelBuilder.Entity <Gender>().HasData(new Gender() { GenderId = 1, Gender1 = "Muško" }); modelBuilder.Entity <Gender>().HasData(new Gender() { GenderId = 2, Gender1 = "Žensko" }); modelBuilder.Entity <Gender>().HasData(new Gender() { GenderId = 3, Gender1 = "Ne želim reći" }); modelBuilder.Entity <ItemType>().HasData(new ItemType() { ItemTypeId = 1, Type = "Hrana" }); modelBuilder.Entity <ItemType>().HasData(new ItemType() { ItemTypeId = 2, Type = "Pića" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 1, ItemTypeId = 1, Category = "Predjela" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 2, ItemTypeId = 1, Category = "Glavna jela" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 3, ItemTypeId = 1, Category = "Deserti" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 5, ItemTypeId = 1, Category = "Salate" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 6, ItemTypeId = 1, Category = "Mesne plate" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 7, ItemTypeId = 2, Category = "Negazirani sokovi" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 8, ItemTypeId = 2, Category = "Gazirani sokovi" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 10, ItemTypeId = 2, Category = "Cijeđeni sokovi" }); modelBuilder.Entity <ItemCategory>().HasData(new ItemCategory() { ItemCategoryId = 11, ItemTypeId = 2, Category = "Voda" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 1, Description = "Đački (5 komada)", Mark = "ĆE" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 2, Description = "Mali (10 komada)", Mark = "ĆE" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 3, Description = "Srednji (15 komada)", Mark = "ĆE" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 4, Description = "Veliki (20 komada)", Mark = "ĆE" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 5, Description = "Mala", Mark = "PI" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 6, Description = "Srednja", Mark = "PI" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 7, Description = "Velika", Mark = "PI" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 8, Description = "Male", Mark = "PLj-SU" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 9, Description = "Velike", Mark = "PLj-SU" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 10, Description = "1 komad", Mark = "KOL" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 11, Description = "0,25L", Mark = "SOK" }); modelBuilder.Entity <Quantity>().HasData(new Quantity() { QuantityId = 12, Description = "0,5L", Mark = "VOD" }); modelBuilder.Entity <Restaurant>().HasData(new Restaurant() { RestaurantId = 1, RestaurantName = "Restoran FIT", CityId = 2, Address = "Sjeverni logor, broj 8", NumberOfTables = 15, OpenAt = new DateTime(2020, 08, 11, 08, 00, 00), CloseAt = new DateTime(2020, 08, 11, 22, 00, 00), Image = File.ReadAllBytes("img/restaurant.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 1, ItemName = "Ćevapi", Price = 5, ItemCategoryId = 2, QuantityId = 2, Image = File.ReadAllBytes("img/chevapi.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 2, ItemName = "Cijeđena narandža", Price = 3, ItemCategoryId = 10, QuantityId = 12, Image = File.ReadAllBytes("img/cnarana.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 3, ItemName = "Mesna plata (Classic)", Price = 17, ItemCategoryId = 6, QuantityId = 6, Image = File.ReadAllBytes("img/mplata.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 4, ItemName = "Pizza Margherita", Price = 4, ItemCategoryId = 2, QuantityId = 5, Image = File.ReadAllBytes("img/pizzam.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 5, ItemName = "Nutella torta", Price = 3, ItemCategoryId = 3, QuantityId = 10, Image = File.ReadAllBytes("img/nutellac.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 6, ItemName = "Cheesecake", Price = 3, ItemCategoryId = 3, QuantityId = 10, Image = File.ReadAllBytes("img/cheesecake.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 7, ItemName = "Paradajz juha", Price = 3, ItemCategoryId = 1, QuantityId = 6, Image = File.ReadAllBytes("img/pjuha.jpg") }); modelBuilder.Entity <RestaurantMenuItem>().HasData(new RestaurantMenuItem() { RestaurantMenuItemId = 8, ItemName = "Omlet", Price = 2, ItemCategoryId = 1, QuantityId = 10, Image = File.ReadAllBytes("img/omlet.jpg") }); //desktop User u1 = new User { UserId = 1, Name = "Desktop", Surname = "User", DateOfBirth = new DateTime(1999, 01, 13), CityId = 4, Address = "Prusac b.b.", PhoneNumber = "062357889", GenderId = 1, Username = "******" }; u1.PasswordSalt = HashGenerator.GenerateSalt(); u1.PasswordHash = HashGenerator.GenerateHash(u1.PasswordSalt, "test"); modelBuilder.Entity <User>().HasData(u1); //visitor User u2 = new User { UserId = 2, Name = "Mobile", Surname = "User", DateOfBirth = new DateTime(1999, 02, 21), CityId = 5, Address = "Mobilna br. 4", PhoneNumber = "062907219", GenderId = 1, Username = "******" }; u2.PasswordSalt = HashGenerator.GenerateSalt(); u2.PasswordHash = HashGenerator.GenerateHash(u2.PasswordSalt, "test"); modelBuilder.Entity <User>().HasData(u2); modelBuilder.Entity <UserRole>().HasData(new UserRole() { UserRoleId = 1, UserId = 1, RoleId = 1 }); modelBuilder.Entity <UserRole>().HasData(new UserRole() { UserRoleId = 2, UserId = 2, RoleId = 2 }); modelBuilder.Entity <Award>().HasData(new Award() { AwardId = 1, UserId = 2, Description = "Besplatan bilo koji proizvod iz kategorije glavnih jela", Active = true, AwardDate = new DateTime(2020, 05, 06, 09, 00, 00) }); modelBuilder.Entity <Discount>().HasData(new Discount() { DiscountId = 1, UserId = 2, DiscountTypeId = 1, ItemTypeId = 1, DiscountDate = new DateTime(2020, 05, 06, 09, 00, 00), Active = true, DiscountValue = Convert.ToDecimal(0.20) }); modelBuilder.Entity <MenuItemsReview>().HasData(new MenuItemsReview() { MenuItemsReviewId = 1, UserId = 2, RestaurantMenuItemId = 1, Description = "Jako ukusni ćevapi. Lepina bi samo mogla biti malo sočnija, sve u svemu super!", Grade = 4 }); modelBuilder.Entity <RestaurantReview>().HasData(new RestaurantReview() { RestaurantReviewId = 1, UserId = 2, Description = "Sve najbolje za restoran. Vrlo ljubazno osoblje i ugodan ambijent!", Grade = 5 }); modelBuilder.Entity <Visit>().HasData(new Visit() { VisitId = 1, UserId = 2, DateOfVisit = new DateTime(2020, 05, 06, 09, 00, 00) }); modelBuilder.Entity <Visit>().HasData(new Visit() { VisitId = 2, UserId = 2, DateOfVisit = new DateTime(2020, 06, 07, 19, 20, 00) }); modelBuilder.Entity <VisitorRecommendation>().HasData(new VisitorRecommendation() { VisitorRecommendationId = 1, UserId = 2, RecommendationDescription = "Preporuka za promjenu muzike, ova je dosta monotona" }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 1, Key1 = 123456789, Active = true }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 2, Key1 = 987654321, Active = true }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 3, Key1 = 123789456, Active = true }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 4, Key1 = 789123456, Active = true }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 5, Key1 = 258963147, Active = true }); modelBuilder.Entity <Key>().HasData(new Key() { KeyId = 6, Key1 = 147258369, Active = true }); }
/// <summary> /// Gets the full IMC information for a given item /// </summary> /// <param name="item"></param> /// <param name="modelInfo"></param> /// <returns>The ImcData data</returns> public ImcData GetFullImcInfo(IItemModel item, XivModelInfo modelInfo) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(item); var imcPath = GetImcPath(modelInfo, itemType); var imcOffset = index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile); if (imcOffset == 0) { throw new Exception($"Could not find offest for {imcPath.Folder}/{imcPath.File}"); } var imcByteData = dat.GetType2Data(imcOffset, _dataFile); using (var br = new BinaryReader(new MemoryStream(imcByteData))) { var imcData = new ImcData() { VariantCount = br.ReadInt16(), Unknown = br.ReadInt16(), GearVariantList = new List <VariantSet>() }; //weapons and monsters do not have variant sets if (itemType == XivItemType.weapon || itemType == XivItemType.monster) { imcData.OtherVariantList = new List <XivImc>(); imcData.DefaultVariant = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }; for (var i = 0; i < imcData.VariantCount; i++) { imcData.OtherVariantList.Add(new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }); } } else { imcData.GearVariantList = new List <VariantSet>(); imcData.DefaultVariantSet = new VariantSet { Slot1 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot2 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot3 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot4 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot5 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; for (var i = 0; i < imcData.VariantCount; i++) { // gets the data for each slot in the current variant set var imcGear = new VariantSet { Slot1 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot2 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot3 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot4 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot5 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; imcData.GearVariantList.Add(imcGear); } } return(imcData); } }
/// <summary> /// Gets the Races and Numbers available for textures in the given Character Item /// </summary> /// <remarks> /// This gives you the race and the numbers available for it /// <example> /// Body, [Hyur Midlander Male, int[] {1, 4, 91, 250} /// </example> /// This means there is 4 body textures for Hyur Midlander Male with those numbers /// </remarks> /// <param name="charaItem">The Character Item</param> /// <returns>A Dictionary containing the race and the numbers available for it</returns> public async Task <Dictionary <XivRace, int[]> > GetRacesAndNumbersForTextures(XivCharacter charaItem) { var availableRacesAndNumbers = new Dictionary <XivRace, int[]>(); var folder = ""; if (charaItem.SecondaryCategory == XivStrings.Hair) { folder = XivStrings.HairMtrlFolder; } else if (charaItem.SecondaryCategory == XivStrings.Face) { folder = XivStrings.FaceMtrlFolder; } else if (charaItem.SecondaryCategory == XivStrings.Body) { if (_language != XivLanguage.Korean) { folder = XivStrings.BodyMtrlFolder; } else { folder = XivStrings.BodyMtrlFolderOld; } } else if (charaItem.SecondaryCategory == XivStrings.Tail) { if (_language != XivLanguage.Korean) { folder = XivStrings.TailMtrlFolder; } else { folder = XivStrings.TailMtrlFolderOld; } } else if (charaItem.SecondaryCategory == XivStrings.Ears) { folder = XivStrings.EarsMtrlFolder; } foreach (var race in IDRaceDictionary) { var testDictionary = new Dictionary <int, int>(); for (var i = 1; i <= 300; i++) { var mtrl = string.Format(folder, race.Key, i.ToString().PadLeft(4, '0')); testDictionary.Add(HashGenerator.GetHash(mtrl), i); } var numList = await _index.GetFolderExistsList(testDictionary, XivDataFile._04_Chara); numList.Sort(); if (numList.Count > 0) { availableRacesAndNumbers.Add(race.Value, numList.ToArray()); } } return(availableRacesAndNumbers); }
/// <summary> /// download HTML as an asynchronous operation. /// </summary> /// <param name="siteUrl">The URL.</param> /// <param name="sitePageType">Type of the page.</param> /// <param name="siteSignature">The siteSignature.</param> /// <param name="proxy">The proxy.</param> /// <returns>Task<System.Boolean>.</returns> public (string html, bool isSuccessful) DownloadHtml(string siteUrl, PageType sitePageType, string siteSignature, WebProxy proxy) { var taskDone = false; string html = null; var isSuccessful = false; var isUsingProxy = false; string instanceHash; // Attach proxy if (proxy != null) { isUsingProxy = true; } // Generate SHA256 for thread name/ Web Instance using (var sha256Hash = SHA256.Create()) { instanceHash = HashGenerator.GetCryptographicHash(sha256Hash, siteUrl); } // Setup EO WebEngine var newWebEngine = Engine.Create(instanceHash); newWebEngine.Options.AllowProprietaryMediaFormats(); newWebEngine.Options.DisableGPU = true; var options = new BrowserOptions { AllowJavaScriptOpenWindow = false, LoadImages = false }; newWebEngine.Options.SetDefaultBrowserOptions(options); newWebEngine.Options.ExtraCommandLineArgs = "--mute-audio"; if (isUsingProxy) { newWebEngine.Options.Proxy = new ProxyInfo(ProxyType.HTTP, proxy.Address.Host, proxy.Address.Port); } // Instantiate thread runner var runner = new ThreadRunner(instanceHash, newWebEngine); var view = runner.CreateWebView(); // Handle certificate error view.CertificateError += (sender, e) => { e.Continue(); }; view.CustomUserAgent = RequesterDefaults.UserAgent; runner.Send(async() => { var task = view.LoadUrl(siteUrl); task.WaitOne(20000); switch (sitePageType) { case PageType.Static: break; case PageType.Javascript: await Task.Delay(RequesterDefaults.JavascriptPageWait); break; case PageType.Cloudflare: await Task.Delay(RequesterDefaults.CloudflarePageWait); break; default: throw new ArgumentOutOfRangeException(typeof(PageType).ToString()); } if (view.CanEvalScript) { html = task.WebView.GetHtml(); if (html.Contains(siteSignature)) { isSuccessful = true; } } taskDone = true; }); while (!taskDone) { Thread.Sleep(2000); } view.Destroy(); newWebEngine.Stop(true); runner.Dispose(); return(html, isSuccessful); }
public void Setup() { _hashGenerator = new HashGenerator(); }
public TrinityActor(ACD acd, ActorType type) : base(acd, type) { Attributes = new AttributesWrapper(CommonData); ObjectHash = HashGenerator.GenerateObjectHash(Position, ActorSnoId, InternalName); }
public override int GetHashCode() { return(HashGenerator.GenerateHashXZ(X, Z)); }
/// <summary> /// Parses the current chat log and saves it. This /// function is called from the backup threads /// </summary> /// <param name="gameClosed"></param> private static void ParseThenSaveToFile(bool gameClosed = false) { try { AppController.InitializeServerIp(); // Parse the chat log string parsed = AppController.ParseChatLog(directoryPath, Properties.Settings.Default.RemoveTimestampsFromBackup, gameClosed); if (string.IsNullOrWhiteSpace(parsed)) { return; } // Store the first line of the chat log: [DATE: 14/NOV/2018 | TIME: 15:44:39] string fileName = parsed.Substring(0, parsed.IndexOf("\n", StringComparison.Ordinal)); // Get the date from the fileName and replace slashes: 14.NOV.2018 string fileNameDate = Regex.Match(fileName, @"\d{1,2}\/[A-Za-z]{3}\/\d{4}").ToString(); fileNameDate = fileNameDate.Replace("/", "."); // Get the year and the month from the fileName string year = Regex.Match(fileNameDate, @"\d{4}").ToString(); string month = Regex.Match(fileNameDate, @"[A-Za-z]{3}").ToString(); // Get the time from the fileName and replace colons: 15.44.39 string fileNameTime = Regex.Match(fileName, @"\d{1,2}:\d{1,2}:\d{1,2}").ToString(); fileNameTime = fileNameTime.Replace(":", "."); // Throw error if the chat log format is incorrect if (string.IsNullOrWhiteSpace(fileName) || string.IsNullOrWhiteSpace(fileNameDate) || string.IsNullOrWhiteSpace(fileNameTime) || string.IsNullOrWhiteSpace(year) || string.IsNullOrWhiteSpace(month)) { throw new IOException(); } // Create the final file name: 14.NOV.2018-15.44.39 // and the file path categorized under the year and month fileName = fileNameDate + "-" + fileNameTime + ".txt"; string path = $"{backupPath}{year}\\{month}\\"; // Make sure directory exists if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } // There is no backup file with this name yet, // we are good to go if (!File.Exists(path + fileName)) { using (StreamWriter sw = new StreamWriter(path + fileName)) { sw.Write(parsed.Replace("\n", Environment.NewLine)); } } else { // If the file already exists (i.e. backed up from the interval worker) // check if the current chat log is larger than the old one // Remove any temporary files that may // exist for some reason if (File.Exists(path + ".temp")) { File.Delete(path + ".temp"); } // Write a temporary file using (StreamWriter sw = new StreamWriter(path + ".temp")) { sw.Write(parsed.Replace("\n", Environment.NewLine)); } // Check to see which file is bigger FileInfo oldFile = new FileInfo(path + fileName); FileInfo newFile = new FileInfo(path + ".temp"); // New file larger, overwrite the old file if (oldFile.Length < newFile.Length) { File.Delete(path + fileName); File.Move(path + ".temp", path + fileName); } else // Old file larger, delete the temporary file { File.Delete(path + ".temp"); } } if (!gameClosed) { return; } if (!Properties.Settings.Default.SuppressNotifications) { DisplayBackupResultMessage(string.Format(Strings.SuccessfulBackup, path + fileName), Strings.Information, MessageBoxButton.OK, MessageBoxImage.Information); } // Save the MD5 hash of the chat log if (Properties.Settings.Default.WarnOnSameHash) { HashGenerator.SaveParsedHash(parsed); } } catch { if (gameClosed) { DisplayBackupResultMessage(Strings.BackupError, Strings.Error, MessageBoxButton.OK, MessageBoxImage.Error); } } }
/// <summary> /// Gets the atex paths for a given item /// </summary> /// <param name="itemModel">The item to get the atex paths for</param> /// <returns>A list of TexTypePath containing the atex info</returns> public async Task <List <TexTypePath> > GetAtexPaths(IItemModel itemModel) { var atexTexTypePathList = new List <TexTypePath>(); var index = new Index(_gameDirectory); var avfx = new Avfx(_gameDirectory, _dataFile); var itemType = ItemType.GetItemType(itemModel); var vfxPath = await GetVfxPath(itemModel, itemType); var vfxOffset = await index.GetDataOffset(HashGenerator.GetHash(vfxPath.Folder), HashGenerator.GetHash(vfxPath.File), _dataFile); if (vfxOffset == 0) { throw new Exception($"Could not find offset for vfx path {vfxPath.Folder}/{vfxPath.File}"); } var aTexPaths = await avfx.GetATexPaths(vfxOffset); foreach (var atexPath in aTexPaths) { var ttp = new TexTypePath { DataFile = _dataFile, Name = Path.GetFileNameWithoutExtension(atexPath), Path = atexPath }; atexTexTypePathList.Add(ttp); } return(atexTexTypePathList); }
/// <summary> /// Gets additional assets when the original asset file contains asset file paths within it /// </summary> /// <param name="assets">The current asset object</param> private async Task GetAdditionalAssets(HousingAssets assets) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); foreach (var additionalAsset in assets.AdditionalAssetList.ToList()) { var assetFolder = Path.GetDirectoryName(additionalAsset).Replace("\\", "/"); var assetFile = Path.GetFileName(additionalAsset); var assetOffset = await index.GetDataOffset(HashGenerator.GetHash(assetFolder), HashGenerator.GetHash(assetFile), XivDataFile._01_Bgcommon); var assetData = await dat.GetType2Data(assetOffset, XivDataFile._01_Bgcommon); await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(assetData))) { br.BaseStream.Seek(20, SeekOrigin.Begin); var skip = br.ReadInt32() + 20; br.BaseStream.Seek(skip + 4, SeekOrigin.Begin); var stringsOffset = br.ReadInt32(); br.BaseStream.Seek(skip + stringsOffset, SeekOrigin.Begin); var pathCounts = 0; while (true) { // Because we don't know the length of the string, we read the data until we reach a 0 value // That 0 value is the space between strings byte a; var pathName = new List <byte>(); while ((a = br.ReadByte()) != 0) { if (a == 0xFF) { break; } pathName.Add(a); } if (a == 0xFF) { break; } // Read the string from the byte array and remove null terminators var path = Encoding.ASCII.GetString(pathName.ToArray()).Replace("\0", ""); if (path.Equals(string.Empty)) { continue; } // Add the attribute to the list if (pathCounts == 0) { assets.Shared = path; } else if (pathCounts == 1) { assets.BaseFileName = path; } else { if (path.Contains(".mdl")) { assets.MdlList.Add(path); } else if (path.Contains(".sgb")) { assets.AdditionalAssetList.Add(path); } else if (!path.Contains(".")) { assets.BaseFolder = path; } else { assets.OthersList.Add(path); } } pathCounts++; } } }); } }
/// <summary> /// Searches for monsters with the given model ID /// </summary> /// <param name="modelID">The ID of the monster model</param> /// <param name="type">The type of monster to look for</param> /// <returns>A list of Search Results</returns> public List <SearchResults> SearchMonstersByModelID(int modelID, XivItemType type) { var searchResultsList = new List <SearchResults>(); var index = new Index(_gameDirectory); var id = modelID.ToString().PadLeft(4, '0'); var bodyVariantDictionary = new Dictionary <int, List <int> >(); if (type == XivItemType.monster) { var folder = $"chara/monster/m{id}/obj/body/b"; for (var i = 0; i < 100; i++) { var folderHashDictionary = new Dictionary <int, int>(); var mtrlFolder = $"{folder}{i.ToString().PadLeft(4, '0')}/material/v"; for (var j = 1; j < 100; j++) { folderHashDictionary.Add(HashGenerator.GetHash($"{mtrlFolder}{j.ToString().PadLeft(4, '0')}"), j); } var variantList = index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara); if (variantList.Count > 0) { variantList.Sort(); bodyVariantDictionary.Add(i, variantList); } } } else if (type == XivItemType.demihuman) { var folder = $"chara/demihuman/d{id}/obj/equipment/e"; for (var i = 0; i < 100; i++) { var folderHashDictionary = new Dictionary <int, int>(); var mtrlFolder = $"{folder}{i.ToString().PadLeft(4, '0')}/material/v"; for (var j = 1; j < 100; j++) { folderHashDictionary.Add(HashGenerator.GetHash($"{mtrlFolder}{j.ToString().PadLeft(4, '0')}"), j); } var variantList = index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara); if (variantList.Count > 0) { variantList.Sort(); bodyVariantDictionary.Add(i, variantList); } } } foreach (var bodyVariant in bodyVariantDictionary) { foreach (var variant in bodyVariant.Value) { searchResultsList.Add(new SearchResults { Body = bodyVariant.Key.ToString(), Slot = XivStrings.Monster, Variant = variant }); } } searchResultsList.Sort(); return(searchResultsList); }
/// <summary> /// Gets the available races that contain texture data for the given gear /// </summary> /// <remarks> /// This checks to see if the mtrl file for each race exists in the mtrl folder /// It creates a list of the races which do have an available mtrl folder /// </remarks> /// <param name="xivGear">A gear item</param> /// <returns>A list of XivRace data</returns> public async Task <List <XivRace> > GetRacesForTextures(XivGear xivGear, XivDataFile dataFile) { // Get the material version for the item from the imc file var imc = new Imc(_gameDirectory, dataFile); var gearVersion = (await imc.GetImcInfo(xivGear)).Variant.ToString().PadLeft(4, '0'); var modelID = xivGear.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var raceList = new List <XivRace>(); var itemType = ItemType.GetPrimaryItemType(xivGear); string mtrlFolder; if (itemType == XivItemType.weapon) { return(new List <XivRace> { XivRace.All_Races }); } switch (itemType) { case XivItemType.equipment: mtrlFolder = $"chara/{itemType}/e{modelID}/material/v{gearVersion}"; break; case XivItemType.accessory: mtrlFolder = $"chara/{itemType}/a{modelID}/material/v{gearVersion}"; break; default: mtrlFolder = ""; break; } var testFilesDictionary = new Dictionary <int, string>(); // loop through each race ID to create a dictionary containing [Hashed file name, race ID] foreach (var ID in IDRaceDictionary.Keys) { string mtrlFile; switch (itemType) { case XivItemType.equipment: mtrlFile = $"mt_c{ID}e{modelID}_{xivGear.GetItemSlotAbbreviation()}_a.mtrl"; break; case XivItemType.accessory: mtrlFile = $"mt_c{ID}a{modelID}_{xivGear.GetItemSlotAbbreviation()}_a.mtrl"; break; default: mtrlFile = ""; break; } testFilesDictionary.Add(HashGenerator.GetHash(mtrlFile), ID); } // get the list of hashed file names from the mtrl folder var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile); // Loop through each entry in the dictionary foreach (var testFile in testFilesDictionary) { // if the file in the dictionary entry is contained in the list of files from the folder // add that race to the race list if (files.Contains(testFile.Key)) { raceList.Add(IDRaceDictionary[testFile.Value]); } } return(raceList); }
public Hash128 GenerateHash128() { return(HashGenerator.GenerateHash128(InputSize == InputSize.OneKB ? _bytes_1KB : _bytes_1MB)); }
public HashGeneratorFixture() { _fileReader = new Mock<IFileReader>(); _hashGenerator = new HashGenerator(_fileReader.Object); }
protected void PrepareDocumentUnitLog(FascicleDocumentUnit entity, FascicleLog fascicleLog) { if (entity.DocumentUnit.Environment == (int)DSWEnvironmentType.Protocol) { Protocol protocol = _unitOfWork.Repository <Protocol>().GetByUniqueId(entity.DocumentUnit.UniqueId).SingleOrDefault(); ProtocolLog protocolLog = new ProtocolLog() { Year = entity.DocumentUnit.Year, Number = entity.DocumentUnit.Number, LogDate = fascicleLog.RegistrationDate.DateTime, LogType = "FS", Program = "Private.WebAPI", LogDescription = fascicleLog.LogDescription, RegistrationUser = fascicleLog.RegistrationUser, SystemComputer = fascicleLog.SystemComputer, Entity = protocol, }; protocolLog.Hash = HashGenerator.GenerateHash(string.Concat(protocolLog.RegistrationUser, "|", protocolLog.Year, "|", protocolLog.Number, "|", protocolLog.LogType, "|", protocolLog.LogDescription, "|", protocolLog.UniqueId, "|", protocolLog.Entity.UniqueId, "|", protocolLog.LogDate.ToString("yyyyMMddHHmmss"))); _unitOfWork.Repository <ProtocolLog>().Insert(protocolLog); } if (entity.DocumentUnit.Environment == (int)DSWEnvironmentType.Resolution) { Resolution resolution = _unitOfWork.Repository <Resolution>().GetByUniqueId(entity.DocumentUnit.UniqueId).SingleOrDefault(); ResolutionLog resolutionLog = new ResolutionLog() { LogDate = fascicleLog.RegistrationDate.DateTime, LogType = "FS", Program = "Private.WebAPI", LogDescription = fascicleLog.LogDescription, RegistrationUser = fascicleLog.RegistrationUser, SystemComputer = fascicleLog.SystemComputer, Entity = resolution, }; resolutionLog.Hash = HashGenerator.GenerateHash(string.Concat(resolutionLog.RegistrationUser, "|", resolutionLog.LogType, "|", resolutionLog.LogDescription, "|", resolutionLog.UniqueId, "|", resolutionLog.Entity.UniqueId, "|", resolutionLog.LogDate.ToString("yyyyMMddHHmmss"))); _unitOfWork.Repository <ResolutionLog>().Insert(resolutionLog); } if (entity.DocumentUnit.Environment == (int)DSWEnvironmentType.DocumentSeries) { DocumentSeriesItem documentSeriesItem = _unitOfWork.Repository <DocumentSeriesItem>().GetByUniqueId(entity.DocumentUnit.UniqueId).SingleOrDefault(); DocumentSeriesItemLog documentSeriesItemLog = new DocumentSeriesItemLog() { LogDate = fascicleLog.RegistrationDate.DateTime, LogType = "FS", Program = "Private.WebAPI", LogDescription = fascicleLog.LogDescription, RegistrationUser = fascicleLog.RegistrationUser, SystemComputer = fascicleLog.SystemComputer, Entity = documentSeriesItem, }; documentSeriesItemLog.Hash = HashGenerator.GenerateHash(string.Concat(documentSeriesItemLog.RegistrationUser, "|", documentSeriesItemLog.LogType, "|", documentSeriesItemLog.LogDescription, "|", documentSeriesItemLog.UniqueId, "|", documentSeriesItemLog.Entity.UniqueId, "|", documentSeriesItemLog.LogDate.ToString("yyyyMMddHHmmss"))); _unitOfWork.Repository <DocumentSeriesItemLog>().Insert(documentSeriesItemLog); } if (entity.DocumentUnit.Environment >= 100) { UDSRepository uDSRepository = _unitOfWork.Repository <UDSRepository>().GetByIdDocumentUnit(entity.DocumentUnit.UniqueId); UDSLog log = new UDSLog() { LogType = UDSLogType.Delete, LogDescription = fascicleLog.LogDescription, SystemComputer = string.IsNullOrEmpty(fascicleLog.SystemComputer) ? Environment.MachineName : fascicleLog.SystemComputer, Entity = uDSRepository, RegistrationDate = fascicleLog.RegistrationDate.DateTime, RegistrationUser = fascicleLog.RegistrationUser, IdUDS = entity.DocumentUnit.UniqueId, Environment = entity.DocumentUnit.Environment, }; log.Hash = HashGenerator.GenerateHash(string.Concat(log.RegistrationUser, "|", log.LogType, "|", log.LogDescription, "|", log.UniqueId, "|", log.IdUDS, "|", log.RegistrationDate.ToString("yyyyMMddHHmmss"))); _unitOfWork.Repository <UDSLog>().Insert(log); } }