Esempio n. 1
0
        ModInfo GetModInfoFromTapiZip(ZipFile zf)
        {
            if (zf.ContainsEntry("ModInfo.json"))
            {
                ZipEntry ze = zf["ModInfo.json"];

                using (MemoryStream ms = new MemoryStream())
                {
                    ze.Extract(ms);

                    StreamReader r = new StreamReader(ms);

                    ModInfo mi = new ModInfo(Compiler) { checkCircularRefs = false };

                    var err = mi.CreateAndValidate(new JsonFile(zf.Name, JsonMapper.ToObject(r.ReadToEnd())));

                    if (!Compiler.CreateOutput(err.ToList()).Succeeded)
                        return null;

                    return mi;
                }
            }

            if (zf.ContainsEntry("Mod.tapimod"))
                using (MemoryStream ms = new MemoryStream())
                {
                    return GetModInfoFromTapiMod(ms.ToArray());
                }

            return null;
        }
Esempio n. 2
0
#pragma warning restore 1591

        ModInfo GetModInfoFromTapiMod(byte[] data)
        {
            BinBuffer bb = new BinBuffer(new BinBufferByte(data));

            uint ver = bb.ReadUInt();

            ModInfo mi = new ModInfo(Compiler) { checkCircularRefs = false };

            var err = mi.CreateAndValidate(new JsonFile(String.Empty, JsonMapper.ToObject(bb.ReadString())));

            if (!Compiler.CreateOutput(err.ToList()).Succeeded)
                return null;

            return mi;
        }
        List<string> WriteRefAssembliesRec(ModInfo mi)
        {
            List<string> ret = new List<string>();

            for (int i = 0; i < mi.modReferences.Length; i++)
            {
                // presence of the mod is checked in ModInfo validation
                WriteAssembly(Compiler.modDict[mi.modReferences[i]], Path.GetTempPath() + "\\MCT\\" + mi.modReferences[i] + ".dll");

                ret.Add(Path.GetTempPath() + "\\MCT\\" + mi.modReferences[i] + ".dll");

                ModInfo mi2 = mi.GetModInfoFromTapi(Compiler.modDict[mi.modReferences[i]]);

                if (mi2 != null)
                    ret.AddRange(WriteRefAssembliesRec(mi2));
            }

            return ret;
        }
Esempio n. 4
0
 /// <summary>
 /// Creates a new instance of the <see cref="ModData" /> class.
 /// </summary>
 /// <param name="mc">The <see cref="ModCompiler" /> that is compiling the mod.</param>
 public ModData(ModCompiler mc)
 {
     Info = new ModInfo(mc);
     Options = new ModOptions(mc);
     CraftGroups = new CraftGroups(mc);
 }
Esempio n. 5
0
        /// <summary>
        /// Create &amp; validate a JSON file.
        /// </summary>
        /// <param name="json">The json to validate</param>
        /// <returns>A collection of all validation errors.</returns>
        public override IEnumerable<CompilerError> CreateAndValidate(JsonFile json)
        {
            List<CompilerError> errors = new List<CompilerError>();

            AddIfNotNull(SetJsonValue(json, "internalName", ref internalName), errors);
            if (internalName == "g")
                errors.Add(new CompilerError(Building)
                {
                    Cause = new ValueNotAllowedException("internalName", internalName),
                    FilePath = json.Path,
                    IsWarning = false,
                    Message = "The internal mod name 'g' cannot be used, as it is reserved as the prefix for crafting groups."
                });

            AddIfNotNull(SetJsonValue(json, "includePDB", ref includePDB, false), errors);
            AddIfNotNull(SetJsonValue(json, "warnOnReload", ref warnOnReload, false), errors);
            AddIfNotNull(SetJsonValue(json, "extractDLL", ref extractDLL, false), errors);

            AddIfNotNull(SetJsonValue(json, "modReferences", ref modReferences, EmptyStringArr), errors);
            for (int i = 0; i < modReferences.Length; i++)
            {
                if (!Compiler.modDict.ContainsKey(modReferences[i]))
                {
                    string d = Compiler.FindSourceFolderFromInternalName(modReferences[i]);

                    // check circular references (and other things) first......
                    ModInfo mi = new ModInfo(Compiler);
                    var err = mi.CreateAndValidate(new JsonFile(d + "\\ModInfo.json", JsonMapper.ToObject(File.ReadAllText(d + "\\ModInfo.json"))));

                    if (!Compiler.CreateOutput(err.ToList()).Succeeded)
                    {
                        foreach (CompilerError ce in err)
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                Cause = ce.Cause,
                                FilePath = ce.FilePath,
                                IsWarning = ce.IsWarning,
                                LocationInFile = ce.LocationInFile,
                                Message = "Error when parsing an uncompiled referenced mod's ModInfo file: " + ce.Message
                            });
                        }
                    }
                    else
                    {
                        if (d == null || !Directory.Exists(d))
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                FilePath = json.Path,
                                Message = "'modReferences[" + i + "]': could not find mod '" + modReferences[i] + "', either as a binary or in a source directory."
                            });
                        }
                        else
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                Cause = new CompilerWarning(),
                                FilePath = json.Path,
                                IsWarning = true,
                                Message = "'modReferences[" + i + "]': could not find mod '" + modReferences[i]
                                    + "', building it first (matching directory: '" + Path.GetDirectoryName(d) + "')."
                            });

                            Compiler.CompileFromSource(d);
                        }
                    }
                }

                if (checkCircularRefs && CheckCircularModRef(this))
                    errors.Add(new CompilerError(Building)
                    {
                        Cause = new CircularReferenceException(circularPath),
                        FilePath = json.Path,
                        Message = "The mod or one of its references contains a circular reference. See the exception for more details."
                    });
            }

            AddIfNotNull(SetJsonValue(json, "dllReferences", ref dllReferences, true, EmptyStringArr), errors);
            for (int i = 0; i < dllReferences.Length; i++)
                try
                {
                    try
                    {
                        Assembly.ReflectionOnlyLoadFrom(dllReferences[i]);
                    }
                    catch
                    {
                        try
                        {
                            Assembly.ReflectionOnlyLoadFrom(Building.OriginPath + "\\" + dllReferences[i]);
                        }
                        catch
                        {
                            Assembly.ReflectionOnlyLoadFrom(Building.OriginPath + "\\References\\" + dllReferences[i]);
                        }
                    }
                }
                catch (Exception e)
                {
                    errors.Add(new CompilerError(Building)
                    {
                        Cause = e,
                        FilePath = json.Path,
                        IsWarning = false,
                        Message = "'dllReferences[" + i + "]': Could not find reference '" + dllReferences[i] + "'."
                    });
                }

            AddIfNotNull(SetJsonValue(json, "MSBuild", ref MSBuild, false), errors);
            if (MSBuild)
            {
                AddIfNotNull(SetJsonValue(json, "msBuildFile", ref msBuildFile, Path.GetDirectoryName(json.Path)
                    + "\\" + new DirectoryInfo(Path.GetDirectoryName(json.Path)).Name + ".csproj"), errors);

                if (!File.Exists(msBuildFile))
                    if (File.Exists(Building.OriginPath + "\\" + msBuildFile))
                        msBuildFile = Building.OriginPath + "\\" + msBuildFile;
                    else
                        errors.Add(new CompilerError(Building)
                        {
                            Cause = new FileNotFoundException(),
                            FilePath = json.Path,
                            IsWarning = false,
                            Message = "'msBuildFile': file '" + msBuildFile + "' not found."
                        });
            }

            // ---

            AddIfNotNull(SetJsonValue(json, "displayName", ref displayName, internalName), errors);
            AddIfNotNull(SetJsonValue(json, "author", ref author, "<unknown>"), errors);

            #region version
            if (json.Json.Has("version"))
            {
                JsonData ver = json.Json["version"];

                if (!ver.IsString)
                {
                    if (!ver.IsArray || ver.Count == 0)
                        errors.Add(new CompilerError(Building)
                        {
                            Cause = new InvalidCastException(),
                            FilePath = json.Path,
                            IsWarning = true,
                            Message = "'version' is a " + json.Json.GetJsonType() + ", not a string or an int[]."
                        });
                    else
                    {
                        int[] values = new int[4] { 1, 0, 0, 0 };

                        for (int i = 0; i < Math.Min(ver.Count, 4); i++)
                            if (!ver[i].IsInt)
                                errors.Add(new CompilerError(Building)
                                {
                                    Cause = new InvalidCastException(),
                                    FilePath = json.Path,
                                    IsWarning = true,
                                    Message = "'version[" + i + "]' is a " + json.Json.GetJsonType() + ", not an int."
                                });
                            else
                            {
                                values[i] = (int)ver[i];

                                try
                                {
                                    version = new Version(values[0], values[1], values[2], values[3]);
                                }
                                catch (Exception e)
                                {
                                    errors.Add(new CompilerError(Building)
                                    {
                                        Cause = e,
                                        FilePath = json.Path,
                                        IsWarning = true,
                                        Message = "Invalid version format. Consider changing it to the general format '<major>.<minor>.<build>.<revision>'."
                                    });
                                }
                            }
                    }
                }
                else
                {
                    try
                    {
                        version = new Version((string)ver);
                    }
                    catch (Exception e)
                    {
                        errors.Add(new CompilerError(Building)
                        {
                            Cause = e,
                            FilePath = json.Path,
                            IsWarning = false,
                            Message = "'version': invalid string format."
                        });
                    }
                }
            }
            #endregion

            AddIfNotNull(SetJsonValue(json, "info", ref info, "Mod " + displayName + " v" + version + " by " + author), errors);

            AddIfNotNull(SetJsonValue(json, "icon", ref icon, null), errors);
            if (icon != null && !Building.Files.ContainsKey(icon + ".png"))
                errors.Add(new CompilerError(Building)
                {
                    Cause = new FileNotFoundException(),
                    FilePath = json.Path,
                    IsWarning = false,
                    Message = "Icon '" + icon + ".png' not found."
                });

            // ---

            AddIfNotNull(SetJsonValue(json, "language", ref language, "C#"), errors);
            AddIfNotNull(SetJsonValue(json, "compress", ref compress, true), errors);
            AddIfNotNull(SetJsonValue(json, "validate", ref validate, true), errors);
            AddIfNotNull(SetJsonValue(json, "includeFiles", ref includeFiles, true), errors);
            AddIfNotNull(SetJsonValue(json, "includeSource", ref includeSource, false), errors);
            AddIfNotNull(SetJsonValue(json, "check", ref check, true), errors);
            AddIfNotNull(SetJsonValue(json, "warningLevel", ref warningLevel, 4), errors);
            AddIfNotNull(SetJsonValue(json, "ignore", ref ignore, EmptyStringArr), errors);
            if (warningLevel < 0 || warningLevel > 4)
                errors.Add(new CompilerError(Building)
                {
                    Cause = new ArgumentOutOfRangeException(),
                    FilePath = json.Path,
                    IsWarning = false,
                    Message = "'warningLevel': value must be an element of [0;4]."
                });
            AddIfNotNull(SetJsonValue(json, "outputName", ref outputName, Building.OriginName), errors);

            return errors;
        }
Esempio n. 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        /// <remarks>Recursive.</remarks>
        bool CheckCircularModRef(ModInfo info)
        {
            for (int i = 0; i < info.modReferences.Length; i++)
            {
                List<string> temp = new List<string>(circularPath);

                if (CheckCircularModRefRec(info.modReferences[i]))
                    return true;

                circularPath = temp; // reset; no circular things were found there
            }

            return false;
        }