RPF Explorer Drag&Drop. Fixed bug (typo) in defragment tool.

This commit is contained in:
dexyfex 2018-02-26 23:49:06 +11:00
parent b5358be9ba
commit 9a81c0ea63
4 changed files with 406 additions and 256 deletions

View File

@ -1382,7 +1382,7 @@ namespace CodeWalker.GameFiles
{
if (child.ParentFileEntry == null) continue;//shouldn't really happen...
var cpos = StartPos + (long)child.ParentFileEntry.FileOffset * 512;
child.UpdateStartPos(newpos);
child.UpdateStartPos(cpos);
}
}
}
@ -1517,10 +1517,26 @@ namespace CodeWalker.GameFiles
return entry;
}
public static RpfFileEntry CreateFile(RpfDirectoryEntry dir, string name, byte[] data)
public static RpfFileEntry CreateFile(RpfDirectoryEntry dir, string name, byte[] data, bool overwrite = true)
{
RpfFile parent = dir.File;
string namel = name.ToLowerInvariant();
if (overwrite)
{
foreach (var exfile in dir.Files)
{
if (exfile.NameLower == namel)
{
//file already exists. delete the existing one first!
//this should probably be optimised to just replace the existing one...
//TODO: investigate along with ExploreForm.ReplaceSelected()
DeleteEntry(exfile);
break;
}
}
}
//else fail if already exists..? items with the same name allowed?
RpfFile parent = dir.File;
string fpath = parent.GetPhysicalFilePath();
string rpath = dir.Path + "\\" + namel;
if (!File.Exists(fpath))
@ -1755,6 +1771,43 @@ namespace CodeWalker.GameFiles
}
public static bool EnsureValidEncryption(RpfFile file, Func<RpfFile, bool> confirm)
{
if (file == null) return false;
//currently assumes OPEN is the valid encryption type.
//TODO: support other encryption types!
bool needsupd = false;
var f = file;
List<RpfFile> files = new List<RpfFile>();
while (f != null)
{
if (f.Encryption != RpfEncryption.OPEN)
{
if (!confirm(f))
{
return false;
}
needsupd = true;
}
if (needsupd)
{
files.Add(f);
}
f = f.Parent;
}
//change encryption types, starting from the root rpf.
files.Reverse();
foreach (var cfile in files)
{
SetEncryptionType(cfile, RpfEncryption.OPEN);
}
return true;
}
public static void SetEncryptionType(RpfFile file, RpfEncryption encryption)
{
file.Encryption = encryption;

190
ExploreForm.Designer.cs generated
View File

@ -91,6 +91,12 @@
this.MainSizeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.MainAttrColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.MainPathColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.EditModeBaseWarningPanel = new System.Windows.Forms.Panel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label1 = new System.Windows.Forms.Label();
this.EditModeModsWarningPanel = new System.Windows.Forms.Panel();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label2 = new System.Windows.Forms.Label();
this.ListContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.ListContextViewMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextViewHexMenu = new System.Windows.Forms.ToolStripMenuItem();
@ -116,6 +122,8 @@
this.ListContextReplaceMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextDeleteMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextEditSeparator = new System.Windows.Forms.ToolStripSeparator();
this.ListContextDefragmentMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextDefragmentSeparator = new System.Windows.Forms.ToolStripSeparator();
this.ListContextSelectAllMenu = new System.Windows.Forms.ToolStripMenuItem();
this.TreeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.TreeContextCopyPathMenu = new System.Windows.Forms.ToolStripMenuItem();
@ -127,14 +135,6 @@
this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog();
this.OpenFileDialog = new System.Windows.Forms.OpenFileDialog();
this.FolderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
this.EditModeBaseWarningPanel = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.EditModeModsWarningPanel = new System.Windows.Forms.Panel();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label2 = new System.Windows.Forms.Label();
this.ListContextDefragmentMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextDefragmentSeparator = new System.Windows.Forms.ToolStripSeparator();
this.MainMenu.SuspendLayout();
this.MainToolbar.SuspendLayout();
this.StatusBar.SuspendLayout();
@ -142,12 +142,12 @@
this.MainSplitContainer.Panel1.SuspendLayout();
this.MainSplitContainer.Panel2.SuspendLayout();
this.MainSplitContainer.SuspendLayout();
this.ListContextMenu.SuspendLayout();
this.TreeContextMenu.SuspendLayout();
this.EditModeBaseWarningPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.EditModeModsWarningPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.ListContextMenu.SuspendLayout();
this.TreeContextMenu.SuspendLayout();
this.SuspendLayout();
//
// MainMenu
@ -175,7 +175,7 @@
//
this.FileExitMenu.Name = "FileExitMenu";
this.FileExitMenu.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
this.FileExitMenu.Size = new System.Drawing.Size(152, 22);
this.FileExitMenu.Size = new System.Drawing.Size(134, 22);
this.FileExitMenu.Text = "Exit";
this.FileExitMenu.Click += new System.EventHandler(this.FileExitMenu_Click);
//
@ -699,6 +699,7 @@
//
// MainListView
//
this.MainListView.AllowDrop = true;
this.MainListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
@ -723,7 +724,11 @@
this.MainListView.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.MainListView_AfterLabelEdit);
this.MainListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.MainListView_ColumnClick);
this.MainListView.ItemActivate += new System.EventHandler(this.MainListView_ItemActivate);
this.MainListView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.MainListView_ItemDrag);
this.MainListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.MainListView_RetrieveVirtualItem);
this.MainListView.DragDrop += new System.Windows.Forms.DragEventHandler(this.MainListView_DragDrop);
this.MainListView.DragEnter += new System.Windows.Forms.DragEventHandler(this.MainListView_DragEnter);
this.MainListView.DragLeave += new System.EventHandler(this.MainListView_DragLeave);
this.MainListView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainListView_KeyDown);
this.MainListView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainListView_KeyUp);
this.MainListView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MainListView_MouseUp);
@ -754,6 +759,72 @@
this.MainPathColumnHeader.Text = "Path";
this.MainPathColumnHeader.Width = 225;
//
// EditModeBaseWarningPanel
//
this.EditModeBaseWarningPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.EditModeBaseWarningPanel.BackColor = System.Drawing.Color.DarkRed;
this.EditModeBaseWarningPanel.Controls.Add(this.pictureBox1);
this.EditModeBaseWarningPanel.Controls.Add(this.label1);
this.EditModeBaseWarningPanel.Location = new System.Drawing.Point(1, 3);
this.EditModeBaseWarningPanel.Name = "EditModeBaseWarningPanel";
this.EditModeBaseWarningPanel.Size = new System.Drawing.Size(559, 24);
this.EditModeBaseWarningPanel.TabIndex = 1;
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(6, 3);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(16, 16);
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(25, 5);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(285, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Warning: You are directly editing base game files";
//
// EditModeModsWarningPanel
//
this.EditModeModsWarningPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.EditModeModsWarningPanel.BackColor = System.Drawing.Color.DarkGreen;
this.EditModeModsWarningPanel.Controls.Add(this.pictureBox2);
this.EditModeModsWarningPanel.Controls.Add(this.label2);
this.EditModeModsWarningPanel.Location = new System.Drawing.Point(1, 28);
this.EditModeModsWarningPanel.Name = "EditModeModsWarningPanel";
this.EditModeModsWarningPanel.Size = new System.Drawing.Size(559, 24);
this.EditModeModsWarningPanel.TabIndex = 2;
//
// pictureBox2
//
this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
this.pictureBox2.Location = new System.Drawing.Point(6, 3);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(16, 16);
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(25, 5);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(225, 13);
this.label2.TabIndex = 0;
this.label2.Text = "You are editing files in the mods folder";
//
// ListContextMenu
//
this.ListContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -783,7 +854,7 @@
this.ListContextDefragmentSeparator,
this.ListContextSelectAllMenu});
this.ListContextMenu.Name = "MainContextMenu";
this.ListContextMenu.Size = new System.Drawing.Size(208, 464);
this.ListContextMenu.Size = new System.Drawing.Size(208, 442);
//
// ListContextViewMenu
//
@ -967,6 +1038,18 @@
this.ListContextEditSeparator.Name = "ListContextEditSeparator";
this.ListContextEditSeparator.Size = new System.Drawing.Size(204, 6);
//
// ListContextDefragmentMenu
//
this.ListContextDefragmentMenu.Name = "ListContextDefragmentMenu";
this.ListContextDefragmentMenu.Size = new System.Drawing.Size(207, 22);
this.ListContextDefragmentMenu.Text = "Defragment Archive...";
this.ListContextDefragmentMenu.Click += new System.EventHandler(this.ListContextDefragmentMenu_Click);
//
// ListContextDefragmentSeparator
//
this.ListContextDefragmentSeparator.Name = "ListContextDefragmentSeparator";
this.ListContextDefragmentSeparator.Size = new System.Drawing.Size(204, 6);
//
// ListContextSelectAllMenu
//
this.ListContextSelectAllMenu.Name = "ListContextSelectAllMenu";
@ -1033,84 +1116,6 @@
//
this.OpenFileDialog.Multiselect = true;
//
// EditModeBaseWarningPanel
//
this.EditModeBaseWarningPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.EditModeBaseWarningPanel.BackColor = System.Drawing.Color.DarkRed;
this.EditModeBaseWarningPanel.Controls.Add(this.pictureBox1);
this.EditModeBaseWarningPanel.Controls.Add(this.label1);
this.EditModeBaseWarningPanel.Location = new System.Drawing.Point(1, 3);
this.EditModeBaseWarningPanel.Name = "EditModeBaseWarningPanel";
this.EditModeBaseWarningPanel.Size = new System.Drawing.Size(559, 24);
this.EditModeBaseWarningPanel.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(25, 5);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(285, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Warning: You are directly editing base game files";
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(6, 3);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(16, 16);
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
// EditModeModsWarningPanel
//
this.EditModeModsWarningPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.EditModeModsWarningPanel.BackColor = System.Drawing.Color.DarkGreen;
this.EditModeModsWarningPanel.Controls.Add(this.pictureBox2);
this.EditModeModsWarningPanel.Controls.Add(this.label2);
this.EditModeModsWarningPanel.Location = new System.Drawing.Point(1, 28);
this.EditModeModsWarningPanel.Name = "EditModeModsWarningPanel";
this.EditModeModsWarningPanel.Size = new System.Drawing.Size(559, 24);
this.EditModeModsWarningPanel.TabIndex = 2;
//
// pictureBox2
//
this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
this.pictureBox2.Location = new System.Drawing.Point(6, 3);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(16, 16);
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(25, 5);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(225, 13);
this.label2.TabIndex = 0;
this.label2.Text = "You are editing files in the mods folder";
//
// ListContextDefragmentMenu
//
this.ListContextDefragmentMenu.Name = "ListContextDefragmentMenu";
this.ListContextDefragmentMenu.Size = new System.Drawing.Size(207, 22);
this.ListContextDefragmentMenu.Text = "Defragment Archive...";
this.ListContextDefragmentMenu.Click += new System.EventHandler(this.ListContextDefragmentMenu_Click);
//
// ListContextDefragmentSeparator
//
this.ListContextDefragmentSeparator.Name = "ListContextDefragmentSeparator";
this.ListContextDefragmentSeparator.Size = new System.Drawing.Size(204, 6);
//
// ExploreForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1124,6 +1129,7 @@
this.MainMenuStrip = this.MainMenu;
this.Name = "ExploreForm";
this.Text = "RPF Explorer - CodeWalker by dexyfex";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ExploreForm_FormClosed);
this.Load += new System.EventHandler(this.ExploreForm_Load);
this.MainMenu.ResumeLayout(false);
this.MainMenu.PerformLayout();
@ -1135,14 +1141,14 @@
this.MainSplitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.MainSplitContainer)).EndInit();
this.MainSplitContainer.ResumeLayout(false);
this.ListContextMenu.ResumeLayout(false);
this.TreeContextMenu.ResumeLayout(false);
this.EditModeBaseWarningPanel.ResumeLayout(false);
this.EditModeBaseWarningPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.EditModeModsWarningPanel.ResumeLayout(false);
this.EditModeModsWarningPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ListContextMenu.ResumeLayout(false);
this.TreeContextMenu.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();

View File

@ -925,7 +925,32 @@ namespace CodeWalker
MainListView.VirtualListSize = CurrentFiles.Count;
}
private void EnsureImportedRpf(RpfFileEntry entry, RpfDirectoryEntry parentrpffldr)
{
if ((entry == null) || (parentrpffldr == null)) return;
var newrpf = parentrpffldr.File?.FindChildArchive(entry);
if (newrpf == null) return;
//an RPF file was imported. add its structure to the UI!
var rootpath = GTAFolder.GetCurrentGTAFolderWithTrailingSlash();
var tnf = CreateRpfTreeFolder(newrpf, newrpf.Path, rootpath + newrpf.Path);
if (CurrentFolder.Children != null)
{
//make sure any existing (replaced!) one is removed first!
foreach (var child in CurrentFolder.Children)
{
if (child.Path == tnf.Path)
{
CurrentFolder.Children.Remove(child);
child.TreeNode.Remove();
break;
}
}
}
CurrentFolder.AddChildToHierarchy(tnf);
RecurseMainTreeViewRPF(tnf, AllRpfs);
RecurseAddMainTreeViewNodes(tnf, CurrentFolder.TreeNode);
}
private void RefreshMainListView()
{
@ -1097,23 +1122,41 @@ namespace CodeWalker
{
data = entry.File.ExtractFile(entry);//extract an RPF from another.
}
else if (!string.IsNullOrEmpty(file.FullPath) && (file.Folder.RpfFile != null))
{
data = File.ReadAllBytes(file.FullPath); //load RPF file from filesystem
}
}
else if (file.File != null)
else if (file.File != null) //load file from RPF
{
//load file from RPF
if (file.File.File != null) //need the reference to the RPF archive
{
data = file.File.File.ExtractFile(file.File);
}
else
{ }
}
else if (!string.IsNullOrEmpty(file.FullPath))
{
//load file from filesystem
data = File.ReadAllBytes(file.FullPath);
data = File.ReadAllBytes(file.FullPath); //load file from filesystem
}
else
{ }
return data;
}
private byte[] GetFileDataCompressResources(MainListItem file)
{
byte[] data = GetFileData(file);
RpfResourceFileEntry rrfe = file.File as RpfResourceFileEntry;
if (rrfe != null) //add resource header if this is a resource file.
{
data = ResourceBuilder.Compress(data); //not completely ideal to recompress it...
data = ResourceBuilder.AddResourceHeader(rrfe, data);
}
return data;
}
private bool CanViewFile(MainListItem item)
{
if (item == null) return false;
@ -1601,47 +1644,21 @@ namespace CodeWalker
private bool EnsureRpfValidEncryption()
private bool EnsureRpfValidEncryption(RpfFile file = null)
{
if (CurrentFolder.RpfFolder == null) return false;
if ((file == null) && (CurrentFolder.RpfFolder == null)) return false;
var rpf = CurrentFolder.RpfFolder.File;
var rpf = file ?? CurrentFolder.RpfFolder.File;
return EnsureRpfValidEncryption(rpf);
}
private bool EnsureRpfValidEncryption(RpfFile rpf)
{
if (rpf == null) return false;
bool needsupd = false;
var f = rpf;
List<RpfFile> files = new List<RpfFile>();
while (f != null)
var confirm = new Func<RpfFile, bool>((f) =>
{
if (f.Encryption != RpfEncryption.OPEN)
{
var msg = "Archive " + f.Name + " is currently set to " + f.Encryption.ToString() + " encryption.\nAre you sure you want to change this archive to OPEN encryption?\nLoading by the game will require OpenIV.asi.";
if (MessageBox.Show(msg, "Change RPF encryption type", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return false;
}
needsupd = true;
}
if (needsupd)
{
files.Add(f);
}
f = f.Parent;
}
var msg = "Archive " + f.Name + " is currently set to " + f.Encryption.ToString() + " encryption.\nAre you sure you want to change this archive to OPEN encryption?\nLoading by the game will require OpenIV.asi.";
return (MessageBox.Show(msg, "Change RPF encryption type", MessageBoxButtons.YesNo) == DialogResult.Yes);
});
//change encryption types, starting from the root rpf.
files.Reverse();
foreach (var file in files)
{
RpfFile.SetEncryptionType(file, RpfEncryption.OPEN);
}
return true;
return RpfFile.EnsureValidEncryption(rpf, confirm);
}
@ -1776,22 +1793,13 @@ namespace CodeWalker
if ((file.Folder == null) || (file.Folder.RpfFile != null))
{
byte[] data = GetFileData(file);
byte[] data = GetFileDataCompressResources(file);
if (data == null)
{
MessageBox.Show("Unable to extract file: " + file.Path);
return;
}
RpfResourceFileEntry rrfe = file.File as RpfResourceFileEntry;
if (rrfe != null) //add resource header if this is a resource file.
{
data = ResourceBuilder.Compress(data); //not completely ideal to recompress it...
data = ResourceBuilder.AddResourceHeader(rrfe, data);
}
SaveFileDialog.FileName = file.Name;
if (SaveFileDialog.ShowDialog() == DialogResult.OK)
{
@ -1823,19 +1831,13 @@ namespace CodeWalker
if ((file.Folder == null) || (file.Folder.RpfFile != null))
{
var path = folderpath + file.Name;
var data = GetFileData(file);
if (data == null)
{
errors.AppendLine("Unable to extract file: " + file.Path);
continue;
}
try
{
RpfResourceFileEntry rrfe = file.File as RpfResourceFileEntry;
if (rrfe != null) //add resource header if this is a resource file.
var data = GetFileDataCompressResources(file);
if (data == null)
{
data = ResourceBuilder.Compress(data); //not completely ideal to recompress it...
data = ResourceBuilder.AddResourceHeader(rrfe, data);
errors.AppendLine("Unable to extract file: " + file.Path);
continue;
}
File.WriteAllBytes(path, data);
@ -1939,19 +1941,13 @@ namespace CodeWalker
if ((file.Folder == null) || (file.Folder.RpfFile != null))
{
var path = folderpath + file.Name;
var data = GetFileData(file);
if (data == null)
{
errors.AppendLine("Unable to extract file: " + file.Path);
continue;
}
try
{
RpfResourceFileEntry rrfe = file.File as RpfResourceFileEntry;
if (rrfe != null) //add resource header if this is a resource file.
var data = GetFileDataCompressResources(file);
if (data == null)
{
data = ResourceBuilder.Compress(data);
data = ResourceBuilder.AddResourceHeader(rrfe, data);
errors.AppendLine("Unable to extract file: " + file.Path);
continue;
}
File.WriteAllBytes(path, data);
@ -2099,10 +2095,10 @@ namespace CodeWalker
return;//canceled
}
try
var fpaths = OpenFileDialog.FileNames;
foreach (var fpath in fpaths)
{
var fpaths = OpenFileDialog.FileNames;
foreach (var fpath in fpaths)
try
{
if (!File.Exists(fpath))
{
@ -2152,26 +2148,13 @@ namespace CodeWalker
byte[] data = ResourceBuilder.Build(meta, 2); //meta is RSC V:2
foreach (var exfile in parentrpffldr.Files)
{
if (exfile.NameLower == fnamel)
{
//file already exists. delete the existing one first!
//this should probably be optimised to just replace the existing one...
//TODO: investigate along with ReplaceSelected()
RpfFile.DeleteEntry(exfile);
break;
}
}
RpfFile.CreateFile(parentrpffldr, fname, data);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to import file");
return;
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to import file");
}
}
CurrentFolder.ListItems = null;
@ -2183,26 +2166,38 @@ namespace CodeWalker
if (!EditMode) return;
if (CurrentFolder?.IsSearchResults ?? false) return;
RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder;
if (parentrpffldr == null)
{
MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again.");
return;
}
if (!EnsureRpfValidEncryption()) return;
OpenFileDialog.Filter = string.Empty;
if (OpenFileDialog.ShowDialog(this) != DialogResult.OK)
{
return;//canceled
}
try
var fpaths = OpenFileDialog.FileNames;
ImportRaw(fpaths, false);//already checked encryption before the file dialog...
}
private void ImportRaw(string[] fpaths, bool checkEncryption = true)
{
if (!EditMode) return;
if (CurrentFolder?.IsSearchResults ?? false) return;
RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder;
if (parentrpffldr == null)
{
var fpaths = OpenFileDialog.FileNames;
foreach (var fpath in fpaths)
MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again.");
return;
}
if (checkEncryption)
{
if (!EnsureRpfValidEncryption()) return;
}
foreach (var fpath in fpaths)
{
try
{
if (!File.Exists(fpath))
{
@ -2211,7 +2206,6 @@ namespace CodeWalker
var fi = new FileInfo(fpath);
var fname = fi.Name;
var fnamel = fname.ToLowerInvariant();
if (fi.Length > 0x3FFFFFFF)
{
@ -2219,54 +2213,20 @@ namespace CodeWalker
continue;
}
Cursor = Cursors.WaitCursor;
byte[] data = File.ReadAllBytes(fpath);
foreach (var exfile in parentrpffldr.Files)
{
if (exfile.NameLower == fnamel)
{
//file already exists. delete the existing one first!
//this should probably be optimised to just replace the existing one...
//TODO: investigate along with ReplaceSelected()
RpfFile.DeleteEntry(exfile);
break;
}
}
var entry = RpfFile.CreateFile(parentrpffldr, fname, data);
EnsureImportedRpf(entry, parentrpffldr); //make sure structure is created if an RPF was imported
var newrpf = parentrpffldr.File?.FindChildArchive(entry);
if (newrpf != null)
{
//an RPF file was imported. add its structure to the UI!
var rootpath = GTAFolder.GetCurrentGTAFolderWithTrailingSlash();
var tnf = CreateRpfTreeFolder(newrpf, newrpf.Path, rootpath + newrpf.Path);
if (CurrentFolder.Children != null)
{
//make sure any existing (replaced!) one is removed first!
foreach (var child in CurrentFolder.Children)
{
if (child.Path == tnf.Path)
{
CurrentFolder.Children.Remove(child);
child.TreeNode.Remove();
break;
}
}
}
CurrentFolder.AddChildToHierarchy(tnf);
RecurseMainTreeViewRPF(tnf, AllRpfs);
RecurseAddMainTreeViewNodes(tnf, CurrentFolder.TreeNode);
}
Cursor = Cursors.Default;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to import file");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to import file");
return;
}
CurrentFolder.ListItems = null;
@ -2641,11 +2601,54 @@ namespace CodeWalker
}
private string GetDropFolder()
{
return Path.Combine(Path.GetTempPath(), "CodeWalkerDrop");
}
private string CreateDropFolder()
{
string drop = GetDropFolder();
if (!Directory.Exists(drop))
{
Directory.CreateDirectory(drop);
}
string dir = Path.Combine(drop, Guid.NewGuid().ToString());
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
return dir;
}
private void CleanupDropFolder()
{
string drop = GetDropFolder();
if (Directory.Exists(drop))
{
try
{
Directory.Delete(drop, true); //so broken :[
}
catch { } //not much we can do here...
}
}
private void ExploreForm_Load(object sender, EventArgs e)
{
Init();
}
private void ExploreForm_FormClosed(object sender, FormClosedEventArgs e)
{
CleanupDropFolder();
}
private void MainTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
var prev = CurrentFolder;
@ -2822,6 +2825,94 @@ namespace CodeWalker
}
}
private void MainListView_ItemDrag(object sender, ItemDragEventArgs e)
{
if (MainListView.SelectedIndices.Count <= 0) return;
var dir = CreateDropFolder();
var filenames = new List<string>();
var errors = new List<string>();
Cursor = Cursors.WaitCursor;
for (int i = 0; i < MainListView.SelectedIndices.Count; i++)
{
var idx = MainListView.SelectedIndices[i];
if ((idx < 0) || (idx >= CurrentFiles.Count)) continue;
var file = CurrentFiles[idx];
if ((file.Folder == null) || (file.Folder.RpfFile != null))
{
if (file.FileSize > 0x6400000) //100MB
{
errors.Add(file.Name + " is greater than 100MB, drag-drop for large files is disabled.");
continue;
}
try
{
var data = GetFileDataCompressResources(file);
var filename = Path.Combine(dir, file.Name);
File.WriteAllBytes(filename, data);
filenames.Add(filename);
}
catch (Exception ex)
{
errors.Add(ex.ToString());
}
}
}
Cursor = Cursors.Default;
if (filenames.Count > 0)
{
DataObject dataobj = new DataObject(DataFormats.FileDrop, filenames.ToArray());
DoDragDrop(dataobj, DragDropEffects.Copy);
}
else
{
if (errors.Count > 0)
{
MessageBox.Show("Errors encountered while dragging:\n" + string.Join("\n", errors.ToArray()));
}
}
}
private void MainListView_DragLeave(object sender, EventArgs e)
{
}
private void MainListView_DragEnter(object sender, DragEventArgs e)
{
if (!EditMode) return;
if (CurrentFolder?.IsSearchResults ?? false) return;
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if ((files != null) && (files.Length > 0))
{
if (!files[0].StartsWith(GetDropFolder(), StringComparison.InvariantCultureIgnoreCase)) //don't dry to drop on ourselves...
{
e.Effect = DragDropEffects.Copy;
}
}
}
}
private void MainListView_DragDrop(object sender, DragEventArgs e)
{
if (!EditMode) return;
if (CurrentFolder?.IsSearchResults ?? false) return;
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if ((files == null) || (files.Length <= 0)) return;
if (files[0].StartsWith(GetDropFolder(), StringComparison.InvariantCultureIgnoreCase)) return; //don't dry to drop on ourselves...
ImportRaw(files);
}
}
private void BackButton_ButtonClick(object sender, EventArgs e)
{
GoBack();

View File

@ -313,7 +313,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADo
HwAAAk1TRnQBSQFMAgEBGAEAAdgBAAHYAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
HwAAAk1TRnQBSQFMAgEBGAEAAfABAAHwAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAAXADAAEBAQABCAYAARwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@ -450,6 +450,24 @@
AQABAQHAAQEBAAEDAcABAQEAAQEBwAEBAQABAwHAAQEBAAEBAQABAQEAAQcBwAEDAQABAQEAAQEBAAEP
AcABAwEAAQEBAAEBAQABDwHAAQMBAAEBAQABAQEAAQ8BwAEDAQABAQHAAQcBAAEPAcABAwEAAQMB4AEP
AQABDwHAAQMBAAEHCw==
</value>
</data>
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAJtJREFUOE+Vj8ENgCAMRdnE1ZzLCwt5cQJvjkDiRfyfUIJQEJo8U2rof5hWOedW
4CNrHI8XLp3PsXjCPo7Hion3tXm/mwD7KQtJlwVTFmW6MGyRp+MYYD9kUaZjlBaQX4s8XVvQtSjTtQWk
aVGmE4yrBaqFlt6jstDSCX5VBuRj0UtvLSDJopX+R7LAx868X4gGVp5hAQcz4LIxLycs8rg+vnkMAAAA
AElFTkSuQmCC
</value>
</data>
<data name="pictureBox2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAALVJREFUOE/dk70NQjEMhLMHDZuRBZiAadgD6YmGNjNAhaB4okkb/IEtvfgZIaDj
pCvi853y4ySPWmsWDsLmSC1r2xwiLoVlON7aandui+2pIzU0euhV2xNqHtf7y8zouTlcCRm7EFkUBN9s
8HUNKWbObM03QUOk6XEyAUN05nfEg5eAsAEaIg3i/ZOAl5doiLTpJf72jDoLJZpCg693gwRk8RjlaBo9
w1EGGvLdZ5pCxA++c0p3WGOjVX9N2kUAAAAASUVORK5CYII=
</value>
</data>
<metadata name="ListContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@ -574,24 +592,6 @@
<metadata name="FolderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>152, 56</value>
</metadata>
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACbSURBVDhPlY/BDYAgDEXZxNWcywsLeXECb45A4kX8n1CC
UBCaPFNq6H+YVjnnVuAjaxyPFy6dz7F4wj6Ox4qJ97V5v5sA+ykLSZcFUxZlujBskafjGGA/ZFGmY5QW
kF+LPF1b0LUo07UFpGlRphOMqwWqhZbeo7LQ0gl+VQbkY9FLby0gyaKV/keywMfOvF+IBlaeYQEHM+Cy
MS8nLPK4Pr55DAAAAABJRU5ErkJggg==
</value>
</data>
<data name="pictureBox2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAC1SURBVDhP3ZO9DUIxDISzBw2bkQWYgGnYA+mJhjYzQIWg
eKJJG/yBLb34GSGg46Qr4vOd8uMkj1prFg7C5kgta9scIi6FZTje2mp3bovtqSM1NHroVdsTah7X+8vM
6Lk5XAkZuxBZFATfbPB1DSlmzmzNN0FDpOlxMgFDdOZ3xIOXgLABGiIN4v2TgJeXaIi06SX+9ow6CyWa
QoOvd4MEZPEY5WgaPcNRBhry3WeaQsQPvnNKd1hjo1V/TdpFAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>126</value>
</metadata>