Exemplo n.º 1
0
        public static CompilerException Compile(string modDirectory, string outputDirectory)
        {
            CommonToolUtilities.RefreshHashes();

            string modName = Path.GetDirectoryName(modDirectory);

            string jsonFile, modInfo;

            CodeDomProvider cdcp = new CSharpCodeProvider();
            string          ext  = "*.cs";

            #region validating ModInfo.json
            jsonFile = modDirectory + "\\ModInfo.json";

            if (!File.Exists(jsonFile))
            {
                File.WriteAllText(jsonFile, "{\"name\":\"" + modName + "\",\"author\":\"<unknown>\"}");
                Console.WriteLine("Warning: You do not have a ModInfo.json file.\n\tUsing the default ModInfo...");
            }

            try
            {
                JsonData json = JsonMapper.ToObject(File.ReadAllText(jsonFile));

                if (!json.Has("name"))
                {
                    throw new CompilerException("Missing ModInfo filed 'name'");
                }
                else
                {
                    modName = (string)json["name"];
                }

                if (!json.Has("author"))
                {
                    throw new CompilerException("Missing ModInfo filed 'author'");
                }

                if (json.Has("code"))
                {
                    JsonData jCode = json["code"];
                    if (jCode.Has("codeType"))
                    {
                        switch (jCode["codeType"].ToString().ToLower().Trim())
                        {
                        case "vb":
                        case "vb.net":
                        case "basic":
                        case "basic.net":
                        case "vbasic":
                        case "vbasic.net":
                        case "visualbasic":
                        case "visualbasic.net":
                        case "visual basic":
                        case "visual basic.net":
                            cdcp = new VBCodeProvider();
                            ext  = "*.vb";
                            Console.WriteLine("Using Visual Basic.NET (VBCodeDomProvider)...");
                            break;

                        case "js":
                        case "js.net":
                        case "jscript":
                        case "jscript.net":
                        case "javascript":
                        case "javascript.net":
                            cdcp = new JScriptCodeProvider();
                            ext  = "*.js";
                            Console.WriteLine("Using JScript.NET (JScriptCodeProvider)...");
                            break;

                        case "cs":
                        case "c#":
                        case "csharp":
                        case "visual cs":
                        case "visual c#":
                        case "visual csharp":
                            // inited as C#
                            Console.WriteLine("Using C# (CSharpCodeProvider)...");
                            break;

                        default:
                            Console.WriteLine("Language not explicitely defined, using C# (CSharpCodeProvider)...");
                            break;
                        }
                    }
                }

                //if (!json.Has("version"))
                //    throw new CompileException("Missing ModInfo field 'version'");
                //if (!json.Has("info"))
                //    throw new CompileException("Missing ModInfo field 'info'");

                modInfo = (string)json;
            }
            catch (Exception e)
            {
                throw new CompilerException("Invalid file: ModInfo.json", e);
            }
            #endregion

            #region compile the code
            List <string> toCompile = new List <string>();
            foreach (string file in Directory.EnumerateFiles(modDirectory, ext, SearchOption.AllDirectories))
            {
                toCompile.Add(file);
            }

            CompilerParameters cp = new CompilerParameters()
            {
                GenerateExecutable = false,
                GenerateInMemory   = false,

                OutputAssembly = outputDirectory + "\\" + modName + ".tapimod"
            };

            string
                xna = Environment.GetEnvironmentVariable("XNAGSv4") + "\\References\\Windows\\x86\\",
                wpf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
                      + "\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0\\Profile\\Client\\",
                here = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            cp.ReferencedAssemblies.Add("tAPI.exe");
            cp.ReferencedAssemblies.Add("Microsoft.JScript.dll");
            cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
            cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");

            cp.ReferencedAssemblies.Add("Accessibility.dll");
            cp.ReferencedAssemblies.Add("mscorlib.dll");
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Core.dll");
            cp.ReferencedAssemblies.Add("System.Drawing.dll");
            cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            cp.ReferencedAssemblies.Add("System.Numerics.dll");
            cp.ReferencedAssemblies.Add("System.Xml.dll");

            cp.ReferencedAssemblies.Add(wpf + "PresentationCore.dll");
            cp.ReferencedAssemblies.Add(wpf + "PresentationFramework.dll");
            cp.ReferencedAssemblies.Add(wpf + "WindowsBase.dll");

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

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

            if (cr.Errors.HasErrors)
            {
                return(CompilerException.CreateException(cr.Errors));
            }
            #endregion

            #region save to .tapimod file

            /*
             * How a .tapimod file looks like:
             *
             *   - version (uint)
             *
             *   - modinfo (string)
             *
             *   - file amount (int)
             *
             *    files:
             *     - file name (string)
             *     - file data length (int)
             *
             *    files:
             *     - file data (byte[])
             *
             *   - assembly data
             */

            // VBCodeProvider automatically adds '.dll'
            string mod = outputDirectory + (cdcp is VBCodeProvider ? ".tapimod.dll" : ".tapimod");

            List <Tuple <string, byte[]> > files = new List <Tuple <string, byte[]> >();
            foreach (string fileName in Directory.EnumerateFiles(modDirectory, "*.*", SearchOption.AllDirectories))
            {
                if (!Path.GetExtension(fileName).EndsWith(ext.Substring(2)))
                {
                    files.Add(new Tuple <string, byte[]>(fileName.Substring(modDirectory.Length + 1).Replace('\\', '/'), File.ReadAllBytes(fileName)));
                }
            }

            BinBuffer bb = new BinBuffer();

            bb.Write(Constants.versionAssembly);

            bb.Write(modInfo);

            bb.Write(files.Count);
            foreach (Tuple <string, byte[]> pfile in files)
            {
                bb.Write(pfile.Item1);
                bb.Write(pfile.Item2.Length);
            }
            foreach (Tuple <string, byte[]> pfile in files)
            {
                bb.Write(pfile.Item2);
            }

            bb.Pos = 0;
            File.WriteAllBytes(cdcp is VBCodeProvider ? Path.ChangeExtension(mod, null) : mod, bb.ReadBytes(bb.GetSize()));

            // generate false hashes
            CommonToolUtilities.AddHashes(modName, modDirectory);
            #endregion

            return(null);
        }
Exemplo n.º 2
0
        public static void Decompile(string modFile)
        {
            CommonToolUtilities.RefreshHashes();

            string
                modName    = Path.GetFileNameWithoutExtension(modFile),
                decompPath = ModDecompiler.decompDir + "\\" + modName;

            // might be a good idea
            if (!Directory.Exists(decompPath))
            {
                Directory.CreateDirectory(decompPath);
            }

            // where to store file data
            List <Tuple <string, byte[]> > files   = new List <Tuple <string, byte[]> >();
            List <Tuple <string, int> >    reading = new List <Tuple <string, int> >();

            // load data into buffer
            BinBuffer bb = new BinBuffer(new BinBufferByte(File.ReadAllBytes(modFile)));

            // first 4 bytes is the version
            uint versionAssembly = bb.ReadUInt();

            // write tAPI version
            if (!File.Exists(decompPath + "\\tAPI r" + versionAssembly))
            {
                File.Create(decompPath + "\\tAPI r" + versionAssembly);
            }

            // write modinfo
            File.WriteAllText(decompPath + "\\ModInfo.json", bb.ReadString());

            // get file amount
            int filesNum = bb.ReadInt();

            // read file name + length
            while (filesNum-- > 0)
            {
                reading.Add(new Tuple <string, int>(bb.ReadString(), bb.ReadInt()));
            }

            // read file data
            foreach (Tuple <string, int> read in reading)
            {
                files.Add(new Tuple <string, byte[]>(read.Item1, bb.ReadBytes(read.Item2)));
            }

            // write files
            foreach (Tuple <string, byte[]> pfile in files)
            {
                if (!Directory.Exists(Path.GetDirectoryName(decompPath + "\\" + pfile.Item1)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(decompPath + "\\" + pfile.Item1));
                }
                File.WriteAllBytes(decompPath + "\\" + pfile.Item1, pfile.Item2);
            }

            // write assembly
            File.WriteAllBytes(decompPath + "\\" + modName + ".dll", bb.ReadBytes(bb.BytesLeft()));

            CommonToolUtilities.RefreshHashes();
        }
Exemplo n.º 3
0
        public static void Compile(string dllFile)
        {
            CommonToolUtilities.RefreshHashes();

            #region setup
            string
                modName = Path.GetFileNameWithoutExtension(dllFile),
                modPath = CommonToolUtilities.modsSrcDir + "\\" + modName,
                modFile = CommonToolUtilities.modsBinDir + "\\" + modName + ".tapimod";

            if (File.Exists(modFile))
            {
                File.Delete(modFile);
            }

            Assembly asm = Assembly.LoadFrom(dllFile);

            List <Tuple <string, byte[]> > files = new List <Tuple <string, byte[]> >();
            #endregion

            string modInfo = null;

            #region load all resources into the list
            foreach (string res in asm.GetManifestResourceNames())
            {
                using (Stream stream = asm.GetManifestResourceStream(res))
                {
                    MemoryStream ms = new MemoryStream();
                    stream.CopyTo(ms);

                    bool foundExt = false;
                    int  index    = 0;

                    for (int i = res.Length - 1; i >= 0; i--)
                    {
                        // find file name
                        if (res[i] == '.')
                        {
                            if (foundExt)
                            {
                                index = i + 1;
                                break;
                            }
                            else
                            {
                                foundExt = true;
                            }
                        }
                    }

                    // not putting ModInfo.json in it
                    if (res.Substring(index) != "ModInfo.json")
                    {
                        files.Add(new Tuple <string, byte[]>(res.Substring(index), ms.ToArray()));
                    }
                    else
                    {
                        StreamReader r = new StreamReader(new MemoryStream(ms.ToArray()));
                        modInfo = r.ReadToEnd();

                        if (modInfo == null)
                        {
                            modInfo = "{\n\t\"displayName\": \"" + modName + "\",\n\t\"author\": \"<unknown>\"\n\t\"info\": \"\"\n}";
                        }
                        else
                        {
                            try
                            {
                                JsonData j = JsonMapper.ToObject(modInfo);

                                if (!j.Has("displayName") || !j.Has("author"))
                                {
                                    modInfo = "{\n\t\"displayName\": \"" + modName + "\",\n\t\"author\": \"<unknown>\"\n\t\"info\": \"\"\n}";
                                }
                            }
                            catch (JsonException) // invalid JSON thrown in JsonMapper.ToObject
                            {
                                modInfo = "{\n\t\"displayName\": \"" + modName + "\",\n\t\"author\": \"<unknown>\"\n\t\"info\": \"\"\n}";
                            }
                        }

                        r.Close();
                    }
                    ms.Dispose();
                }
            }
            #endregion

            File.Copy(dllFile, modFile);

            #region write data
            BinBuffer bb = new BinBuffer();

            // write version
            bb.Write(Constants.versionAssembly);

            // write modinfo
            bb.Write(modInfo);

            // write file name + length
            bb.Write(files.Count);
            foreach (Tuple <string, byte[]> pfile in files)
            {
                bb.Write(pfile.Item1);
                bb.Write(pfile.Item2.Length);
            }

            // write file data
            foreach (Tuple <string, byte[]> pfile in files)
            {
                bb.Write(pfile.Item2);
            }

            // write assembly
            bb.Write(File.ReadAllBytes(dllFile));

            // reset
            bb.Pos = 0;

            // write it all to the .tapimod file
            File.WriteAllBytes(modFile, bb.ReadBytes(bb.GetSize()));
            #endregion

            #region generate false folders & files to foul the hash checker, and generate hashes
            // not checked anymore in r4

            /*if (!Directory.Exists(modPath))
             *  Directory.CreateDirectory(modPath);
             *
             * // get info to write to modinfo.cs
             * JsonData jModInfo = JsonMapper.ToObject(modInfo);
             *
             * string actualModName = modName;
             * string codeModBaseName = "TAPI." + actualModName + ".ModBase";
             *
             * if (jModInfo.Has("name"))
             *  codeModBaseName = "TAPI." + (actualModName = (string)jModInfo["name"]) + ".ModBase";
             *
             * if (jModInfo != null && jModInfo.Has("code") && jModInfo["code"].Has("modBaseName"))
             *  codeModBaseName = (string)jModInfo["code"]["modBaseName"];
             *
             * // get namespace (and modbase class name)
             * string[] nsSplit = codeModBaseName.Split('.');
             *
             * string @namespace = nsSplit[0];
             * for (int i = 1; i < nsSplit.Length - 1; i++)
             *  @namespace += "." + nsSplit[i];
             *
             * // kinda crucial
             * using (FileStream fs = new FileStream(modPath + "\\" + nsSplit[nsSplit.Length - 1] + ".cs", FileMode.Create))
             * {
             *  using (StreamWriter bw = new StreamWriter(fs))
             *  {
             *      bw.Write(
             *              "using System;\n" +
             *              "using TAPI;\n" +
             *              "\n" +
             *              "namespace " + @namespace + "\n" +
             *              "{\n" +
             *              "    public class " + nsSplit[nsSplit.Length - 1] + " : TAPI.ModBase\n" +
             *              "    {\n" +
             *              "        public " + nsSplit[nsSplit.Length - 1] + "() : base() { }\n" +
             *              "    }\n" +
             *              "}\n"
             *          );
             *  }
             * }
             *
             * // write modinfo
             * File.WriteAllText(modPath + "\\ModInfo.json", modInfo);
             *
             * // write .dll file, you'll never know if...
             * File.Copy(dllFile, modPath + "\\" + Path.GetFileName(dllFile), true);
             *
             * CommonToolUtilities.AddHashes(modName, modPath);*/
            #endregion
        }