mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-04 22:06:06 +02:00
Refactor Discord RPC
This commit is contained in:
+113
-106
@@ -16,12 +16,13 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
public static readonly Discord Instance;
|
public static readonly Discord Instance;
|
||||||
private readonly ReaderWriterLockSlim m_Lock;
|
private readonly ReaderWriterLockSlim _lock;
|
||||||
private readonly RichPresence m_Presence;
|
private readonly RichPresence _presence;
|
||||||
private DiscordRpcClient m_Client;
|
private DiscordRpcClient _client;
|
||||||
private readonly Timer m_Timer;
|
private readonly Timer _timer;
|
||||||
private bool m_Active;
|
private bool _active;
|
||||||
public static string DiscordAppId;
|
private string _discordAppId;
|
||||||
|
private const string VrcxUrl = "https://vrcx.app";
|
||||||
|
|
||||||
static Discord()
|
static Discord()
|
||||||
{
|
{
|
||||||
@@ -30,22 +31,22 @@ namespace VRCX
|
|||||||
|
|
||||||
public Discord()
|
public Discord()
|
||||||
{
|
{
|
||||||
m_Lock = new ReaderWriterLockSlim();
|
_lock = new ReaderWriterLockSlim();
|
||||||
m_Presence = new RichPresence();
|
_presence = new RichPresence();
|
||||||
m_Timer = new Timer(TimerCallback, null, -1, -1);
|
_timer = new Timer(TimerCallback, null, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
m_Timer.Change(0, 1000);
|
_timer.Change(0, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Exit()
|
public void Exit()
|
||||||
{
|
{
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
m_Timer.Change(-1, -1);
|
_timer.Change(-1, -1);
|
||||||
m_Client?.Dispose();
|
_client?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,41 +67,41 @@ namespace VRCX
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (m_Client == null && m_Active)
|
if (_client == null && _active)
|
||||||
{
|
{
|
||||||
m_Client = new DiscordRpcClient(DiscordAppId);
|
_client = new DiscordRpcClient(_discordAppId);
|
||||||
if (!m_Client.Initialize())
|
if (!_client.Initialize())
|
||||||
{
|
{
|
||||||
m_Client.Dispose();
|
_client.Dispose();
|
||||||
m_Client = null;
|
_client = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Client != null && !m_Active)
|
if (_client != null && !_active)
|
||||||
{
|
{
|
||||||
m_Client.Dispose();
|
_client.Dispose();
|
||||||
m_Client = null;
|
_client = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Client != null && !m_Lock.IsWriteLockHeld)
|
if (_client != null && !_lock.IsWriteLockHeld)
|
||||||
{
|
{
|
||||||
m_Lock.EnterReadLock();
|
_lock.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_Client.SetPresence(m_Presence);
|
_client.SetPresence(_presence);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
m_Lock.ExitReadLock();
|
_lock.ExitReadLock();
|
||||||
}
|
}
|
||||||
m_Client.Invoke();
|
_client.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetActive(bool active)
|
public bool SetActive(bool active)
|
||||||
{
|
{
|
||||||
m_Active = active;
|
_active = active;
|
||||||
return m_Active;
|
return _active;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/1225052/best-way-to-shorten-utf8-string-based-on-byte-length
|
// https://stackoverflow.com/questions/1225052/best-way-to-shorten-utf8-string-based-on-byte-length
|
||||||
@@ -119,106 +120,112 @@ namespace VRCX
|
|||||||
return Encoding.UTF8.GetString(bytesArr, 0, bytesArr.Length - bytesToRemove);
|
return Encoding.UTF8.GetString(bytesArr, 0, bytesArr.Length - bytesToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetText(string details, string state)
|
public void SetAssets(
|
||||||
{
|
string details,
|
||||||
if (m_Client == null || m_Lock.IsReadLockHeld)
|
string state,
|
||||||
return;
|
string stateUrl,
|
||||||
|
|
||||||
m_Lock.EnterWriteLock();
|
string largeKey,
|
||||||
try
|
string largeText,
|
||||||
{
|
|
||||||
m_Presence.Details = LimitByteLength(details, 127);
|
|
||||||
m_Presence.State = LimitByteLength(state, 127);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitWriteLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAssets(string largeKey, string largeText, string smallKey, string smallText, string partyId, int partySize, int partyMax, string buttonText, string buttonUrl, string appId, int activityType = 0)
|
string smallKey,
|
||||||
|
string smallText,
|
||||||
|
|
||||||
|
double startUnixMilliseconds,
|
||||||
|
double endUnixMilliseconds,
|
||||||
|
|
||||||
|
string partyId,
|
||||||
|
int partySize,
|
||||||
|
int partyMax,
|
||||||
|
string buttonText,
|
||||||
|
string buttonUrl,
|
||||||
|
string appId,
|
||||||
|
int activityType)
|
||||||
{
|
{
|
||||||
m_Lock.EnterWriteLock();
|
_lock.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(largeKey) &&
|
if (string.IsNullOrEmpty(largeKey) &&
|
||||||
string.IsNullOrEmpty(smallKey))
|
string.IsNullOrEmpty(smallKey))
|
||||||
{
|
{
|
||||||
m_Presence.Assets = null;
|
_presence.Assets = null;
|
||||||
|
_presence.Party = null;
|
||||||
|
_presence.Timestamps = null;
|
||||||
|
_lock.ExitWriteLock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_presence.Details = LimitByteLength(details, 127);
|
||||||
|
// _presence.DetailsUrl
|
||||||
|
_presence.StateUrl = !string.IsNullOrEmpty(stateUrl) ? stateUrl : null;
|
||||||
|
_presence.State = LimitByteLength(state, 127);
|
||||||
|
_presence.Assets ??= new Assets();
|
||||||
|
|
||||||
|
_presence.Assets.LargeImageKey = largeKey;
|
||||||
|
_presence.Assets.LargeImageText = largeText;
|
||||||
|
_presence.Assets.LargeImageUrl = VrcxUrl;
|
||||||
|
|
||||||
|
_presence.Assets.SmallImageKey = smallKey;
|
||||||
|
_presence.Assets.SmallImageText = smallText;
|
||||||
|
// m_Presence.Assets.SmallImageUrl
|
||||||
|
|
||||||
|
if (startUnixMilliseconds == 0)
|
||||||
|
{
|
||||||
|
_presence.Timestamps = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Presence.Assets ??= new Assets();
|
_presence.Timestamps ??= new Timestamps();
|
||||||
m_Presence.Party ??= new Party();
|
_presence.Timestamps.StartUnixMilliseconds = (ulong)startUnixMilliseconds;
|
||||||
m_Presence.Assets.LargeImageKey = largeKey;
|
if (endUnixMilliseconds == 0)
|
||||||
m_Presence.Assets.LargeImageText = largeText;
|
_presence.Timestamps.End = null;
|
||||||
m_Presence.Assets.SmallImageKey = smallKey;
|
|
||||||
m_Presence.Assets.SmallImageText = smallText;
|
|
||||||
m_Presence.Party.ID = partyId;
|
|
||||||
m_Presence.Party.Size = partySize;
|
|
||||||
m_Presence.Party.Max = partyMax;
|
|
||||||
m_Presence.Type = (ActivityType)activityType;
|
|
||||||
Button[] buttons = [];
|
|
||||||
if (!string.IsNullOrEmpty(buttonUrl))
|
|
||||||
{
|
|
||||||
buttons =
|
|
||||||
[
|
|
||||||
new Button { Label = buttonText, Url = buttonUrl }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
m_Presence.Buttons = buttons;
|
|
||||||
if (DiscordAppId != appId)
|
|
||||||
{
|
|
||||||
DiscordAppId = appId;
|
|
||||||
if (m_Client != null)
|
|
||||||
{
|
|
||||||
m_Client.Dispose();
|
|
||||||
m_Client = null;
|
|
||||||
}
|
|
||||||
Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitWriteLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTimestamps(double startUnixMilliseconds, double endUnixMilliseconds)
|
|
||||||
{
|
|
||||||
var _startUnixMilliseconds = (ulong)startUnixMilliseconds;
|
|
||||||
var _endUnixMilliseconds = (ulong)endUnixMilliseconds;
|
|
||||||
|
|
||||||
m_Lock.EnterWriteLock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_startUnixMilliseconds == 0)
|
|
||||||
{
|
|
||||||
m_Presence.Timestamps = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Presence.Timestamps ??= new Timestamps();
|
|
||||||
m_Presence.Timestamps.StartUnixMilliseconds = _startUnixMilliseconds;
|
|
||||||
|
|
||||||
if (_endUnixMilliseconds == 0)
|
|
||||||
{
|
|
||||||
m_Presence.Timestamps.End = null;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
_presence.Timestamps.EndUnixMilliseconds = (ulong)endUnixMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partyMax == 0)
|
||||||
|
{
|
||||||
|
_presence.Party = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_presence.Party ??= new Party();
|
||||||
|
_presence.Party.ID = partyId;
|
||||||
|
_presence.Party.Size = partySize;
|
||||||
|
_presence.Party.Max = partyMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
_presence.Type = (ActivityType)activityType;
|
||||||
|
_presence.StatusDisplay = StatusDisplayType.Details;
|
||||||
|
|
||||||
|
Button[] buttons = [];
|
||||||
|
if (!string.IsNullOrEmpty(buttonUrl))
|
||||||
|
{
|
||||||
|
buttons =
|
||||||
|
[
|
||||||
|
new Button { Label = buttonText, Url = buttonUrl }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
_presence.Buttons = buttons;
|
||||||
|
|
||||||
|
if (_discordAppId != appId)
|
||||||
|
{
|
||||||
|
_discordAppId = appId;
|
||||||
|
if (_client != null)
|
||||||
{
|
{
|
||||||
m_Presence.Timestamps.EndUnixMilliseconds = _endUnixMilliseconds;
|
_client.Dispose();
|
||||||
|
_client = null;
|
||||||
}
|
}
|
||||||
|
Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Error setting timestamps in Discord Rich Presence {Error}", ex.Message);
|
_logger.Error(ex, "Error setting Discord Rich Presence assets: {Error}", ex.Message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
m_Lock.ExitWriteLock();
|
_lock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,14 +93,14 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CefSharp.OffScreen.NETCore" Version="138.0.170" />
|
<PackageReference Include="CefSharp.OffScreen.NETCore" Version="138.0.170" />
|
||||||
<PackageReference Include="CefSharp.WinForms.NETCore" Version="138.0.170" />
|
<PackageReference Include="CefSharp.WinForms.NETCore" Version="138.0.170" />
|
||||||
<PackageReference Include="DiscordRichPresence" Version="1.3.0.28" />
|
<PackageReference Include="DiscordRichPresence" Version="1.5.0.51" />
|
||||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="NLog" Version="6.0.2" />
|
<PackageReference Include="NLog" Version="6.0.2" />
|
||||||
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
||||||
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
|
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.6" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
|
||||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />
|
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />
|
||||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
|
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
|
||||||
|
|||||||
+4
-22
@@ -28,22 +28,12 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
lastLocation: {
|
lastLocation: {
|
||||||
date: 0,
|
date: null,
|
||||||
location: '',
|
location: '',
|
||||||
name: '',
|
name: '',
|
||||||
playerList: new Map(),
|
playerList: new Map(),
|
||||||
friendList: new Map()
|
friendList: new Map()
|
||||||
},
|
},
|
||||||
lastLocation$: {
|
|
||||||
tag: '',
|
|
||||||
instanceId: '',
|
|
||||||
accessType: '',
|
|
||||||
worldName: '',
|
|
||||||
worldCapacity: 0,
|
|
||||||
joinUrl: '',
|
|
||||||
statusName: '',
|
|
||||||
statusImage: ''
|
|
||||||
},
|
|
||||||
lastLocationDestination: '',
|
lastLocationDestination: '',
|
||||||
lastLocationDestinationTime: 0
|
lastLocationDestinationTime: 0
|
||||||
});
|
});
|
||||||
@@ -55,13 +45,6 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const lastLocation$ = computed({
|
|
||||||
get: () => state.lastLocation$,
|
|
||||||
set: (value) => {
|
|
||||||
state.lastLocation$ = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const lastLocationDestination = computed({
|
const lastLocationDestination = computed({
|
||||||
get: () => state.lastLocationDestination,
|
get: () => state.lastLocationDestination,
|
||||||
set: (value) => {
|
set: (value) => {
|
||||||
@@ -153,7 +136,7 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
const L = parseLocation(location);
|
const L = parseLocation(location);
|
||||||
|
|
||||||
state.lastLocation.location = location;
|
state.lastLocation.location = location;
|
||||||
state.lastLocation.date = dt;
|
state.lastLocation.date = Date.now();
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
created_at: dt,
|
created_at: dt,
|
||||||
@@ -174,7 +157,7 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
instanceStore.applyGroupDialogInstances();
|
instanceStore.applyGroupDialogInstances();
|
||||||
} else {
|
} else {
|
||||||
state.lastLocation.location = '';
|
state.lastLocation.location = '';
|
||||||
state.lastLocation.date = '';
|
state.lastLocation.date = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +201,7 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
gameLogStore.addGameLog(entry);
|
gameLogStore.addGameLog(entry);
|
||||||
}
|
}
|
||||||
database.addGamelogJoinLeaveBulk(dataBaseEntries);
|
database.addGamelogJoinLeaveBulk(dataBaseEntries);
|
||||||
if (state.lastLocation.date !== 0) {
|
if (state.lastLocation.date !== null && state.lastLocation.date > 0) {
|
||||||
const update = {
|
const update = {
|
||||||
time: dateTimeStamp - state.lastLocation.date,
|
time: dateTimeStamp - state.lastLocation.date,
|
||||||
created_at: new Date(state.lastLocation.date).toJSON()
|
created_at: new Date(state.lastLocation.date).toJSON()
|
||||||
@@ -248,7 +231,6 @@ export const useLocationStore = defineStore('Location', () => {
|
|||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
lastLocation,
|
lastLocation,
|
||||||
lastLocation$,
|
|
||||||
lastLocationDestination,
|
lastLocationDestination,
|
||||||
lastLocationDestinationTime,
|
lastLocationDestinationTime,
|
||||||
updateCurrentUserLocation,
|
updateCurrentUserLocation,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { userRequest, worldRequest } from '../../api';
|
import { worldRequest } from '../../api';
|
||||||
import configRepository from '../../service/config';
|
import configRepository from '../../service/config';
|
||||||
import {
|
import {
|
||||||
getGroupName,
|
getGroupName,
|
||||||
@@ -14,7 +14,6 @@ import { useGameLogStore } from '../gameLog';
|
|||||||
import { useLocationStore } from '../location';
|
import { useLocationStore } from '../location';
|
||||||
import { useUpdateLoopStore } from '../updateLoop';
|
import { useUpdateLoopStore } from '../updateLoop';
|
||||||
import { useUserStore } from '../user';
|
import { useUserStore } from '../user';
|
||||||
import { useWorldStore } from '../world';
|
|
||||||
import { useAdvancedSettingsStore } from './advanced';
|
import { useAdvancedSettingsStore } from './advanced';
|
||||||
import { ActivityType } from '../../shared/constants/discord';
|
import { ActivityType } from '../../shared/constants/discord';
|
||||||
|
|
||||||
@@ -24,7 +23,6 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
const locationStore = useLocationStore();
|
const locationStore = useLocationStore();
|
||||||
const gameStore = useGameStore();
|
const gameStore = useGameStore();
|
||||||
const advancedSettingsStore = useAdvancedSettingsStore();
|
const advancedSettingsStore = useAdvancedSettingsStore();
|
||||||
const worldStore = useWorldStore();
|
|
||||||
const gameLogStore = useGameLogStore();
|
const gameLogStore = useGameLogStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const updateLoopStore = useUpdateLoopStore();
|
const updateLoopStore = useUpdateLoopStore();
|
||||||
@@ -35,7 +33,20 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
discordHideInvite: true,
|
discordHideInvite: true,
|
||||||
discordJoinButton: false,
|
discordJoinButton: false,
|
||||||
discordHideImage: false,
|
discordHideImage: false,
|
||||||
isDiscordActive: false
|
isDiscordActive: false,
|
||||||
|
lastLocationDetails: {
|
||||||
|
tag: '',
|
||||||
|
instanceName: '',
|
||||||
|
accessType: '',
|
||||||
|
worldId: '',
|
||||||
|
worldName: '',
|
||||||
|
thumbnailImageUrl: '',
|
||||||
|
worldCapacity: 0,
|
||||||
|
joinUrl: '',
|
||||||
|
worldLink: '',
|
||||||
|
accessName: '',
|
||||||
|
groupAccessType: ''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function initDiscordPresenceSettings() {
|
async function initDiscordPresenceSettings() {
|
||||||
@@ -98,186 +109,218 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
|
|
||||||
initDiscordPresenceSettings();
|
initDiscordPresenceSettings();
|
||||||
|
|
||||||
function updateDiscord() {
|
async function updateDiscord() {
|
||||||
let platform;
|
|
||||||
let currentLocation = locationStore.lastLocation.location;
|
let currentLocation = locationStore.lastLocation.location;
|
||||||
let timeStamp = locationStore.lastLocation.date;
|
let startTime = locationStore.lastLocation.date;
|
||||||
if (locationStore.lastLocation.location === 'traveling') {
|
if (locationStore.lastLocation.location === 'traveling') {
|
||||||
currentLocation = locationStore.lastLocationDestination;
|
currentLocation = locationStore.lastLocationDestination;
|
||||||
timeStamp = locationStore.lastLocationDestinationTime;
|
startTime = locationStore.lastLocationDestinationTime;
|
||||||
|
}
|
||||||
|
if (advancedSettingsStore.gameLogDisabled) {
|
||||||
|
// game log disabled, use API location
|
||||||
|
currentLocation = userStore.currentUser.$locationTag;
|
||||||
|
startTime = userStore.currentUser.$location_at;
|
||||||
|
if (userStore.currentUser.$travelingToLocation) {
|
||||||
|
currentLocation =
|
||||||
|
userStore.currentUser.$travelingToLocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!state.discordActive ||
|
!state.discordActive ||
|
||||||
(!gameStore.isGameRunning &&
|
(!gameStore.isGameRunning &&
|
||||||
!advancedSettingsStore.gameLogDisabled) ||
|
!advancedSettingsStore.gameLogDisabled) ||
|
||||||
(!currentLocation && !locationStore.lastLocation$.tag)
|
!isRealInstance(currentLocation)
|
||||||
) {
|
) {
|
||||||
setIsDiscordActive(false);
|
setIsDiscordActive(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsDiscordActive(true);
|
if (currentLocation !== state.lastLocationDetails.tag) {
|
||||||
let L = locationStore.lastLocation$;
|
const L = parseLocation(currentLocation);
|
||||||
if (currentLocation !== locationStore.lastLocation$.tag) {
|
state.lastLocationDetails = {
|
||||||
Discord.SetTimestamps(timeStamp, 0);
|
tag: L.tag,
|
||||||
L = parseLocation(currentLocation);
|
instanceName: L.instanceName,
|
||||||
L.worldName = '';
|
accessType: L.accessType,
|
||||||
L.thumbnailImageUrl = '';
|
worldId: L.worldId,
|
||||||
L.worldCapacity = 0;
|
worldName: '',
|
||||||
L.joinUrl = '';
|
thumbnailImageUrl: '',
|
||||||
L.accessName = '';
|
worldCapacity: 0,
|
||||||
if (L.worldId) {
|
joinUrl: '',
|
||||||
const ref = worldStore.cachedWorlds.get(L.worldId);
|
worldLink: '',
|
||||||
if (ref) {
|
accessName: '',
|
||||||
L.worldName = ref.name;
|
groupAccessType: ''
|
||||||
L.thumbnailImageUrl = ref.thumbnailImageUrl;
|
};
|
||||||
L.worldCapacity = ref.capacity;
|
try {
|
||||||
} else {
|
const args = await worldRequest.getCachedWorld({
|
||||||
worldRequest
|
worldId: L.worldId
|
||||||
.getWorld({
|
});
|
||||||
worldId: L.worldId
|
state.lastLocationDetails.worldName = args.ref.name;
|
||||||
})
|
state.lastLocationDetails.thumbnailImageUrl =
|
||||||
.then((args) => {
|
args.ref.thumbnailImageUrl;
|
||||||
L.worldName = args.ref.name;
|
state.lastLocationDetails.worldCapacity = args.ref.capacity;
|
||||||
L.thumbnailImageUrl =
|
if (args.ref.releaseStatus === 'public') {
|
||||||
args.ref.thumbnailImageUrl;
|
state.lastLocationDetails.worldLink = `https://vrchat.com/home/world/${L.worldId}`;
|
||||||
L.worldCapacity = args.ref.capacity;
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (gameStore.isGameNoVR) {
|
} catch (e) {
|
||||||
platform = 'Desktop';
|
console.error(
|
||||||
} else {
|
`Failed to get world details for ${L.worldId}`,
|
||||||
platform = 'VR';
|
e
|
||||||
}
|
);
|
||||||
let groupAccessType = '';
|
}
|
||||||
if (L.groupAccessType) {
|
|
||||||
if (L.groupAccessType === 'public') {
|
let platform = gameStore.isGameNoVR ? 'Desktop' : 'VR';
|
||||||
groupAccessType = 'Public';
|
if (L.groupAccessType) {
|
||||||
} else if (L.groupAccessType === 'plus') {
|
if (L.groupAccessType === 'public') {
|
||||||
groupAccessType = 'Plus';
|
state.lastLocationDetails.groupAccessType = 'Public';
|
||||||
}
|
} else if (L.groupAccessType === 'plus') {
|
||||||
}
|
state.lastLocationDetails.groupAccessType = 'Plus';
|
||||||
switch (L.accessType) {
|
|
||||||
case 'public':
|
|
||||||
L.joinUrl = getLaunchURL(L);
|
|
||||||
L.accessName = `Public #${L.instanceName} (${platform})`;
|
|
||||||
break;
|
|
||||||
case 'invite+':
|
|
||||||
L.accessName = `Invite+ #${L.instanceName} (${platform})`;
|
|
||||||
break;
|
|
||||||
case 'invite':
|
|
||||||
L.accessName = `Invite #${L.instanceName} (${platform})`;
|
|
||||||
break;
|
|
||||||
case 'friends':
|
|
||||||
L.accessName = `Friends #${L.instanceName} (${platform})`;
|
|
||||||
break;
|
|
||||||
case 'friends+':
|
|
||||||
L.accessName = `Friends+ #${L.instanceName} (${platform})`;
|
|
||||||
break;
|
|
||||||
case 'group':
|
|
||||||
L.accessName = `Group #${L.instanceName} (${platform})`;
|
|
||||||
getGroupName(L.groupId).then((groupName) => {
|
|
||||||
if (groupName) {
|
|
||||||
L.accessName = `Group${groupAccessType}(${groupName}) #${L.instanceName} (${platform})`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locationStore.lastLocation$ = L;
|
switch (L.accessType) {
|
||||||
|
case 'public':
|
||||||
|
state.lastLocationDetails.joinUrl = getLaunchURL(L);
|
||||||
|
state.lastLocationDetails.accessName = `Public #${L.instanceName} (${platform})`;
|
||||||
|
break;
|
||||||
|
case 'invite+':
|
||||||
|
state.lastLocationDetails.accessName = `Invite+ #${L.instanceName} (${platform})`;
|
||||||
|
break;
|
||||||
|
case 'invite':
|
||||||
|
state.lastLocationDetails.accessName = `Invite #${L.instanceName} (${platform})`;
|
||||||
|
break;
|
||||||
|
case 'friends':
|
||||||
|
state.lastLocationDetails.accessName = `Friends #${L.instanceName} (${platform})`;
|
||||||
|
break;
|
||||||
|
case 'friends+':
|
||||||
|
state.lastLocationDetails.accessName = `Friends+ #${L.instanceName} (${platform})`;
|
||||||
|
break;
|
||||||
|
case 'group':
|
||||||
|
state.lastLocationDetails.accessName = `Group #${L.instanceName} (${platform})`;
|
||||||
|
try {
|
||||||
|
const groupName = await getGroupName(L.groupId);
|
||||||
|
state.lastLocationDetails.accessName = `Group${state.lastLocationDetails.groupAccessType}(${groupName}) #${L.instanceName} (${platform})`;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(
|
||||||
|
`Failed to get group name for ${L.groupId}`,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
setIsDiscordActive(true);
|
||||||
let hidePrivate = false;
|
let hidePrivate = false;
|
||||||
if (
|
if (
|
||||||
state.discordHideInvite &&
|
state.discordHideInvite &&
|
||||||
(L.accessType === 'invite' ||
|
(state.lastLocationDetails.accessType === 'invite' ||
|
||||||
L.accessType === 'invite+' ||
|
state.lastLocationDetails.accessType === 'invite+' ||
|
||||||
L.groupAccessType === 'members')
|
state.lastLocationDetails.groupAccessType === 'members')
|
||||||
) {
|
) {
|
||||||
hidePrivate = true;
|
hidePrivate = true;
|
||||||
}
|
}
|
||||||
|
let statusName = '';
|
||||||
|
let statusImage = '';
|
||||||
switch (userStore.currentUser.status) {
|
switch (userStore.currentUser.status) {
|
||||||
case 'active':
|
case 'active':
|
||||||
L.statusName = 'Online';
|
statusName = 'Online';
|
||||||
L.statusImage = 'active';
|
statusImage = 'active';
|
||||||
break;
|
break;
|
||||||
case 'join me':
|
case 'join me':
|
||||||
L.statusName = 'Join Me';
|
statusName = 'Join Me';
|
||||||
L.statusImage = 'joinme';
|
statusImage = 'joinme';
|
||||||
break;
|
break;
|
||||||
case 'ask me':
|
case 'ask me':
|
||||||
L.statusName = 'Ask Me';
|
statusName = 'Ask Me';
|
||||||
L.statusImage = 'askme';
|
statusImage = 'askme';
|
||||||
if (state.discordHideInvite) {
|
if (state.discordHideInvite) {
|
||||||
hidePrivate = true;
|
hidePrivate = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'busy':
|
case 'busy':
|
||||||
L.statusName = 'Do Not Disturb';
|
statusName = 'Do Not Disturb';
|
||||||
L.statusImage = 'busy';
|
statusImage = 'busy';
|
||||||
|
hidePrivate = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusName = 'Offline';
|
||||||
|
statusImage = 'offline';
|
||||||
hidePrivate = true;
|
hidePrivate = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
let details = state.lastLocationDetails.worldName;
|
||||||
|
let stateText = state.lastLocationDetails.accessName;
|
||||||
|
let endTime = 0;
|
||||||
let activityType = ActivityType.Playing;
|
let activityType = ActivityType.Playing;
|
||||||
let appId = '883308884863901717';
|
let appId = '883308884863901717';
|
||||||
let bigIcon = 'vrchat';
|
let bigIcon = 'vrchat';
|
||||||
let partyId = `${L.worldId}:${L.instanceName}`;
|
let stateUrl = state.lastLocationDetails.worldLink;
|
||||||
|
|
||||||
|
let partyId = `${state.lastLocationDetails.worldId}:${state.lastLocationDetails.instanceName}`;
|
||||||
let partySize = locationStore.lastLocation.playerList.size;
|
let partySize = locationStore.lastLocation.playerList.size;
|
||||||
let partyMaxSize = L.worldCapacity;
|
let partyMaxSize = state.lastLocationDetails.worldCapacity;
|
||||||
if (partySize > partyMaxSize) {
|
if (partySize > partyMaxSize) {
|
||||||
partyMaxSize = partySize;
|
partyMaxSize = partySize;
|
||||||
}
|
}
|
||||||
let buttonText = 'Join';
|
|
||||||
let buttonUrl = L.joinUrl;
|
|
||||||
if (!state.discordJoinButton) {
|
|
||||||
buttonText = '';
|
|
||||||
buttonUrl = '';
|
|
||||||
}
|
|
||||||
if (!state.discordInstance) {
|
if (!state.discordInstance) {
|
||||||
partySize = 0;
|
partySize = 0;
|
||||||
partyMaxSize = 0;
|
partyMaxSize = 0;
|
||||||
|
stateText = '';
|
||||||
}
|
}
|
||||||
if (hidePrivate) {
|
|
||||||
partyId = '';
|
let buttonText = 'Join';
|
||||||
partySize = 0;
|
let buttonUrl = state.lastLocationDetails.joinUrl;
|
||||||
partyMaxSize = 0;
|
if (!state.discordJoinButton) {
|
||||||
buttonText = '';
|
buttonText = '';
|
||||||
buttonUrl = '';
|
buttonUrl = '';
|
||||||
} else if (isRpcWorld(L.tag)) {
|
}
|
||||||
|
|
||||||
|
if (isRpcWorld(state.lastLocationDetails.tag)) {
|
||||||
// custom world rpc
|
// custom world rpc
|
||||||
if (
|
if (
|
||||||
L.worldId === 'wrld_f20326da-f1ac-45fc-a062-609723b097b1' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_10e5e467-fc65-42ed-8957-f02cace1398c' ||
|
'wrld_f20326da-f1ac-45fc-a062-609723b097b1' ||
|
||||||
L.worldId === 'wrld_04899f23-e182-4a8d-b2c7-2c74c7c15534'
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_10e5e467-fc65-42ed-8957-f02cace1398c' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_04899f23-e182-4a8d-b2c7-2c74c7c15534'
|
||||||
) {
|
) {
|
||||||
activityType = ActivityType.Listening;
|
activityType = ActivityType.Listening;
|
||||||
appId = '784094509008551956';
|
appId = '784094509008551956';
|
||||||
bigIcon = 'pypy';
|
bigIcon = 'pypy';
|
||||||
} else if (
|
} else if (
|
||||||
L.worldId === 'wrld_42377cf1-c54f-45ed-8996-5875b0573a83' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_dd6d2888-dbdc-47c2-bc98-3d631b2acd7c'
|
'wrld_42377cf1-c54f-45ed-8996-5875b0573a83' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_dd6d2888-dbdc-47c2-bc98-3d631b2acd7c'
|
||||||
) {
|
) {
|
||||||
activityType = ActivityType.Listening;
|
activityType = ActivityType.Listening;
|
||||||
appId = '846232616054030376';
|
appId = '846232616054030376';
|
||||||
bigIcon = 'vr_dancing';
|
bigIcon = 'vr_dancing';
|
||||||
} else if (
|
} else if (
|
||||||
L.worldId === 'wrld_52bdcdab-11cd-4325-9655-0fb120846945' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_2d40da63-8f1f-4011-8a9e-414eb8530acd'
|
'wrld_52bdcdab-11cd-4325-9655-0fb120846945' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_2d40da63-8f1f-4011-8a9e-414eb8530acd'
|
||||||
) {
|
) {
|
||||||
activityType = ActivityType.Listening;
|
activityType = ActivityType.Listening;
|
||||||
appId = '939473404808007731';
|
appId = '939473404808007731';
|
||||||
bigIcon = 'zuwa_zuwa_dance';
|
bigIcon = 'zuwa_zuwa_dance';
|
||||||
} else if (
|
} else if (
|
||||||
L.worldId === 'wrld_74970324-58e8-4239-a17b-2c59dfdf00db' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_db9d878f-6e76-4776-8bf2-15bcdd7fc445' ||
|
'wrld_74970324-58e8-4239-a17b-2c59dfdf00db' ||
|
||||||
L.worldId === 'wrld_435bbf25-f34f-4b8b-82c6-cd809057eb8e' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_f767d1c8-b249-4ecc-a56f-614e433682c8'
|
'wrld_db9d878f-6e76-4776-8bf2-15bcdd7fc445' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_435bbf25-f34f-4b8b-82c6-cd809057eb8e' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_f767d1c8-b249-4ecc-a56f-614e433682c8'
|
||||||
) {
|
) {
|
||||||
activityType = ActivityType.Watching;
|
activityType = ActivityType.Watching;
|
||||||
appId = '968292722391785512';
|
appId = '968292722391785512';
|
||||||
bigIcon = 'ls_media';
|
bigIcon = 'ls_media';
|
||||||
} else if (
|
} else if (
|
||||||
L.worldId === 'wrld_266523e8-9161-40da-acd0-6bd82e075833' ||
|
state.lastLocationDetails.worldId ===
|
||||||
L.worldId === 'wrld_27c7e6b2-d938-447e-a270-3d1a873e2cf3'
|
'wrld_266523e8-9161-40da-acd0-6bd82e075833' ||
|
||||||
|
state.lastLocationDetails.worldId ===
|
||||||
|
'wrld_27c7e6b2-d938-447e-a270-3d1a873e2cf3'
|
||||||
) {
|
) {
|
||||||
activityType = ActivityType.Watching;
|
activityType = ActivityType.Watching;
|
||||||
appId = '1095440531821170820';
|
appId = '1095440531821170820';
|
||||||
@@ -291,24 +334,54 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gameLogStore.nowPlaying.name) {
|
if (gameLogStore.nowPlaying.name) {
|
||||||
L.worldName = gameLogStore.nowPlaying.name;
|
details = gameLogStore.nowPlaying.name;
|
||||||
}
|
}
|
||||||
if (gameLogStore.nowPlaying.playing) {
|
if (gameLogStore.nowPlaying.playing) {
|
||||||
Discord.SetTimestamps(
|
startTime = gameLogStore.nowPlaying.startTime * 1000;
|
||||||
gameLogStore.nowPlaying.startTime * 1000,
|
endTime =
|
||||||
(gameLogStore.nowPlaying.startTime +
|
(gameLogStore.nowPlaying.startTime +
|
||||||
gameLogStore.nowPlaying.length) *
|
gameLogStore.nowPlaying.length) *
|
||||||
1000
|
1000;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (!state.discordHideImage && L.thumbnailImageUrl) {
|
} else if (
|
||||||
bigIcon = L.thumbnailImageUrl;
|
!state.discordHideImage &&
|
||||||
|
state.lastLocationDetails.thumbnailImageUrl
|
||||||
|
) {
|
||||||
|
bigIcon = state.lastLocationDetails.thumbnailImageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hidePrivate) {
|
||||||
|
partyId = '';
|
||||||
|
partySize = 0;
|
||||||
|
partyMaxSize = 0;
|
||||||
|
buttonText = '';
|
||||||
|
buttonUrl = '';
|
||||||
|
stateUrl = '';
|
||||||
|
details = 'Private';
|
||||||
|
stateText = '';
|
||||||
|
startTime = 0;
|
||||||
|
endTime = 0;
|
||||||
|
appId = '883308884863901717'; // default VRChat app id
|
||||||
|
activityType = ActivityType.Playing;
|
||||||
|
}
|
||||||
|
if (details.length < 2) {
|
||||||
|
// 글자 수가 짧으면 업데이트가 안된다..
|
||||||
|
details += '\uFFA0'.repeat(2 - details.length);
|
||||||
}
|
}
|
||||||
Discord.SetAssets(
|
Discord.SetAssets(
|
||||||
|
details, // main text
|
||||||
|
stateText, // secondary text
|
||||||
|
stateUrl, // state url
|
||||||
|
|
||||||
bigIcon, // big icon
|
bigIcon, // big icon
|
||||||
'Powered by VRCX', // big icon hover text
|
'Powered by VRCX', // big icon hover text
|
||||||
L.statusImage, // small icon
|
|
||||||
L.statusName, // small icon hover text
|
statusImage, // small icon
|
||||||
|
statusName, // small icon hover text
|
||||||
|
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
|
||||||
partyId, // party id
|
partyId, // party id
|
||||||
partySize, // party size
|
partySize, // party size
|
||||||
partyMaxSize, // party max size
|
partyMaxSize, // party max size
|
||||||
@@ -317,19 +390,6 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
appId, // app id
|
appId, // app id
|
||||||
activityType // activity type
|
activityType // activity type
|
||||||
);
|
);
|
||||||
// NOTE
|
|
||||||
// 글자 수가 짧으면 업데이트가 안된다..
|
|
||||||
if (L.worldName.length < 2) {
|
|
||||||
L.worldName += '\uFFA0'.repeat(2 - L.worldName.length);
|
|
||||||
}
|
|
||||||
if (hidePrivate) {
|
|
||||||
Discord.SetText('Private', '');
|
|
||||||
Discord.SetTimestamps(0, 0);
|
|
||||||
} else if (state.discordInstance) {
|
|
||||||
Discord.SetText(L.worldName, L.accessName);
|
|
||||||
} else {
|
|
||||||
Discord.SetText(L.worldName, '');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setIsDiscordActive(active) {
|
async function setIsDiscordActive(active) {
|
||||||
@@ -339,7 +399,7 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function saveDiscordOption(configLabel = '') {
|
async function saveDiscordOption(configLabel = '') {
|
||||||
locationStore.lastLocation$.tag = '';
|
state.lastLocationDetails.tag = '';
|
||||||
updateLoopStore.nextDiscordUpdate = 3;
|
updateLoopStore.nextDiscordUpdate = 3;
|
||||||
updateDiscord();
|
updateDiscord();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const nextDiscordUpdate = computed({
|
||||||
|
get: () => state.nextDiscordUpdate,
|
||||||
|
set: (value) => {
|
||||||
|
state.nextDiscordUpdate = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function updateLoop() {
|
async function updateLoop() {
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -158,6 +165,7 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
|
|||||||
state,
|
state,
|
||||||
nextGroupInstanceRefresh,
|
nextGroupInstanceRefresh,
|
||||||
nextCurrentUserRefresh,
|
nextCurrentUserRefresh,
|
||||||
|
nextDiscordUpdate,
|
||||||
updateLoop
|
updateLoop
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+1
@@ -3,6 +3,7 @@ import { BaseWorld } from '../common';
|
|||||||
// API functions
|
// API functions
|
||||||
export type GetWorld = (params: { worldId: string }) => Promise<{
|
export type GetWorld = (params: { worldId: string }) => Promise<{
|
||||||
json: GetWorldResponse;
|
json: GetWorldResponse;
|
||||||
|
ref: any;
|
||||||
params: { worldId: string };
|
params: { worldId: string };
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|||||||
Vendored
+5
-5
@@ -123,15 +123,16 @@ declare global {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Discord: {
|
const Discord: {
|
||||||
SetTimestamps(
|
|
||||||
startTimestamp: number,
|
|
||||||
endTimestamp: number
|
|
||||||
): Promise<void>;
|
|
||||||
SetAssets(
|
SetAssets(
|
||||||
|
details: string,
|
||||||
|
state: string,
|
||||||
|
stateUrl: string,
|
||||||
bigIcon: string,
|
bigIcon: string,
|
||||||
bigIconText: string,
|
bigIconText: string,
|
||||||
smallIcon: string,
|
smallIcon: string,
|
||||||
smallIconText: string,
|
smallIconText: string,
|
||||||
|
startTime: number,
|
||||||
|
endTime: number,
|
||||||
partyId: string,
|
partyId: string,
|
||||||
partySize: number,
|
partySize: number,
|
||||||
partyMaxSize: number,
|
partyMaxSize: number,
|
||||||
@@ -140,7 +141,6 @@ declare global {
|
|||||||
appId: string,
|
appId: string,
|
||||||
activityType: number
|
activityType: number
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
SetText(details: string, state: string): Promise<void>;
|
|
||||||
SetActive(active: boolean): Promise<boolean>;
|
SetActive(active: boolean): Promise<boolean>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user