private async void FVariableEditor_Load(object sender, EventArgs e)
        {
            string localAppData      = Environment.GetEnvironmentVariable("LocalAppData");
            string exePath           = Path.Combine(localAppData, "Roblox Studio", "RobloxStudioBeta.exe");
            string installedDatabase = Program.ModManagerRegistry.GetValue("BuildDatabase") as string;

            bool installFirst = true;

            if (!File.Exists(exePath))
            {
                MessageBox.Show("Roblox Studio will be installed prior to editing so that FVariable scans can be done.", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (database != installedDatabase)
            {
                DialogResult result = MessageBox.Show("The branch you have selected hasn't been installed, and thus FVariable scans will not be representative of this branch.\nWould you like to install it now?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.No)
                {
                    installFirst = false;
                }
            }
            else
            {
                installFirst = false;
            }

            if (installFirst)
            {
                fvarsLoaded = false;
                using (RobloxInstaller installer = new RobloxInstaller(!File.Exists(exePath)))
                {
                    Enabled = false;
                    SendToBack();
                    await installer.RunInstaller(database, true);

                    Enabled = true;
                    BringToFront();
                }
            }

            if (!fvarsLoaded)
            {
                if (!File.Exists(exePath))
                {
                    error("Could not find Roblox Studio's exe, did you close the installer before it finished?", true);
                    return;
                }

                try
                {
                    Enabled = false;
                    fvars   = new List <string>();

                    foreach (string fvar in fvarRegistry.GetSubKeyNames())
                    {
                        if (!fvars.Contains(fvar))
                        {
                            RegistryKey fvarEntry = getFVarEntry(fvar);
                            bool        custom    = bool.Parse(fvarEntry.GetValue("Custom", "false") as string);
                            if (custom)
                            {
                                fvars.Add(fvar);
                            }
                        }
                    }

                    RegistryKey fvarScan = Program.ModManagerRegistry.CreateSubKey("SavedFVariableScan");
                    foreach (string fvar in fvarScan.GetValueNames())
                    {
                        if (!fvars.Contains(fvar))
                        {
                            fvars.Add(fvar);
                        }
                    }

                    string fvarProtocol = Program.ModManagerRegistry.GetValue("FVariable Protocol Version", "v0") as string;
                    int    version      = int.Parse(fvarProtocol.Substring(1));
                    if (version < 1)
                    {
                        // Convert any legacy registry keys over to the new system.
                        RegistryKey fflagRegistry = Program.GetSubKey(Program.ModManagerRegistry, "FFlags");
                        foreach (string key in fflagRegistry.GetValueNames())
                        {
                            string      value     = fflagRegistry.GetValue(key) as string;
                            RegistryKey fvarEntry = getFVarEntry(key);
                            fvarEntry.SetValue("Type", "Flag");
                            fvarEntry.SetValue("Value", value);
                        }
                        Program.ModManagerRegistry.DeleteSubKey("FFlags");

                        version = 1;
                        Program.ModManagerRegistry.SetValue("FVariable Protocol Version", "v1");
                    }

                    await setStatus("Loading Layout...");

                    reassembleListings();

                    await setStatus("Ready!");

                    Enabled     = true;
                    fvarsLoaded = true;
                }
                catch (Exception ex)
                {
                    error("Exception thrown while loading FVariable Editor: " + ex.Message + '\n' + ex.StackTrace, true);
                }
            }
            else
            {
                reassembleListings();
            }
        }
Пример #2
0
        private async void launchStudio_Click(object sender = null, EventArgs e = null)
        {
            Hide();

            string          dataBase  = (string)dataBaseSelect.SelectedItem;
            RobloxInstaller installer = new RobloxInstaller();

            string studioPath = await installer.RunInstaller(dataBase, forceRebuild.Checked);

            string studioRoot = Directory.GetParent(studioPath).ToString();
            string modPath    = getModPath();

            string[] studioFiles = Directory.GetFiles(studioRoot);
            string[] modFiles    = Directory.GetFiles(modPath, "*.*", SearchOption.AllDirectories);

            foreach (string modFile in modFiles)
            {
                try
                {
                    byte[]   fileContents   = File.ReadAllBytes(modFile);
                    FileInfo modFileControl = new FileInfo(modFile);
                    bool     allow          = true;
                    if (modFileControl.Name == "ClientAppSettings.json")
                    {
                        DialogResult result = MessageBox.Show("A custom ClientAppSettings configuration was detected in your mods folder. This will override the configuration provided by the FVariable Editor.\nAre you sure you want to use this one instead?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                        if (result == DialogResult.No)
                        {
                            allow = false;
                        }
                    }
                    if (allow)
                    {
                        string relativeFile = modFile.Replace(modPath, studioRoot);
                        string relativeDir  = Directory.GetParent(relativeFile).ToString();
                        if (!Directory.Exists(relativeDir))
                        {
                            Directory.CreateDirectory(relativeDir);
                        }

                        if (File.Exists(relativeFile))
                        {
                            byte[] relativeContents = File.ReadAllBytes(relativeFile);
                            if (!fileContents.SequenceEqual(relativeContents))
                            {
                                modFileControl.CopyTo(relativeFile, true);
                            }
                        }
                        else
                        {
                            File.WriteAllBytes(relativeFile, fileContents);
                        }
                    }
                }
                catch
                {
                    Console.WriteLine("Failed to overwrite " + modFile + "\nMight be open in another program\nThats their problem, not mine <3");
                }
            }

            // Hack in the metadata plugin.
            // This is used to provide an end-point to custom StarterScripts that are trying to fork what branch they are on.
            // It creates a BindableFunction inside of the ScriptContext called GetModManagerBranch, which returns the branch set in the launcher.

            try
            {
                Assembly self = Assembly.GetExecutingAssembly();
                string   metaScript;

                using (Stream stream = self.GetManifestResourceStream("RobloxStudioModManager.Resources.ModManagerMetadata.lua"))
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        metaScript = reader.ReadToEnd();
                        metaScript = metaScript.Replace("%MOD_MANAGER_VERSION%", '"' + dataBase + '"'); // TODO: Make this something more generic?
                    }

                string dir = Path.Combine(studioRoot, "BuiltInPlugins");
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                string   metaScriptFile = Path.Combine(dir, "__rbxModManagerMetadata.lua");
                FileInfo info           = new FileInfo(metaScriptFile);
                if (info.Exists)
                {
                    info.Attributes = FileAttributes.Normal;
                }

                File.WriteAllText(metaScriptFile, metaScript);

                // Make the file as readonly so that it (hopefully) won't be messed with.
                // I can't hide the file because Roblox Studio will ignore it.
                // If someone has the file open with write permissions, it will fail to write.

                info.Attributes = FileAttributes.ReadOnly;
            }
            catch
            {
                Console.WriteLine("Failed to write __rbxModManagerMetadata.lua");
            }

            ProcessStartInfo robloxStudioInfo = new ProcessStartInfo();

            robloxStudioInfo.FileName = studioPath;
            if (args != null)
            {
                string firstArg = args[0];
                if (firstArg != null && firstArg.StartsWith("roblox-studio"))
                {
                    foreach (string commandPair in firstArg.Split('+'))
                    {
                        if (commandPair.Contains(':'))
                        {
                            string[] keyVal = commandPair.Split(':');
                            string   key    = keyVal[0];
                            string   val    = keyVal[1];
                            if (key == "script")
                            {
                                Uri scriptQuery           = new Uri(WebUtility.UrlDecode(val));
                                NameValueCollection query = HttpUtility.ParseQueryString(scriptQuery.Query);
                                robloxStudioInfo.Arguments = "-task EditPlace -placeId " + query["placeId"];
                                break;
                            }
                            else if (key == "pluginid")
                            {
                                robloxStudioInfo.Arguments = "-task InstallPlugin -pluginId " + val;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    robloxStudioInfo.Arguments = string.Join(" ", args);
                }
            }

            Process process;

            if (openStudioDirectory.Checked)
            {
                process = Process.Start(studioRoot);
            }
            else
            {
                process = Process.Start(robloxStudioInfo);
            }

            Environment.Exit(0);
        }