-
Notifications
You must be signed in to change notification settings - Fork 8
SS13 "Classic Servers" Support #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
DEATHB4DEFEAT
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all notes for when I take over this PR, and this is all without the context of existing systems, I need to compare them later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete
| ## Strings for the "servers" tab | ||
|
|
||
| tab-servers-title = Servers | ||
| tab-servers-classic-title = Classic Servers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| tab-servers-classic-title = Classic Servers | |
| tab-servers-classic-title = BYOND Servers |
|
|
||
| tab-servers-title = Servers | ||
| tab-servers-classic-title = Classic Servers | ||
| tab-servers-classic-desc = All servers listed here connect via the BYOND client. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this gets used
| { | ||
| var response = await _http.GetStringAsync("http://www.byond.com/games/exadv1/spacestation13?format=text"); | ||
| // Log.Information("BYOND Response: {Response}", response); | ||
| await File.WriteAllTextAsync("byond_dump.txt", response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very odd choice, and it doesn't look like this ever gets deleted
| private List<ClassicServerStatusData> ParseByondResponse(string response) | ||
| { | ||
| var list = new List<ClassicServerStatusData>(); | ||
| using var reader = new StringReader(response); | ||
|
|
||
| string? line; | ||
| string? currentName = null; | ||
| string? currentUrl = null; | ||
| string? currentStatus = null; | ||
| int currentPlayers = 0; | ||
|
|
||
| // Simple state machine to parse the text format | ||
| // The format uses 'world/ID' blocks for servers. | ||
|
|
||
| bool inServerBlock = false; | ||
|
|
||
| while ((line = reader.ReadLine()) != null) | ||
| { | ||
| var trimmed = line.Trim(); | ||
| if (string.IsNullOrWhiteSpace(trimmed)) continue; | ||
|
|
||
| if (trimmed.StartsWith("world/")) | ||
| { | ||
| // If we were parsing a server, save it | ||
| if (inServerBlock && currentUrl != null) | ||
| { | ||
| // Name might be missing, try to extract from status or use URL | ||
| var name = currentName ?? ExtractNameFromStatus(currentStatus) ?? "Unknown Server"; | ||
| var roundTime = ExtractRoundTimeFromStatus(currentStatus); | ||
| list.Add(new ClassicServerStatusData(name, currentUrl, currentPlayers, CleanStatus(currentStatus, name) ?? "", roundTime ?? "In-Lobby")); | ||
| } | ||
|
|
||
| // Reset for new server | ||
| inServerBlock = true; | ||
| currentName = null; | ||
| currentUrl = null; | ||
| currentStatus = null; | ||
| currentPlayers = 0; | ||
| } | ||
| else if (inServerBlock) | ||
| { | ||
| if (trimmed.StartsWith("name =")) | ||
| { | ||
| currentName = ParseStringValue(trimmed); | ||
| } | ||
| else if (trimmed.StartsWith("url =")) | ||
| { | ||
| currentUrl = ParseStringValue(trimmed); | ||
| } | ||
| else if (trimmed.StartsWith("status =")) | ||
| { | ||
| currentStatus = ParseStringValue(trimmed); | ||
| } | ||
| else if (trimmed.StartsWith("players = list(")) | ||
| { | ||
| // "players = list("Bob","Alice")" | ||
| // Just count the commas + 1, correcting for empty list "list()" | ||
| var content = trimmed.Substring("players = list(".Length); | ||
| if (content.EndsWith(")")) | ||
| { | ||
| content = content.Substring(0, content.Length - 1); | ||
| if (string.IsNullOrWhiteSpace(content)) | ||
| { | ||
| currentPlayers = 0; | ||
| } | ||
| else | ||
| { | ||
| // A simple Count(',') + 1 is risky if names contain commas, but usually they are quoted. | ||
| // However, parsing full CSV is safer but 'Splitting by ",' might be enough? | ||
| // Let's iterate and count quoted segments. | ||
| // Or simpler: Splitting by ',' is mostly fine for SS13 ckeys. | ||
| currentPlayers = content.Split(',').Length; | ||
| } | ||
| } | ||
| } | ||
| else if (trimmed.StartsWith("players =")) | ||
| { | ||
| // Fallback for simple number if ever used | ||
| var parts = trimmed.Split('='); | ||
| if (parts.Length > 1 && int.TryParse(parts[1].Trim(), out var p)) | ||
| { | ||
| currentPlayers = p; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Add the last one if exists | ||
| if (inServerBlock && currentUrl != null) | ||
| { | ||
| var name = currentName ?? ExtractNameFromStatus(currentStatus) ?? "Unknown Server"; | ||
| var roundTime = ExtractRoundTimeFromStatus(currentStatus); | ||
| list.Add(new ClassicServerStatusData(name, currentUrl, currentPlayers, CleanStatus(currentStatus, name) ?? "", roundTime ?? "In-Lobby")); | ||
| } | ||
|
|
||
| return list; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could all be made into a regex
| public string Name { get; set; } = string.Empty; | ||
| public string Address { get; set; } = string.Empty; | ||
| public int PlayerCount { get; set; } | ||
| public string Status { get; set; } = string.Empty; | ||
| public string RoundTime { get; set; } = string.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these not default to empty strings?
| // Prompt to download | ||
| // We can use the native MessageBox helper from Helpers if available or just open the link. | ||
| // Following the prompt instructions mostly literally: "prompted to install it first by going to this link" | ||
|
|
||
| // On Windows we can use the MessageBox to be nicer. | ||
| // NOTE: Helper MessageBox returns int, 1 is usually OK. | ||
| if (OperatingSystem.IsWindows()) | ||
| { | ||
| var res = Helpers.MessageBoxHelper( | ||
| "BYOND not detected. You need the BYOND client to play Space Station 13. Go to download page?", | ||
| "BYOND Missing", | ||
| 0x00000004 | 0x00000030); // MB_YESNO | MB_ICONWARNING | ||
|
|
||
| if (res == 6) // IDYES | ||
| { | ||
| Helpers.OpenUri(new Uri("https://www.byond.com/download/")); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| // Non-windows, just open the link? Or maybe they have it via Wine? | ||
| // For now, let's open the link if we can't be sure, or maybe just try launching it? | ||
| // The prompt was "Check if they have BYOND... If not... prompt". | ||
| // Since I can't check on Linux easily, I'll assume they might not have it if I can't check. | ||
| // But actually, opening the URI is the best 'try'. | ||
| // Let's just try to open it on non-windows. | ||
| Helpers.OpenUri(new Uri(_server.Address)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the existing in-app notification dialog helper instead of worrying about platform
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And use the compiler flags for platform instead of ifs
| if (!OperatingSystem.IsWindows()) | ||
| { | ||
| // On Linux/Mac, we can't easily check for BYOND (usually running under Wine). | ||
| // We'll return true to let the OS/Wine try to handle the protocol. | ||
| return true; | ||
| } | ||
|
|
||
| try | ||
| { | ||
| // Check for BYOND in Registry | ||
| // HKCU\Software\Dantom\BYOND is the standard key. | ||
| using var key = Registry.CurrentUser.OpenSubKey(@"Software\Dantom\BYOND"); | ||
| return key != null; | ||
| } | ||
| catch | ||
| { | ||
| return false; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto on the compiler flags. I can make a check for an xdg protocol for linux, mac will be left unhandled yet again, and I'll see if we can do this without a try/catch.


This PR adds a new tab for "Classic Servers", which provides the list of all Space Station 13 servers for the user to search through. These servers can be connected to via simple button, though the user is required to have the Byond client installed. If they don't have it, they'll be prompted to install it from byond's website.
I have tested this PR and verified that it works.
AuroraThroughSteam.mp4