Skip to content

Commit c0fcbcb

Browse files
committed
this shit is so code
1 parent b98b473 commit c0fcbcb

File tree

10 files changed

+68
-95
lines changed

10 files changed

+68
-95
lines changed

.vscode/launch.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

SS14.Launcher.sln.DotSettings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
44
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VM/@EntryIndexedValue">VM</s:String>
55
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean>
6+
<s:Boolean x:Key="/Default/UserDictionary/Words/=byond/@EntryIndexedValue">True</s:Boolean>
67
<s:Boolean x:Key="/Default/UserDictionary/Words/=prerelease/@EntryIndexedValue">True</s:Boolean>
78
<s:Boolean x:Key="/Default/UserDictionary/Words/=ROWID/@EntryIndexedValue">True</s:Boolean>
89
<s:Boolean x:Key="/Default/UserDictionary/Words/=zeroblob/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

SS14.Launcher/Assets/Locale/en-US/text.ftl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,10 @@ region-short-south-america-west = SA West
234234
## Strings for the "servers" tab
235235

236236
tab-servers-title = Servers
237-
tab-servers-classic-title = Classic Servers
238-
tab-servers-classic-desc = All servers listed here connect via the BYOND client.
237+
tab-servers-byond-title = BYOND Servers
238+
tab-servers-byond-error-msg = BYOND not installed or found
239+
tab-servers-byond-error-desc = To connect to BYOND servers, please install BYOND from https://www.byond.com/download/ and ensure it is set as the default program for handling byond:// links.
240+
tab-servers-byond-error-link-text = Download BYOND
239241
tab-servers-refresh = Refresh
240242
filters = Filters ({ $filteredServers } / { $totalServers })
241243
tab-servers-search-watermark = Search For Servers…

SS14.Launcher/Models/ServerStatus/ClassicServerListCache.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ public async Task Refresh()
2929
try
3030
{
3131
var response = await _http.GetStringAsync("http://www.byond.com/games/exadv1/spacestation13?format=text");
32-
// Log.Information("BYOND Response: {Response}", response);
33-
await File.WriteAllTextAsync("byond_dump.txt", response);
3432
var servers = ParseByondResponse(response);
3533

3634
Avalonia.Threading.Dispatcher.UIThread.Post(() =>
@@ -79,7 +77,7 @@ private List<ClassicServerStatusData> ParseByondResponse(string response)
7977
var roundTime = ExtractRoundTimeFromStatus(currentStatus);
8078
list.Add(new ClassicServerStatusData(name, currentUrl, currentPlayers, CleanStatus(currentStatus, name) ?? "", roundTime ?? "In-Lobby"));
8179
}
82-
80+
8381
// Reset for new server
8482
inServerBlock = true;
8583
currentName = null;
@@ -149,7 +147,7 @@ private List<ClassicServerStatusData> ParseByondResponse(string response)
149147
private string? ExtractRoundTimeFromStatus(string? status)
150148
{
151149
if (string.IsNullOrEmpty(status)) return null;
152-
150+
153151
// Try to match "Round time: <b>00:07</b>" or similar
154152
var match = System.Text.RegularExpressions.Regex.Match(status, @"Round\s+time:\s+(?:<b>)?(\d{1,2}:\d{2})(?:</b>)?", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
155153
if (match.Success)
@@ -171,20 +169,20 @@ private List<ClassicServerStatusData> ParseByondResponse(string response)
171169
var clean = System.Text.RegularExpressions.Regex.Replace(raw, "<.*?>", String.Empty);
172170
return System.Net.WebUtility.HtmlDecode(clean);
173171
}
174-
return null;
172+
return null;
175173
}
176174

177175
private string? CleanStatus(string? status, string? nameToRemove)
178176
{
179177
if (string.IsNullOrEmpty(status)) return null;
180-
178+
181179
var s = status.Replace("<br>", "\n").Replace("<br/>", "\n").Replace("<br />", "\n");
182180
// Remove tags
183181
s = System.Text.RegularExpressions.Regex.Replace(s, "<.*?>", String.Empty);
184-
182+
185183
// Decode HTML
186184
s = System.Net.WebUtility.HtmlDecode(s);
187-
185+
188186
if (nameToRemove != null && s.StartsWith(nameToRemove))
189187
{
190188
s = s.Substring(nameToRemove.Length);
@@ -211,13 +209,13 @@ private string ParseStringValue(string line)
211209

212210
// Extract content inside quotes
213211
var inner = line.Substring(idx + 1, lastIdx - idx - 1);
214-
212+
215213
// Unescape BYOND/C string escapes
216214
// \" -> "
217215
// \n -> newline
218216
// \\ -> \
219217
// The most critical one is \n showing up as literal \n in UI.
220-
218+
221219
// Simple manual unescape for common sequences
222220
return inner.Replace("\\\"", "\"")
223221
.Replace("\\n", "\n")
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
1-
using System.Collections.Generic;
2-
31
namespace SS14.Launcher.Models.ServerStatus;
42

5-
public class ClassicServerStatusData
3+
public class ClassicServerStatusData(string name, string address, int playerCount, string status, string roundTime)
64
{
7-
public string Name { get; set; } = string.Empty;
8-
public string Address { get; set; } = string.Empty;
9-
public int PlayerCount { get; set; }
10-
public string Status { get; set; } = string.Empty;
11-
public string RoundTime { get; set; } = string.Empty;
12-
13-
public ClassicServerStatusData(string name, string address, int playerCount, string status, string roundTime)
14-
{
15-
Name = name;
16-
Address = address;
17-
PlayerCount = playerCount;
18-
Status = status;
19-
RoundTime = roundTime;
20-
}
5+
public string Name { get; } = name;
6+
public string Address { get; } = address;
7+
public int PlayerCount { get; } = playerCount;
8+
public string Status { get; } = status;
9+
public string RoundTime { get; } = roundTime;
2110
}
Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
using System;
22
using System.Diagnostics;
3-
using Microsoft.Win32;
43
using ReactiveUI;
5-
using SS14.Launcher;
4+
using Serilog;
5+
using Splat;
66
using SS14.Launcher.Localization;
7+
using SS14.Launcher.Models;
78
using SS14.Launcher.Models.ServerStatus;
8-
using SS14.Launcher.ViewModels;
9+
using SS14.Launcher.Utility;
910

1011
namespace SS14.Launcher.ViewModels.MainWindowTabs;
1112

1213
public class ClassicServerEntryViewModel : ViewModelBase
1314
{
15+
private readonly MainWindowViewModel _mainWindow;
1416
private readonly ClassicServerStatusData _server;
1517

1618
public string Name => _server.Name;
@@ -20,6 +22,7 @@ public class ClassicServerEntryViewModel : ViewModelBase
2022
public string RoundTime => _server.RoundTime;
2123

2224
private bool _isExpanded;
25+
2326
public bool IsExpanded
2427
{
2528
get => _isExpanded;
@@ -28,8 +31,9 @@ public bool IsExpanded
2831

2932
public ReactiveCommand<System.Reactive.Unit, System.Reactive.Unit> ConnectCommand { get; }
3033

31-
public ClassicServerEntryViewModel(ClassicServerStatusData server)
34+
public ClassicServerEntryViewModel(MainWindowViewModel mainWindow, ClassicServerStatusData server)
3235
{
36+
_mainWindow = mainWindow;
3337
_server = server;
3438

3539
ConnectCommand = ReactiveCommand.Create(Connect);
@@ -38,61 +42,47 @@ public ClassicServerEntryViewModel(ClassicServerStatusData server)
3842
private void Connect()
3943
{
4044
if (IsByondInstalled())
41-
{
42-
Helpers.OpenUri(new Uri(_server.Address));
43-
}
45+
Helpers.OpenUri(new Uri(Address));
4446
else
4547
{
46-
// Prompt to download
47-
// We can use the native MessageBox helper from Helpers if available or just open the link.
48-
// Following the prompt instructions mostly literally: "prompted to install it first by going to this link"
49-
50-
// On Windows we can use the MessageBox to be nicer.
51-
// NOTE: Helper MessageBox returns int, 1 is usually OK.
52-
if (OperatingSystem.IsWindows())
48+
Log.Information("User attempted to connect to BYOND server but BYOND is not installed.");
49+
// Set the MainWindowViewModel's CustomInfo to show the BYOND not installed message
50+
// I didn't wanna make another dialog, reuse the generic thing :)
51+
_mainWindow.CustomInfo = new LauncherInfoManager.CustomInfo()
5352
{
54-
var res = Helpers.MessageBoxHelper(
55-
"BYOND not detected. You need the BYOND client to play Space Station 13. Go to download page?",
56-
"BYOND Missing",
57-
0x00000004 | 0x00000030); // MB_YESNO | MB_ICONWARNING
58-
59-
if (res == 6) // IDYES
60-
{
61-
Helpers.OpenUri(new Uri("https://www.byond.com/download/"));
62-
}
63-
}
64-
else
65-
{
66-
// Non-windows, just open the link? Or maybe they have it via Wine?
67-
// For now, let's open the link if we can't be sure, or maybe just try launching it?
68-
// The prompt was "Check if they have BYOND... If not... prompt".
69-
// Since I can't check on Linux easily, I'll assume they might not have it if I can't check.
70-
// But actually, opening the URI is the best 'try'.
71-
// Let's just try to open it on non-windows.
72-
Helpers.OpenUri(new Uri(_server.Address));
73-
}
53+
Message = LocalizationManager.Instance.GetString("tab-servers-byond-error-msg"),
54+
Description = LocalizationManager.Instance.GetString("tab-servers-byond-error-desc"),
55+
LinkText = LocalizationManager.Instance.GetString("tab-servers-byond-error-link-text"),
56+
Link = "https://www.byond.com/download/",
57+
};
7458
}
7559
}
7660

7761
private bool IsByondInstalled()
7862
{
79-
if (!OperatingSystem.IsWindows())
63+
#if WINDOWS
64+
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Dantom\BYOND");
65+
return key != null;
66+
#elif LINUX
67+
// Ask xdg-mime if BYOND is registered
68+
var process = new Process
8069
{
81-
// On Linux/Mac, we can't easily check for BYOND (usually running under Wine).
82-
// We'll return true to let the OS/Wine try to handle the protocol.
83-
return true;
84-
}
70+
StartInfo = new ProcessStartInfo
71+
{
72+
FileName = "xdg-mime",
73+
Arguments = "query default x-scheme-handler/byond",
74+
RedirectStandardOutput = true,
75+
UseShellExecute = false,
76+
CreateNoWindow = true,
77+
},
78+
};
79+
process.Start();
80+
var output = process.StandardOutput.ReadToEnd();
81+
process.WaitForExit();
8582

86-
try
87-
{
88-
// Check for BYOND in Registry
89-
// HKCU\Software\Dantom\BYOND is the standard key.
90-
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Dantom\BYOND");
91-
return key != null;
92-
}
93-
catch
94-
{
95-
return false;
96-
}
83+
return !string.IsNullOrWhiteSpace(output);
84+
#elif MACOS
85+
return true; // No idea, they might have it, might not
86+
#endif
9787
}
9888
}

SS14.Launcher/ViewModels/MainWindowTabs/ClassicServerListTabViewModel.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ namespace SS14.Launcher.ViewModels.MainWindowTabs;
1111

1212
public class ClassicServerListTabViewModel : MainWindowTabViewModel
1313
{
14+
private readonly MainWindowViewModel _mainWindow;
1415
private readonly ClassicServerListCache _cache;
1516

1617
private readonly LocalizationManager _loc = LocalizationManager.Instance;
1718

18-
public override string Name => _loc.GetString("tab-servers-classic-title");
19+
public override string Name => _loc.GetString("tab-servers-byond-title");
1920

2021
private string? _searchString;
2122

@@ -32,11 +33,12 @@ public string? SearchString
3233
public ObservableCollection<ClassicServerEntryViewModel> AllServers { get; } = new();
3334
public ReactiveCommand<System.Reactive.Unit, System.Reactive.Unit> RefreshPressed { get; }
3435

35-
public ClassicServerListTabViewModel()
36+
public ClassicServerListTabViewModel(MainWindowViewModel mainWindow)
3637
{
38+
_mainWindow = mainWindow;
3739
_cache = Locator.Current.GetRequiredService<ClassicServerListCache>();
3840
RefreshPressed = ReactiveCommand.CreateFromTask(_cache.Refresh);
39-
41+
4042
// Initial populate if any
4143
UpdateList();
4244

@@ -54,18 +56,18 @@ private void UpdateList()
5456
// Filter then Sort by Players descending
5557
var filtered = _cache.AllServers.Where(DoesSearchMatch);
5658
var sorted = filtered.OrderByDescending(s => s.PlayerCount).ToList();
57-
59+
5860
foreach (var s in sorted)
5961
{
60-
AllServers.Add(new ClassicServerEntryViewModel(s));
62+
AllServers.Add(new ClassicServerEntryViewModel(_mainWindow, s));
6163
}
6264
}
6365

6466
private bool DoesSearchMatch(ClassicServerStatusData data)
6567
{
6668
if (string.IsNullOrWhiteSpace(_searchString))
6769
return true;
68-
70+
6971
return data.Name.Contains(_searchString, System.StringComparison.CurrentCultureIgnoreCase);
7072
}
7173

SS14.Launcher/ViewModels/MainWindowTabs/HomePageViewModel.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Linq;
32
using System.Collections.Generic;
43
using System.Collections.ObjectModel;
54
using System.Diagnostics.CodeAnalysis;

SS14.Launcher/ViewModels/MainWindowTabs/ServerEntryViewModel.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Linq;
44
using Avalonia.Controls;
55
using Avalonia.VisualTree;
6-
using DynamicData;
76
using Microsoft.Toolkit.Mvvm.ComponentModel;
87
using Microsoft.Toolkit.Mvvm.Messaging;
98
using SS14.Launcher.Api;

SS14.Launcher/ViewModels/MainWindowViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public MainWindowViewModel()
5252
_loc = LocalizationManager.Instance;
5353

5454
ServersTab = new ServerListTabViewModel(this);
55-
ClassicServersTab = new ClassicServerListTabViewModel();
55+
ClassicServersTab = new ClassicServerListTabViewModel(this);
5656
NewsTab = new NewsTabViewModel();
5757
HomeTab = new HomePageViewModel(this);
5858
OptionsTab = new OptionsTabViewModel();

0 commit comments

Comments
 (0)