mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-13 16:51:29 -07:00
150 lines
5.0 KiB
C#
150 lines
5.0 KiB
C#
using System.Web;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using Bloxstrap.Models.APIs;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
namespace Bloxstrap.Models.Entities
|
|
{
|
|
public class ActivityData
|
|
{
|
|
private long _universeId = 0;
|
|
|
|
/// <summary>
|
|
/// If the current activity stems from an in-universe teleport, then this will be
|
|
/// set to the activity that corresponds to the initial game join
|
|
/// </summary>
|
|
public ActivityData? RootActivity;
|
|
|
|
public long UniverseId
|
|
{
|
|
get => _universeId;
|
|
set
|
|
{
|
|
_universeId = value;
|
|
UniverseDetails.LoadFromCache(value);
|
|
}
|
|
}
|
|
|
|
public long PlaceId { get; set; } = 0;
|
|
|
|
public string JobId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// This will be empty unless the server joined is a private server
|
|
/// </summary>
|
|
public string AccessCode { get; set; } = string.Empty;
|
|
|
|
public string MachineAddress { 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;
|
|
|
|
public DateTime TimeJoined { get; set; }
|
|
|
|
public DateTime? TimeLeft { get; set; }
|
|
|
|
// everything below here is optional strictly for bloxstraprpc, discord rich presence, or game history
|
|
|
|
/// <summary>
|
|
/// This is intended only for other people to use, i.e. context menu invite link, rich presence joining
|
|
/// </summary>
|
|
public string RPCLaunchData { get; set; } = string.Empty;
|
|
|
|
public UniverseDetails? UniverseDetails { get; set; }
|
|
|
|
public string GameHistoryDescription
|
|
{
|
|
get
|
|
{
|
|
string desc = string.Format("{0} • {1} - {2}", UniverseDetails?.Data.Creator.Name, TimeJoined.ToString("h:mm tt"), TimeLeft?.ToString("h:mm tt"));
|
|
|
|
if (ServerType != ServerType.Public)
|
|
desc += " • " + ServerType.ToTranslatedString();
|
|
|
|
return desc;
|
|
}
|
|
}
|
|
|
|
public ICommand RejoinServerCommand => new RelayCommand(RejoinServer);
|
|
|
|
private SemaphoreSlim serverQuerySemaphore = new(1, 1);
|
|
|
|
public string GetInviteDeeplink(bool launchData = true)
|
|
{
|
|
string deeplink = $"roblox://experiences/start?placeId={PlaceId}";
|
|
|
|
if (ServerType == ServerType.Private)
|
|
deeplink += "&accessCode=" + AccessCode;
|
|
else
|
|
deeplink += "&gameInstanceId=" + JobId;
|
|
|
|
if (launchData && !string.IsNullOrEmpty(RPCLaunchData))
|
|
deeplink += "&launchData=" + HttpUtility.UrlEncode(RPCLaunchData);
|
|
|
|
return deeplink;
|
|
}
|
|
|
|
public async Task<string?> QueryServerLocation()
|
|
{
|
|
const string LOG_IDENT = "ActivityData::QueryServerLocation";
|
|
|
|
if (!MachineAddressValid)
|
|
throw new InvalidOperationException($"Machine address is invalid ({MachineAddress})");
|
|
|
|
await serverQuerySemaphore.WaitAsync();
|
|
|
|
if (GlobalCache.ServerLocation.TryGetValue(MachineAddress, out string? location))
|
|
{
|
|
serverQuerySemaphore.Release();
|
|
return location;
|
|
}
|
|
|
|
try
|
|
{
|
|
var ipInfo = await Http.GetJson<IPInfoResponse>($"https://ipinfo.io/{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}";
|
|
|
|
GlobalCache.ServerLocation[MachineAddress] = location;
|
|
serverQuerySemaphore.Release();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {MachineAddress}");
|
|
App.Logger.WriteException(LOG_IDENT, ex);
|
|
|
|
GlobalCache.ServerLocation[MachineAddress] = location;
|
|
serverQuerySemaphore.Release();
|
|
|
|
Frontend.ShowConnectivityDialog(
|
|
string.Format(Strings.Dialog_Connectivity_UnableToConnect, "ipinfo.io"),
|
|
Strings.ActivityWatcher_LocationQueryFailed,
|
|
MessageBoxImage.Warning,
|
|
ex
|
|
);
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
public override string ToString() => $"{PlaceId}/{JobId}";
|
|
|
|
private void RejoinServer()
|
|
{
|
|
string playerPath = Path.Combine(Paths.Roblox, "Player", "RobloxPlayerBeta.exe");
|
|
|
|
Process.Start(playerPath, GetInviteDeeplink(false));
|
|
}
|
|
}
|
|
}
|