Esempio n. 1
0
        public static async Task BringUpToDate(string branch, string expectedVersion, string updateReason)
        {
            string currentVersion = versionRegistry.GetString("VersionGuid");

            if (currentVersion != expectedVersion)
            {
                DialogResult check = MessageBox.Show
                                     (
                    "Roblox Studio is out of date!\n"
                    + updateReason +
                    "\nWould you like to update now?",

                    "Out of date!",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning
                                     );

                if (check == DialogResult.Yes)
                {
                    StudioBootstrapper installer = new StudioBootstrapper(false);

                    await installer.RunInstaller(branch, false);

                    installer.Dispose();
                }
            }
        }
        public static void ApplyFlags()
        {
            var configs = new List <string>();

            foreach (string flagName in flagRegistry.GetSubKeyNames())
            {
                RegistryKey flagKey = flagRegistry.OpenSubKey(flagName);

                string type  = flagKey.GetString("Type"),
                       value = flagKey.GetString("Value");

                if (type.EndsWith("String", Program.StringFormat))
                {
                    value = $"\"{value.Replace("\"", "")}\"";
                }

                configs.Add($"\t\"{flagName}\": {value}");
            }
            ;

            string json      = "{\r\n" + string.Join(",\r\n", configs) + "\r\n}";
            string studioDir = StudioBootstrapper.GetStudioDirectory();

            string clientSettings = Path.Combine(studioDir, "ClientSettings");

            Directory.CreateDirectory(clientSettings);

            string filePath = Path.Combine(clientSettings, "ClientAppSettings.json");

            File.WriteAllText(filePath, json);
        }
        public static async Task BringUpToDate(string branch, string expectedVersion, string updateReason)
        {
            string currentVersion = Program.VersionRegistry.GetString("VersionGuid");

            if (currentVersion != expectedVersion)
            {
                DialogResult check = MessageBox.Show
                                     (
                    "Roblox Studio is out of date!\n"
                    + updateReason +
                    "\nWould you like to update now?",

                    "Out of date!",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning
                                     );

                if (check == DialogResult.Yes)
                {
                    var bootstrapper = new StudioBootstrapper()
                    {
                        Branch = branch
                    };

                    using (var installer = new BootstrapperForm(bootstrapper))
                    {
                        var bootstrap = installer.Bootstrap();
                        await bootstrap.ConfigureAwait(true);
                    }
                }
            }
        }
        public static async Task PatchExplorerIcons()
        {
            string studioDir = StudioBootstrapper.GetStudioDirectory();
            string iconPath  = Path.Combine(studioDir, iconManifest);

            var   getPatched = Task.Run(() => getPatchedExplorerIcons());
            Image patched    = await getPatched.ConfigureAwait(true);

            patched.Save(iconPath);
        }
        private static string getExplorerIconDir()
        {
            string studioBin   = StudioBootstrapper.GetStudioDirectory();
            string explorerBin = Path.Combine(studioBin, "ExplorerIcons");

            if (!Directory.Exists(explorerBin))
            {
                Directory.CreateDirectory(explorerBin);
            }

            return(explorerBin);
        }
        private async void editFVariables_Click(object sender, EventArgs e)
        {
            bool allow = true;

            // Create a warning prompt if the user hasn't disabled this warning.
            var warningDisabled = Program.GetBool("Disable Flag Warning");

            if (!warningDisabled)
            {
                SystemSounds.Hand.Play();
                allow = false;

                using (Form warningPrompt = createFlagWarningPrompt())
                {
                    warningPrompt.ShowDialog();

                    if (warningPrompt.DialogResult == DialogResult.Yes)
                    {
                        Program.SetValue("Disable Flag Warning", warningPrompt.Enabled);
                        allow = true;
                    }
                }
            }

            if (allow)
            {
                string branch = getSelectedBranch();

                Enabled       = false;
                UseWaitCursor = true;

                var infoTask = StudioBootstrapper.GetCurrentVersionInfo(branch);
                var info     = await infoTask.ConfigureAwait(true);

                Hide();

                var updateTask = BootstrapperForm.BringUpToDate(branch, info.Guid, "Some newer flags might be missing.");
                await updateTask.ConfigureAwait(true);

                using (FlagEditor editor = new FlagEditor())
                    editor.ShowDialog();

                Show();
                BringToFront();

                Enabled       = true;
                UseWaitCursor = false;
            }
        }
Esempio n. 7
0
        private async void editFVariables_Click(object sender, EventArgs e)
        {
            bool allow = true;

            // Create a warning prompt if the user hasn't disabled this warning.
            var warningDisabled = Program.GetBool("Disable Flag Warning");

            if (!warningDisabled)
            {
                SystemSounds.Hand.Play();
                allow = false;

                Form warningPrompt = createFlagWarningPrompt();
                warningPrompt.ShowDialog();

                DialogResult result = warningPrompt.DialogResult;

                if (result == DialogResult.Yes)
                {
                    Program.SetValue("Disable Flag Warning", warningPrompt.Enabled);
                    allow = true;
                }
            }

            if (allow)
            {
                string branch = getSelectedBranch();

                Enabled       = false;
                UseWaitCursor = true;

                ClientVersionInfo info = await StudioBootstrapper.GetCurrentVersionInfo(branch);

                Hide();

                await StudioBootstrapper.BringUpToDate(branch, info.Guid, "某些新参数可能无法在旧版本使用!");

                FlagEditor editor = new FlagEditor(branch);
                editor.ShowDialog();

                Show();
                BringToFront();

                Enabled       = true;
                UseWaitCursor = false;
            }
        }
        public BootstrapperForm(StudioBootstrapper bootstrapper, bool exitWhenClosed = false)
        {
            Contract.Requires(bootstrapper != null);
            InitializeComponent();

            Bootstrapper = bootstrapper;
            exitOnClose  = exitWhenClosed;

            bootstrapper.EchoFeed      += new MessageEventHandler(Bootstrapper_EchoFeed);
            bootstrapper.StatusChanged += new MessageEventHandler(Bootstrapper_StatusChanged);

            bootstrapper.ProgressChanged         += new ChangeEventHandler <int>(Bootstrapper_ProgressChanged);
            bootstrapper.ProgressBarStyleChanged += new ChangeEventHandler <ProgressBarStyle>(Bootstrapper_ProgressBarStyleChanged);

            Show();
            BringToFront();
        }
        private static Image getExplorerIcons()
        {
            string manifestHash = manifestRegistry.GetString(iconManifest);
            string currentHash  = infoRegistry.GetString("LastClassIconhash");

            if (currentHash != manifestHash)
            {
                string studioDir = StudioBootstrapper.GetStudioDirectory();
                UpdateExplorerIcons(studioDir);

                infoRegistry.SetValue("LastClassIconHash", manifestHash);
            }

            string imagePath     = infoRegistry.GetString("SourceLocation");
            Image  explorerIcons = Image.FromFile(imagePath);

            numIcons = explorerIcons.Width / iconSize;
            return(explorerIcons);
        }
Esempio n. 10
0
        public static async Task <StudioDeployLogs> Get(string branch)
        {
            StudioDeployLogs logs = null;

            if (LogCache.ContainsKey(branch))
            {
                logs = LogCache[branch];
            }
            else
            {
                logs = new StudioDeployLogs(branch);
            }

            var    getDeployHistory = HistoryCache.GetDeployHistory(branch);
            string deployHistory    = await getDeployHistory.ConfigureAwait(false);

            if (logs.LastDeployHistory != deployHistory)
            {
                int maxVersion = int.MaxValue;

                if (branch == "roblox")
                {
                    string binaryType = StudioBootstrapper.GetStudioBinaryType();

                    var getInfo = ClientVersionInfo.Get(binaryType);
                    var info    = await getInfo.ConfigureAwait(false);

                    int version = info.Version
                                  .Split('.')
                                  .Select(int.Parse)
                                  .Skip(1)
                                  .First();

                    maxVersion = version;
                }

                logs.LastDeployHistory = deployHistory;
                logs.UpdateLogs(deployHistory, maxVersion);
            }

            return(logs);
        }
Esempio n. 11
0
        public static async Task <bool> PatchExplorerIcons()
        {
            bool success = false;

            try
            {
                string studioDir = StudioBootstrapper.GetStudioDirectory();
                string iconPath  = Path.Combine(studioDir, iconManifest);

                Image patched = await Task.Factory.StartNew(getPatchedExplorerIcons);

                patched.Save(iconPath);
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred while trying to patch the explorer icons: {0}", e.Message);
            }

            return(success);
        }
Esempio n. 12
0
        private async void editExplorerIcons_Click(object sender, EventArgs e)
        {
            Enabled       = false;
            UseWaitCursor = true;

            string            branch = (string)branchSelect.SelectedItem;
            ClientVersionInfo info   = await StudioBootstrapper.GetCurrentVersionInfo(branch);

            Hide();
            await StudioBootstrapper.BringUpToDate(branch, info.Guid, "The class icons may have received an update.");

            var editor = new ClassIconEditor(branch);

            editor.ShowDialog();

            Show();
            BringToFront();

            Enabled       = true;
            UseWaitCursor = false;
        }
Esempio n. 13
0
        public static bool ApplyFlags()
        {
            try
            {
                List <string> configs = new List <string>();

                foreach (string flagName in flagRegistry.GetSubKeyNames())
                {
                    RegistryKey flagKey = flagRegistry.OpenSubKey(flagName);

                    string type  = flagKey.GetString("Type"),
                           value = flagKey.GetString("Value");

                    if (type.EndsWith("String"))
                    {
                        value = $"\"{value.Replace("\"", "")}\"";
                    }

                    configs.Add($"\t\"{flagName}\": {value}");
                }
                ;

                string json      = "{\r\n" + string.Join(",\r\n", configs) + "\r\n}";
                string studioDir = StudioBootstrapper.GetStudioDirectory();

                string clientSettings = Path.Combine(studioDir, "ClientSettings");
                Directory.CreateDirectory(clientSettings);

                string filePath = Path.Combine(clientSettings, "ClientAppSettings.json");
                File.WriteAllText(filePath, json);

                return(true);
            }
            catch
            {
                Console.WriteLine("Failed to apply flag editor configuration!");
                return(false);
            }
        }
Esempio n. 14
0
        private async void editExplorerIcons_Click(object sender, EventArgs e)
        {
            Enabled       = false;
            UseWaitCursor = true;

            string branch = (string)branchSelect.SelectedItem;

            Hide();

            var infoTask = StudioBootstrapper.GetCurrentVersionInfo(branch);
            var info     = await infoTask.ConfigureAwait(true);

            var updateTask = BootstrapperForm.BringUpToDate(branch, info.VersionGuid, "The class icons may have received an update.");
            await updateTask.ConfigureAwait(true);

            using (var editor = new ClassIconEditor())
                editor.ShowDialog();

            Show();
            BringToFront();

            Enabled       = true;
            UseWaitCursor = false;
        }
Esempio n. 15
0
        private async void initializeEditor()
        {
            string localAppData = Environment.GetEnvironmentVariable("LocalAppData");

            string settingsDir  = Path.Combine(localAppData, "Roblox", "ClientSettings");
            string settingsPath = Path.Combine(settingsDir, "StudioAppSettings.json");

            string lastExecVersion = versionRegistry.GetString("LastExecutedVersion");
            string versionGuid     = versionRegistry.GetString("VersionGuid");

            if (lastExecVersion != versionGuid)
            {
                // Reset the settings file.
                Directory.CreateDirectory(settingsDir);
                File.WriteAllText(settingsPath, "");

                // Create some system events for studio so we can hide the splash screen.
                SystemEvent start = new SystemEvent("FFlagExtract");
                SystemEvent show  = new SystemEvent("NoSplashScreen");

                // Run Roblox Studio briefly so we can update the settings file.
                ProcessStartInfo studioStartInfo = new ProcessStartInfo()
                {
                    FileName  = StudioBootstrapper.GetStudioPath(),
                    Arguments = $"-startEvent {start.Name} -showEvent {show.Name}"
                };

                Process studio = Process.Start(studioStartInfo);
                await start.WaitForEvent();

                FileInfo info = new FileInfo(settingsPath);

                // Wait for the settings path to be written.
                while (info.Length == 0)
                {
                    await Task.Delay(30);

                    info.Refresh();
                }

                // Nuke studio and flag the version we updated with.
                versionRegistry.SetValue("LastExecutedVersion", versionGuid);
                studio.Kill();
            }

            // Initialize flag browser
            string[] flagNames = flagRegistry.GetSubKeyNames();

            string settings = File.ReadAllText(settingsPath);
            var    json     = Program.ReadJsonDictionary(settings);

            int numFlags  = json.Count;
            var flagSetup = new List <FVariable>(numFlags);

            var autoComplete = new AutoCompleteStringCollection();

            foreach (var pair in json)
            {
                string key     = pair.Key,
                         value = pair.Value;

                FVariable flag = new FVariable(key, value);
                autoComplete.Add(flag.Name);
                flagSetup.Add(flag);

                if (flagNames.Contains(flag.Name))
                {
                    // Update what the flag should be reset to if removed?
                    RegistryKey flagKey = flagRegistry.GetSubKey(flag.Name);
                    flagKey.SetValue("Reset", value);

                    // Set the flag's editor.
                    flag.SetEditor(flagKey);
                }
            }

            flagSearchFilter.AutoCompleteCustomSource = autoComplete;

            allFlags = flagSetup
                       .OrderBy(flag => flag.Name)
                       .ToList();

            refreshFlags();

            // Initialize override table.
            overrideTable = new DataTable();

            foreach (DataGridViewColumn column in overrideDataGridView.Columns)
            {
                overrideTable.Columns.Add(column.DataPropertyName);
            }

            DataView overrideView = new DataView(overrideTable);

            overrideView.Sort = "Name";

            foreach (string flagName in flagNames)
            {
                if (flagLookup.ContainsKey(flagName))
                {
                    int       index = flagLookup[flagName];
                    FVariable flag  = flags[index];
                    addFlagOverride(flag, true);
                }
            }

            overrideStatus.Visible          = true;
            overrideDataGridView.DataSource = overrideView;
        }
        private async void launchStudio_Click(object sender = null, EventArgs e = null)
        {
            string branch = getSelectedBranch();

            var bootstrapper = new StudioBootstrapper
            {
                ForceInstall           = forceRebuild.Checked,
                ApplyModManagerPatches = true,

                SetStartEvent = true,
                Branch        = branch
            };

            Hide();

            using (var installer = new BootstrapperForm(bootstrapper))
            {
                var install = installer.Bootstrap();
                await install.ConfigureAwait(true);
            }

            string studioRoot = StudioBootstrapper.GetStudioDirectory();
            string modPath    = getModPath();

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

            foreach (string modFile in modFiles)
            {
                try
                {
                    byte[]   fileContents   = File.ReadAllBytes(modFile);
                    FileInfo modFileControl = new FileInfo(modFile);

                    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))
                        {
                            continue;
                        }

                        modFileControl.CopyTo(relativeFile, true);
                        continue;
                    }

                    File.WriteAllBytes(relativeFile, fileContents);
                }
                catch
                {
                    Console.WriteLine("Failed to overwrite {0}!", modFile);
                }
            }

            var robloxStudioInfo = new ProcessStartInfo()
            {
                FileName  = StudioBootstrapper.GetStudioPath(),
                Arguments = $"-startEvent {StudioBootstrapper.StartEvent}"
            };

            if (args != null)
            {
                string firstArg = args[0];

                if (firstArg != null && firstArg.StartsWith("roblox-studio", Program.StringFormat))
                {
                    // Arguments were passed by URI.
                    var argMap = new Dictionary <string, string>();

                    foreach (string commandPair in firstArg.Split('+'))
                    {
                        if (commandPair.Contains(':'))
                        {
                            string[] kvPair = commandPair.Split(':');

                            string key = kvPair[0];
                            string val = kvPair[1];

                            if (key == "gameinfo")
                            {
                                // The user is authenticating. This argument is a special case.
                                robloxStudioInfo.Arguments += " -url https://www.roblox.com/Login/Negotiate.ashx -ticket " + val;
                            }
                            else
                            {
                                argMap.Add(key, val);
                                robloxStudioInfo.Arguments += " -" + key + ' ' + val;
                            }
                        }
                    }

                    if (argMap.ContainsKey("launchmode") && !argMap.ContainsKey("task"))
                    {
                        string launchMode = argMap["launchmode"];

                        if (launchMode == "plugin")
                        {
                            string pluginId = argMap["pluginid"];
                            robloxStudioInfo.Arguments += "-task InstallPlugin -pluginId " + pluginId;
                        }
                        else if (launchMode == "edit")
                        {
                            robloxStudioInfo.Arguments += "-task EditPlace";
                        }
                    }
                }
                else
                {
                    // Arguments were passed directly.
                    for (int i = 0; i < args.Length; i++)
                    {
                        string arg = args[i];

                        if (arg.Contains(' '))
                        {
                            arg = $"\"{arg}\"";
                        }

                        robloxStudioInfo.Arguments += ' ' + arg;
                    }
                }
            }

            if (openStudioDirectory.Checked)
            {
                Process.Start(studioRoot);
                Environment.Exit(0);
            }
            else
            {
                string currentVersion = versionRegistry.GetString("VersionGuid");
                versionRegistry.SetValue("LastExecutedVersion", currentVersion);

                Process.Start(robloxStudioInfo);
            }
        }
        private async void ClassIconEditor_Load(object sender, EventArgs e)
        {
            Enabled       = false;
            UseWaitCursor = true;

            EventHandler iconBtnClicked = new EventHandler(onIconBtnClicked);
            string       studioPath     = StudioBootstrapper.GetStudioPath();

            showModifiedIcons = explorerRegistry.GetBool("ShowModifiedIcons");
            darkTheme         = explorerRegistry.GetBool("DarkTheme");

            showModified.Checked = showModifiedIcons;
            themeSwitcher.Text   = "Theme: " + (darkTheme ? "Dark" : "Light");

            selectedIcon.BackColor = (darkTheme ? THEME_DARK_NORMAL : THEME_LIGHT_NORMAL);
            selectedIcon.Refresh();

            int   extraSlots  = getExtraItemSlots();
            Image defaultIcon = null;

            SuspendLayout();

            var load = Task.Run(() =>
            {
                Image explorerIcons = getExplorerIcons();

                // Load Main Icons
                for (int i = 0; i < numIcons; i++)
                {
                    Button iconBtn = createIconButton(iconBtnClicked);

                    Bitmap icon = new Bitmap(iconSize, iconSize);
                    iconLookup.Add(icon);

                    Rectangle srcRect  = new Rectangle(i * iconSize, 0, iconSize, iconSize);
                    Rectangle iconRect = new Rectangle(0, 0, iconSize, iconSize);

                    using (Graphics graphics = Graphics.FromImage(icon))
                        graphics.DrawImage(explorerIcons, iconRect, srcRect, GraphicsUnit.Pixel);

                    if (defaultIcon == null)
                    {
                        defaultIcon = icon;
                    }

                    buttonLookup.Add(iconBtn);
                    iconBtnIndex.Add(iconBtn, i);

                    if (showModifiedIcons)
                    {
                        iconBtn.BackgroundImage = getIconForIndex(i);
                    }
                    else
                    {
                        iconBtn.BackgroundImage = icon;
                    }

                    AddControlAcrossThread(iconContainer, iconBtn);
                }

                // Load Extra Slots
                for (int i = 0; i < maxExtraIcons; i++)
                {
                    int slot = numIcons + i;

                    Button iconBtn  = createIconButton(iconBtnClicked);
                    iconBtn.Visible = (i < extraSlots);

                    string fileName = getExplorerIconPath(slot);

                    if (i < extraSlots && File.Exists(fileName))
                    {
                        Image icon = getIconForIndex(slot);
                        iconBtn.BackgroundImage = icon;
                    }

                    iconLookup.Add(defaultIcon);
                    buttonLookup.Add(iconBtn);
                    iconBtnIndex.Add(iconBtn, slot);

                    AddControlAcrossThread(iconContainer, iconBtn);
                }

                explorerIcons.Dispose();
            });

            await load.ConfigureAwait(true);

            setSelectedIndex(0);
            ResumeLayout();

            itemSlots.Value = extraSlots;
            header.Text     = "Select Icon";

            iconWatcher = new FileSystemWatcher(getExplorerIconDir())
            {
                Filter = "*.png",
                EnableRaisingEvents = true
            };

            iconWatcher.Created += safeFileEventHandler(onFileCreated);
            iconWatcher.Changed += safeFileEventHandler(onFileChanged);
            iconWatcher.Deleted += safeFileEventHandler(onFileDeleted);

            Enabled       = true;
            UseWaitCursor = false;
        }