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;
        }
        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);
            }
        }
Example #3
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;
        }