/// <summary> /// Activates the given fomod. /// </summary> /// <remarks> /// This method checks to see if the given fomod could be an upgrade for another fomod. /// </remarks> /// <param name="mod">The fomod to activate.</param> private void ActivateFomod(fomod mod) { var booFound = false; foreach (ListViewItem lviFomod in lvModList.Items) { var fomodMod = (fomod)lviFomod.Tag; if (fomodMod.ModName.Equals(mod.ModName) && fomodMod.IsActive && !fomodMod.BaseName.Equals(mod.BaseName)) { //ask to do upgrade var strUpgradeMessage = "A different version of {0} has been detected. The installed version is {1}, the new version is {2}. Would you like to upgrade?" + Environment.NewLine + "Selecting No will install the new FOMod normally."; switch ( MessageBox.Show( String.Format(strUpgradeMessage, fomodMod.ModName, fomodMod.HumanReadableVersion, mod.HumanReadableVersion), "Upgrade", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { case DialogResult.Yes: var mduUpgrader = new ModUpgrader(mod, fomodMod.BaseName); mduUpgrader.Upgrade(); if (mod.IsActive) { fomodMod.IsActive = false; lviFomod.Checked = false; } return; case DialogResult.No: booFound = true; break; } } if (booFound) { break; } } var mdiInstaller = new ModInstaller(mod); mdiInstaller.Install(); }
/// <summary> /// Sets up the script. /// </summary> /// <remarks> /// This method sets the <see cref="ModInstaller"/> this script will use /// to perform its work. /// </remarks> /// <param name="p_mdiScript">The <see cref="ModInstaller"/> this script will use /// to perform its work.</param> public static void Setup(ModInstaller p_mdiScript) { Installer = p_mdiScript; }
/// <summary> /// Executes a custom install script. /// </summary> /// <param name="script">The script to run.</param> /// <param name="p_midInstaller">The installer script to use the execute the custom script.</param> /// <returns> /// <lang langref="true" /> if the script return <lang langref="true" />; /// <lang langref="null" /> otherwise. /// </returns> public static bool Execute(string script, ModInstaller p_midInstaller) { if (script.StartsWith("#fommScript")) { if (fommScriptObject == null) { LoadFommScriptObject(); } return (bool) fommScriptObject.GetType().GetMethod("RunScript").Invoke(fommScriptObject, new object[] { script, p_midInstaller }); } var data = Compile(script); if (data == null) { MessageBox.Show("C# script failed to compile", "Error"); return false; } var asm = AppDomain.CurrentDomain.Load(data); var s = asm.CreateInstance("Script"); if (s == null) { MessageBox.Show("C# or vb script did not contain a 'Script' class in the root namespace", "Error"); return false; } try { MethodInfo mifMethod = null; for (var tpeScriptType = s.GetType(); mifMethod == null; tpeScriptType = tpeScriptType.BaseType) { mifMethod = tpeScriptType.GetMethod("Setup", new[] { typeof (ModInstaller) }); } mifMethod.Invoke(s, new object[] { p_midInstaller }); return (bool) s.GetType().GetMethod("OnActivate").Invoke(s, null); } catch (Exception ex) { MessageBox.Show("An exception occured. The mod may not have been activated completely.\n" + "Check" + Environment.NewLine + Path.Combine(Program.GameMode.InstallInfoDirectory, "ScriptException.txt") + Environment.NewLine + "for full details", "Error"); var str = ex.ToString(); while (ex.InnerException != null) { ex = ex.InnerException; str += Environment.NewLine + Environment.NewLine + ex; } File.WriteAllText( Path.Combine(Program.GameMode.InstallInfoDirectory, "ScriptException.txt"), str); return false; } }
public static bool Execute(string InputScript, ModInstaller p_midInstaller) { m_midInstaller = p_midInstaller; variables = new Dictionary<string, string>(); Stack<FlowControlStruct> FlowControl = new Stack<FlowControlStruct>(); Queue<string> ExtraLines = new Queue<string>(); variables["NewLine"] = Environment.NewLine; variables["Tab"] = "\t"; string[] script = InputScript.Replace("\r", "").Split('\n'); string[] line; string s; string SkipTo = null; bool Break = false; bool Fatal = false; for (int i = 1; i < script.Length || ExtraLines.Count > 0; i++) { if (ExtraLines.Count > 0) { i--; s = ExtraLines.Dequeue().Replace('\t', ' ').Trim(); } else { s = script[i].Replace('\t', ' ').Trim(); } cLine = i.ToString(); while (s.EndsWith("\\")) { s = s.Remove(s.Length - 1); if (ExtraLines.Count > 0) { s += ExtraLines.Dequeue().Replace('\t', ' ').Trim(); } else { if (++i == script.Length) Warn("Run-on line passed end of script"); else s += script[i].Replace('\t', ' ').Trim(); } } if (SkipTo != null) { if (s == SkipTo) SkipTo = null; else continue; } line = SplitLine(s); if (line.Length == 0) continue; if (FlowControl.Count != 0 && !FlowControl.Peek().active) { switch (line[0]) { case "": Warn("Empty function"); break; case "If": case "IfNot": FlowControl.Push(new FlowControlStruct(0)); break; case "Else": if (FlowControl.Count != 0 && FlowControl.Peek().type == 0) { FlowControl.Peek().active = FlowControl.Peek().line != -1; } else Warn("Unexpected Else"); break; case "EndIf": if (FlowControl.Count != 0 && FlowControl.Peek().type == 0) FlowControl.Pop(); else Warn("Unexpected EndIf"); break; case "Select": case "SelectMany": case "SelectWithPreview": case "SelectManyWithPreview": case "SelectWithDescriptions": case "SelectManyWithDescriptions": case "SelectWithDescriptionsAndPreviews": case "SelectManyWithDescriptionsAndPreviews": case "SelectVar": case "SelectString": FlowControl.Push(new FlowControlStruct(1)); break; case "Case": if (FlowControl.Count != 0 && FlowControl.Peek().type == 1) { if (FlowControl.Peek().line != -1 && Array.IndexOf<string>(FlowControl.Peek().values, s) != -1) { FlowControl.Peek().active = true; FlowControl.Peek().hitCase = true; } } else Warn("Unexpected Break"); break; case "Default": if (FlowControl.Count != 0 && FlowControl.Peek().type == 1) { if (FlowControl.Peek().line != -1 && !FlowControl.Peek().hitCase) FlowControl.Peek().active = true; } else Warn("Unexpected Default"); break; case "EndSelect": if (FlowControl.Count != 0 && FlowControl.Peek().type == 1) FlowControl.Pop(); else Warn("Unexpected EndSelect"); break; case "For": FlowControl.Push(new FlowControlStruct(2)); break; case "EndFor": if (FlowControl.Count != 0 && FlowControl.Peek().type == 2) FlowControl.Pop(); else Warn("Unexpected EndFor"); break; case "Break": case "Continue": case "Exit": break; } } else { switch (line[0]) { case "": Warn("Empty function"); break; //Control structures case "Goto": if (line.Length < 2) { Warn("Not enough arguments to function 'Goto'"); } else { if (line.Length > 2) Warn("Unexpected extra arguments to function 'Goto'"); SkipTo = "Label " + line[1]; FlowControl.Clear(); } break; case "Label": break; case "If": FlowControl.Push(new FlowControlStruct(i, FunctionIf(line))); break; case "IfNot": FlowControl.Push(new FlowControlStruct(i, !FunctionIf(line))); break; case "Else": if (FlowControl.Count != 0 && FlowControl.Peek().type == 0) FlowControl.Peek().active = false; else Warn("Unexpected Else"); break; case "EndIf": if (FlowControl.Count != 0 && FlowControl.Peek().type == 0) FlowControl.Pop(); else Warn("Unexpected EndIf"); break; case "Select": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, false, false, false))); break; case "SelectMany": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, true, false, false))); break; case "SelectWithPreview": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, false, true, false))); break; case "SelectManyWithPreview": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, true, true, false))); break; case "SelectWithDescriptions": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, false, false, true))); break; case "SelectManyWithDescriptions": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, true, false, true))); break; case "SelectWithDescriptionsAndPreviews": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, false, true, true))); break; case "SelectManyWithDescriptionsAndPreviews": FlowControl.Push(new FlowControlStruct(i, FunctionSelect(line, true, true, true))); break; case "SelectVar": FlowControl.Push(new FlowControlStruct(i, FunctionSelectVar(line, true))); break; case "SelectString": FlowControl.Push(new FlowControlStruct(i, FunctionSelectVar(line, false))); break; case "Break": { bool found = false; FlowControlStruct[] fcs = FlowControl.ToArray(); for (int k = 0; k < fcs.Length; k++) { if (fcs[k].type == 1) { for (int j = 0; j <= k; j++) fcs[j].active = false; found = true; break; } } if (!found) Warn("Unexpected Break"); break; } case "Case": if (FlowControl.Count == 0 || FlowControl.Peek().type != 1) Warn("Unexpected Case"); break; case "Default": if (FlowControl.Count == 0 || FlowControl.Peek().type != 1) Warn("Unexpected Default"); break; case "EndSelect": if (FlowControl.Count != 0 && FlowControl.Peek().type == 1) FlowControl.Pop(); else Warn("Unexpected EndSelect"); break; case "For": { FlowControlStruct fc = FunctionFor(line, i); FlowControl.Push(fc); if (fc.line != -1 && fc.values.Length > 0) { variables[fc.var] = fc.values[0]; fc.active = true; } break; } case "Continue": { bool found = false; FlowControlStruct[] fcs = FlowControl.ToArray(); for (int k = 0; k < fcs.Length; k++) { if (fcs[k].type == 2) { fcs[k].forCount++; if (fcs[k].forCount == fcs[k].values.Length) { for (int j = 0; j <= k; j++) fcs[j].active = false; } else { i = fcs[k].line; variables[fcs[k].var] = fcs[k].values[fcs[k].forCount]; for (int j = 0; j < k; j++) FlowControl.Pop(); } found = true; break; } } if (!found) Warn("Unexpected Continue"); break; } case "Exit": { bool found = false; FlowControlStruct[] fcs = FlowControl.ToArray(); for (int k = 0; k < fcs.Length; k++) { if (fcs[k].type == 2) { for (int j = 0; j <= k; j++) FlowControl.Peek().active = false; found = true; break; } } if (!found) Warn("Unexpected Exit"); break; } case "EndFor": if (FlowControl.Count != 0 && FlowControl.Peek().type == 2) { FlowControlStruct fc = FlowControl.Peek(); fc.forCount++; if (fc.forCount == fc.values.Length) FlowControl.Pop(); else { i = fc.line; variables[fc.var] = fc.values[fc.forCount]; } } else Warn("Unexpected EndFor"); break; //Functions case "Message": FunctionMessage(line); break; case "PerformBasicInstall": FunctionPerformBasicInstall(line); break; case "InstallDataFile": FunctionInstallDataFile(line); break; case "CopyDataFile": FunctionCopyDataFile(line); break; case "FatalError": Break = true; Fatal = true; break; case "Return": Break = true; break; case "SetPluginActivation": FunctionSetPluginActivation(line); break; case "EditINI": FunctionEditINI(line, IniType.Fallout); break; case "EditPrefsINI": FunctionEditINI(line, IniType.FalloutPrefs); break; case "EditGeckINI": FunctionEditINI(line, IniType.Geck); break; case "EditGeckPrefsINI": FunctionEditINI(line, IniType.GeckPrefs); break; case "EditSDP": case "EditShader": FunctionEditShader(line); break; case "SetVar": FunctionSetVar(line); break; case "GetFolderName": case "GetDirectoryName": FunctionGetDirectoryName(line); break; case "GetFileName": FunctionGetFileName(line); break; case "GetFileNameWithoutExtension": FunctionGetFileNameWithoutExtension(line); break; case "CombinePaths": FunctionCombinePaths(line); break; case "Substring": FunctionSubstring(line); break; case "RemoveString": FunctionRemoveString(line); break; case "StringLength": FunctionStringLength(line); break; case "ReadINI": //TODO: Split into 4 FunctionReadINI(line, IniType.Fallout); break; case "ReadPrefsINI": FunctionReadINI(line, IniType.FalloutPrefs); break; case "ReadGeckINI": FunctionReadINI(line, IniType.Geck); break; case "ReadGeckPrefsINI": FunctionReadINI(line, IniType.GeckPrefs); break; case "ReadRendererInfo": FunctionReadRenderer(line); break; case "ExecLines": FunctionExecLines(line, ExtraLines); break; case "iSet": FunctionSet(line, true); break; case "fSet": FunctionSet(line, false); break; default: Warn("Unknown function '" + line[0] + "'"); break; } } if (Break) break; } if (SkipTo != null) Warn("Expected " + SkipTo); variables = null; return !Fatal; }
/// <summary> /// Executes a custom install script. /// </summary> /// <param name="script">The script to run.</param> /// <param name="p_midInstaller">The installer script to use the execute the custom script.</param> /// <returns> /// <lang langref="true" /> if the script return <lang langref="true" />; /// <lang langref="null" /> otherwise. /// </returns> public static bool Execute(string script, ModInstaller p_midInstaller) { if (script.StartsWith("#fommScript")) { if (fommScriptObject == null) { LoadFommScriptObject(); } return((bool)fommScriptObject.GetType().GetMethod("RunScript").Invoke(fommScriptObject, new object[] { script, p_midInstaller })); } var data = Compile(script); if (data == null) { MessageBox.Show("C# script failed to compile", "Error"); return(false); } var asm = AppDomain.CurrentDomain.Load(data); var s = asm.CreateInstance("Script"); if (s == null) { MessageBox.Show("C# or vb script did not contain a 'Script' class in the root namespace", "Error"); return(false); } try { MethodInfo mifMethod = null; for (var tpeScriptType = s.GetType(); mifMethod == null; tpeScriptType = tpeScriptType.BaseType) { mifMethod = tpeScriptType.GetMethod("Setup", new[] { typeof(ModInstaller) }); } mifMethod.Invoke(s, new object[] { p_midInstaller }); return((bool)s.GetType().GetMethod("OnActivate").Invoke(s, null)); } catch (Exception ex) { MessageBox.Show("An exception occured. The mod may not have been activated completely.\n" + "Check" + Environment.NewLine + Path.Combine(Program.GameMode.InstallInfoDirectory, "ScriptException.txt") + Environment.NewLine + "for full details", "Error"); var str = ex.ToString(); while (ex.InnerException != null) { ex = ex.InnerException; str += Environment.NewLine + Environment.NewLine + ex; } File.WriteAllText( Path.Combine(Program.GameMode.InstallInfoDirectory, "ScriptException.txt"), str); return(false); } }
/// <summary> /// Activates the given fomod. /// </summary> /// <remarks> /// This method checks to see if the given fomod could be an upgrade for another fomod. /// </remarks> /// <param name="mod">The fomod to activate.</param> private void ActivateFomod(fomod mod) { bool booFound = false; fomod fomodMod = null; foreach (ListViewItem lviFomod in lvModList.Items) { fomodMod = (fomod)lviFomod.Tag; if (fomodMod.ModName.Equals(mod.ModName) && fomodMod.IsActive && !fomodMod.BaseName.Equals(mod.BaseName)) { //ask to do upgrade string strUpgradeMessage = "A different version of {0} has been detected. The installed version is {1}, the new version is {2}. Would you like to upgrade?" + Environment.NewLine + "Selecting No will install the new FOMod normally."; switch (MessageBox.Show(String.Format(strUpgradeMessage, fomodMod.ModName, fomodMod.HumanReadableVersion, mod.HumanReadableVersion), "Upgrade", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { case DialogResult.Yes: ModUpgrader mduUpgrader = new ModUpgrader(mod, fomodMod.BaseName); mduUpgrader.Upgrade(); if (mod.IsActive) { fomodMod.IsActive = false; lviFomod.Checked = false; } return; case DialogResult.No: booFound = true; break; } } if (booFound) break; } ModInstaller mdiInstaller = new ModInstaller(mod); mdiInstaller.Install(); }