Implemented some addon.json stuff.

lua-bytecode
Icedream 2014-10-22 16:29:51 +02:00
parent 41375e121a
commit 919f45c9f2
5 changed files with 178 additions and 8 deletions

View File

@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Text;
using CRC32;
using Newtonsoft.Json;
namespace GarrysMod.AddonCreator
{
@ -132,10 +133,26 @@ namespace GarrysMod.AddonCreator
throw new FileNotFoundException("Addon building requires a valid addon.json file.");
}
// TODO: Check addon.json for errors
// TODO: Ignore or remove files marked to be ignored in addon.json
// TODO: Sort in alphabetic order
// TODO: Filter files by general whitelist
var files = Files;
// Check for errors and ignores in addon.json
var addonJson = JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents()));
addonJson.CheckForErrors();
addonJson.RemoveIgnoredFiles(ref files);
// Sort files
var resultingFiles = new SortedDictionary<string, AddonFileInfo>(files);
// General whitelist
var blacklistedFiles = AddonWhitelist
.FindBlacklistedFiles(resultingFiles.Select(i => i.Key))
.ToArray();
if (blacklistedFiles.Any())
{
throw new InvalidOperationException("Found files which aren't whitelisted. Remove or ignore those files before you retry packing your addon:"
+ Environment.NewLine + Environment.NewLine
+ string.Join(Environment.NewLine, blacklistedFiles));
}
using (var stream = new MemoryStream())
{
@ -175,7 +192,7 @@ namespace GarrysMod.AddonCreator
throw new IndexOutOfRangeException("Number of addon files must not exceed " + uint.MaxValue + " elements.");
}
uint fileNum = 0;
foreach (var file in Files)
foreach (var file in resultingFiles)
{
fileNum++;
sw.Write(fileNum);
@ -186,7 +203,7 @@ namespace GarrysMod.AddonCreator
sw.Write((uint)0); // End of file list
// File contents
foreach (var file in Files)
foreach (var file in resultingFiles)
{
if (file.Value.Size == 0)
continue;

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace GarrysMod.AddonCreator
{
public class AddonJson
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("tags")]
public List<string> Tags { get; set; }
[JsonProperty("ignore")]
public List<string> Ignores { get; set; }
public void CheckForErrors()
{
if (string.IsNullOrEmpty(Title))
{
throw new MissingFieldException("Title is empty or not specified.");
}
if (!string.IsNullOrEmpty(Description) && Description.Contains('\0'))
{
throw new InvalidDataException("Description contains NULL character.");
}
if (string.IsNullOrEmpty(Type))
{
throw new MissingFieldException("Type is empty or not specified.");
}
}
public void RemoveIgnoredFiles(ref Dictionary<string, AddonFileInfo> files)
{
foreach (var key in files.Keys.ToArray())
// ToArray makes a shadow copy of Keys to avoid "mid-loop-removal" conflicts
{
if (Ignores.Any(w => w.WildcardRegex().IsMatch(key)))
files.Remove(key);
}
}
}
}

View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator
{
public class AddonWhitelist
{
private static readonly string[] Whitelist =
{
"addon.json",
"lua/*.lua",
"scenes/*.vcd",
"particles/*.pcf",
"resource/fonts/*.ttf",
"scripts/vehicles/*.txt",
"resource/localization/*/*.properties",
"maps/*.bsp",
"maps/*.nav",
"maps/*.ain",
"maps/thumb/*.png",
"sound/*.wav",
"sound/*.mp3",
"sound/*.ogg",
"materials/*.vmt",
"materials/*.vtf",
"materials/*.png",
"materials/*.jpg",
"materials/*.jpeg",
"models/*.mdl",
"models/*.vtx",
"models/*.phy",
"models/*.ani",
"models/*.vvd",
"gamemodes/*/*.txt",
"gamemodes/*/*.fgd",
"gamemodes/*/logo.png",
"gamemodes/*/icon24.png",
"gamemodes/*/gamemode/*.lua",
"gamemodes/*/entities/effects/*.lua",
"gamemodes/*/entities/weapons/*.lua",
"gamemodes/*/entities/entities/*.lua",
"gamemodes/*/backgrounds/*.png",
"gamemodes/*/backgrounds/*.jpg",
"gamemodes/*/backgrounds/*.jpeg",
"gamemodes/*/content/models/*.mdl",
"gamemodes/*/content/models/*.vtx",
"gamemodes/*/content/models/*.phy",
"gamemodes/*/content/models/*.ani",
"gamemodes/*/content/models/*.vvd",
"gamemodes/*/content/materials/*.vmt",
"gamemodes/*/content/materials/*.vtf",
"gamemodes/*/content/materials/*.png",
"gamemodes/*/content/materials/*.jpg",
"gamemodes/*/content/materials/*.jpeg",
"gamemodes/*/content/scenes/*.vcd",
"gamemodes/*/content/particles/*.pcf",
"gamemodes/*/content/resource/fonts/*.ttf",
"gamemodes/*/content/scripts/vehicles/*.txt",
"gamemodes/*/content/resource/localization/*/*.properties",
"gamemodes/*/content/maps/*.bsp",
"gamemodes/*/content/maps/*.nav",
"gamemodes/*/content/maps/*.ain",
"gamemodes/*/content/maps/thumb/*.png",
"gamemodes/*/content/sound/*.wav",
"gamemodes/*/content/sound/*.mp3",
"gamemodes/*/content/sound/*.ogg"
};
private static Regex[] RegularExpressions;
static void ConvertWhitelist()
{
if (RegularExpressions != null)
return;
RegularExpressions = Whitelist.Select(w => w.WildcardRegex).ToArray();
}
public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files)
{
return files.Where(f => RegularExpressions.Any(rx => !rx.IsMatch(f)));
}
}
}

View File

@ -3,11 +3,20 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator
{
static class BinaryCodecExt
static class Extensions
{
public static Regex WildcardRegex(this string pattern)
{
return new Regex("^" + Regex.Escape(pattern)
.Replace(@"\*", ".*")
.Replace(@"\?", ".")
+ "$");
}
public static string ReadString(this BinaryReader br, bool nullTerminated)
{
if (!nullTerminated)

View File

@ -54,7 +54,9 @@
<ItemGroup>
<Compile Include="Addon.cs" />
<Compile Include="AddonFileInfo.cs" />
<Compile Include="BinaryCodecExt.cs" />
<Compile Include="AddonJson.cs" />
<Compile Include="AddonWhitelist.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="JsonAddonFileInfo.cs" />
<Compile Include="OptimizedCRC.cs" />
<Compile Include="ParallelCRC.cs" />