mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Merge branch 'main' into user-pfp-discord-rpc
This commit is contained in:
commit
3855ac68dd
9
Bloxstrap/GlobalCache.cs
Normal file
9
Bloxstrap/GlobalCache.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Bloxstrap
|
||||
{
|
||||
public static class GlobalCache
|
||||
{
|
||||
public static readonly Dictionary<string, Task> PendingTasks = new();
|
||||
|
||||
public static readonly Dictionary<string, string> ServerLocation = new();
|
||||
}
|
||||
}
|
@ -494,7 +494,7 @@ namespace Bloxstrap
|
||||
string oldStartPath = Path.Combine(Paths.WindowsStartMenu, "Bloxstrap");
|
||||
|
||||
if (File.Exists(oldDesktopPath))
|
||||
File.Move(oldDesktopPath, DesktopShortcut);
|
||||
File.Move(oldDesktopPath, DesktopShortcut, true);
|
||||
|
||||
if (Directory.Exists(oldStartPath))
|
||||
{
|
||||
|
@ -127,7 +127,6 @@ namespace Bloxstrap.Integrations
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: i need to double check how this handles failed game joins (connection error, invalid permissions, etc)
|
||||
private void ReadLogEntry(string entry)
|
||||
{
|
||||
const string LOG_IDENT = "ActivityWatcher::ReadLogEntry";
|
||||
@ -144,7 +143,17 @@ namespace Bloxstrap.Integrations
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Read {_logEntriesRead} log entries");
|
||||
|
||||
if (entry.Contains(GameLeavingEntry))
|
||||
OnAppClose?.Invoke(this, new EventArgs());
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, "User is back into the desktop app");
|
||||
|
||||
OnAppClose?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
if (Data.PlaceId != 0 && !InGame)
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, "User appears to be leaving from a cancelled/errored join");
|
||||
Data = new();
|
||||
}
|
||||
}
|
||||
|
||||
if (!InGame && Data.PlaceId == 0)
|
||||
{
|
||||
@ -183,6 +192,9 @@ namespace Bloxstrap.Integrations
|
||||
Data.JobId = match.Groups[1].Value;
|
||||
Data.MachineAddress = match.Groups[3].Value;
|
||||
|
||||
if (App.Settings.Prop.ShowServerDetails && Data.MachineAddressValid)
|
||||
_ = Data.QueryServerLocation();
|
||||
|
||||
if (_teleportMarker)
|
||||
{
|
||||
Data.IsTeleport = true;
|
||||
@ -195,7 +207,7 @@ namespace Bloxstrap.Integrations
|
||||
_reservedTeleportMarker = false;
|
||||
}
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Joining Game ({Data.PlaceId}/{Data.JobId}/{Data.MachineAddress})");
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Joining Game ({Data})");
|
||||
}
|
||||
}
|
||||
else if (!InGame && Data.PlaceId != 0)
|
||||
@ -234,7 +246,7 @@ namespace Bloxstrap.Integrations
|
||||
{
|
||||
var lastActivity = History.First();
|
||||
|
||||
if (lastActivity is not null && Data.UniverseId == lastActivity.UniverseId && Data.IsTeleport)
|
||||
if (Data.UniverseId == lastActivity.UniverseId && Data.IsTeleport)
|
||||
Data.RootActivity = lastActivity.RootActivity ?? lastActivity;
|
||||
}
|
||||
}
|
||||
@ -251,7 +263,10 @@ namespace Bloxstrap.Integrations
|
||||
|
||||
Data.MachineAddress = match.Groups[1].Value;
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Server is UDMUX protected ({Data.PlaceId}/{Data.JobId}/{Data.MachineAddress})");
|
||||
if (App.Settings.Prop.ShowServerDetails)
|
||||
_ = Data.QueryServerLocation();
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Server is UDMUX protected ({Data})");
|
||||
}
|
||||
else if (entry.Contains(GameJoinedEntry))
|
||||
{
|
||||
@ -264,7 +279,7 @@ namespace Bloxstrap.Integrations
|
||||
return;
|
||||
}
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Joined Game ({Data.PlaceId}/{Data.JobId}/{Data.MachineAddress})");
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Joined Game ({Data})");
|
||||
|
||||
InGame = true;
|
||||
Data.TimeJoined = DateTime.Now;
|
||||
@ -278,7 +293,7 @@ namespace Bloxstrap.Integrations
|
||||
|
||||
if (entry.Contains(GameDisconnectedEntry))
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Disconnected from Game ({Data.PlaceId}/{Data.JobId}/{Data.MachineAddress})");
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Disconnected from Game ({Data})");
|
||||
|
||||
Data.TimeLeft = DateTime.Now;
|
||||
History.Insert(0, Data);
|
||||
@ -290,7 +305,7 @@ namespace Bloxstrap.Integrations
|
||||
}
|
||||
else if (entry.Contains(GameTeleportingEntry))
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Initiating teleport to server ({Data.PlaceId}/{Data.JobId}/{Data.MachineAddress})");
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Initiating teleport to server ({Data})");
|
||||
_teleportMarker = true;
|
||||
}
|
||||
else if (_teleportMarker && entry.Contains(GameJoiningReservedServerEntry))
|
||||
@ -378,44 +393,6 @@ namespace Bloxstrap.Integrations
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetServerLocation()
|
||||
{
|
||||
const string LOG_IDENT = "ActivityWatcher::GetServerLocation";
|
||||
|
||||
if (GeolocationCache.ContainsKey(Data.MachineAddress))
|
||||
return GeolocationCache[Data.MachineAddress];
|
||||
|
||||
try
|
||||
{
|
||||
string location = "";
|
||||
var ipInfo = await Http.GetJson<IPInfoResponse>($"https://ipinfo.io/{Data.MachineAddress}/json");
|
||||
|
||||
if (String.IsNullOrEmpty(ipInfo.City))
|
||||
throw new InvalidHTTPResponseException("Reported city was blank");
|
||||
|
||||
if (ipInfo.City == ipInfo.Region)
|
||||
location = $"{ipInfo.Region}, {ipInfo.Country}";
|
||||
else
|
||||
location = $"{ipInfo.City}, {ipInfo.Region}, {ipInfo.Country}";
|
||||
|
||||
GeolocationCache[Data.MachineAddress] = location;
|
||||
|
||||
if (!InGame)
|
||||
return "";
|
||||
|
||||
return location;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {Data.MachineAddress}");
|
||||
App.Logger.WriteException(LOG_IDENT, ex);
|
||||
|
||||
Frontend.ShowMessageBox($"{Strings.ActivityWatcher_LocationQueryFailed}\n\n{ex.Message}", MessageBoxImage.Warning);
|
||||
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Web;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
@ -38,6 +39,8 @@ namespace Bloxstrap.Models
|
||||
|
||||
public string UserId { get; set; } = String.Empty;
|
||||
|
||||
public bool MachineAddressValid => !String.IsNullOrEmpty(MachineAddress) && !MachineAddress.StartsWith("10.");
|
||||
|
||||
public bool IsTeleport { get; set; } = false;
|
||||
|
||||
public ServerType ServerType { get; set; } = ServerType.Public;
|
||||
@ -85,6 +88,55 @@ namespace Bloxstrap.Models
|
||||
return deeplink;
|
||||
}
|
||||
|
||||
public async Task<string> QueryServerLocation()
|
||||
{
|
||||
const string LOG_IDENT = "ActivityData::QueryServerLocation";
|
||||
|
||||
if (!MachineAddressValid)
|
||||
throw new InvalidOperationException($"Machine address is invalid ({MachineAddress})");
|
||||
|
||||
if (GlobalCache.PendingTasks.TryGetValue(MachineAddress, out Task? task))
|
||||
await task;
|
||||
|
||||
if (GlobalCache.ServerLocation.TryGetValue(MachineAddress, out string? location))
|
||||
return location;
|
||||
|
||||
try
|
||||
{
|
||||
location = "";
|
||||
var ipInfoTask = Http.GetJson<IPInfoResponse>($"https://ipinfo.io/{MachineAddress}/json");
|
||||
|
||||
GlobalCache.PendingTasks.Add(MachineAddress, ipInfoTask);
|
||||
|
||||
var ipInfo = await ipInfoTask;
|
||||
|
||||
GlobalCache.PendingTasks.Remove(MachineAddress);
|
||||
|
||||
if (String.IsNullOrEmpty(ipInfo.City))
|
||||
throw new InvalidHTTPResponseException("Reported city was blank");
|
||||
|
||||
if (ipInfo.City == ipInfo.Region)
|
||||
location = $"{ipInfo.Region}, {ipInfo.Country}";
|
||||
else
|
||||
location = $"{ipInfo.City}, {ipInfo.Region}, {ipInfo.Country}";
|
||||
|
||||
GlobalCache.ServerLocation[MachineAddress] = location;
|
||||
|
||||
return location;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {MachineAddress}");
|
||||
App.Logger.WriteException(LOG_IDENT, ex);
|
||||
|
||||
Frontend.ShowMessageBox($"{Strings.ActivityWatcher_LocationQueryFailed}\n\n{ex.Message}", MessageBoxImage.Warning);
|
||||
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => $"{PlaceId}/{JobId}";
|
||||
|
||||
private void RejoinServer()
|
||||
{
|
||||
string playerPath = Path.Combine(Paths.Versions, App.State.Prop.PlayerVersionGuid, "RobloxPlayerBeta.exe");
|
||||
|
47
Bloxstrap/Resources/Strings.Designer.cs
generated
47
Bloxstrap/Resources/Strings.Designer.cs
generated
@ -719,15 +719,6 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Loading, please wait....
|
||||
/// </summary>
|
||||
public static string ContextMenu_ServerInformation_Loading {
|
||||
get {
|
||||
return ResourceManager.GetString("ContextMenu.ServerInformation.Loading", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Location.
|
||||
/// </summary>
|
||||
@ -2727,7 +2718,25 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This feature requires activity tracking to be enabled and the Discord desktop app to be installed and running..
|
||||
/// Looks up a localized string similar to When in-game, you'll be able to see where your server is located via [ipinfo.io]({0})..
|
||||
/// </summary>
|
||||
public static string Menu_Integrations_QueryServerLocation_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Integrations.QueryServerLocation.Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Query server location.
|
||||
/// </summary>
|
||||
public static string Menu_Integrations_QueryServerLocation_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Integrations.QueryServerLocation.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This feature requires activity tracking to be enabled and the Discord desktop app to be installed and running. [Find out more]({0})..
|
||||
/// </summary>
|
||||
public static string Menu_Integrations_RequiresActivityTracking {
|
||||
get {
|
||||
@ -2753,24 +2762,6 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to When you join a game, you'll be notified of where your server's located. Won't show in fullscreen..
|
||||
/// </summary>
|
||||
public static string Menu_Integrations_ShowServerDetails_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Integrations.ShowServerDetails.Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to See server location when joining a game.
|
||||
/// </summary>
|
||||
public static string Menu_Integrations_ShowServerDetails_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Integrations.ShowServerDetails.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Integrations.
|
||||
/// </summary>
|
||||
|
@ -268,9 +268,6 @@ Your ReShade configuration files will still be saved, and you can locate them by
|
||||
<data name="ContextMenu.ServerInformation.InstanceId" xml:space="preserve">
|
||||
<value>Instance ID</value>
|
||||
</data>
|
||||
<data name="ContextMenu.ServerInformation.Loading" xml:space="preserve">
|
||||
<value>Loading, please wait...</value>
|
||||
</data>
|
||||
<data name="ContextMenu.ServerInformation.Location" xml:space="preserve">
|
||||
<value>Location</value>
|
||||
</data>
|
||||
@ -761,7 +758,7 @@ Selecting 'No' will ignore this warning and continue installation.</value>
|
||||
<value>Enable activity tracking</value>
|
||||
</data>
|
||||
<data name="Menu.Integrations.RequiresActivityTracking" xml:space="preserve">
|
||||
<value>This feature requires activity tracking to be enabled and the Discord desktop app to be installed and running.</value>
|
||||
<value>This feature requires activity tracking to be enabled and the Discord desktop app to be installed and running. [Find out more]({0}).</value>
|
||||
</data>
|
||||
<data name="Menu.Integrations.ShowGameActivity.Description" xml:space="preserve">
|
||||
<value>The Roblox game you're playing will be shown on your Discord profile. [Not working?]({0})</value>
|
||||
@ -769,11 +766,11 @@ Selecting 'No' will ignore this warning and continue installation.</value>
|
||||
<data name="Menu.Integrations.ShowGameActivity.Title" xml:space="preserve">
|
||||
<value>Show game activity</value>
|
||||
</data>
|
||||
<data name="Menu.Integrations.ShowServerDetails.Description" xml:space="preserve">
|
||||
<value>When you join a game, you'll be notified of where your server's located. Won't show in fullscreen.</value>
|
||||
<data name="Menu.Integrations.QueryServerLocation.Description" xml:space="preserve">
|
||||
<value>When in-game, you'll be able to see where your server is located via [ipinfo.io]({0}).</value>
|
||||
</data>
|
||||
<data name="Menu.Integrations.ShowServerDetails.Title" xml:space="preserve">
|
||||
<value>See server location when joining a game</value>
|
||||
<data name="Menu.Integrations.QueryServerLocation.Title" xml:space="preserve">
|
||||
<value>Query server location</value>
|
||||
</data>
|
||||
<data name="Menu.Integrations.Title" xml:space="preserve">
|
||||
<value>Integrations</value>
|
||||
|
@ -28,6 +28,8 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
||||
|
||||
private ServerInformation? _serverInformationWindow;
|
||||
|
||||
private ServerHistory? _gameHistoryWindow;
|
||||
|
||||
public MenuContainer(Watcher watcher)
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -51,14 +53,14 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
||||
{
|
||||
if (_serverInformationWindow is null)
|
||||
{
|
||||
_serverInformationWindow = new ServerInformation(_watcher);
|
||||
_serverInformationWindow = new(_watcher);
|
||||
_serverInformationWindow.Closed += (_, _) => _serverInformationWindow = null;
|
||||
}
|
||||
|
||||
if (!_serverInformationWindow.IsVisible)
|
||||
_serverInformationWindow.Show();
|
||||
|
||||
_serverInformationWindow.Activate();
|
||||
_serverInformationWindow.ShowDialog();
|
||||
else
|
||||
_serverInformationWindow.Activate();
|
||||
}
|
||||
|
||||
public void ActivityWatcher_OnLogOpen(object? sender, EventArgs e) =>
|
||||
@ -135,7 +137,16 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
||||
if (_activityWatcher is null)
|
||||
throw new ArgumentNullException(nameof(_activityWatcher));
|
||||
|
||||
new ServerHistory(_activityWatcher).ShowDialog();
|
||||
if (_gameHistoryWindow is null)
|
||||
{
|
||||
_gameHistoryWindow = new(_activityWatcher);
|
||||
_gameHistoryWindow.Closed += (_, _) => _gameHistoryWindow = null;
|
||||
}
|
||||
|
||||
if (!_gameHistoryWindow.IsVisible)
|
||||
_gameHistoryWindow.ShowDialog();
|
||||
else
|
||||
_gameHistoryWindow.Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,14 +46,14 @@
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_InstanceId}" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding InstanceId, Mode=OneWay}" />
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_Location}" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerLocation, Mode=OneWay}" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_Location}" Visibility="{Binding ServerLocationVisibility, Mode=OneTime}" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerLocation, Mode=OneWay}" Visibility="{Binding ServerLocationVisibility, Mode=OneTime}" />
|
||||
</Grid>
|
||||
|
||||
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
|
||||
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
|
||||
<Button MinWidth="100" Content="{x:Static resources:Strings.ContextMenu_ServerInformation_CopyInstanceId}" Command="{Binding CopyInstanceIdCommand, Mode=OneTime}" />
|
||||
<Button Margin="12,0,0,0" MinWidth="100" Content="{x:Static resources:Strings.Common_Close}" Command="{Binding CloseWindowCommand, Mode=OneTime}" />
|
||||
<Button Margin="12,0,0,0" MinWidth="100" Content="{x:Static resources:Strings.Common_Close}" IsCancel="True" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
@ -24,11 +24,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
||||
{
|
||||
public ServerInformation(Watcher watcher)
|
||||
{
|
||||
var viewModel = new ServerInformationViewModel(watcher);
|
||||
|
||||
viewModel.RequestCloseEvent += (_, _) => Close();
|
||||
|
||||
DataContext = viewModel;
|
||||
DataContext = new ServerInformationViewModel(watcher);
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,9 @@
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Description}"
|
||||
Header="{x:Static resources:Strings.Menu_Integrations_QueryServerLocation_Title}"
|
||||
Description="{Binding Source={x:Static resources:Strings.Menu_Integrations_QueryServerLocation_Description}, Converter={StaticResource StringFormatConverter}, ConverterParameter='https://ipinfo.io'}"
|
||||
HelpLink="https://github.com/pizzaboxer/bloxstrap/wiki/What-is-activity-tracking%3F#server-location-querying"
|
||||
IsEnabled="{Binding InnerContent.IsChecked, ElementName=ActivityTrackingOption, Mode=OneWay}">
|
||||
<ui:ToggleSwitch IsChecked="{Binding ShowServerDetailsEnabled, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
@ -40,7 +41,7 @@
|
||||
</controls:OptionControl>
|
||||
|
||||
<TextBlock Text="{x:Static resources:Strings.Common_DiscordRichPresence}" FontSize="20" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<TextBlock Text="{x:Static resources:Strings.Menu_Integrations_RequiresActivityTracking}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<controls:MarkdownTextBlock MarkdownText="{Binding Source={x:Static resources:Strings.Menu_Integrations_RequiresActivityTracking}, Converter={StaticResource StringFormatConverter}, ConverterParameter='https://github.com/pizzaboxer/bloxstrap/wiki/What-is-activity-tracking%3F#discord-rich-presence'}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Integrations_ShowGameActivity_Title}"
|
||||
|
@ -26,7 +26,7 @@ namespace Bloxstrap.UI
|
||||
|
||||
_watcher = watcher;
|
||||
|
||||
_notifyIcon = new()
|
||||
_notifyIcon = new(new System.ComponentModel.Container())
|
||||
{
|
||||
Icon = Properties.Resources.IconBloxstrap,
|
||||
Text = App.ProjectName,
|
||||
@ -35,7 +35,7 @@ namespace Bloxstrap.UI
|
||||
|
||||
_notifyIcon.MouseClick += MouseClickEventHandler;
|
||||
|
||||
if (_activityWatcher is not null)
|
||||
if (_activityWatcher is not null && App.Settings.Prop.ShowServerDetails)
|
||||
_activityWatcher.OnGameJoin += OnGameJoin;
|
||||
|
||||
_menuContainer = new(_watcher);
|
||||
@ -59,7 +59,7 @@ namespace Bloxstrap.UI
|
||||
if (_activityWatcher is null)
|
||||
return;
|
||||
|
||||
string serverLocation = await _activityWatcher.GetServerLocation();
|
||||
string serverLocation = await _activityWatcher.Data.QueryServerLocation();
|
||||
|
||||
if (string.IsNullOrEmpty(serverLocation))
|
||||
return;
|
||||
@ -81,6 +81,7 @@ namespace Bloxstrap.UI
|
||||
}
|
||||
#endregion
|
||||
|
||||
// we may need to create our own handler for this, because this sorta sucks
|
||||
public void ShowAlert(string caption, string message, int duration, EventHandler? clickHandler)
|
||||
{
|
||||
string id = Guid.NewGuid().ToString()[..8];
|
||||
|
@ -36,8 +36,7 @@ namespace Bloxstrap.UI.ViewModels.ContextMenu
|
||||
|
||||
if (entries.Any())
|
||||
{
|
||||
// TODO: this will duplicate universe ids
|
||||
string universeIds = String.Join(',', entries.Select(x => x.UniverseId));
|
||||
string universeIds = String.Join(',', entries.GroupBy(x => x.UniverseId).Select(x => x.First()));
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -13,27 +13,28 @@ namespace Bloxstrap.UI.ViewModels.ContextMenu
|
||||
|
||||
public string ServerType => _activityWatcher.Data.ServerType.ToTranslatedString();
|
||||
|
||||
public string ServerLocation { get; private set; } = Strings.ContextMenu_ServerInformation_Loading;
|
||||
public string ServerLocation { get; private set; } = Strings.Common_Loading;
|
||||
|
||||
public Visibility ServerLocationVisibility => App.Settings.Prop.ShowServerDetails ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public ICommand CopyInstanceIdCommand => new RelayCommand(CopyInstanceId);
|
||||
|
||||
public ICommand CloseWindowCommand => new RelayCommand(RequestClose);
|
||||
|
||||
public EventHandler? RequestCloseEvent;
|
||||
|
||||
public ServerInformationViewModel(Watcher watcher)
|
||||
{
|
||||
_activityWatcher = watcher.ActivityWatcher!;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
ServerLocation = await _activityWatcher.GetServerLocation();
|
||||
OnPropertyChanged(nameof(ServerLocation));
|
||||
});
|
||||
if (ServerLocationVisibility == Visibility.Visible)
|
||||
QueryServerLocation();
|
||||
}
|
||||
|
||||
public async void QueryServerLocation()
|
||||
{
|
||||
ServerLocation = await _activityWatcher.Data.QueryServerLocation();
|
||||
OnPropertyChanged(nameof(ServerLocation));
|
||||
}
|
||||
|
||||
private void CopyInstanceId() => Clipboard.SetDataObject(InstanceId);
|
||||
|
||||
private void RequestClose() => RequestCloseEvent?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
namespace Bloxstrap.UI.ViewModels.Installer
|
||||
{
|
||||
// TODO: administrator check?
|
||||
public class WelcomeViewModel : NotifyPropertyChangedViewModel
|
||||
{
|
||||
// formatting is done here instead of in xaml, it's just a bit easier
|
||||
|
Loading…
Reference in New Issue
Block a user