mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Add setting deeplink launch data from BloxstrapRPC
plus a bunch of tweaks to the bootstrapper
This commit is contained in:
parent
719fbb898e
commit
f747f40ca5
@ -281,20 +281,22 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
SetStatus(Strings.Bootstrapper_Status_Starting);
|
SetStatus(Strings.Bootstrapper_Status_Starting);
|
||||||
|
|
||||||
if (App.Settings.Prop.ForceRobloxLanguage)
|
if (_launchMode == LaunchMode.Player)
|
||||||
{
|
{
|
||||||
var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)", RegexOptions.CultureInvariant);
|
if (App.Settings.Prop.ForceRobloxLanguage)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)", RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
if (match.Groups.Count == 2)
|
if (match.Groups.Count == 2)
|
||||||
_launchCommandLine = _launchCommandLine.Replace("robloxLocale:en_us", $"robloxLocale:{match.Groups[1].Value}", StringComparison.InvariantCultureIgnoreCase);
|
_launchCommandLine = _launchCommandLine.Replace("robloxLocale:en_us", $"robloxLocale:{match.Groups[1].Value}", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(_launchCommandLine))
|
||||||
|
_launchCommandLine += " ";
|
||||||
|
|
||||||
|
_launchCommandLine += "-isInstallerLaunch";
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed for the start event to fire
|
|
||||||
if (!String.IsNullOrEmpty(_launchCommandLine))
|
|
||||||
_launchCommandLine += " ";
|
|
||||||
|
|
||||||
_launchCommandLine += "-isInstallerLaunch";
|
|
||||||
|
|
||||||
var startInfo = new ProcessStartInfo()
|
var startInfo = new ProcessStartInfo()
|
||||||
{
|
{
|
||||||
FileName = _playerLocation,
|
FileName = _playerLocation,
|
||||||
@ -308,7 +310,7 @@ namespace Bloxstrap
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using var startEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "www.roblox.com/robloxStartedEvent");
|
using var startEvent = new EventWaitHandle(false, EventResetMode.ManualReset, AppData.StartEvent);
|
||||||
|
|
||||||
// v2.2.0 - byfron will trip if we keep a process handle open for over a minute, so we're doing this now
|
// v2.2.0 - byfron will trip if we keep a process handle open for over a minute, so we're doing this now
|
||||||
int gameClientPid;
|
int gameClientPid;
|
||||||
@ -357,7 +359,6 @@ namespace Bloxstrap
|
|||||||
autoclosePids.Add(pid);
|
autoclosePids.Add(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string args = gameClientPid.ToString();
|
string args = gameClientPid.ToString();
|
||||||
|
|
||||||
if (autoclosePids.Any())
|
if (autoclosePids.Any())
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Bloxstrap.Integrations
|
using System.Web;
|
||||||
|
|
||||||
|
namespace Bloxstrap.Integrations
|
||||||
{
|
{
|
||||||
public class ActivityWatcher : IDisposable
|
public class ActivityWatcher : IDisposable
|
||||||
{
|
{
|
||||||
@ -43,6 +45,7 @@
|
|||||||
public string ActivityMachineAddress = "";
|
public string ActivityMachineAddress = "";
|
||||||
public bool ActivityMachineUDMUX = false;
|
public bool ActivityMachineUDMUX = false;
|
||||||
public bool ActivityIsTeleport = false;
|
public bool ActivityIsTeleport = false;
|
||||||
|
public string ActivityLaunchData = "";
|
||||||
public ServerType ActivityServerType = ServerType.Public;
|
public ServerType ActivityServerType = ServerType.Public;
|
||||||
|
|
||||||
public bool IsDisposed = false;
|
public bool IsDisposed = false;
|
||||||
@ -119,6 +122,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetActivityDeeplink()
|
||||||
|
{
|
||||||
|
string deeplink = $"roblox://experiences/start?placeId={ActivityPlaceId}&gameInstanceId={ActivityJobId}";
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(ActivityLaunchData))
|
||||||
|
deeplink += "&launchData=" + HttpUtility.UrlEncode(ActivityLaunchData);
|
||||||
|
|
||||||
|
return deeplink;
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadLogEntry(string entry)
|
private void ReadLogEntry(string entry)
|
||||||
{
|
{
|
||||||
const string LOG_IDENT = "ActivityWatcher::ReadLogEntry";
|
const string LOG_IDENT = "ActivityWatcher::ReadLogEntry";
|
||||||
@ -222,6 +235,7 @@
|
|||||||
ActivityMachineAddress = "";
|
ActivityMachineAddress = "";
|
||||||
ActivityMachineUDMUX = false;
|
ActivityMachineUDMUX = false;
|
||||||
ActivityIsTeleport = false;
|
ActivityIsTeleport = false;
|
||||||
|
ActivityLaunchData = "";
|
||||||
ActivityServerType = ServerType.Public;
|
ActivityServerType = ServerType.Public;
|
||||||
|
|
||||||
OnGameLeave?.Invoke(this, new EventArgs());
|
OnGameLeave?.Invoke(this, new EventArgs());
|
||||||
@ -280,6 +294,35 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.Command == "SetLaunchData")
|
||||||
|
{
|
||||||
|
string? data;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data = message.Data.Deserialize<string>();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization threw an exception)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data is null)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization returned null)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.Length > 200)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Data cannot be longer than 200 characters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityLaunchData = data;
|
||||||
|
}
|
||||||
|
|
||||||
OnRPCMessage?.Invoke(this, message);
|
OnRPCMessage?.Invoke(this, message);
|
||||||
|
|
||||||
LastRPCRequest = DateTime.Now;
|
LastRPCRequest = DateTime.Now;
|
||||||
|
@ -51,7 +51,7 @@ namespace Bloxstrap.Integrations
|
|||||||
{
|
{
|
||||||
const string LOG_IDENT = "DiscordRichPresence::ProcessRPCMessage";
|
const string LOG_IDENT = "DiscordRichPresence::ProcessRPCMessage";
|
||||||
|
|
||||||
if (message.Command != "SetRichPresence")
|
if (message.Command != "SetRichPresence" && message.Command != "SetLaunchData")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_currentPresence is null || _currentPresenceCopy is null)
|
if (_currentPresence is null || _currentPresenceCopy is null)
|
||||||
@ -61,95 +61,107 @@ namespace Bloxstrap.Integrations
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Models.BloxstrapRPC.RichPresence? presenceData;
|
|
||||||
|
|
||||||
// a lot of repeated code here, could this somehow be cleaned up?
|
// a lot of repeated code here, could this somehow be cleaned up?
|
||||||
|
|
||||||
try
|
if (message.Command == "SetLaunchData")
|
||||||
{
|
{
|
||||||
presenceData = message.Data.Deserialize<Models.BloxstrapRPC.RichPresence>();
|
var buttonQuery = _currentPresence.Buttons.Where(x => x.Label == "Join server");
|
||||||
|
|
||||||
|
if (!buttonQuery.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
buttonQuery.First().Url = _activityWatcher.GetActivityDeeplink();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
else if (message.Command == "SetRichPresence")
|
||||||
{
|
{
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization threw an exception)");
|
Models.BloxstrapRPC.RichPresence? presenceData;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presenceData is null)
|
try
|
||||||
{
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization returned null)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presenceData.Details is not null)
|
|
||||||
{
|
|
||||||
if (presenceData.Details.Length > 128)
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Details cannot be longer than 128 characters");
|
|
||||||
else if (presenceData.Details == "<reset>")
|
|
||||||
_currentPresence.Details = _currentPresenceCopy.Details;
|
|
||||||
else
|
|
||||||
_currentPresence.Details = presenceData.Details;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presenceData.State is not null)
|
|
||||||
{
|
|
||||||
if (presenceData.State.Length > 128)
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"State cannot be longer than 128 characters");
|
|
||||||
else if (presenceData.State == "<reset>")
|
|
||||||
_currentPresence.State = _currentPresenceCopy.State;
|
|
||||||
else
|
|
||||||
_currentPresence.State = presenceData.State;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presenceData.TimestampStart == 0)
|
|
||||||
_currentPresence.Timestamps.Start = null;
|
|
||||||
else if (presenceData.TimestampStart is not null)
|
|
||||||
_currentPresence.Timestamps.StartUnixMilliseconds = presenceData.TimestampStart * 1000;
|
|
||||||
|
|
||||||
if (presenceData.TimestampEnd == 0)
|
|
||||||
_currentPresence.Timestamps.End = null;
|
|
||||||
else if (presenceData.TimestampEnd is not null)
|
|
||||||
_currentPresence.Timestamps.EndUnixMilliseconds = presenceData.TimestampEnd * 1000;
|
|
||||||
|
|
||||||
if (presenceData.SmallImage is not null)
|
|
||||||
{
|
|
||||||
if (presenceData.SmallImage.Clear)
|
|
||||||
{
|
{
|
||||||
_currentPresence.Assets.SmallImageKey = "";
|
presenceData = message.Data.Deserialize<Models.BloxstrapRPC.RichPresence>();
|
||||||
}
|
}
|
||||||
else if (presenceData.SmallImage.Reset)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
_currentPresence.Assets.SmallImageText = _currentPresenceCopy.Assets.SmallImageText;
|
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization threw an exception)");
|
||||||
_currentPresence.Assets.SmallImageKey = _currentPresenceCopy.Assets.SmallImageKey;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (presenceData.SmallImage.AssetId is not null)
|
|
||||||
_currentPresence.Assets.SmallImageKey = $"https://assetdelivery.roblox.com/v1/asset/?id={presenceData.SmallImage.AssetId}";
|
|
||||||
|
|
||||||
if (presenceData.SmallImage.HoverText is not null)
|
if (presenceData is null)
|
||||||
_currentPresence.Assets.SmallImageText = presenceData.SmallImage.HoverText;
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization returned null)");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (presenceData.LargeImage is not null)
|
if (presenceData.Details is not null)
|
||||||
{
|
|
||||||
if (presenceData.LargeImage.Clear)
|
|
||||||
{
|
{
|
||||||
_currentPresence.Assets.LargeImageKey = "";
|
if (presenceData.Details.Length > 128)
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Details cannot be longer than 128 characters");
|
||||||
|
else if (presenceData.Details == "<reset>")
|
||||||
|
_currentPresence.Details = _currentPresenceCopy.Details;
|
||||||
|
else
|
||||||
|
_currentPresence.Details = presenceData.Details;
|
||||||
}
|
}
|
||||||
else if (presenceData.LargeImage.Reset)
|
|
||||||
{
|
|
||||||
_currentPresence.Assets.LargeImageText = _currentPresenceCopy.Assets.LargeImageText;
|
|
||||||
_currentPresence.Assets.LargeImageKey = _currentPresenceCopy.Assets.LargeImageKey;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (presenceData.LargeImage.AssetId is not null)
|
|
||||||
_currentPresence.Assets.LargeImageKey = $"https://assetdelivery.roblox.com/v1/asset/?id={presenceData.LargeImage.AssetId}";
|
|
||||||
|
|
||||||
if (presenceData.LargeImage.HoverText is not null)
|
if (presenceData.State is not null)
|
||||||
_currentPresence.Assets.LargeImageText = presenceData.LargeImage.HoverText;
|
{
|
||||||
|
if (presenceData.State.Length > 128)
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"State cannot be longer than 128 characters");
|
||||||
|
else if (presenceData.State == "<reset>")
|
||||||
|
_currentPresence.State = _currentPresenceCopy.State;
|
||||||
|
else
|
||||||
|
_currentPresence.State = presenceData.State;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (presenceData.TimestampStart == 0)
|
||||||
|
_currentPresence.Timestamps.Start = null;
|
||||||
|
else if (presenceData.TimestampStart is not null)
|
||||||
|
_currentPresence.Timestamps.StartUnixMilliseconds = presenceData.TimestampStart * 1000;
|
||||||
|
|
||||||
|
if (presenceData.TimestampEnd == 0)
|
||||||
|
_currentPresence.Timestamps.End = null;
|
||||||
|
else if (presenceData.TimestampEnd is not null)
|
||||||
|
_currentPresence.Timestamps.EndUnixMilliseconds = presenceData.TimestampEnd * 1000;
|
||||||
|
|
||||||
|
if (presenceData.SmallImage is not null)
|
||||||
|
{
|
||||||
|
if (presenceData.SmallImage.Clear)
|
||||||
|
{
|
||||||
|
_currentPresence.Assets.SmallImageKey = "";
|
||||||
|
}
|
||||||
|
else if (presenceData.SmallImage.Reset)
|
||||||
|
{
|
||||||
|
_currentPresence.Assets.SmallImageText = _currentPresenceCopy.Assets.SmallImageText;
|
||||||
|
_currentPresence.Assets.SmallImageKey = _currentPresenceCopy.Assets.SmallImageKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (presenceData.SmallImage.AssetId is not null)
|
||||||
|
_currentPresence.Assets.SmallImageKey = $"https://assetdelivery.roblox.com/v1/asset/?id={presenceData.SmallImage.AssetId}";
|
||||||
|
|
||||||
|
if (presenceData.SmallImage.HoverText is not null)
|
||||||
|
_currentPresence.Assets.SmallImageText = presenceData.SmallImage.HoverText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (presenceData.LargeImage is not null)
|
||||||
|
{
|
||||||
|
if (presenceData.LargeImage.Clear)
|
||||||
|
{
|
||||||
|
_currentPresence.Assets.LargeImageKey = "";
|
||||||
|
}
|
||||||
|
else if (presenceData.LargeImage.Reset)
|
||||||
|
{
|
||||||
|
_currentPresence.Assets.LargeImageText = _currentPresenceCopy.Assets.LargeImageText;
|
||||||
|
_currentPresence.Assets.LargeImageKey = _currentPresenceCopy.Assets.LargeImageKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (presenceData.LargeImage.AssetId is not null)
|
||||||
|
_currentPresence.Assets.LargeImageKey = $"https://assetdelivery.roblox.com/v1/asset/?id={presenceData.LargeImage.AssetId}";
|
||||||
|
|
||||||
|
if (presenceData.LargeImage.HoverText is not null)
|
||||||
|
_currentPresence.Assets.LargeImageText = presenceData.LargeImage.HoverText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
|||||||
|
|
||||||
private void RichPresenceMenuItem_Click(object sender, RoutedEventArgs e) => _watcher.RichPresence?.SetVisibility(((MenuItem)sender).IsChecked);
|
private void RichPresenceMenuItem_Click(object sender, RoutedEventArgs e) => _watcher.RichPresence?.SetVisibility(((MenuItem)sender).IsChecked);
|
||||||
|
|
||||||
private void InviteDeeplinkMenuItem_Click(object sender, RoutedEventArgs e) => Clipboard.SetDataObject($"roblox://experiences/start?placeId={_activityWatcher?.ActivityPlaceId}&gameInstanceId={_activityWatcher?.ActivityJobId}");
|
private void InviteDeeplinkMenuItem_Click(object sender, RoutedEventArgs e) => Clipboard.SetDataObject(_activityWatcher?.GetActivityDeeplink());
|
||||||
|
|
||||||
private void ServerDetailsMenuItem_Click(object sender, RoutedEventArgs e) => ShowServerInformationWindow();
|
private void ServerDetailsMenuItem_Click(object sender, RoutedEventArgs e) => ShowServerInformationWindow();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user