private async void MainForm_Load(object sender, EventArgs e) { // Hide the connect button, show the loading button to make the user clear that the servers are being fetched btnConnect.Visible = false; pctrLoading.Visible = true; Application.DoEvents(); await Task.Delay(1); // Check the state of the current version VersionState vs = await VersionChecker.GetCurrentState(); if (vs == VersionState.BLACKLISTED) { // If the current version is blacklisted, prevent the user from using it. MessageBox.Show($"Your current version ({VersionChecker.CurrentVersion}) is blacklisted.\r\n\r\nThis can happen when the version contains security flaws or other things that could interrupt a good user experience.\r\n\r\nPlease download the newest version of the switcher from its website. (github.com/minisbett/ultimate-osu-server-switcher/releases).", "Ultimate Osu Server Switcher", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(0); return; } else if (vs == VersionState.MAINTENANCE) { // If the switcher is in maintenance, also prevent the user from using it. MessageBox.Show("The switcher is currently hold in maintenance mode which means that the switcher is currently not available.\r\n\r\nJoin our discord server for more informations.\r\nThe discord server and be found on our github page.", "Ultimate Osu Server Switcher", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(0); return; } else if (vs == VersionState.OUTDATED) { // Show the user a message that a new version is available if the current switcher is outdated. MessageBox.Show($"Your switcher version ({VersionChecker.CurrentVersion}) is outdated.\r\nA newer version ({await VersionChecker.GetNewestVersion()}) is available.\r\n\r\nYou can download it from our github page.", "Ultimate Osu Server Switcher", MessageBoxButtons.OK, MessageBoxIcon.Warning); } lblInfo.Text = "Fetching mirrors..."; Application.DoEvents(); // Try to load online data and verify servers List <Mirror> mirrors = null; try { // Download the mirror data from github and deserialize it into a mirror list mirrors = JsonConvert.DeserializeObject <List <Mirror> >(await WebHelper.DownloadStringAsync(Urls.Mirrors)); } catch { // If it was not successful, github may cannot currently be reached or I made a mistake in the json data. MessageBox.Show("Error whilst parsing the server mirrors from GitHub!\r\nPlease make sure you can connect to www.github.com in your browser.\r\n\r\nIf this issue persists, please visit our discord. You can find the invite link on our GitHub Page (minisbett/ultimate-osu-server-switcher)", "Ultimate Osu Server Switcher", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); return; } imgLoadingBar.Maximum = mirrors.Count; // Try to load all servers List <Server> servers = new List <Server>(); foreach (Mirror mirror in mirrors) { lblInfo.Text = $"Parsing mirror {mirror.Url}"; Application.DoEvents(); Server server = null; // Try to serialize the mirror into a server try { // Download the data from the mirror and try to parse it into a server object. server = JsonConvert.DeserializeObject <Server>(await WebHelper.DownloadStringAsync(mirror.Url)); } catch { // If the cast was not successful (invalid json) or the mirror could not be reached, skip the mirror continue; } // Forward mirror variables to the server server.IsFeatured = mirror.Featured; server.UID = mirror.UID; lblInfo.Text = $"Parsing mirror {mirror.Url} ({server.ServerName})"; Application.DoEvents(); // Check if UID is 6 letters long (If not I made a mistake) if (server.UID.Length != 6) { continue; } // Check if the UID is really unique (I may accidentally put the same uid for two servers) if (servers.Any(x => x.UID == server.UID)) { continue; } // Check if everything is set if (server.ServerName == null || server.IP == null || server.IconUrl == null || server.CertificateUrl == null || server.DiscordUrl == null) { continue; } // Check if server name length is valid (between 3 and 24) if (server.ServerName.Replace(" ", "").Length < 3 || server.ServerName.Length > 24) { continue; } // Check if it neither start with a space, nor end if (server.ServerName.StartsWith(" ")) { continue; } if (server.ServerName.EndsWith(" ")) { continue; } // // Only a-zA-Z0-9 ! is allowed if (!Regex.Match(server.ServerName.Replace("!", "").Replace(" ", ""), "^\\w+$").Success) { continue; } // Double spaces are invalid because its hard to tell how many spaces there are // (One server could be named test 123 and the other test 123) if (server.ServerName.Replace(" ", "") != server.ServerName) { continue; } // Check if the server fakes a hardcoded server if (Server.StaticServers.Any(x => x.ServerName == server.ServerName)) { continue; } // Check if the server ip is formatted correctly if (!Regex.IsMatch(server.IP, @"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$")) { continue; } // Check if that server name already exists (if so, prioritize the first one) if (servers.Any(x => x.ServerName.ToLower().Replace(" ", "") == server.ServerName.ToLower().Replace(" ", ""))) { continue; } // Check if its a real discord invite url if (!server.DiscordUrl.Replace("https", "").Replace("http", "").Replace("://", "").StartsWith("discord.gg")) { continue; } // Initialize variables like Certificate and Icon that are downloaded from their urls when // all checks are done (IconUrl, CertificateUrl) try { // Try to parse the certificate from the given url server.Certificate = await WebHelper.DownloadBytesAsync(server.CertificateUrl); server.CertificateThumbprint = new X509Certificate2(server.Certificate).Thumbprint; } catch // Cerfiticate url not valid or certificate type is not cer (base64 encoded) { continue; } // Check if icon is valid try { // Download the icon and check if its at least 256x256 Image icon = await WebHelper.DownloadImageAsync(server.IconUrl); if (icon.Width < 256 || icon.Height < 256) { continue; } // Scale the image to 256x256 server.Icon = new Bitmap(icon, new Size(256, 256)); // Add the server to the servers that were successfully parsed and checked servers.Add(server); } catch // Image could not be downloaded or loaded { continue; } imgLoadingBar.Value++; } // Load bancho and localhost try { // Download the icon and check if its at least 256x256 Image icon = await WebHelper.DownloadImageAsync(Server.BanchoServer.IconUrl); if (icon.Width >= 256 && icon.Height >= 256) { // Add the bancho server Server s = Server.BanchoServer; // Scale the image to 256x256 s.Icon = new Bitmap(icon, new Size(256, 256)); servers.Add(s); } } catch // Image could not be downloaded or loaded { } try { // Download the icon and check if its at least 256x256 Image icon = await WebHelper.DownloadImageAsync(Server.LocalhostServer.IconUrl); if (icon.Width >= 256 && icon.Height >= 256) { // Add the localhost server Server s = Server.LocalhostServer; // Scale the image to 256x256 s.Icon = new Bitmap(icon, new Size(256, 256)); servers.Add(s); } } catch // Image could not be downloaded or loaded { } // Sort the servers by priority (first bancho, then featured, then normal, then localhost) servers = servers.OrderByDescending(x => x.Priority).ToList(); // Create .ico files for shortcuts foreach (Server server in servers) { using (FileStream fs = File.OpenWrite(Paths.IconCacheFolder + $@"\{server.UID}.ico")) using (MemoryStream ms = new MemoryStream((byte[])new ImageConverter().ConvertTo(server.Icon, typeof(byte[])))) ImagingHelper.ConvertToIcon(ms, fs, server.Icon.Width, true); } Switcher.Servers = servers; // Enable/Disable the timer depending on if useDiscordRichPresence is true or false // Set here because the timer needs to have the servers loaded richPresenceUpdateTimer.Enabled = m_settings["useDiscordRichPresence"] == "true"; // Initialize the current selected server variable m_currentSelectedServer = Switcher.GetCurrentServer(); if (m_currentSelectedServer.IsUnidentified) { m_currentSelectedServer = Switcher.Servers.First(x => x.UID == "bancho"); } // Hide loading button and loading bar after all mirrors are loaded pctrLoading.Visible = false; imgLoadingBar.Visible = false; // Show the account manager button because all servers are loaded now btnAccountManager.Visible = true; // Update the UI UpdateUI(); }