Implemented some addon.json stuff.
parent
41375e121a
commit
919f45c9f2
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -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" />
|
||||
|
|
Loading…
Reference in New Issue