Пример #1
0
        /// <summary>
        /// Parses the mod's information from Json, loading any required references, and returns its <see cref="ModInfo"/> object.
        /// </summary>
        /// <param name="j">Json Data to load the <see cref="ModInfo"/> from</param>
        /// <param name="path">The path to the mod</param>
        /// <returns>The <see cref="ModInfo"/> of the mod</returns>
        public static ModInfo ParseModInfo(JsonData j, string path)
        {
            var refs = new List<IReference>();

            if (j.Has("dllReferences"))
                foreach (object s in j["dllReferences"])
                    refs.Add(new AssemblyReference(s.ToString(), path));
            if (j.Has("modReferences"))
                foreach (object s in j["modReferences"])
                    refs.Add(new ModReference(s.ToString()));

            string internalName = j.GetOrExn<string>("internalName");

            return new ModInfo(
                path,
                internalName,
                j.GetOrDef("displayName", internalName),
                j.GetOrDef("author", "<unspecified>"),
                j.GetOrDef("version", "0.0.0.0"),
                j.GetOrDef<string>("description"),
                j.GetOrExn<string>("asmFileName"),
                j.GetOrExn<string>("modDefTypeName"),
                refs.ToArray()
            );
        }
Пример #2
0
        static void BuildSource(string sourcePath, string outputPath, JsonData modInfo, CompileException cex, Dictionary<string, string> dictNames)
        {

            string[] modPathSplit = sourcePath.Split('\\', '/');
            string modName = modPathSplit[modPathSplit.Length - 1].Split('.')[0];

            if (modInfo.Has("MSBuild"))
                if ((bool)modInfo["MSBuild"])
                {
                    // done by msbuild anyway
                    ModsCompile.BuildSource(sourcePath, outputPath, modInfo, cex, dictNames);
                    return;
                }

            bool generatePDB = false;
            if (modInfo.Has("includePDB"))
                generatePDB = (bool)modInfo["includePDB"];

            // but this has to change - other CodeDomProviders (default stays C#)
            CodeDomProvider cdp = new CSharpCodeProvider();

            foreach (string fileName in Directory.EnumerateFiles(sourcePath, "*.json", SearchOption.AllDirectories))
            {
                string fname = fileName.Substring(sourcePath.Length + 1).Replace('\\', '/');
                if (fname == "ModInfo.json")
                    continue;
                try
                {
                    JsonData json2 = JsonMapper.ToObject(File.ReadAllText(fileName));
                    if (fname.ToLower().StartsWith("item/"))
                        ValidateJson.Item(modName, fileName, json2, cex);
                    if (fname.ToLower().StartsWith("npc/"))
                        ValidateJson.NPC(modName, fileName, json2, cex);
                    if (fname.ToLower().StartsWith("projectile/"))
                        ValidateJson.Projectile(modName, fileName, json2, cex);
                    //TODO: check all the JSON files other than ModInfo.json for required fields
                }
                catch (Exception e)
                {
                    cex.AddProblem(fileName, "Invalid JSON file.\n" + e.Message);
                }
            }

            CompilerParameters cp = new CompilerParameters();

            cp.GenerateExecutable = false;

            cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

            cp.IncludeDebugInformation = generatePDB;

            cp.ReferencedAssemblies.Add("mscorlib.dll");
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Core.dll");
            cp.ReferencedAssemblies.Add("System.Numerics.dll");
            cp.ReferencedAssemblies.Add("System.Xml.dll");

            cp.ReferencedAssemblies.Add("System.Drawing.dll");
            cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");

            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.dll");
            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Xact.dll");
            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Game.dll");
            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Graphics.dll");

            if (modInfo != null)
            {
                if (modInfo.Has("language"))
                    switch (((string)modInfo["language"]).ToLowerInvariant())
                    {
                        case "js":
                        case "js.net":
                        case "jscript":
                        case "jscript.net":
                        case "javascript":
                        case "javascript.net":
                            cdp = new JScriptCodeProvider();
                            break;
                        case "vb":
                        case "vb.net":
                        case "visualbasic":
                        case "visualbasic.net":
                        case "visual basic":
                        case "visual basic.net":
                            cdp = new VBCodeProvider();
                            break;
                    }

                if (modInfo.Has("modReferences"))
                {
                    if (Directory.Exists(Mods.pathDirMods + "/.Temp"))
                        Directory.Delete(Mods.pathDirMods + "/.Temp", true);
                    Directory.CreateDirectory(Mods.pathDirMods + "/.Temp");
                    JsonData jRefs = (JsonData)modInfo["modReferences"];
                    for (int i = 0; i < jRefs.Count; i++)
                    {
                        string jRef = (string)jRefs[i];
                        if (!dictNames.ContainsKey(jRef))
                            continue;
                        string modfile = dictNames[jRef];
                        cp.ReferencedAssemblies.Add(Mods.pathDirMods + "/.Temp/" + jRef + ".dll");

                        string[] split = jRef.Split('\\');
                        if (modfile.EndsWith(".tapimod"))
                        {
                            using (FileStream fileStream = new FileStream(modfile, FileMode.Open))
                            {
                                BinBuffer bb2 = new BinBuffer(new BinBufferStream(fileStream));
                                bb2.ReadInt();
                                bb2.ReadString();
                                int count = bb2.ReadInt();
                                int skip = 0;
                                while (count-- > 0)
                                {
                                    bb2.ReadString();
                                    skip += bb2.ReadInt();
                                }
                                while (skip-- > 0)
                                    bb2.ReadByte();
                                File.WriteAllBytes(Mods.pathDirMods + "/.Temp/" + jRef + ".dll", bb2.ReadBytes(bb2.BytesLeft()));
                            }
                        }
                        else if (modfile.EndsWith(".tapi"))
                        {
                            using (ZipFile zip = ZipFile.Read(modfile))
                            {
                                if (zip.ContainsEntry("Mod.tapimod"))
                                {
                                    ZipEntry ze = zip["Mod.tapimod"];
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        ze.Extract(ms);
                                        ms.Position = 0;
                                        BinBuffer bb2 = new BinBuffer(new BinBufferStream(ms));
                                        bb2.ReadInt();
                                        bb2.ReadString();
                                        int count = bb2.ReadInt();
                                        int skip = 0;
                                        while (count-- > 0)
                                        {
                                            bb2.ReadString();
                                            skip += bb2.ReadInt();
                                        }
                                        while (skip-- > 0)
                                            bb2.ReadByte();
                                        File.WriteAllBytes(Mods.pathDirMods + "/.Temp/" + jRef + ".dll", bb2.ReadBytes(bb2.BytesLeft()));
                                    }
                                }
                            }
                        }
                    }
                }
                if (modInfo.Has("dllReferences"))
                {
                    JsonData jRefs = (JsonData)modInfo["dllReferences"];
                    for (int i = 0; i < jRefs.Count; i++)
                    {
                        string jRef = (string)jRefs[i];
                        if (File.Exists(sourcePath + "/" + jRef)) // remove .dll -> can also reference .exes
                            cp.ReferencedAssemblies.Add(sourcePath + "/" + jRef);
                        else
                            cp.ReferencedAssemblies.Add(jRef); // somewhere else, like the GAC
                    }
                }
            }

            cp.OutputAssembly = outputPath + (cdp is VBCodeProvider ? "" : ".dll"); // VBCodeProvider automatically adds '.dll'

            List<string> toCompile = new List<string>();
            foreach (string fileName in Directory.EnumerateFiles(sourcePath, cdp.FileExtension, SearchOption.AllDirectories))
                toCompile.Add(fileName);

            CompilerResults cr = cdp.CompileAssemblyFromFile(cp, toCompile.ToArray());

            if (Directory.Exists(Mods.pathDirMods + "/.Temp"))
                Directory.Delete(Mods.pathDirMods + "/.Temp", true);

            if (cr.Errors.HasErrors)
            {
                foreach (CodeDomError ce in cr.Errors)
                {
                    StringBuilder sb = new StringBuilder();
                    if (ce.FileName != "")
                    {
                        sb.Append("(" + ce.Column + "," + ce.Line + "): " + ce.ErrorText);
                        sb.Append("\n" + File.ReadLines(ce.FileName).Skip(ce.Line - 1).Take(1).First().Replace("\t", " "));
                        sb.Append('\n');
                        for (int i = 0; i < ce.Column - 1; i++)
                            sb.Append(' ');
                        sb.Append('^');
                        cex.AddProblem(ce.FileName, sb.ToString());
                    }
                    else // general error (without file) - .dll not found, etc
                        cex.AddProblem(outputPath, (ce.IsWarning ? "warning" : "error") + " " + ce.ErrorNumber + ": " + ce.ErrorText);
                }
            }

            if (cex.problems.Count != 0)
            {
                if (File.Exists(outputPath + ".dll"))
                    File.Delete(outputPath + ".dll");

                throw cex;
            }
        }