mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-25 22:10:22 +00:00
Add working SDF (Mario and Rabbids) archive support.
This commit is contained in:
parent
3ab44e1f63
commit
8f849bf260
25 changed files with 737 additions and 176 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,10 +7,11 @@ using Switch_Toolbox;
|
|||
using System.Windows.Forms;
|
||||
using Switch_Toolbox.Library;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using Switch_Toolbox.Library.Forms;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class SDF : TreeNodeFile, IFileFormat
|
||||
public class SDF : IArchiveFile, IFileFormat
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Archive;
|
||||
|
||||
|
@ -21,6 +22,11 @@ namespace FirstPlugin
|
|||
public string FilePath { get; set; }
|
||||
public IFileInfo IFileInfo { get; set; }
|
||||
|
||||
public bool CanAddFiles { get; set; } = false;
|
||||
public bool CanRenameFiles { get; set; } = false;
|
||||
public bool CanReplaceFiles { get; set; } = false;
|
||||
public bool CanDeleteFiles { get; set; } = false;
|
||||
|
||||
public bool Identify(System.IO.Stream stream)
|
||||
{
|
||||
using (var reader = new Switch_Toolbox.Library.IO.FileReader(stream, true))
|
||||
|
@ -38,15 +44,19 @@ namespace FirstPlugin
|
|||
}
|
||||
}
|
||||
|
||||
public List<FileEntry> files = new List<FileEntry>();
|
||||
public IEnumerable<ArchiveFileInfo> Files => files;
|
||||
|
||||
SDFTOC_Header Header;
|
||||
SDFTOC_ID startId;
|
||||
int[] block1;
|
||||
SDFTOC_ID[] blockIds;
|
||||
SDFTOC_Block2[] block2Array;
|
||||
public SDFTOC_Block2[] block2Array;
|
||||
byte[] DecompressedBlock;
|
||||
SDFTOC_ID endId;
|
||||
|
||||
List<string> FilePaths = new List<string>();
|
||||
//Temp but just for now as this is expeirmental. Need to optmize tree loading
|
||||
private readonly int MAX_FILE_DISPLAY = 4000;
|
||||
|
||||
//Thanks to https://github.com/GoldFarmer/rouge_sdf/blob/master/main.cpp for docs/structs
|
||||
public void Load(System.IO.Stream stream)
|
||||
|
@ -97,30 +107,14 @@ namespace FirstPlugin
|
|||
//Read last id
|
||||
endId = new SDFTOC_ID(reader);
|
||||
|
||||
Text = FileName;
|
||||
MessageBox.Show("Note! Support for this format is experimental. The tool will only load < 4000 files atm due to slow loading");
|
||||
|
||||
LoadTree();
|
||||
for (int i = 0; i < FileEntries.Count; i++)
|
||||
if (i < MAX_FILE_DISPLAY)
|
||||
files.Add(FileEntries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadTree()
|
||||
{
|
||||
// Get a list of everything under the users' temp folder as an example
|
||||
string[] fileList;
|
||||
fileList = FilePaths.ToArray();
|
||||
|
||||
// Parse the file list into a TreeNode collection
|
||||
TreeNode node = GetNodes(new TreeNode(), fileList);
|
||||
Nodes.Add(node); // Add the new nodes
|
||||
|
||||
// Copy the new nodes to an array
|
||||
int nodeCount = node.Nodes.Count;
|
||||
TreeNode[] nodes = new TreeNode[nodeCount];
|
||||
node.Nodes.CopyTo(nodes, 0);
|
||||
|
||||
Nodes.AddRange(nodes); // Add the new nodes
|
||||
}
|
||||
|
||||
private TreeNode GetNodes(TreeNode parent, string[] fileList)
|
||||
{
|
||||
// build a TreeNode collection from the file list
|
||||
|
@ -151,53 +145,6 @@ namespace FirstPlugin
|
|||
return parent;
|
||||
}
|
||||
|
||||
void FillTreeNodes(TreeNode root, List<string> files)
|
||||
{
|
||||
var rootText = root.Text;
|
||||
var rootTextLength = rootText.Length;
|
||||
var nodeStrings = files;
|
||||
foreach (var node in nodeStrings)
|
||||
{
|
||||
string nodeString = node;
|
||||
nodeString = nodeString.Replace(@"\", "/");
|
||||
|
||||
var roots = nodeString.Split(new char[] { '/' },
|
||||
StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// The initial parent is the root node
|
||||
var parentNode = root;
|
||||
var sb = new StringBuilder(rootText, nodeString.Length + rootTextLength);
|
||||
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
|
||||
{
|
||||
// Build the node name
|
||||
var parentName = roots[rootIndex];
|
||||
sb.Append("/");
|
||||
sb.Append(parentName);
|
||||
var nodeName = sb.ToString();
|
||||
|
||||
// Search for the node
|
||||
var index = parentNode.Nodes.IndexOfKey(nodeName);
|
||||
if (index == -1)
|
||||
{
|
||||
// Node was not found, add it
|
||||
|
||||
var temp = new TreeNode(parentName, 0, 0);
|
||||
if (rootIndex == roots.Length - 1)
|
||||
temp = new TreeNode(parentName); //File entry
|
||||
|
||||
temp.Name = nodeName;
|
||||
parentNode.Nodes.Add(temp);
|
||||
parentNode = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Node was found, set that as parent and continue
|
||||
parentNode = parentNode.Nodes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DecompressNameBlock(uint magic, byte[] CompressedBlock, SDFTOC_Header header)
|
||||
{
|
||||
byte[] decomp = null;
|
||||
|
@ -226,11 +173,108 @@ namespace FirstPlugin
|
|||
return result;
|
||||
}
|
||||
|
||||
public bool AddFile(ArchiveFileInfo archiveFileInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DeleteFile(ArchiveFileInfo archiveFileInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public class FileEntry : ArchiveFileInfo
|
||||
{
|
||||
public SDF SDFParent;
|
||||
public string FilePath;
|
||||
public string FolderPath;
|
||||
public string FileBlockPath;
|
||||
public ulong PackageID;
|
||||
public ulong Offset;
|
||||
public ulong DecompressedSize;
|
||||
public List<ulong> CompressedSizes;
|
||||
public ulong DdsType;
|
||||
public bool UseDDS;
|
||||
public bool IsCompressed = false;
|
||||
|
||||
public override byte[] FileData
|
||||
{
|
||||
get => GetFileBytes();
|
||||
set => base.FileData = value;
|
||||
}
|
||||
|
||||
public override IFileFormat OpenFile()
|
||||
{
|
||||
var FileFormat = STFileLoader.OpenFileFormat(
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), FileData, true);
|
||||
|
||||
if (FileFormat is DDS)
|
||||
((DDS)FileFormat).SwitchSwizzle = true;
|
||||
|
||||
return FileFormat;
|
||||
}
|
||||
|
||||
public byte[] GetFileBytes()
|
||||
{
|
||||
List<byte[]> Data = new List<byte[]>();
|
||||
if (File.Exists(FileBlockPath))
|
||||
{
|
||||
var block = File.Open(FileBlockPath, FileMode.Open);
|
||||
using (var stream = new FileReader(block))
|
||||
{
|
||||
if (CompressedSizes.Count == 0)
|
||||
{
|
||||
//Decompressed File
|
||||
string FileNameBlock = Path.Combine(FolderPath, FilePath);
|
||||
string FolerPath = Path.GetDirectoryName(FileNameBlock);
|
||||
if (!Directory.Exists(FolerPath))
|
||||
Directory.CreateDirectory(FolerPath);
|
||||
|
||||
return stream.getSection((int)Offset, (int)DecompressedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
var PageSize = (double)0x10000;
|
||||
var DecompOffset = 0;
|
||||
var CompOffset = 0;
|
||||
IsCompressed = true;
|
||||
|
||||
if (UseDDS)
|
||||
{
|
||||
Data.Add(SDFParent.block2Array[DdsType].Data);
|
||||
}
|
||||
|
||||
for (var i = 0; i < CompressedSizes.Count; i++)
|
||||
{
|
||||
var decompSize = (int)Math.Min((int)DecompressedSize - DecompOffset, PageSize);
|
||||
if (CompressedSizes[i] == 0 || decompSize == (int)CompressedSizes[i])
|
||||
{
|
||||
stream.Seek((int)Offset + CompOffset, SeekOrigin.Begin);
|
||||
CompressedSizes[i] = (ulong)decompSize;
|
||||
Data.Add( stream.ReadBytes(decompSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Seek((int)Offset + CompOffset, SeekOrigin.Begin);
|
||||
Data.Add(STLibraryCompression.ZSTD.Decompress(stream.ReadBytes((int)CompressedSizes[i])));
|
||||
}
|
||||
DecompOffset += (int)decompSize;
|
||||
CompOffset += (int)CompressedSizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block.Dispose();
|
||||
}
|
||||
|
||||
return Utils.CombineByteArray(Data.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public List<FileEntry> FileEntries = new List<FileEntry>();
|
||||
|
||||
public void ParseNames(FileReader reader, string Name = "")
|
||||
{
|
||||
if (!Name.Contains("dummy") && FilePaths.Count < 200)
|
||||
FilePaths.Add(Name);
|
||||
|
||||
char ch = reader.ReadChar();
|
||||
|
||||
if (ch == 0)
|
||||
|
@ -253,7 +297,7 @@ namespace FirstPlugin
|
|||
int flag1 = (ch >> 3) & 1;
|
||||
// int flag1 = ch & 8;
|
||||
|
||||
if (count1 != 0)
|
||||
if (count1 > 0)
|
||||
{
|
||||
uint strangeId = reader.ReadUInt32();
|
||||
byte chr2 = reader.ReadByte();
|
||||
|
@ -264,10 +308,10 @@ namespace FirstPlugin
|
|||
for (int chunkIndex = 0; chunkIndex < count1; chunkIndex++)
|
||||
{
|
||||
byte ch3 = reader.ReadByte();
|
||||
if (ch3 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// if (ch3 == 0)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
|
||||
int compressedSizeByteCount = (ch3 & 3) + 1;
|
||||
int packageOffsetByteCount = (ch3 >> 2) & 7;
|
||||
|
@ -295,7 +339,7 @@ namespace FirstPlugin
|
|||
|
||||
if (packageId >= Header.Block1Count)
|
||||
{
|
||||
throw new InvalidDataException("SDF Package ID outside of TOC range");
|
||||
// throw new InvalidDataException($"SDF Package ID ({packageId}) outside of TOC range ({ Header.Block1Count})");
|
||||
}
|
||||
|
||||
|
||||
|
@ -317,8 +361,8 @@ namespace FirstPlugin
|
|||
|
||||
if (Header.Version <= 0x16)
|
||||
{
|
||||
fileId = (long)readVariadicInteger(4, reader);
|
||||
}
|
||||
// fileId = (long)readVariadicInteger(4, reader);
|
||||
}
|
||||
|
||||
if (compSizeArray.Count == 0 && hasCompression)
|
||||
compSizeArray.Add(compressedSize);
|
||||
|
@ -333,7 +377,7 @@ namespace FirstPlugin
|
|||
{
|
||||
reader.ReadByte();
|
||||
reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -345,32 +389,43 @@ namespace FirstPlugin
|
|||
}
|
||||
}
|
||||
|
||||
public static ulong NextMultiple(ulong value, ulong multiple) => NextMultiple((long)value, multiple);
|
||||
public static ulong NextMultiple(long value, ulong multiple)
|
||||
{
|
||||
return (ulong)Math.Ceiling(value / (double)multiple) * multiple;
|
||||
}
|
||||
|
||||
public void DumpFile(string Name, ulong packageId, ulong packageOffset, ulong decompresedSize,
|
||||
List<ulong> compressedSize, ulong ddsType, bool Append, bool UseDDS)
|
||||
{
|
||||
string PathFolder = Path.GetDirectoryName(FileName);
|
||||
string PathFolder = Path.GetDirectoryName(FilePath);
|
||||
|
||||
string layer;
|
||||
Console.WriteLine(Name + " " + packageId + " " + packageOffset + " " + decompresedSize + " " + ddsType + " " + UseDDS);
|
||||
if (packageId < 1000)
|
||||
if (packageId < 1000) layer = "A";
|
||||
else if (packageId < 2000) layer = "B";
|
||||
else if (packageId < 3000) layer = "C";
|
||||
else layer = "D";
|
||||
|
||||
string ID = packageId.ToString("D" + 4);
|
||||
|
||||
string BlockFilePath = Path.Combine(PathFolder, $"sdf-{layer}-{ID}.sdfdata");
|
||||
if (Append)
|
||||
{
|
||||
layer = "A";
|
||||
}
|
||||
else if (packageId < 2000)
|
||||
{
|
||||
layer = "B";
|
||||
}
|
||||
else
|
||||
{
|
||||
layer = "C";
|
||||
|
||||
}
|
||||
|
||||
bool IsFile = !Name.Contains("dummy") && decompresedSize > 5;
|
||||
if (IsFile)
|
||||
{
|
||||
FileEntries.Add(new FileEntry()
|
||||
{
|
||||
SDFParent = this,
|
||||
FileName = Name,
|
||||
FileBlockPath = BlockFilePath,
|
||||
FilePath = Name,
|
||||
FolderPath = PathFolder,
|
||||
CompressedSizes = compressedSize,
|
||||
DdsType = ddsType,
|
||||
UseDDS = UseDDS,
|
||||
DecompressedSize = decompresedSize,
|
||||
PackageID = packageId,
|
||||
Offset = packageOffset,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
|
|
|
@ -413,15 +413,16 @@ namespace FirstPlugin
|
|||
|
||||
if (SelectedSection is ExternalFileData)
|
||||
{
|
||||
HexEditor editor = (HexEditor)bfresEditor.GetActiveEditor(typeof(HexEditor));
|
||||
ArchiveFilePanel editor = (ArchiveFilePanel)LibraryGUI.Instance.GetActiveContent(typeof(ArchiveFilePanel));
|
||||
if (editor == null)
|
||||
{
|
||||
editor = new HexEditor();
|
||||
editor = new ArchiveFilePanel();
|
||||
editor.Dock = DockStyle.Fill;
|
||||
bfresEditor.LoadEditor(editor);
|
||||
LibraryGUI.Instance.LoadEditor(editor);
|
||||
}
|
||||
editor.Text = Text;
|
||||
editor.LoadData(((ExternalFileData)SelectedSection).Data);
|
||||
|
||||
editor.LoadFile(((ExternalFileData)SelectedSection).ArchiveFileInfo);
|
||||
editor.UpdateEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -781,6 +782,8 @@ namespace FirstPlugin
|
|||
((BNTX)node).Unload();
|
||||
}
|
||||
Nodes.Clear();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
|
|
|
@ -9,23 +9,106 @@ namespace Bfres.Structs
|
|||
{
|
||||
public class ExternalFileData : STGenericWrapper
|
||||
{
|
||||
public ArchiveFileInfo ArchiveFileInfo;
|
||||
|
||||
public override string ExportFilter => "All files (*.*)|*.*";
|
||||
|
||||
//Format to attach
|
||||
public IFileFormat FileFormat;
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return ArchiveFileInfo.FileData;
|
||||
}
|
||||
set
|
||||
{
|
||||
ArchiveFileInfo.FileData = value;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Data;
|
||||
public ExternalFileData(string name, byte[] data)
|
||||
{
|
||||
ImageKey = "folder";
|
||||
|
||||
Text = name;
|
||||
Data = data;
|
||||
|
||||
CanDelete = true;
|
||||
CanRename = true;
|
||||
CanReplace = true;
|
||||
CanExport = true;
|
||||
|
||||
ArchiveFileInfo = new ArchiveFileInfo();
|
||||
ArchiveFileInfo.FileData = data;
|
||||
}
|
||||
|
||||
//Todo move all of this data into one single class
|
||||
//Using ArchiveFileWrapper would be used wrong due to requring an IArchiveFile
|
||||
public override void OnDoubleMouseClick(TreeView treeview)
|
||||
{
|
||||
IFileFormat file = ArchiveFileInfo.OpenFile();
|
||||
if (file == null) //Format not supported so return
|
||||
return;
|
||||
|
||||
ArchiveFileInfo.FileFormat = file;
|
||||
|
||||
if (Utils.HasInterface(file.GetType(), typeof(IEditor<>)))
|
||||
{
|
||||
OpenFormDialog(file);
|
||||
}
|
||||
else if (file != null && file is TreeNodeFile)
|
||||
ReplaceNode(this, (TreeNodeFile)file);
|
||||
}
|
||||
|
||||
public static void ReplaceNode(TreeNode replaceNode, TreeNodeFile NewNode)
|
||||
{
|
||||
if (NewNode == null)
|
||||
return;
|
||||
|
||||
// node.Nodes.RemoveAt(index);
|
||||
// node.Nodes.Insert(index, NewNode);
|
||||
|
||||
|
||||
NewNode.ImageKey = replaceNode.ImageKey;
|
||||
NewNode.SelectedImageKey = replaceNode.SelectedImageKey;
|
||||
NewNode.Text = replaceNode.Text;
|
||||
}
|
||||
|
||||
private void OpenFormDialog(IFileFormat fileFormat)
|
||||
{
|
||||
UserControl form = GetEditorForm(fileFormat);
|
||||
form.Text = (((IFileFormat)fileFormat).FileName);
|
||||
|
||||
var parentForm = LibraryGUI.Instance.GetActiveForm();
|
||||
|
||||
GenericEditorForm editorForm = new GenericEditorForm(true, form);
|
||||
editorForm.FormClosing += (sender, e) => FormClosing(sender, e, fileFormat);
|
||||
if (editorForm.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (fileFormat.CanSave)
|
||||
{
|
||||
ArchiveFileInfo.FileData = fileFormat.Save();
|
||||
UpdateEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FormClosing(object sender, EventArgs args, IFileFormat fileFormat)
|
||||
{
|
||||
if (((Form)sender).DialogResult != DialogResult.OK)
|
||||
return;
|
||||
}
|
||||
|
||||
public UserControl GetEditorForm(IFileFormat fileFormat)
|
||||
{
|
||||
Type objectType = fileFormat.GetType();
|
||||
foreach (var inter in objectType.GetInterfaces())
|
||||
{
|
||||
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
|
||||
{
|
||||
System.Reflection.MethodInfo method = objectType.GetMethod("OpenForm");
|
||||
return (UserControl)method.Invoke(fileFormat, new object[0]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeview) {
|
||||
|
|
|
@ -193,6 +193,8 @@ namespace FirstPlugin
|
|||
|
||||
if (PluginRuntime.bntxContainers.Contains(this))
|
||||
PluginRuntime.bntxContainers.Remove(this);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public static byte[] CreateNewBNTX(string Name)
|
||||
|
@ -225,6 +227,20 @@ namespace FirstPlugin
|
|||
Textures.Remove(textureData.Text);
|
||||
LibraryGUI.Instance.UpdateViewport();
|
||||
}
|
||||
|
||||
public override UserControl GetEditor()
|
||||
{
|
||||
STPropertyGrid editor = new STPropertyGrid();
|
||||
editor.Text = Text;
|
||||
editor.Dock = DockStyle.Fill;
|
||||
return editor;
|
||||
}
|
||||
|
||||
public override void FillEditor(UserControl control)
|
||||
{
|
||||
((STPropertyGrid)control).LoadProperty(BinaryTexFile, OnPropertyChanged);
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeView)
|
||||
{
|
||||
if (Parent != null && Parent is BFRES)
|
||||
|
|
|
@ -69,17 +69,17 @@ namespace FirstPlugin
|
|||
|
||||
public List<GTXDataBlock> blocks = new List<GTXDataBlock>();
|
||||
|
||||
public override void OnClick(TreeView treeview)
|
||||
public override UserControl GetEditor()
|
||||
{
|
||||
STPropertyGrid editor = (STPropertyGrid)LibraryGUI.Instance.GetActiveContent(typeof(STPropertyGrid));
|
||||
if (editor == null)
|
||||
{
|
||||
editor = new STPropertyGrid();
|
||||
LibraryGUI.Instance.LoadEditor(editor);
|
||||
}
|
||||
STPropertyGrid editor = new STPropertyGrid();
|
||||
editor.Text = Text;
|
||||
editor.Dock = DockStyle.Fill;
|
||||
editor.LoadProperty(header, null);
|
||||
return editor;
|
||||
}
|
||||
|
||||
public override void FillEditor(UserControl control)
|
||||
{
|
||||
((STPropertyGrid)control).LoadProperty(header);
|
||||
}
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
|
|
|
@ -318,12 +318,12 @@ namespace FirstPlugin
|
|||
|
||||
Formats.Add(typeof(Turbo.Course_MapCamera_bin));
|
||||
Formats.Add(typeof(Turbo.PartsBIN));
|
||||
Formats.Add(typeof(SDF));
|
||||
|
||||
//Unfinished wip formats not ready for use
|
||||
if (Runtime.DEVELOPER_DEBUG_MODE)
|
||||
{
|
||||
Formats.Add(typeof(GFBMDL));
|
||||
Formats.Add(typeof(SDF));
|
||||
Formats.Add(typeof(NCA));
|
||||
Formats.Add(typeof(XCI));
|
||||
Formats.Add(typeof(BFLAN));
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -766,10 +766,10 @@ namespace Switch_Toolbox.Library
|
|||
ArrayCount = DX10header.arrayFlag;
|
||||
}
|
||||
|
||||
public bool Swizzle = false;
|
||||
public bool SwitchSwizzle = false;
|
||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
if (Swizzle)
|
||||
if (SwitchSwizzle)
|
||||
return TegraX1Swizzle.GetImageData(this, bdata, ArrayLevel, MipLevel);
|
||||
|
||||
return GetArrayFaces(this, ArrayCount)[ArrayLevel].mipmaps[MipLevel];
|
||||
|
|
56
Switch_Toolbox_Library/FileFormats/ZIP.cs
Normal file
56
Switch_Toolbox_Library/FileFormats/ZIP.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace Switch_Toolbox.Library
|
||||
{
|
||||
public class ZIP : TreeNodeFile, IFileFormat
|
||||
{
|
||||
const int MagicFileConstant = 0x504B0304;
|
||||
|
||||
public FileType FileType { get; set; } = FileType.Archive;
|
||||
|
||||
public bool CanSave { get; set; }
|
||||
public string[] Description { get; set; } = new string[] { "ZIP" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.zip" };
|
||||
public string FileName { get; set; }
|
||||
public string FilePath { get; set; }
|
||||
public IFileInfo IFileInfo { get; set; }
|
||||
|
||||
public bool Identify(System.IO.Stream stream)
|
||||
{
|
||||
using (var reader = new Switch_Toolbox.Library.IO.FileReader(stream, true))
|
||||
{
|
||||
reader.SetByteOrder(true);
|
||||
return reader.ReadInt32() == MagicFileConstant;
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,7 +52,6 @@ namespace Switch_Toolbox.Library.Forms
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateEditor()
|
||||
{
|
||||
if (GetEditor() == 0)
|
||||
|
@ -65,18 +64,25 @@ namespace Switch_Toolbox.Library.Forms
|
|||
|
||||
private void UpdateFileEditor()
|
||||
{
|
||||
if (!ArchiveFileInfo.IsSupportedFileFormat())
|
||||
{
|
||||
AddControl(new STUserControl());
|
||||
return;
|
||||
}
|
||||
|
||||
var File = ArchiveFileInfo.FileFormat;
|
||||
if (File == null)
|
||||
if (File == null) //If the file is not open yet, try temporarily for a preview
|
||||
File = ArchiveFileInfo.OpenFile();
|
||||
|
||||
UserControl control = GetEditorForm(File);
|
||||
if (control != null)
|
||||
{
|
||||
AddControl(control);
|
||||
|
||||
// if (CheckActiveType(control.GetType()))
|
||||
// AddControl(control);
|
||||
}
|
||||
|
||||
//If the format isn't active we can just dispose it
|
||||
if (ArchiveFileInfo.FileFormat == null)
|
||||
File.Unload();
|
||||
}
|
||||
|
||||
private bool CheckActiveType(Type type)
|
||||
|
@ -89,13 +95,30 @@ namespace Switch_Toolbox.Library.Forms
|
|||
if (fileFormat == null)
|
||||
return new STUserControl() { Dock = DockStyle.Fill };
|
||||
|
||||
if (fileFormat is TreeNodeFile)
|
||||
{
|
||||
var Editor = ((TreeNodeFile)fileFormat).GetEditor();
|
||||
var ActiveEditor = GetActiveEditor(Editor.GetType());
|
||||
if (ActiveEditor != null)
|
||||
Editor = ActiveEditor;
|
||||
|
||||
((TreeNodeFile)fileFormat).FillEditor(Editor);
|
||||
|
||||
return Editor;
|
||||
}
|
||||
|
||||
Type objectType = fileFormat.GetType();
|
||||
foreach (var inter in objectType.GetInterfaces())
|
||||
{
|
||||
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
|
||||
{
|
||||
System.Reflection.MethodInfo method = objectType.GetMethod("OpenForm");
|
||||
return (UserControl)method.Invoke(fileFormat, new object[0]);
|
||||
var Editor = (UserControl)method.Invoke(fileFormat, new object[0]);
|
||||
var ActiveEditor = GetActiveEditor(Editor.GetType());
|
||||
if (ActiveEditor != null)
|
||||
Editor = ActiveEditor;
|
||||
|
||||
return Editor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace Switch_Toolbox.Library
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TreeNodeFile : TreeNodeCustom
|
||||
{
|
||||
public bool CanDelete
|
||||
|
@ -38,6 +39,23 @@ namespace Switch_Toolbox.Library
|
|||
}
|
||||
}
|
||||
|
||||
public virtual UserControl GetEditor() { return new STUserControl(); }
|
||||
public virtual void FillEditor(UserControl control) { }
|
||||
|
||||
public override void OnClick(TreeView treeview)
|
||||
{
|
||||
var Editor = GetEditor();
|
||||
Editor.Dock = DockStyle.Fill;
|
||||
|
||||
var ActiveEditor = LibraryGUI.Instance.GetActiveContent(Editor.GetType());
|
||||
if (ActiveEditor != null)
|
||||
Editor = ActiveEditor;
|
||||
else
|
||||
LibraryGUI.Instance.LoadEditor(Editor);
|
||||
|
||||
FillEditor(Editor);
|
||||
}
|
||||
|
||||
public TreeNodeFile()
|
||||
{
|
||||
|
||||
|
|
|
@ -77,13 +77,13 @@
|
|||
this.findToolStripMenuItem.Text = "Find";
|
||||
this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click);
|
||||
//
|
||||
// HexEditor
|
||||
// HexEditor2
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.hexBox1);
|
||||
this.Controls.Add(this.stContextMenuStrip1);
|
||||
this.Name = "HexEditor";
|
||||
this.Name = "HexEditor2";
|
||||
this.Size = new System.Drawing.Size(529, 454);
|
||||
this.stContextMenuStrip1.ResumeLayout(false);
|
||||
this.stContextMenuStrip1.PerformLayout();
|
||||
|
|
|
@ -11,10 +11,38 @@ using Be.Windows.Forms;
|
|||
|
||||
namespace Switch_Toolbox.Library.Forms
|
||||
{
|
||||
public partial class HexEditor : UserControl
|
||||
public partial class HexEditor : STUserControl
|
||||
{
|
||||
FindOptions _findOptions = new FindOptions();
|
||||
|
||||
public HexEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
hexBox1.BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||
hexBox1.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
hexBox1.SelectionBackColor = FormThemes.BaseTheme.FormContextMenuSelectColor;
|
||||
hexBox1.SelectionForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
}
|
||||
|
||||
public override void OnControlClosing()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
if (hexBox1.ByteProvider != null)
|
||||
{
|
||||
hexBox1.ByteProvider.DeleteBytes(0, hexBox1.ByteProvider.Length);
|
||||
|
||||
IDisposable byteProvider = hexBox1.ByteProvider as IDisposable;
|
||||
if (byteProvider != null)
|
||||
byteProvider.Dispose();
|
||||
hexBox1.ByteProvider = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableMenuBar
|
||||
{
|
||||
set
|
||||
|
@ -30,18 +58,12 @@ namespace Switch_Toolbox.Library.Forms
|
|||
}
|
||||
}
|
||||
|
||||
public HexEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
hexBox1.BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||
hexBox1.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
hexBox1.SelectionBackColor = FormThemes.BaseTheme.FormContextMenuSelectColor;
|
||||
hexBox1.SelectionForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
}
|
||||
public void LoadData(byte[] data)
|
||||
{
|
||||
hexBox1.ByteProvider = new DynamicByteProvider(data);
|
||||
Cleanup();
|
||||
|
||||
IByteProvider provider = new DynamicByteProvider(data);
|
||||
hexBox1.ByteProvider = provider;
|
||||
}
|
||||
|
||||
private void findToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
|
|
56
Switch_Toolbox_Library/Forms/Editors/HexEditor/HexEditorNew.Designer.cs
generated
Normal file
56
Switch_Toolbox_Library/Forms/Editors/HexEditor/HexEditorNew.Designer.cs
generated
Normal file
|
@ -0,0 +1,56 @@
|
|||
namespace Switch_Toolbox.Library.Forms.Old
|
||||
{
|
||||
partial class HexEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.stPanel1 = new Switch_Toolbox.Library.Forms.STPanel();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// stPanel1
|
||||
//
|
||||
this.stPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.stPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.stPanel1.Name = "stPanel1";
|
||||
this.stPanel1.Size = new System.Drawing.Size(529, 454);
|
||||
this.stPanel1.TabIndex = 2;
|
||||
//
|
||||
// HexEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.stPanel1);
|
||||
this.Name = "HexEditor";
|
||||
this.Size = new System.Drawing.Size(529, 454);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private STPanel stPanel1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Windows.Forms;
|
||||
using Be.Windows.Forms;
|
||||
|
||||
namespace Switch_Toolbox.Library.Forms.Old
|
||||
{
|
||||
public partial class HexEditor : STUserControl
|
||||
{
|
||||
FindOptions _findOptions = new FindOptions();
|
||||
ByteViewer ByteViewer;
|
||||
|
||||
public HexEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ByteViewer = new ByteViewer();
|
||||
ByteViewer.BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||
ByteViewer.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
|
||||
ByteViewer.Dock = DockStyle.Fill;
|
||||
stPanel1.Controls.Add(ByteViewer);
|
||||
}
|
||||
|
||||
public override void OnControlClosing()
|
||||
{
|
||||
Cleanup();
|
||||
ByteViewer.Dispose();
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void LoadData(byte[] data)
|
||||
{
|
||||
Cleanup();
|
||||
ByteViewer.SetBytes(data);
|
||||
}
|
||||
|
||||
private void findToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
120
Switch_Toolbox_Library/Forms/Editors/HexEditor/HexEditorNew.resx
Normal file
120
Switch_Toolbox_Library/Forms/Editors/HexEditor/HexEditorNew.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -114,52 +114,63 @@ namespace Switch_Toolbox.Library.Forms
|
|||
{
|
||||
var rootText = root.Text;
|
||||
var rootTextLength = rootText.Length;
|
||||
var nodeStrings = archiveFile.Files;
|
||||
foreach (var node in nodeStrings)
|
||||
var nodeFiles = archiveFile.Files;
|
||||
if (nodeFiles.Count() > 400)
|
||||
{
|
||||
string nodeString = node.FileName;
|
||||
|
||||
var roots = nodeString.Split(new char[] { '/' },
|
||||
StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// The initial parent is the root node
|
||||
var parentNode = root;
|
||||
var sb = new StringBuilder(rootText, nodeString.Length + rootTextLength);
|
||||
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
|
||||
foreach (var node in nodeFiles)
|
||||
{
|
||||
// Build the node name
|
||||
var parentName = roots[rootIndex];
|
||||
sb.Append("/");
|
||||
sb.Append(parentName);
|
||||
var nodeName = sb.ToString();
|
||||
ArchiveFileWrapper wrapperFile = new ArchiveFileWrapper(node.FileName, node, archiveFile);
|
||||
root.Nodes.Add(wrapperFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var node in nodeFiles)
|
||||
{
|
||||
string nodeString = node.FileName;
|
||||
|
||||
// Search for the node
|
||||
var index = parentNode.Nodes.IndexOfKey(nodeName);
|
||||
if (index == -1)
|
||||
var roots = nodeString.Split(new char[] { '/' },
|
||||
StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// The initial parent is the root node
|
||||
var parentNode = root;
|
||||
var sb = new StringBuilder(rootText, nodeString.Length + rootTextLength);
|
||||
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
|
||||
{
|
||||
// Node was not found, add it
|
||||
// Build the node name
|
||||
var parentName = roots[rootIndex];
|
||||
sb.Append("/");
|
||||
sb.Append(parentName);
|
||||
var nodeName = sb.ToString();
|
||||
|
||||
var folder = new ArchiveFolderNodeWrapper(parentName, archiveFile);
|
||||
|
||||
if (rootIndex == roots.Length - 1)
|
||||
// Search for the node
|
||||
var index = parentNode.Nodes.IndexOfKey(nodeName);
|
||||
if (index == -1)
|
||||
{
|
||||
ArchiveFileWrapper wrapperFile = new ArchiveFileWrapper(parentName, node, archiveFile);
|
||||
wrapperFile.Name = nodeName;
|
||||
parentNode.Nodes.Add(wrapperFile);
|
||||
parentNode = wrapperFile;
|
||||
// Node was not found, add it
|
||||
|
||||
var folder = new ArchiveFolderNodeWrapper(parentName, archiveFile);
|
||||
|
||||
if (rootIndex == roots.Length - 1)
|
||||
{
|
||||
ArchiveFileWrapper wrapperFile = new ArchiveFileWrapper(parentName, node, archiveFile);
|
||||
wrapperFile.Name = nodeName;
|
||||
parentNode.Nodes.Add(wrapperFile);
|
||||
parentNode = wrapperFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder.Name = nodeName;
|
||||
parentNode.Nodes.Add(folder);
|
||||
parentNode = folder;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
folder.Name = nodeName;
|
||||
parentNode.Nodes.Add(folder);
|
||||
parentNode = folder;
|
||||
// Node was found, set that as parent and continue
|
||||
parentNode = parentNode.Nodes[index];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Node was found, set that as parent and continue
|
||||
parentNode = parentNode.Nodes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,32 @@ namespace Switch_Toolbox.Library
|
|||
|
||||
public FileType FileDataType = FileType.Default;
|
||||
|
||||
public IFileFormat OpenFile()
|
||||
public virtual IFileFormat OpenFile()
|
||||
{
|
||||
return STFileLoader.OpenFileFormat(
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), FileData, true);
|
||||
}
|
||||
|
||||
public bool IsSupportedFileFormat()
|
||||
{
|
||||
if (FileData == null || FileData.Length <= 4)
|
||||
return false;
|
||||
|
||||
using (var stream = new MemoryStream(FileData))
|
||||
{
|
||||
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||
{
|
||||
fileFormat.FileName = FileName;
|
||||
if (fileFormat.Identify(stream))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void Replace()
|
||||
{
|
||||
string fileName = Path.GetFileName(FileName.RemoveIllegaleFileNameCharacters());
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AssimpNet">
|
||||
<HintPath>..\Toolbox\Lib\AssimpNet.dll</HintPath>
|
||||
|
@ -224,6 +227,7 @@
|
|||
<Compile Include="FileFormats\R4G4.cs" />
|
||||
<Compile Include="FileFormats\SizeTables\RSTB.cs" />
|
||||
<Compile Include="FileFormats\SizeTables\TPFileSizeTable.cs" />
|
||||
<Compile Include="FileFormats\ZIP.cs" />
|
||||
<Compile Include="Forms\Archive\ArchiveFilePanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -370,6 +374,12 @@
|
|||
<DependentUpon>AudioPlayer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Editors\Audio\AudioFile.cs" />
|
||||
<Compile Include="Forms\Editors\HexEditor\HexEditorNew.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Editors\HexEditor\HexEditorNew.Designer.cs">
|
||||
<DependentUpon>HexEditorNew.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Editors\HexEditor\HexEditor.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -780,6 +790,9 @@
|
|||
<EmbeddedResource Include="Forms\Editors\CubeMapFaceCreator.resx">
|
||||
<DependentUpon>CubeMapFaceCreator.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Editors\HexEditor\HexEditorNew.resx">
|
||||
<DependentUpon>HexEditorNew.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Editors\HexEditor\HexEditor.resx">
|
||||
<DependentUpon>HexEditor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Runtime.Serialization.Formatters.Binary;
|
|||
using System.Drawing;
|
||||
using OpenTK;
|
||||
using System.Reflection;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
|
||||
namespace Switch_Toolbox.Library
|
||||
{
|
||||
|
@ -135,6 +136,16 @@ namespace Switch_Toolbox.Library
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static byte[] SubArray(Stream data, uint offset, uint length)
|
||||
{
|
||||
using (var reader = new FileReader(data))
|
||||
{
|
||||
reader.Position = offset;
|
||||
return reader.ReadBytes((int)length);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SubArray(byte[] data, uint offset, uint length)
|
||||
{
|
||||
return data.Skip((int)offset).Take((int)length).ToArray();
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
|
Loading…
Reference in a new issue