Fixed to the point where addon extraction works without issues.
- Don't dispose import stream after importing. - Added debug lines - Fixed metadata not getting imported and therefore getting information out of sync - Added some generic debug assertions for official-gmad-generated addons, will be removed later - Fixed whitelist regex generation code - missing brackets - Fixed SegmentedAddonFileInfo.GetContents caused by file seek for long filesize compatibility.lua-bytecode
parent
919f45c9f2
commit
2ab88b8a24
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -28,7 +29,8 @@ namespace GarrysMod.AddonCreator
|
||||||
/// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param>
|
/// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param>
|
||||||
public void Import(string path, bool withMetadata = true)
|
public void Import(string path, bool withMetadata = true)
|
||||||
{
|
{
|
||||||
using (var stream = File.OpenRead(path))
|
var stream = File.OpenRead(path);
|
||||||
|
|
||||||
{
|
{
|
||||||
var sr = new BinaryReader(stream, Encoding.GetEncoding("windows-1252"));
|
var sr = new BinaryReader(stream, Encoding.GetEncoding("windows-1252"));
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ namespace GarrysMod.AddonCreator
|
||||||
|
|
||||||
// Check addon's CRC32 hash
|
// Check addon's CRC32 hash
|
||||||
{
|
{
|
||||||
|
Debug.WriteLine("Checking CRC32...");
|
||||||
var baseAddon = new byte[stream.Length - sizeof (int)];
|
var baseAddon = new byte[stream.Length - sizeof (int)];
|
||||||
var oldpos = stream.Position;
|
var oldpos = stream.Position;
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
|
@ -48,26 +51,49 @@ namespace GarrysMod.AddonCreator
|
||||||
{
|
{
|
||||||
throw new IOException("Data corrupted (calculated hash mismatching hash in addon file)");
|
throw new IOException("Data corrupted (calculated hash mismatching hash in addon file)");
|
||||||
}
|
}
|
||||||
|
stream.Position = oldpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import metadata
|
// Import metadata
|
||||||
var newSteamID = sr.ReadUInt64();
|
var newSteamID = sr.ReadUInt64();
|
||||||
var newBuildTimestamp = sr.ReadUInt64();
|
var newBuildTimestamp = sr.ReadUInt64();
|
||||||
var newRequiredContentLen = sr.ReadByte();
|
var newRequiredContentLen = sr.ReadByte();
|
||||||
|
var newTitle = sr.ReadString(true);
|
||||||
|
var newDescription = sr.ReadString(true);
|
||||||
|
var newAuthor = sr.ReadString(true);
|
||||||
|
var newVersion = sr.ReadInt32();
|
||||||
|
|
||||||
|
Debug.WriteLine("## Metadata ##");
|
||||||
|
Debug.WriteLine("Steam ID: {0}", newSteamID);
|
||||||
|
Debug.WriteLine("Build time: {0}", newBuildTimestamp);
|
||||||
|
Debug.WriteLine("Required content count: {0}", newRequiredContentLen);
|
||||||
|
|
||||||
|
Debug.Assert(newSteamID == 0);
|
||||||
|
Debug.Assert(newRequiredContentLen == 0);
|
||||||
|
|
||||||
for (var b = 0; b < newRequiredContentLen; b++)
|
for (var b = 0; b < newRequiredContentLen; b++)
|
||||||
{
|
{
|
||||||
var value = sr.ReadString(true);
|
var value = sr.ReadString(true);
|
||||||
if (withMetadata && !RequiredContent.Contains(value))
|
if (withMetadata && !RequiredContent.Contains(value))
|
||||||
RequiredContent.Add(value);
|
RequiredContent.Add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withMetadata)
|
if (withMetadata)
|
||||||
{
|
{
|
||||||
SteamID = newSteamID;
|
SteamID = newSteamID;
|
||||||
BuildTimestamp = newBuildTimestamp;
|
BuildTimestamp = newBuildTimestamp;
|
||||||
|
Title = newTitle;
|
||||||
|
Description = newDescription;
|
||||||
|
Author = newAuthor;
|
||||||
|
Version = newVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine("");
|
||||||
|
|
||||||
// file list
|
// file list
|
||||||
|
Debug.WriteLine("## File list ##");
|
||||||
var newFilesList = new Dictionary<string, Tuple<long, int>>();
|
var newFilesList = new Dictionary<string, Tuple<long, int>>();
|
||||||
|
var expectedFileId = 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var fileId = sr.ReadUInt32();
|
var fileId = sr.ReadUInt32();
|
||||||
|
@ -79,6 +105,11 @@ namespace GarrysMod.AddonCreator
|
||||||
var fileSize = sr.ReadInt64();
|
var fileSize = sr.ReadInt64();
|
||||||
var fileHash = sr.ReadInt32();
|
var fileHash = sr.ReadInt32();
|
||||||
|
|
||||||
|
Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, fileSize / 1024, fileId);
|
||||||
|
Debug.Assert(fileId == expectedFileId);
|
||||||
|
|
||||||
|
expectedFileId++;
|
||||||
|
|
||||||
// avoid duplicates
|
// avoid duplicates
|
||||||
if (newFilesList.ContainsKey(filePath))
|
if (newFilesList.ContainsKey(filePath))
|
||||||
{
|
{
|
||||||
|
@ -87,12 +118,17 @@ namespace GarrysMod.AddonCreator
|
||||||
|
|
||||||
newFilesList.Add(filePath, new Tuple<long, int>(fileSize, fileHash));
|
newFilesList.Add(filePath, new Tuple<long, int>(fileSize, fileHash));
|
||||||
} while (true);
|
} while (true);
|
||||||
|
Debug.WriteLine("");
|
||||||
|
|
||||||
|
Debug.WriteLine("## File import ##");
|
||||||
foreach (var file in newFilesList)
|
foreach (var file in newFilesList)
|
||||||
{
|
{
|
||||||
var filePath = file.Key;
|
var filePath = file.Key;
|
||||||
var fileSize = file.Value.Item1;
|
var fileSize = file.Value.Item1;
|
||||||
var fileHash = file.Value.Item2;
|
var fileHash = file.Value.Item2;
|
||||||
|
|
||||||
|
Debug.WriteLine("Extracting: {0} ({1:0.00} kB)", filePath, fileSize / 1024);
|
||||||
|
|
||||||
var fileContent = new byte[fileSize];
|
var fileContent = new byte[fileSize];
|
||||||
|
|
||||||
// long-compatible file reading
|
// long-compatible file reading
|
||||||
|
@ -140,6 +176,8 @@ namespace GarrysMod.AddonCreator
|
||||||
addonJson.CheckForErrors();
|
addonJson.CheckForErrors();
|
||||||
addonJson.RemoveIgnoredFiles(ref files);
|
addonJson.RemoveIgnoredFiles(ref files);
|
||||||
|
|
||||||
|
// TODO: Extract data from addon.json
|
||||||
|
|
||||||
// Sort files
|
// Sort files
|
||||||
var resultingFiles = new SortedDictionary<string, AddonFileInfo>(files);
|
var resultingFiles = new SortedDictionary<string, AddonFileInfo>(files);
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace GarrysMod.AddonCreator
|
||||||
if (RegularExpressions != null)
|
if (RegularExpressions != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RegularExpressions = Whitelist.Select(w => w.WildcardRegex).ToArray();
|
RegularExpressions = Whitelist.Select(w => w.WildcardRegex()).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files)
|
public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files)
|
||||||
|
|
|
@ -25,14 +25,16 @@ namespace GarrysMod.AddonCreator
|
||||||
var output = new byte[_len];
|
var output = new byte[_len];
|
||||||
var oldpos = _stream.Position;
|
var oldpos = _stream.Position;
|
||||||
_stream.Position = _pos;
|
_stream.Position = _pos;
|
||||||
for (long i = 0; i < _len; i += int.MaxValue) // for loop for supporting long file sizes
|
for (long i = 0; i < _len; i += int.MaxValue) // for-loop for supporting long file sizes
|
||||||
{
|
{
|
||||||
var toRead = (int) Math.Min(int.MaxValue, _len);
|
var toRead = (int) Math.Min(int.MaxValue, _len);
|
||||||
var buffer = new byte[toRead];
|
var buffer = new byte[toRead];
|
||||||
var readReal = _stream.Read(buffer, 0, toRead);
|
var readReal = _stream.Read(buffer, 0, toRead);
|
||||||
i -= (toRead - readReal); // make absolutely sure everything gets read
|
|
||||||
buffer.CopyTo(output, i);
|
buffer.CopyTo(output, i);
|
||||||
|
|
||||||
|
i -= (toRead - readReal); // make absolutely sure everything gets read
|
||||||
}
|
}
|
||||||
|
_stream.Position = oldpos;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue