예제 #1
0
        /// <summary>
        /// Extracts JSON and other files from a managed assembly's embedded resources.
        /// </summary>
        /// <param name="asm">The assembly to extract the files from.</param>
        /// <returns>A tuple containing the list of the JSON files an a list of the other files, together with all errors.</returns>
        internal Tuple<List<JsonFile>, Dictionary<string, byte[]>, List<CompilerError>> ExtractData(Assembly asm)
        {
            List<CompilerError> errors = new List<CompilerError>();

            List<JsonFile> jsons = new List<JsonFile>();
            Dictionary<string, byte[]> files = new Dictionary<string, byte[]>();

            JsonFile
                modInfo     = new JsonFile(),
                modOptions  = new JsonFile(),
                craftGroups = new JsonFile();

            string asmName = asm.GetName().Name;

            foreach (string res in asm.GetManifestResourceNames())
                using (Stream s = asm.GetManifestResourceStream(res))
                {
                    string name = res;

                    if (name.Length > asmName.Length + 1 && name.StartsWith(asmName + "."))
                        name = name.Substring(asmName.Length + 1);

                    if (name.EndsWith(".json"))
                    {
                        JsonFile current = new JsonFile();

                        try
                        {
                            string fileName = res;
                            int index;

                            while ((index = fileName.IndexOf('.')) != fileName.LastIndexOf('.') && index != -1) // keep extension
                                fileName = fileName.Remove(index, 1).Insert(index, "/");

                            current = new JsonFile(fileName, JsonMapper.ToObject(new StreamReader(s)));
                        }
                        catch (Exception e)
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                IsWarning = false,
                                Cause = e,
                                Message = "Invalid JSON file: '" + res + "'."
                            });
                        }

                        if (name == "ModInfo.json")
                            modInfo = current;
                        else if (name == "ModOptions.json")
                            modOptions = current;
                        else if (name == "CraftGroups.json")
                            craftGroups = current;
                        else
                            jsons.Add(current);
                    }

                    using (MemoryStream ms = new MemoryStream())
                    {
                        s.CopyTo(ms);

                        if (name != "ModInfo.json")
                            files.Add(Path.ChangeExtension(name, Path.GetExtension(name).ToLowerInvariant()), ms.ToArray());
                    }

                    Compiler.Log("Extracted file " + name + ", path is " + Path.GetExtension(name).ToLowerInvariant() + ".", MessageImportance.Low);
                }

            if (modInfo.IsEmpty)
            {
                modInfo = new JsonFile(String.Empty, ModCompile.GenerateBlankModInfo(asmName));

                errors.Add(new CompilerError(Building)
                {
                    IsWarning = true,
                    Cause = new FileNotFoundException("Could not find ModInfo.json."),
                    Message = "Could not find ModInfo.json, using default..."
                });
            }

            jsons.Insert(0, modInfo    );
            jsons.Insert(1, modOptions ); // check if it's null later
            jsons.Insert(2, craftGroups); // same here

            return new Tuple<List<JsonFile>, Dictionary<string, byte[]>, List<CompilerError>>(jsons, files, errors);
        }
예제 #2
0
        /// <summary>
        /// Loads JSON and other files from a mod's source folder.
        /// </summary>
        /// <param name="directory">The mod's source folder.</param>
        /// <returns>A tuple containing the list of the JSON files an a list of the other files, together with all errors.</returns>
        internal Tuple<List<JsonFile>, Dictionary<string, byte[]>, List<CompilerError>> LoadFiles(string directory)
        {
            List<CompilerError> errors = new List<CompilerError>();

            List<JsonFile> jsons = new List<JsonFile>();
            Dictionary<string, byte[]> files = new Dictionary<string, byte[]>();

            JsonFile
                modInfo     = new JsonFile(),
                modOptions  = new JsonFile(),
                craftGroups = new JsonFile();

            foreach (string s in Directory.EnumerateFiles(directory, "*.*", SearchOption.AllDirectories))
            {
                if (Path.GetDirectoryName(s).ToLowerInvariant().EndsWith(".sln.ide")) // roslyn temp directory, probably has open file handles
                    continue;

                byte[] fileBin = null;
                string fileStr = null;

                try
                {
                    fileBin = File.ReadAllBytes(s);
                    fileStr = File.ReadAllText (s);
                }
                catch (IOException e)
                {
                    errors.Add(new CompilerError(Building)
                    {
                        Cause = e,
                        FilePath = s,
                        IsWarning = true,
                        Message = "A file handle is open. Please close the file in the program which owns the file handle.\n"
                            + "This file will not be included in the build, but the build itself will continue."
                    });

                    continue;
                }

                string
                    fileName         = Path.GetFileName(s),
                    relativeFileName = s.Substring(directory.Length + 1).Replace('\\', '/'),
                    relativeFileNameExt = Path.GetExtension(relativeFileName).ToLowerInvariant();

                relativeFileName = Path.ChangeExtension(relativeFileName, relativeFileNameExt);

                if (s.ToLowerInvariant().EndsWith(JSON_EXT))
                {
                    JsonFile current = new JsonFile();

                    try
                    {
                        current = new JsonFile(s, JsonMapper.ToObject(fileStr));
                    }
                    catch (Exception e)
                    {
                        errors.Add(new CompilerError(Building)
                        {
                            IsWarning = false,
                            Cause = e,
                            FilePath = relativeFileName,
                            Message = "Invalid JSON file: '" + relativeFileName + "'."
                        });
                    }

                    if (relativeFileName == MODINFO)
                        modInfo = current;
                    else if (relativeFileName == MODOPT)
                        modOptions = current;
                    else if (relativeFileName == CGROUP)
                        craftGroups = current;
                    else
                        jsons.Add(current);
                }

                if (relativeFileName != MODINFO)
                    files.Add(Path.ChangeExtension(relativeFileName, Path.GetExtension(relativeFileName).ToLowerInvariant()), fileBin);

                Compiler.Log(L_FILE + fileName + P_IS + relativeFileName + DOT, MessageImportance.Low);
            }

            if (modInfo.IsEmpty)
            {
                modInfo = new JsonFile(String.Empty, ModCompile.GenerateBlankModInfo(Path.GetDirectoryName(directory)));

                errors.Add(new CompilerError(Building)
                {
                    IsWarning = true,
                    Cause = new FileNotFoundException("Could not find ModInfo.json."),
                    Message = "Could not find ModInfo.json, using default..."
                });
            }

            jsons.Insert(0, modInfo    );
            jsons.Insert(1, modOptions ); // check if it's null later
            jsons.Insert(2, craftGroups); // same here

            return new Tuple<List<JsonFile>, Dictionary<string, byte[]>, List<CompilerError>>(jsons, files, errors);
        }