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
Icedream 2014-10-22 19:07:03 +02:00
parent 919f45c9f2
commit 2ab88b8a24
3 changed files with 44 additions and 4 deletions

View File

@ -1,6 +1,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@ -28,7 +29,8 @@ namespace GarrysMod.AddonCreator
/// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param>
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"));
@ -39,6 +41,7 @@ namespace GarrysMod.AddonCreator
// Check addon's CRC32 hash
{
Debug.WriteLine("Checking CRC32...");
var baseAddon = new byte[stream.Length - sizeof (int)];
var oldpos = stream.Position;
stream.Position = 0;
@ -48,26 +51,49 @@ namespace GarrysMod.AddonCreator
{
throw new IOException("Data corrupted (calculated hash mismatching hash in addon file)");
}
stream.Position = oldpos;
}
// Import metadata
var newSteamID = sr.ReadUInt64();
var newBuildTimestamp = sr.ReadUInt64();
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++)
{
var value = sr.ReadString(true);
if (withMetadata && !RequiredContent.Contains(value))
RequiredContent.Add(value);
}
if (withMetadata)
{
SteamID = newSteamID;
BuildTimestamp = newBuildTimestamp;
Title = newTitle;
Description = newDescription;
Author = newAuthor;
Version = newVersion;
}
Debug.WriteLine("");
// file list
Debug.WriteLine("## File list ##");
var newFilesList = new Dictionary<string, Tuple<long, int>>();
var expectedFileId = 1;
do
{
var fileId = sr.ReadUInt32();
@ -79,6 +105,11 @@ namespace GarrysMod.AddonCreator
var fileSize = sr.ReadInt64();
var fileHash = sr.ReadInt32();
Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, fileSize / 1024, fileId);
Debug.Assert(fileId == expectedFileId);
expectedFileId++;
// avoid duplicates
if (newFilesList.ContainsKey(filePath))
{
@ -87,12 +118,17 @@ namespace GarrysMod.AddonCreator
newFilesList.Add(filePath, new Tuple<long, int>(fileSize, fileHash));
} while (true);
Debug.WriteLine("");
Debug.WriteLine("## File import ##");
foreach (var file in newFilesList)
{
var filePath = file.Key;
var fileSize = file.Value.Item1;
var fileHash = file.Value.Item2;
Debug.WriteLine("Extracting: {0} ({1:0.00} kB)", filePath, fileSize / 1024);
var fileContent = new byte[fileSize];
// long-compatible file reading
@ -140,6 +176,8 @@ namespace GarrysMod.AddonCreator
addonJson.CheckForErrors();
addonJson.RemoveIgnoredFiles(ref files);
// TODO: Extract data from addon.json
// Sort files
var resultingFiles = new SortedDictionary<string, AddonFileInfo>(files);

View File

@ -76,7 +76,7 @@ namespace GarrysMod.AddonCreator
if (RegularExpressions != null)
return;
RegularExpressions = Whitelist.Select(w => w.WildcardRegex).ToArray();
RegularExpressions = Whitelist.Select(w => w.WildcardRegex()).ToArray();
}
public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files)

View File

@ -25,14 +25,16 @@ namespace GarrysMod.AddonCreator
var output = new byte[_len];
var oldpos = _stream.Position;
_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 buffer = new byte[toRead];
var readReal = _stream.Read(buffer, 0, toRead);
i -= (toRead - readReal); // make absolutely sure everything gets read
buffer.CopyTo(output, i);
i -= (toRead - readReal); // make absolutely sure everything gets read
}
_stream.Position = oldpos;
return output;
}
}