Example #1
0
        private async void initializeEditor()
        {
            string localAppData = Environment.GetEnvironmentVariable("LocalAppData");
            string settingsPath = Path.Combine(localAppData, "Roblox", "ClientSettings", "StudioAppSettings.json");

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

            if (lastExecVersion != versionGuid || settingsPath == "")
            {
                // Run Roblox Studio briefly so we can update the settings file.
                ProcessStartInfo studioStartInfo = new ProcessStartInfo()
                {
                    CreateNoWindow  = true,
                    UseShellExecute = false,
                    WindowStyle     = ProcessWindowStyle.Hidden,
                    FileName        = RobloxStudioInstaller.GetStudioPath()
                };

                Process studio = Process.Start(studioStartInfo);

                DateTime startTime = DateTime.Now;
                FileInfo info      = new FileInfo(settingsPath);

                // Wait for the settings path file to exist or for it to be updated.
                while (!info.Exists || info.LastWriteTime.Ticks < startTime.Ticks)
                {
                    await Task.Delay(100);

                    info.Refresh();
                }

                // Wait just a moment so we don't access the file while its in a write lock.
                await Task.Delay(500);

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

            string[] flagNames = flagRegistry.GetSubKeyNames();
            string   settings  = File.ReadAllText(settingsPath)
                                 .Replace('\r', ' ').Replace('\n', ' ')
                                 .Replace("{\"", "").Replace("\"}", "");

            // Initialize Flag Table
            flagTable = createFlagDataTable();
            var splitPairs = new string[1] {
                ",\""
            };

            foreach (string kvPairStr in settings.Split(splitPairs, StringSplitOptions.None))
            {
                string[] kvPair = kvPairStr
                                  .Replace("\"", "")
                                  .Split(':');

                if (kvPair.Length == 2)
                {
                    string key   = kvPair[0].Replace('"', ' ').Trim();
                    string value = kvPair[1].Replace('"', ' ').Trim();

                    string type = flagPrefixes
                                  .Where(pre => key.StartsWith(pre))
                                  .FirstOrDefault();

                    if (type.Length > 0)
                    {
                        string name = key.Substring(type.Length);
                        flagTable.Rows.Add(name, type, value);

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

            // Setup flag->row lookup table.
            flagView = initializeDataGridView(flagDataGridView, flagTable);

            foreach (DataGridViewRow row in flagDataGridView.Rows)
            {
                var cells = row.Cells;

                string name  = cells[0].Value as string;
                string type  = cells[1].Value as string;
                string value = cells[2].Value as string;

                flagRowLookup.Add(type + name, row);
            }

            // Initialize Override Table
            overrideTable = createFlagDataTable();
            initializeDataGridView(overrideDataGridView, overrideTable);

            foreach (string flagName in flagNames)
            {
                RegistryKey flagKey = flagRegistry.GetSubKey(flagName);

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

                addFlagOverride(name, type, value, true);
            }

            var columns = overrideDataGridView.Columns;

            columns[0].ReadOnly = true;
            columns[1].ReadOnly = true;

            // Resume layout and enable interaction.
            flagDataGridView.CurrentCell = flagDataGridView[0, 0];
            flagDataGridView.ResumeLayout();

            overrideStatus.Visible = true;
            overrideDataGridView.ResumeLayout();
        }
Example #2
0
        private async void launchStudio_Click(object sender = null, EventArgs e = null)
        {
            Hide();

            string branch = (string)branchSelect.SelectedItem;

            RobloxStudioInstaller installer = new RobloxStudioInstaller(forceRebuild.Checked);
            await installer.RunInstaller(branch);

            string studioRoot = RobloxStudioInstaller.GetStudioDirectory();
            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);

                    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 {0}!", modFile);
                }
            }

            // 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%", '"' + branch + '"'); // 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");
            }

            var robloxStudioInfo = new ProcessStartInfo();

            robloxStudioInfo.FileName = RobloxStudioInstaller.GetStudioPath();

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

                if (firstArg != null && firstArg.StartsWith("roblox-studio"))
                {
                    // 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"))
                    {
                        robloxStudioInfo.Arguments += "-task ";

                        string launchMode = argMap["launchmode"];
                        string addToArgs  = "";

                        if (launchMode == "plugin")
                        {
                            addToArgs = "InstallPlugin";
                        }
                        else if (launchMode == "edit")
                        {
                            addToArgs = "EditPlace";
                        }

                        robloxStudioInfo.Arguments += addToArgs;
                    }
                }
                else
                {
                    // Arguments were passed directly.
                    string fullArg = string.Join(" ", args);
                    robloxStudioInfo.Arguments += fullArg;
                }
            }

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

                Process.Start(robloxStudioInfo);
            }

            Environment.Exit(0);
        }
Example #3
0
        private async void ExplorerIconEditor_Load(object sender, EventArgs e)
        {
            Enabled       = false;
            UseWaitCursor = true;

            EventHandler iconBtnClicked = new EventHandler(onIconBtnClicked);
            string       studioPath     = RobloxStudioInstaller.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();

            await 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))
                    {
                        try
                        {
                            Image icon = getIconForIndex(slot);
                            iconBtn.BackgroundImage = icon;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Couldn't load extra slot {0} - {1}", i, ex.Message);
                        }
                    }

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

                    addControlAcrossThread(iconContainer, iconBtn);
                }

                explorerIcons.Dispose();
            });

            setSelectedIndex(0);
            ResumeLayout();

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

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

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

            Enabled       = true;
            UseWaitCursor = false;
        }