private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) { TreeNode node = e.Node; if (node != null && node.Parent != null && node.SelectedImageKey != UIConstants.ICON_FOLDER && node.SelectedImageKey != UIConstants.ICON_PACKED) { string absolutePath = node.Name; if (string.IsNullOrEmpty(absolutePath)) { return; } //Extract string fullExtractedFile = _ProjectManager.ExtractResource(absolutePath); uint crcFile = Crc32.Compute(File.ReadAllBytes(fullExtractedFile)); //Plugin ResourceSelected hooks bool pluginUsed = false; string relativePath = _ProjectManager.GetRelativePath(absolutePath); ResourceCollection resCol = GetFirstLevelNode(node).Tag as ResourceCollection; foreach (Sm4shBasePlugin plugin in _ProjectManager.Plugins) { if (plugin.InternalResourceSelected(resCol, relativePath, fullExtractedFile)) { pluginUsed = true; break; } } //If no plugin used, try hexeditor if (!pluginUsed) { if (string.IsNullOrEmpty(_ProjectManager.CurrentProject.ProjectHexEditorFile)) { LogHelper.Info(UIStrings.INFO_FILE_HEX); return; } Process process = Process.Start(_ProjectManager.CurrentProject.ProjectHexEditorFile, "\"" + fullExtractedFile + "\""); process.WaitForExit(); } //Check extract file, if changed, ask to add in workspace uint compareCrcFile = Crc32.Compute(File.ReadAllBytes(fullExtractedFile)); if (crcFile != compareCrcFile) { if (MessageBox.Show(string.Format(UIStrings.INFO_FILE_MODIFIED, absolutePath), UIStrings.CAPTION_FILE_MODIFIED, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes) { AddOrReplaceFiles(treeView.SelectedNode.Parent, new string[] { fullExtractedFile }); } } } }
public MyMusicFile(Sm4shProject projectManager, SoundEntryCollection sEntryCollection, string path) { string mymusicFile = projectManager.ExtractResource(path, PathHelper.FolderTemp); SoundEntryCollection = sEntryCollection; _Path = path; using (FileStream fileStream = File.Open(mymusicFile, FileMode.Open)) { using (BinaryReader b = new BinaryReader(fileStream)) { if (new string(b.ReadChars(3)) != "MMB") { throw new Exception(string.Format("Can't load '{0}', the file is either compressed or its not a MMB file.", mymusicFile)); } //Keep header b.BaseStream.Position = 0; _Header = b.ReadBytes(HEADER_LEN); //Number of elements b.BaseStream.Position = HEADER_LEN; int nbrStages = b.ReadInt32(); //Offsets per element int[] offsetsPerElement = new int[nbrStages]; for (int i = 0; i < nbrStages; i++) { offsetsPerElement[i] = b.ReadInt32(); } //Stage offset int stageStartOffset = HEADER_LEN + 0x4 + (nbrStages * 0x4) + 0x20; //0x20 = Magic Padding for (int i = 0; i < nbrStages; i++) { MyMusicStage myMusicStage = new MyMusicStage(i); int currentStageOffset = stageStartOffset + offsetsPerElement[i]; b.BaseStream.Position = currentStageOffset; uint nbrBGMs = b.ReadUInt32(); currentStageOffset += 0x4; for (int j = 0; j < nbrBGMs; j++) { b.BaseStream.Position = currentStageOffset + (j * 0x3c); myMusicStage.BGMs.Add(ParseBGMEntry(b)); } SoundEntryCollection.MyMusicStages.Add(myMusicStage); } } } }
public PropertyFile(Sm4shProject projectManager, SoundEntryCollection sEntryCollection, string path) { string propertyFile = projectManager.ExtractResource(path, PathHelper.FolderTemp); SoundEntryCollection = sEntryCollection; _Path = path; using (FileStream fileStream = File.Open(propertyFile, FileMode.Open)) { using (BinaryReader b = new BinaryReader(fileStream)) { if (new string(b.ReadChars(3)) != "MPB") { throw new Exception(string.Format("Can't load '{0}', the file is either compressed or its not a MPB file", propertyFile)); } //Keep header b.BaseStream.Position = 0; _Header = b.ReadBytes(HEADER_LEN); //Nbr BGM b.BaseStream.Position = HEADER_LEN; uint nbrBgm = b.ReadUInt32(); //Songtable uint songTableOffset = HEADER_LEN + 0x4 + (nbrBgm * 0x4); uint[] songIds = new uint[nbrBgm]; b.BaseStream.Position = HEADER_LEN + 0x4; for (int i = 0; i < nbrBgm; i++) { songIds[i] = b.ReadUInt32(); } //Parsing for (int i = 0; i < nbrBgm; i++) { if (songIds[i] != 0xffffffff) { b.BaseStream.Position = songTableOffset + songIds[i]; BGMEntry sEntry = ParseProperty(b, i); SoundEntryCollection.SoundEntriesBGMs.Add(sEntry); } } } } }
public UISoundDBFile(Sm4shProject projectManager, SoundEntryCollection sEntryCollection, string path) { string uiSoundDBFile = projectManager.ExtractResource(path, PathHelper.FolderTemp); SoundEntryCollection = sEntryCollection; _Path = path; _Project = projectManager; using (FileStream fileStream = File.Open(uiSoundDBFile, FileMode.Open)) { using (BinaryReader b = new BinaryReader(fileStream)) { byte[] header = b.ReadBytes(2); if (header[0] != 0xff || header[1] != 0xff) { throw new Exception(string.Format("Can't load '{0}', the file doesn't appear to be 'ui_sound_db.bin'.", uiSoundDBFile)); } //Keep header b.BaseStream.Position = 0; _Header = b.ReadBytes(HEADER_LEN); //Number of elements b.BaseStream.Position = HEADER_LEN; int nbrStages = ReadNbrEntries(b); //Offset to second table int offsetUnknownSecondTable = HEADER_LEN + 0x5 + (nbrStages * 0xd2); b.BaseStream.Position = offsetUnknownSecondTable; int nbrUnknownSecondTableBlocs = ReadNbrEntries(b); b.BaseStream.Position = offsetUnknownSecondTable; _SecondBloc = b.ReadBytes((int)(0x5 + (nbrUnknownSecondTableBlocs * 0xa))); //Offset to variable/songid table int offsetSongTable = offsetUnknownSecondTable + 0x5 + (nbrUnknownSecondTableBlocs * 0xa); b.BaseStream.Position = offsetSongTable; int nbrSoundEntries = ReadNbrEntries(b); //Retrieve all sounds for (int i = 0; i < nbrSoundEntries; i++) { int index = ReadInt32(b); SoundEntry sEntry = ParseSoundEntry(b, index); if (sEntry != null && (INCLUDE_EMPTY_SOUND || sEntry.BGMFiles.Count == 0 || sEntry.BGMFiles[0].BGMID != 0x450)) { SoundEntryCollection.SoundEntries.Add(sEntry); } } //Retrieve info per stage for (int i = 0; i < nbrStages; i++) { b.BaseStream.Position = HEADER_LEN + 0x5 + (i * 0xd2); int stageId = ReadInt32(b); int nbrSounds = ReadInt32(b); List <SoundDBStageSoundEntry> stageSoundEntries = new List <SoundDBStageSoundEntry>(); for (int j = 0; j < nbrSounds; j++) { int sEntryIndex = ReadInt32(b); stageSoundEntries.Add(new SoundDBStageSoundEntry(SoundEntryCollection, sEntryIndex)); } SoundDBStage soundDBStage = new SoundDBStage(SoundEntryCollection, stageId); soundDBStage.SoundEntries = stageSoundEntries; SoundEntryCollection.SoundDBStages.Add(soundDBStage); } } } }
public SoundMSBTFile(Sm4shProject projectManager, SoundEntryCollection sEntryCollection, string path) { _ResCol = projectManager.GetResourceCollection(path); string soundMSBTFile = projectManager.ExtractResource(path, PathHelper.FolderTemp); SoundEntryCollection = sEntryCollection; _VarsMSBT = new SortedDictionary <string, MSBTVariable>(); _Path = path; using (FileStream fileStream = File.Open(soundMSBTFile, FileMode.Open)) { using (BinaryReader b = new BinaryReader(fileStream)) { ParseFileHeader(b); if (_Header.Label != "MsgStdBn") { throw new Exception(string.Format("Can't load '{0}', the file doesn't appear to be a MSBT file.", soundMSBTFile)); } //Keep header b.BaseStream.Position = 0; uint offSetLBL1 = HEADER_LEN; //Getting offset to ATR1 b.BaseStream.Position = offSetLBL1; _SectionLBL1 = ParseSectionHeader(b); if (_SectionLBL1.Label != "LBL1") { throw new Exception(string.Format("Error while reading '{0}', can't find LBL1 section.", soundMSBTFile)); } uint offSetATR1 = offSetLBL1 + HEADER_LBL1 + _SectionLBL1.SectionSize; while (offSetATR1 % 0x10 != 0)// || offSetATR1 == offSetLBL1 + HEADER_LBL1 + _SectionLBL1.SectionSize) { offSetATR1++; } //Getting offset to TXT2 b.BaseStream.Position = offSetATR1; _SectionATR1 = ParseSectionHeader(b); if (_SectionATR1.Label != "ATR1") { throw new Exception(string.Format("Error while reading '{0}', can't find ATR1 section.", soundMSBTFile)); } b.BaseStream.Position = offSetATR1 + HEADER_ATR1; _ATR1Bloc = b.ReadBytes((int)_SectionATR1.SectionSize); uint offSetTXT2 = offSetATR1 + HEADER_ATR1 + _SectionATR1.SectionSize; while (offSetTXT2 % 0x10 != 0)// || offSetTXT2 == offSetATR1 + HEADER_ATR1 + _SectionATR1.SectionSize) { offSetTXT2++; } //Parsing TXT2 b.BaseStream.Position = offSetTXT2; _SectionTXT2 = ParseSectionHeader(b); if (_SectionTXT2.Label != "TXT2") { throw new Exception(string.Format("Error while reading '{0}', can't find TXT2 section.", soundMSBTFile)); } b.BaseStream.Position += 8; uint txt2NbrEntries = ReadUInt32BigEndian(b); uint[] offSetIntList = new uint[txt2NbrEntries]; for (int i = 0; i < txt2NbrEntries; i++) { offSetIntList[i] = ReadUInt32BigEndian(b); } b.BaseStream.Position = offSetTXT2 + HEADER_TXT2; byte[] txt2Bloc = b.ReadBytes((int)_SectionTXT2.SectionSize); string[] msbtvariables = GetMSBTStringVariables(txt2Bloc, txt2NbrEntries, offSetIntList); //Associate strings to variable names b.BaseStream.Position = offSetLBL1 + HEADER_LBL1; _SizeHashTable = ReadUInt32BigEndian(b); uint lbl1ChecksumSize = _SizeHashTable * 0x8; uint nbrEntries = 0; for (int i = 0; i < _SizeHashTable; i++) { nbrEntries += ReadUInt32BigEndian(b); b.BaseStream.Position += 4; } if (msbtvariables.Length != nbrEntries) { throw new Exception(string.Format("Error while reading '{0}', the number of LBL1 entries doesn't match the number of TXT2 entries.", soundMSBTFile)); } b.BaseStream.Position = offSetLBL1 + HEADER_LBL1 + 0x4 + lbl1ChecksumSize; for (int i = 0; i < nbrEntries; i++) { string variableName = b.ReadString(); uint variableIndex = ReadUInt32BigEndian(b); MSBTVariable newVariable = new MSBTVariable(variableName, msbtvariables[variableIndex]); _VarsMSBT.Add(variableName, newVariable); } } } //Assign SoundEntries variables if (!_ResCol.IsRegion) { foreach (SoundEntry sEntry in sEntryCollection.SoundEntries) { sEntry.Title = GetVariableValue(VAR_TITLE + sEntry.OriginalSoundLabel, Strings.DEFAULT_SENTRY_TITLE); sEntry.SoundTestTitle = GetVariableValue(VAR_TITLE2 + sEntry.OriginalSoundLabel, Strings.DEFAULT_SENTRY_TITLE2); sEntry.Description = GetVariableValue(VAR_DESCRIPTION + sEntry.OriginalSoundLabel, string.Empty); sEntry.Description2 = GetVariableValue(VAR_DESCRIPTION2 + sEntry.OriginalSoundLabel, string.Empty); sEntry.Source = GetVariableValue(VAR_SOURCE + sEntry.OriginalSoundLabel, string.Empty); } } }