Esempio n. 1
0
        static ModCompiler CreateMod()
        {
            ModCompiler mc = new ModCompiler();

            ModData md = new ModData(mc);

            md.Assembly = Assembly.GetExecutingAssembly();
            md.Info = new ModInfo(mc);
            md.Info.author = "PoroCYon";
            md.Info.displayName = "Test Mod";
            md.Info.includePDB = true;
            md.Info.internalName = "TestMod";
            md.Info.info = "Mod meant to test the MCT Tools";
            md.OriginName = "TestMod";
            md.OriginPath = Directory.GetCurrentDirectory() + "\\TestMod";

            md.items.Add(new Item(mc)
            {
                internalName = "TestMod:TestItem",
                displayName = "Test Item",
                maxStack = 999,
                rare = 2,
                recipes = new List<Recipe>()
                {
                    new Recipe(mc)
                    {
                        creates = 3,
                        items = new Dictionary<string, int>()
                        {
                            { "g:Wood"          , 5 },
                            { "TestMod:TestItem", 1 }
                        },
                        tiles = new List<string>()
                        {
                            "Work Bench"
                        }
                    }
                },
                value = 50
            });

            return mc;
        }
Esempio n. 2
0
 public BuildLogger(ModData md)
 {
     building = md;
 }
Esempio n. 3
0
        IEnumerable<CompilerError> ClearFolders(ModData mod)
        {
            List<CompilerError> errors = new List<CompilerError>();

            List<string> toRemove = new List<string>();

            foreach (string key in mod.Files.Keys)
            {
                if (key.Contains(BIN) || key.Contains(OBJ) || key.Contains(DEBUG) || key.Contains(RELEASE) || key.Contains(IPCH) ||
                        key.Contains(GIT) || key.Contains(SVN) || key.Contains(SLN_IDE) || key.Contains(VS) ||
                        key.EndsWith(SDF) || key.EndsWith(O_SDF) || key.EndsWith(SUO) || key.EndsWith(USER) || key.EndsWith(CACHE) ||
                        key.EndsWith(GIT_IGN) || key.EndsWith(GIT_ATTR) || key.EndsWith(DB))
                    toRemove.Add(key);

                else if (!File.Exists(mod.OriginPath))
                {
                    foreach (string ignore in mod.Info.ignore)
                    {
                        try
                        {
                            foreach (string d in Directory.EnumerateFiles(mod.OriginPath, ignore, SearchOption.AllDirectories))
                                if (d.Substring(mod.OriginPath.Length) == key)
                                    toRemove.Add(d);
                        }
                        catch (Exception e)
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                Cause = e,
                                FilePath = mod.OriginPath,
                                IsWarning = false,
                                Message = "Error when searching for files to exclude."
                            });
                        }
                        try
                        {
                            foreach (string d in Directory.EnumerateDirectories(mod.OriginPath, ignore, SearchOption.AllDirectories))
                                if (d.Substring(mod.OriginPath.Length) == Path.GetDirectoryName(key))
                                    toRemove.Add(d);
                        }
                        catch (Exception e)
                        {
                            errors.Add(new CompilerError(Building)
                            {
                                Cause = e,
                                FilePath = mod.OriginPath,
                                IsWarning = false,
                                Message = "Error when searching for direcries to exclude."
                            });
                        }
                    }
                }
            }

            foreach (string r in toRemove)
                mod.files.Remove(r);

            return errors;
        }
Esempio n. 4
0
        CompilerOutput MainCompileStuff(ModData mod, Assembly asm)
        {
            if (asm == null)
                return null;

            mod.Assembly = asm;

            List<CompilerError> errors = new List<CompilerError>();

            Log("Checking JSON files.", MessageImportance.High);

            errors.AddRange(new Checker(this).Check());

            Log("Writing output file.", MessageImportance.High);

            errors.AddRange(new Writer (this).Write());

            CompilerOutput outp = CreateOutput(errors);
            if (outp.Succeeded)
                outp.outputFile = Mods.pathCompiled + "\\" + mod.OriginName + (mod.Info.compress ? ".tapi" : ".tapimod");

            LogResult(outp);

            EndCompile(mod.OriginPath);

            return outp;
        }
Esempio n. 5
0
        bool BeginCompile(string path)
        {
            if (!Debugger.IsAttached && AppendBuilding(path))
                return false;

            if (!Directory.Exists(Consts.MctDirectory))
                Directory.CreateDirectory(Consts.MctDirectory);

            if (!File.Exists(Consts.MctDirectory + "\\.building.json"))
                File.WriteAllText(Consts.MctDirectory + "\\.building.json", "[]");

            if (building == null)
            {
                building = new ModData(this);

                building.OriginPath = path;
                building.OriginName = Path.GetFileNameWithoutExtension(path);
            }

            modDict = GetInternalNameToPathDictionary(); // dat name

            if (!Directory.Exists(Path.GetTempPath() + "\\MCT"))
                Directory.CreateDirectory(Path.GetTempPath() + "\\MCT");

            return true;
        }
Esempio n. 6
0
        /// <summary>
        /// Compiles a mod from a managed assembly.
        /// </summary>
        /// <param name="asm">The assembly to compile.</param>
        /// <returns>The output of the compiler.</returns>
        public CompilerOutput CompileFromAssembly(Assembly asm)
        {
            for (int i = 0; i < Loggers.Count; i++)
                Loggers[i].compiler_wr = new WeakReference<ModCompiler>(this);

            Log("Compiling assembly " + asm, MessageImportance.Normal);

            if (building == null)
            {
                building = new ModData(this);

                building.OriginPath = asm.Location;
                building.OriginName = Path.GetFileNameWithoutExtension(asm.Location);
            }

            if (!BeginCompile(asm.Location))
            {
                Exception cause;
                LogError(cause = new CompilerException("Mod already building!"));

                CompilerOutput o;
                LogResult(o = CreateOutput(new List<CompilerError>()
                {
                    new CompilerError(building)
                    {
                        Cause = cause,
                        FilePath = asm.Location,
                        IsWarning = true,
                        Message = "The mod is already being built."
                    }
                }));

                return o;
            }

            try
            {
                CompilerOutput outp;

                Log("Extracting files.", MessageImportance.High);

                var extracted = new Extractor(this).ExtractData(asm);
                outp = CreateOutput(extracted.Item3);
                if (!outp.Succeeded)
                {
                    LogResult(outp);
                    EndCompile(asm.Location);
                    return outp;
                }

                Log("Validating JSONs.", MessageImportance.High);

                outp = Validate(extracted.Item1, extracted.Item2, true);
                if (!outp.Succeeded)
                {
                    LogResult(outp);
                    EndCompile(asm.Location);
                    return outp;
                }

                return MainCompileStuff(building, asm);
            }
            catch (Exception e)
            {
                EndCompile(asm.Location);

                LogError(e, "Unexpected error.");

                CompilerOutput o;
                LogResult(o = CreateOutput(new List<CompilerError>()
                {
                    new CompilerError(building)
                    {
                        Cause = e,
                        FilePath = asm.Location,
                        IsWarning = false,
                        Message = "An unexpected error occured while compiling."
                    }
                }));

                return o;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Compiles a mod from a managed assembly.
        /// </summary>
        /// <param name="assemblyPath">The path to the assembly file, either relative to the working directory or an absolute path.</param>
        /// <returns>The output of the compiler.</returns>
        public CompilerOutput CompileFromAssembly(string assemblyPath)
        {
            for (int i = 0; i < Loggers.Count; i++)
                Loggers[i].compiler_wr = new WeakReference<ModCompiler>(this);

            assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);

            Log("Compiling assembly from path " + assemblyPath, MessageImportance.Normal);

            building = new ModData(this);

            building.OriginPath = assemblyPath;
            building.OriginName = Path.GetFileNameWithoutExtension(assemblyPath);

            if (!BeginCompile(assemblyPath))
            {
                Exception cause;
                LogError(cause = new CompilerException("Mod already building!"));

                CompilerOutput o;
                LogResult(o = CreateOutput(new List<CompilerError>()
                {
                    new CompilerError(building)
                    {
                        Cause = cause,
                        FilePath = assemblyPath,
                        IsWarning = true,
                        Message = "The mod is already being built."
                    }
                }));

                return o;
            }

            try
            {
                #region check if file exists
                if (!File.Exists(assemblyPath))
                {
                    CompilerOutput o;
                    LogResult(o = new CompilerOutput()
                    {
                        Succeeded = false,
                        errors = new List<CompilerError>()
                        {
                            new CompilerError(building)
                            {
                                Cause = new FileNotFoundException("File '" + assemblyPath + "' not found."),
                                Message = "The assembly '" + assemblyPath + "' was not found."
                            }
                        }
                    });

                    return o;
                }
                #endregion

                Assembly asm;

                try
                {
                    asm = Assembly.LoadFile(assemblyPath);
                }
                #region check if assembly is valid
                catch (BadImageFormatException e)
                // if (e is BadImageFormatException || e is DllNotFoundException || e is InvalidProgramException || e is TypeLoadException)
                {
                    LogError(e);

                    CompilerOutput o;
                    LogResult(o = new CompilerOutput()
                    {
                        Succeeded = false,
                        errors = new List<CompilerError>()
                        {
                            new CompilerError(building)
                            {
                                Cause = e,
                                Message = "The assembly is not a manged assembly -or- is not compiled with the x86 architecture.",
                                FilePath = assemblyPath
                            }
                        }
                    });

                    return o;
                }
                catch (Exception e)
                {
                    LogError(e);

                    CompilerOutput o;
                    LogResult(o = new CompilerOutput()
                    {
                        Succeeded = false,
                        errors = new List<CompilerError>()
                        {
                            new CompilerError(building)
                            {
                                Cause = e,
                                Message = "The assembly could not be loaded.",
                                FilePath = assemblyPath
                            }
                        }
                    });

                    return o;
                }
                #endregion

                return CompileFromAssembly(asm);
            }
            catch (Exception e)
            {
                LogError(e, "Unexpected error.");

                EndCompile(assemblyPath);

                CompilerOutput o;
                LogResult(o = CreateOutput(new List<CompilerError>()
                {
                    new CompilerError(building)
                    {
                        Cause = e,
                        FilePath = assemblyPath,
                        IsWarning = false,
                        Message = "An unexpected error occured while compiling."
                    }
                }));

                return o;
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Compiles a mod from its source folder.
        /// </summary>
        /// <param name="folder">The mod's folder. Either an absolute path,
        /// relative to the working directory or the name of a folder in the Mods\Sources folder</param>
        /// <returns>The output of the compiler.</returns>
        public CompilerOutput CompileFromSource  (string folder)
        {
            for (int i = 0; i < Loggers.Count; i++)
                Loggers[i].compiler_wr = new WeakReference<ModCompiler>(this);

            folder = Environment.ExpandEnvironmentVariables(folder);

            if (folder.EndsWith("\\"))
                folder = folder.Remove(folder.Length - 1);

            if (folder[1] != ':' && !folder.StartsWith("\\")) // <drive>:\path or \\ServerName\path
                // if the folder doesn't exist, it's maybe a folder in the Mods\Sources directory?
                if (!Directory.Exists(folder))
                    folder = Mods.pathSources + "\\" + folder;
                else
                    folder = Path.GetFullPath(folder);

            Log("Compiling source " + folder, MessageImportance.Normal);

            building = new ModData(this);

            try
            {
                building.OriginPath = folder;
                building.OriginName = Path.GetFileName(folder);

                if (!BeginCompile(folder))
                {
                    Exception cause;
                    LogError(cause = new CompilerException("Mod already building!"));

                    CompilerOutput o;
                    LogResult(o = CreateOutput(new List<CompilerError>()
                    {
                        new CompilerError(building)
                        {
                            Cause = cause,
                            FilePath = folder,
                            IsWarning = true,
                            Message = "The mod is already being built."
                        }
                    }));

                    return o;
                }

                #region check if folder exists
                if (!Directory.Exists(folder))
                {
                    EndCompile(folder);

                    Exception cause;
                    LogError(cause = new DirectoryNotFoundException("Directory '" + folder + "' not found."));

                    CompilerOutput o;
                    LogResult(o = new CompilerOutput()
                    {
                        Succeeded = false,
                        errors = new List<CompilerError>()
                        {
                            new CompilerError(building)
                            {
                                Cause = cause,
                                Message = "The mod directory (" + folder + ") was not found",
                                IsWarning = false,
                                FilePath = folder
                            }
                        }
                    });

                    return o;
                }
                #endregion

                CompilerOutput outp;

                Log("Loading files.", MessageImportance.High);

                var readFiles = new FileLoader(this).LoadFiles(folder);
                outp = CreateOutput(readFiles.Item3);
                if (!outp.Succeeded)
                {
                    LogResult (outp  );
                    EndCompile(folder);
                    return outp;
                }

                Log("Validating JSONs.", MessageImportance.High);

                outp = Validate(readFiles.Item1, readFiles.Item2, true);
                if (!outp.Succeeded)
                {
                    LogResult (outp  );
                    EndCompile(folder);
                    return outp;
                }

                Log("Building sources.", MessageImportance.High);

                var compiled = new Builder(this).Build();
                outp = CreateOutput(compiled.Item3);
                outp.Succeeded &= compiled.Item1 != null;
                if (!outp.Succeeded)
                {
                    LogResult (outp  );
                    EndCompile(folder);
                    return outp;
                }

                return MainCompileStuff(building, compiled.Item1);
            }
            catch (Exception e)
            {
                LogError(e, "Unexpected error.");

                EndCompile(folder);

                CompilerOutput o;
                LogResult(o = CreateOutput(new List<CompilerError>()
                {
                    new CompilerError(building)
                    {
                        Cause     = e,
                        FilePath  = folder,
                        IsWarning = false,
                        Message   = "An unexpected error occured while compiling."
                    }
                }));

                return o;
            }
        }
 /// <summary>
 /// Creates a new instance of the <see cref="CompilerError" /> class.
 /// </summary>
 /// <param name="built">The mod that was being built.</param>
 public CompilerError(ModData built)
 {
     data = built;
 }
        /// <summary>
        /// Compiles all source files of the mod into a managed assembly.
        /// </summary>
        /// <param name="mod">The mod to compile.</param>
        /// <returns>
        /// A tuple containing the built assembly (null if failed), and a collection of all errors.
        /// The assembly must be saved on the disk, because the .pdb file must be loaded afterwards.
        /// </returns>
        public Tuple<Assembly, IEnumerable<CompilerError>> Compile(ModData mod)
        {
            Mod = mod;

            List<CompilerError> errors = new List<CompilerError>();

            CodeDomProvider cdp = CreateCompiler();

            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = false;
            cp.IncludeDebugInformation = mod.Info.includePDB;
            cp.OutputAssembly = Path.GetTempPath() + "MCT\\" + mod.Info.internalName + ".dll";
            cp.WarningLevel = mod.Info.warningLevel;

            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.Game.dll");
            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Graphics.dll");
            cp.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Xact.dll");

            cp.ReferencedAssemblies.AddRange(LanguageDependancyAssemblies);

            cp.ReferencedAssemblies.Add("tAPI.exe"); // hmm hmm hmm

            cp.ReferencedAssemblies.AddRange(mod.Info.dllReferences);
            cp.ReferencedAssemblies.AddRange(mod.Info.modReferences);

            for (int i = 0; i < mod.Info.modReferences.Length; i++)
                try
                {
                    cp.ReferencedAssemblies.AddRange(WriteRefAssembliesRec(mod.Info).ToArray());
                }
                catch (Exception e)
                {
                    errors.Add(new CompilerError(Building)
                    {
                        Cause = e,
                        FilePath = Path.GetTempPath() + "MCT\\" + mod.Info.modReferences[i] + ".dll",
                        IsWarning = false,
                        Message = "Something went wrong when extracting the mod's assembly. See the exception for more details."
                    });
                }

            ModifyCompilerParameters(cp);

            var files = GetFiles();

            for (int i = 0; i < files.Length; i++)
                files[i] = mod.OriginPath + "\\" + files[i].Replace('/', '\\');

            CompilerResults cr = cdp.CompileAssemblyFromFile(cp, files);

            foreach (CodeDomError ce in cr.Errors)
                errors.Add(new CompilerError(Building)
                {
                    Cause = new CompilerException(ce.ErrorNumber),
                    FilePath = ce.FileName,
                    IsWarning = ce.IsWarning,
                    LocationInFile = new Point(ce.Column, ce.Line),
                    Message = (ce.IsWarning ? "Warning" : "Error") + " " + ce.ErrorNumber + ": " + ce.ErrorText,
                });

            return new Tuple<Assembly, IEnumerable<CompilerError>>(cr.Errors.HasErrors ? null : cr.CompiledAssembly, errors);
        }