Beispiel #1
0
        // -------------------------------------------------------------------
        // Private
        // -------------------------------------------------------------------
        private void Compile()
        {
            if (this.sourceDirectory == null || this.targetDirectory == null)
            {
                this.Arguments.PrintArgumentUse();
                return;
            }

            if (!this.sourceDirectory.Exists)
            {
                Diagnostic.Error("Source directory does not exist: {0}", this.sourceDirectory);
                return;
            }

            this.config.Load(new CarbonFile(Constants.ConfigFileName));

            var context = new CompileContext();
            context.Initialize(this.sourceDirectory, this.targetDirectory);

            var scanner = this.factory.Resolve<IAddonScanner>();
            if (!scanner.Run(context) || context.HasError)
            {
                Diagnostic.Error("Scanning Addons failed: {0}\n{1}", context.LastError, context.LastErrorException?.ToString() ?? "N/A");
                return;
            }

            var compiler = this.factory.Resolve<ICompiler>();
            if (!compiler.Run(context) || context.HasError)
            {
                Diagnostic.Error("Compilation failed: {0}\n{1}", context.LastError, context.LastErrorException?.ToString() ?? "N/A");
            }
        }
Beispiel #2
0
        private static void PurgeDuplicateContent(CompileContext context)
        {
            int duplicateFileCount = 0;
            IDictionary<string, CompileContent> duplicateCheck = new Dictionary<string, CompileContent>();
            foreach (CompileContent content in new List<CompileContent>(context.FullContentList))
            {
                if (!content.AbsoluteFile.Extension.Equals(Constants.ExtensionLua))
                {
                    // This check only applies to .lua scripts
                    continue;
                }

                CompileContent existingContent;
                if (duplicateCheck.TryGetValue(content.Md5, out existingContent))
                {
                    duplicateFileCount++;
                    context.FullContentList.Remove(content);
                    continue;
                }

                duplicateCheck.Add(content.Md5, content);
            }

            Diagnostic.Info("Removed {0} Duplicate Content Files, {1} left", duplicateFileCount, context.FullContentList.Count);
        }
Beispiel #3
0
        // -------------------------------------------------------------------
        // Public
        // -------------------------------------------------------------------
        public bool Run(CompileContext context)
        {
            Diagnostic.Info(string.Empty);
            Diagnostic.Info("Starting compilation of {0} Addons", context.ScannedEntries.Count);

            ResolveAddonDependency(context);
            AssembleContent(context);
            PurgeDuplicateContent(context);
            WriteContentToTarget(context);

            return true;
        }
Beispiel #4
0
        private static void AssembleContent(CompileContext context)
        {
            context.Target.Create();

            foreach (AddonEntry entry in context.EntriesOrderedByPriority)
            {
                foreach (AddonContent content in entry.Contents.Values)
                {
                    AssembleContentRecursive(context, entry, content);
                }
            }

            Diagnostic.Info("Found {0} Content files to compile", context.FullContentList.Count);
        }
Beispiel #5
0
        private static AddonEntry ReadToc(CompileContext context, CarbonFile file)
        {
            var entry = new AddonEntry(file);
            context.CurrentScanEntry = entry;
            using (var stream = file.OpenRead())
            {
                using (var reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        var line = reader.ReadLine();
                        ParseTocLine(context, line);
                    }
                }
            }

            context.FinalizeScannedEntry();
            return entry;
        }
Beispiel #6
0
        private static void ParseTocLine(CompileContext context, string line)
        {
            string trimmedLine = line.Trim();
            if (string.IsNullOrEmpty(trimmedLine))
            {
                // skip emptry lines
                return;
            }

            Match match = TocMetaRegex.Match(line);
            if (match.Success)
            {
                string key = match.Groups[1].Value.Trim();
                string value = match.Groups[2].Value.Trim();
                context.CurrentScanEntry.AddMeta(key, value);
                return;
            }

            if (trimmedLine.StartsWith("#"))
            {
                // Ignore comments
                return;
            }

            if (trimmedLine.EndsWith(Constants.ExtensionLua))
            {
                context.CurrentScanEntry.AddContent(new AddonContent(new CarbonFile(trimmedLine), context.CurrentScanEntry.RootDirectory));
                return;
            }

            if (trimmedLine.EndsWith(Constants.ExtensionXml))
            {
                AddonContent xmlContent = ReadXMLContent(new CarbonFile(line), context.CurrentScanEntry.RootDirectory);
                if (xmlContent != null)
                {
                    context.CurrentScanEntry.AddContent(xmlContent);
                }

                return;
            }

            Diagnostic.Warning("Unhandled Toc Entry: {0}", trimmedLine);
        }
Beispiel #7
0
        private static void AssembleContentRecursive(CompileContext context, AddonEntry addon, AddonContent currentContent)
        {
            foreach (AddonContent subContent in currentContent.SubContent)
            {
                AssembleContentRecursive(context, addon, subContent);
            }

            CarbonFile absoluteFile = currentContent.RootDirectory.ToFile(currentContent.File);
            if (!absoluteFile.Exists)
            {
                Diagnostic.Warning("Content File {0} does not exist! ({1})", absoluteFile, currentContent.File);
                return;
            }

            var content = new CompileContent(addon, absoluteFile, absoluteFile.ToRelative<CarbonFile>(context.Source.ToDirectory(addon.Name)));
            using (var stream = absoluteFile.OpenRead())
            {
                byte[] md5 = HashUtils.GetMd5(stream);
                content.Md5 = HashUtils.Md5ToString(md5);
            }

            context.FullContentList.Add(content);
        }
Beispiel #8
0
        private static void WriteContentToTarget(CompileContext context)
        {
            StringBuilder contentTocBuilder = new StringBuilder();
            contentTocBuilder.AppendLine("## Interface: 60200");
            contentTocBuilder.AppendLine("## Title: Built");
            contentTocBuilder.AppendLine("## Notes: Built");
            contentTocBuilder.AppendLine("## Author: AddonCompiler");
            contentTocBuilder.AppendLine("## Version: 6.0.001");

            int filesCopied = 0;
            int resourcesCopied = 0;
            foreach (CompileContent content in context.FullContentList)
            {
                CarbonFile targetRelativeFile = new CarbonDirectory(content.Addon.Name).ToFile(content.RelativeFile);
                CarbonFile targetAbsoluteFile = context.Target.ToFile(targetRelativeFile);

                if (content.AbsoluteFile.Extension == Constants.ExtensionXml)
                {
                    if (!WriteXmlContentToTarget(content.AbsoluteFile, targetAbsoluteFile))
                    {
                        continue;
                    }

                    filesCopied++;
                }
                else
                {
                    if (!WriteScriptContentToTarget(content, targetAbsoluteFile))
                    {
                        continue;
                    }

                    filesCopied++;
                }

                // Register the content in the TOC
                contentTocBuilder.AppendLine(targetRelativeFile.GetPath());
            }

            foreach (AddonEntry addon in context.EntriesOrderedByPriority)
            {
                foreach (CarbonFile resource in addon.Resources)
                {
                    CarbonFile targetAbsoluteResourceFile = context.Target.ToDirectory(addon.Name).ToFile(resource);
                    CarbonFile sourceAbsoluteResourceFile = addon.RootDirectory.ToFile(resource);
                    sourceAbsoluteResourceFile.CopyTo(targetAbsoluteResourceFile, true);
                    resourcesCopied++;
                }
            }

            CarbonFile builtTocFile = context.Target.ToFile("Built.toc");
            builtTocFile.WriteAsString(contentTocBuilder.ToString());

            Diagnostic.Info("Finished Compile with {0} content files and {1} resources", filesCopied, resourcesCopied);
        }
Beispiel #9
0
        // -------------------------------------------------------------------
        // Private
        // -------------------------------------------------------------------
        private static void ResolveAddonDependency(CompileContext context)
        {
            foreach (AddonEntry entry in context.ScannedEntries.Values)
            {
                string dependencyValues;
                if (entry.Meta.TryGetValue(Constants.MetaDependencies, out dependencyValues))
                {
                    string[] dependencies = dependencyValues.Split(',');
                    foreach (string dependency in dependencies)
                    {
                        if (dependency.Contains(Constants.BlizzardAddonPrefix))
                        {
                            continue;
                        }

                        AddonEntry dependencyEntry;
                        if (context.ScannedEntries.TryGetValue(dependency.Trim(), out dependencyEntry))
                        {
                            entry.AddDependency(dependencyEntry);
                            dependencyEntry.ModifyOrder(1);
                        }
                        else
                        {
                            Diagnostic.Warning("Could not resolve dependency {0} of {1}", dependency, entry.Name);
                        }
                    }
                }
            }

            context.EntriesOrderedByPriority = context.ScannedEntries.Values.OrderByDescending(x => x.Order).ThenBy(x => x.Name).ToList();
        }
Beispiel #10
0
        // -------------------------------------------------------------------
        // Public
        // -------------------------------------------------------------------
        public bool Run(CompileContext context)
        {
            ScanSource(context);

            return true;
        }
Beispiel #11
0
        // -------------------------------------------------------------------
        // Private
        // -------------------------------------------------------------------
        private static void ScanSource(CompileContext context)
        {
            context.ScannedEntries.Clear();

            CarbonDirectoryResult[] candidates = context.Source.GetDirectories();
            foreach (CarbonDirectoryResult candidate in candidates)
            {
                CarbonFileResult[] tocResults = candidate.Absolute.GetFiles("*" + Constants.ExtensionToc);
                if (tocResults == null || tocResults.Length <= 0)
                {
                    Diagnostic.Info("Skipping directory {0}, no TOC found", candidate.Absolute.DirectoryNameWithoutPath);
                    continue;
                }

                foreach (CarbonFileResult tocResult in tocResults)
                {
                    Diagnostic.Info("Scanning {0}", tocResult.Absolute.FileName);
                    AddonEntry entry = ReadToc(context, tocResult.Absolute);

                    // Now scan for resources
                    CarbonFileResult[] fileResults = candidate.Absolute.GetFiles(options: SearchOption.AllDirectories);
                    foreach (CarbonFileResult fileResult in fileResults)
                    {
                        if (Constants.ResourceExtensions.Contains(fileResult.Absolute.Extension.ToLowerInvariant()))
                        {
                            entry.AddResource(fileResult.Relative);
                        }
                    }

                    continue;
                }
            }
        }