Beispiel #1
0
        public void Create(ProgressHandler progress)
        {
            string modFilePath = GetFolderPath() + System.IO.Path.DirectorySeparatorChar + "Mod" + System.IO.Path.DirectorySeparatorChar + this.ID + ".dll";
            if (!System.IO.File.Exists(modFilePath))
            {
                Debug.Log("Mod: "+ID, "Couldn't find the compiled mod dll at \""+modFilePath+"\".", Debug.Type.ERROR);
                SetProgress(progress, "Error.FileNotFound");
                return;
            }

            string modInfoPath = GetFolderPath() + System.IO.Path.DirectorySeparatorChar + "ModInfo.xml";
            if (!System.IO.File.Exists(modInfoPath))
            {
                Debug.Log("Mod: "+ID, "Couldn't find the mod configuration at \""+modInfoPath+"\".", Debug.Type.ERROR);
                SetProgress(progress, "Error.FileNotFound");
                return;
            }

            string libraryFolder = Game.ModLibrary.GetLibraryFolder();
            string baseModLibPath = libraryFolder + System.IO.Path.DirectorySeparatorChar + "BaseModLib.dll";

            if (!System.IO.File.Exists(baseModLibPath))
            {
                Debug.Log("Mod: "+ID, "Couldn't find BaseModLib.dll at \""+baseModLibPath+"\".", Debug.Type.ERROR);
                SetProgress(progress, "Error.FileNotFound");
                return;
            }

            ModuleDefinition modModule;
            ModuleDefinition baseModLib;
            try
            {
                SetProgress(progress, 0f, "Preparing");
                baseModLib = ModuleDefinition.ReadModule(baseModLibPath);
                SetProgress(progress, 5f);
                modModule = ModuleDefinition.ReadModule(modFilePath);
                SetProgress(progress, 10f);
            }
            catch (Exception e)
            {
                Debug.Log("Mod: "+ID, "One of the assemblies is corrupted: "+e.ToString(), Debug.Type.ERROR);
                SetProgress(progress, "Error.CorruptAssembly");
                return;
            }

            Mod mod = new Mod(this.Game, "");
            mod.header = new Mod.Header(mod, System.IO.File.ReadAllText(modInfoPath));
            mod.module = modModule;
            MemoryStream stream = new MemoryStream();
            mod.module.Write(stream);
            stream.Position = 0;
            mod.originalModule = ModuleDefinition.ReadModule(stream);

            SetProgress(progress, 15f);

            try
            {
                Dictionary<MethodReference, MethodReference> baseModLibRemap = new Dictionary<MethodReference, MethodReference>();
                foreach (TypeDefinition baseModLibType in baseModLib.Types)
                {
                    foreach (MethodDefinition method in baseModLibType.Methods)
                    {
                        if (method.HasCustomAttributes && method.CustomAttributes[0].AttributeType.Name == "AddModname")
                        {
                            foreach (MethodDefinition method2 in baseModLibType.Methods)
                            {
                                if (!method2.HasCustomAttributes && method2.Name == method.Name && method2.Parameters.Count > method.Parameters.Count)
                                {
                                    bool add = true;
                                    for (int i = 0; i < method.Parameters.Count; i++)
                                    {
                                        ParameterDefinition param = method.Parameters[i];
                                        if (param.ParameterType.FullName != method2.Parameters[i].ParameterType.FullName)
                                            add = false;
                                    }
                                    if (add)
                                    {
                                        baseModLibRemap.Add(method, method2);
                                    }
                                }
                            }
                        }
                    }
                }
                SetProgress(progress, 20f, "FetchingTypes");

                Dictionary<string, string> injectableClasses = new Dictionary<string, string>();
                Dictionary<string, Dictionary<string, TypeDefinition>> assemblyTypes = new Dictionary<string, Dictionary<string, TypeDefinition>>();

                for (int i = 0; i < Game.GameConfiguration.IncludeAssemblies.Count; i++)
                {
                    string assembly = libraryFolder + System.IO.Path.DirectorySeparatorChar + Game.ParsePath(Game.GameConfiguration.IncludeAssemblies[i]);
                    ModuleDefinition module = ModuleDefinition.ReadModule(assembly);
                    string key = System.IO.Path.GetFileNameWithoutExtension(assembly);
                    assemblyTypes.Add(key, new Dictionary<string, TypeDefinition>());
                    foreach (TypeDefinition type in module.Types)
                    {
                        if (!ModLib.CheckName(type.Namespace, Game.GameConfiguration.ExcludeNamespaces) && !ModLib.CheckName(type.FullName, Game.GameConfiguration.ExcludeTypes) && !ModLib.CheckName(type.FullName, Game.GameConfiguration.NoFamily))
                        {
                            assemblyTypes[key].Add(type.FullName, type);
                            if (!injectableClasses.ContainsKey(type.FullName))
                            {
                                injectableClasses.Add(type.FullName, key);
                            }
                        }
                    }
                    SetProgress(progress, 20f + ((float)i / (float)Game.GameConfiguration.IncludeAssemblies.Count) * 30f);
                }

                SetProgress(progress, 50f, "ConvertingClasses");
                Dictionary<string, TypeDefinition> newClasses = new Dictionary<string, TypeDefinition>();
                for (int i = 0; i < modModule.Types.Count; i++)
                {
                    TypeDefinition type = modModule.Types[i];
                    if (type.FullName == "<Module>")
                        continue;

                    foreach (MethodDefinition method in type.Methods)
                    {
                        if (method != null && method.Body != null)
                        {
                            for (int j = 0; j < method.Body.Instructions.Count; j++)
                            {
                                ILProcessor methodIL = method.Body.GetILProcessor();

                                Instruction instruction = method.Body.Instructions[j];
                                if (instruction.OpCode == OpCodes.Call && instruction.Operand != null)
                                {
                                    foreach (KeyValuePair<MethodReference, MethodReference> map in baseModLibRemap)
                                    {
                                        if (((MethodReference)instruction.Operand).FullName == map.Key.FullName)
                                        {
                                            instruction.Operand = type.Module.Import(map.Value);
                                            Instruction newInstruction = methodIL.Create(OpCodes.Ldstr, ID);
                                            methodIL.InsertBefore(instruction, newInstruction);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    string assemblyName = "";
                    if (type.BaseType != null && injectableClasses.ContainsKey(type.BaseType.FullName))
                        assemblyName = injectableClasses[type.BaseType.FullName];
                    if (assemblyName == "" || !assemblyTypes[assemblyName].ContainsKey(type.BaseType.FullName))
                    {
                        Mod.Header.AddClass addClass = new Mod.Header.AddClass(mod);
                        addClass.Type = type;
                        mod.header.AddAddClass(addClass);
                    }
                    else
                    {
                        foreach (Mono.Cecil.FieldDefinition field in type.Fields)
                        {
                            Mod.Header.AddField addField = new Mod.Header.AddField(mod);
                            addField.Field = field;
                            addField.AssemblyName = assemblyName;
                            mod.header.AddAddField(addField);
                        }
                        foreach (MethodDefinition method in type.Methods)
                        {
                            if (method == null) continue;
                            int priority = int.MaxValue;

                            if (method.CustomAttributes != null)
                            {
                                foreach (CustomAttribute attribute in method.CustomAttributes)
                                {
                                    if (attribute.AttributeType.Name == "Priority")
                                    {
                                        priority = (int)attribute.ConstructorArguments[0].Value;
                                    }
                                }
                            }

                            bool inject = false;

                            if (method.IsVirtual || method.IsStatic || method.IsConstructor)
                            {
                                foreach (MethodDefinition _m in assemblyTypes[assemblyName][type.BaseType.FullName].Methods)
                                {
                                    if (_m.Name == method.Name)
                                    {
                                        if ((_m.IsStatic && method.IsStatic) || (_m.IsConstructor && method.IsConstructor))
                                        {
                                            if (method.Parameters.Count == _m.Parameters.Count)
                                            {
                                                bool ok = true;
                                                for (int pi = 0; pi < _m.Parameters.Count; pi++)
                                                {
                                                    ParameterDefinition param = _m.Parameters[pi];
                                                    if (param.ParameterType.FullName != method.Parameters[pi].ParameterType.FullName)
                                                    {
                                                        ok = false;
                                                        break;
                                                    }
                                                }
                                                if (ok)
                                                {
                                                    inject = true;
                                                }
                                            }
                                        }
                                        else if (!_m.IsStatic && !method.IsStatic)
                                            inject = true;
                                        break;
                                    }
                                }
                            }

                            if (inject)
                            {
                                Mod.Header.InjectInto injectInto = new Mod.Header.InjectInto(mod);
                                injectInto.Method = method;
                                injectInto.Priority = priority;
                                injectInto.AssemblyName = assemblyName;
                                mod.header.AddInjectInto(injectInto);
                            }
                            else
                            {
                                Mod.Header.AddMethod addMethod = new Mod.Header.AddMethod(mod);
                                addMethod.Method = method;
                                addMethod.AssemblyName = assemblyName;
                                mod.header.AddAddMethod(addMethod);
                            }
                        }
                    }
                    SetProgress(progress, 50f + ((float)i / (float)modModule.Types.Count) * 30f);
                }

                foreach (AssemblyNameReference aref in modModule.AssemblyReferences)
                {
                    if (aref.Name == "mscorlib" || aref.Name == "System")
                    {
                        aref.Version = new System.Version("2.0.0.0");
                        aref.PublicKeyToken = new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 };
                    }
                    if (aref.Name == "System.Core")
                    {
                        aref.Version = new System.Version("3.5.0.0");
                        aref.PublicKeyToken = new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 };
                    }
                    if (aref.Name == "System.Xml")
                    {
                        aref.Version = new System.Version("2.0.0.0");
                        aref.PublicKeyToken = new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 };
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Log("Mod: "+ID, "An unexpected error occured while parsing the assembly: "+e.ToString(), Debug.Type.ERROR);
                SetProgress(progress, "Error.UnexpectedError");
                return;
            }

            string modResourcesPath = GetFolderPath() + System.IO.Path.DirectorySeparatorChar + "Resources/";
            if (!System.IO.Directory.Exists(modResourcesPath))
            {
                System.IO.Directory.CreateDirectory(modResourcesPath);
            }
            if (System.IO.Directory.GetFiles(modResourcesPath).Length > 0 || System.IO.Directory.GetDirectories(modResourcesPath).Length > 0)
            {
                ZipFile newZipFile = new ZipFile();
                newZipFile.AddDirectory(modResourcesPath);
                newZipFile.Comment = "Automaticlly created resources zip file.";
                mod.Resources = newZipFile;
            }

            try
            {
                SetProgress(progress, 90f, "SavingMod");

                string modFolder = System.IO.Path.GetFullPath(Configuration.GetPath("mods") + System.IO.Path.DirectorySeparatorChar + Game.GameConfiguration.ID);

                if (!System.IO.Directory.Exists(modFolder))
                    System.IO.Directory.CreateDirectory(modFolder);

                mod.FileName = System.IO.Path.GetFullPath(modFolder + System.IO.Path.DirectorySeparatorChar + mod.UniqueID + ".mod");
                if (mod.Save())
                {
                    string key = mod.ID + "-" + mod.header.GetVersion();
                    if (Mod.Mods.ContainsKey(key))
                    {
                        if (Mod.Mods[key].FileName != mod.FileName)
                            Mod.Mods[key].Remove();
                        //Mod.Mods[key] = mod;
                    }
                    /*else
                    {
                        Mod.Mods.Add(key, mod);
                    }*/
                    SetProgress(progress, 100f, "Finish");
                }
                else
                {
                    Debug.Log("Mod: "+ID, "Could not save the mod.", Debug.Type.ERROR);
                    SetProgress(progress, "Error.Save");
                }
            }
            catch (Exception e)
            {
                Debug.Log("Mod: "+ID, "An error occured while saving the mod: "+e.ToString(), Debug.Type.ERROR);
                SetProgress(progress, "Error.Save");
            }
        }
Beispiel #2
0
 internal static void Add(Mod mod, string path, Texture2D texture)
 {
     string key = mod.ID + "::" + path.ToLower();
     if (!TextureResources.ContainsKey(key))
         TextureResources.Add(key, texture);
 }
Beispiel #3
0
        public static void Initialize()
        {
            if (!Initialized)
            {
                Initialized = true;
                ModsFolder = System.IO.Path.GetFullPath(Application.dataPath + "/../Mods") + System.IO.Path.DirectorySeparatorChar;
                try
                {
                    XDocument configuration = XDocument.Load(ModsFolder + "RuntimeConfiguration.xml");
                    foreach (XElement modConfiguration in configuration.Root.Elements("Mod"))
                    {
                        try
                        {
                            Mod newMod = new Mod(modConfiguration);
                            if (newMod.ID != "")
                                Mods.Add(newMod.ID, newMod);
                            newMod.Assembly = Assembly.Load(new AssemblyName(newMod.ID));
                            ModAPI.Mods.Add(newMod);
                        }
                        catch (Exception e)
                        {
                            XAttribute idAttribute = modConfiguration.Attribute("ID");
                            string ID = "Core";
                            if (idAttribute != null) ID = idAttribute.Value;
                            Log.Write("Something went wrong while initializing a mod: " + e.ToString(), ID);
                        }
                    }

                    foreach (XElement ExecuteEveryFrame in configuration.Root.Elements("ExecuteEveryFrame"))
                    {
                        MethodInfo m = FindMethod(ExecuteEveryFrame.Value.ToString());
                        if (m != null)
                        {
                            string OnlyInGame = ExecuteEveryFrame.Attribute("OnlyInGame").Value;
                            if (OnlyInGame == "true")
                                BaseSystem.ExecuteEveryFrameInGame.Add(new Execution() { Method = m, ModID = ExecuteEveryFrame.Attribute("ModID").Value });
                            else
                                BaseSystem.ExecuteEveryFrame.Add(new Execution() { Method = m, ModID = ExecuteEveryFrame.Attribute("ModID").Value });
                        }
                        else
                        {
                            Log.Write("Could not find method for execute every frame: " + ExecuteEveryFrame.Value.ToString(), "Core");
                        }
                    }

                    foreach (XElement ExecuteOnApplicationStart in configuration.Root.Elements("ExecuteOnApplicationStart"))
                    {
                        MethodInfo m = FindMethod(ExecuteOnApplicationStart.Value.ToString());
                        if (m != null)
                        {
                            BaseSystem.ExecuteOnApplicationStart.Add(new Execution() { Method = m, ModID = ExecuteOnApplicationStart.Attribute("ModID").Value });
                        }
                        else
                        {
                            Log.Write("Could not find method for execute on application start: " + ExecuteOnApplicationStart.Value.ToString(), "Core");
                        }
                    }

                    foreach (XElement ExecuteOnGameStart in configuration.Root.Elements("ExecuteOnGameStart"))
                    {
                        MethodInfo m = FindMethod(ExecuteOnGameStart.Value.ToString());
                        if (m != null)
                        {
                            BaseSystem.ExecuteOnGameStart.Add(new Execution() { Method = m, ModID = ExecuteOnGameStart.Attribute("ModID").Value });
                        }
                        else
                        {
                            Log.Write("Could not find method for execute on game start: " + ExecuteOnGameStart.Value.ToString(), "Core");
                        }
                    }

                    WWW www = new WWW("file://" + ModsFolder + "GUI.assetbundle");
                    while (www.progress < 1)
                    {
                    }
                    if ((www.error == "" || www.error == null) && www.assetBundle != null)
                    {
                        ModAPI.GUI.Skin = (GUISkin)www.assetBundle.mainAsset;
                    }
                }
                catch (Exception e)
                {
                    Log.Write("Something went wrong while initializing: " + e.ToString(), "Core");
                }
            }
            if (SystemObject == null)
            {
                ModAPI.Log.Write(Application.loadedLevel + "", "Core");
                SystemObject = new GameObject("__ModAPISystem__"); ;
                Input.Initialize(SystemObject);
                Console.Initialize(SystemObject);
                if (SystemObject.GetComponent<BaseSystem>() == null)
                    SystemObject.AddComponent<BaseSystem>();
                if (SystemObject.GetComponent<LiveInspector>() == null)
                    SystemObject.AddComponent<LiveInspector>();

                if (Application.loadedLevel > 0)
                {
                    Execute(BaseSystem.ExecuteOnGameStart);
                }
                else
                {
                    Execute(BaseSystem.ExecuteOnApplicationStart);
                }
            }
        }
Beispiel #4
0
 public static void Add(Mod mod)
 {
     LoadedMods.Add(mod.ID, mod);
 }