Relaunch on game crash, log udon exceptions

This commit is contained in:
Natsumi
2023-03-23 02:26:12 +13:00
parent 2060e0e3de
commit 11f1f8063e
6 changed files with 194 additions and 77 deletions
+11 -2
View File
@@ -194,18 +194,22 @@ namespace VRCX
} }
} }
public void StartGameFromPath(string path, string arguments) public bool StartGameFromPath(string path, string arguments)
{ {
if (!path.EndsWith(".exe")) if (!path.EndsWith(".exe"))
path = Path.Combine(path, "start_protected_game.exe"); path = Path.Combine(path, "start_protected_game.exe");
if (!File.Exists(path))
return false;
Process.Start(new ProcessStartInfo Process.Start(new ProcessStartInfo
{ {
WorkingDirectory = Path.GetDirectoryName(path), WorkingDirectory = Path.GetDirectoryName(path),
FileName = path, FileName = path,
UseShellExecute = false, UseShellExecute = false,
Arguments = arguments Arguments = arguments
}).Close(); })?.Close();
return true;
} }
public void OpenLink(string url) public void OpenLink(string url)
@@ -428,6 +432,11 @@ namespace VRCX
return Program.Version; return Program.Version;
} }
public bool VrcClosedGracefully()
{
return LogWatcher.Instance.VrcClosedGracefully;
}
public void ChangeTheme(int value) public void ChangeTheme(int value)
{ {
WinformThemer.SetGlobalTheme(value); WinformThemer.SetGlobalTheme(value);
+104 -68
View File
@@ -4,40 +4,28 @@
// This work is licensed under the terms of the MIT license. // This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>. // For a copy, see <https://opensource.org/licenses/MIT>.
using CefSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using CefSharp;
namespace VRCX namespace VRCX
{ {
public class LogWatcher public class LogWatcher
{ {
private class LogContext
{
public long Length;
public long Position;
public string RecentWorldName;
public bool ShaderKeywordsLimitReached = false;
public bool AudioDeviceChanged = false;
public string LastAudioDevice;
public string LastVideoError;
public string onJoinPhotonDisplayName;
public string locationDestination;
}
public static readonly LogWatcher Instance; public static readonly LogWatcher Instance;
private readonly DirectoryInfo m_LogDirectoryInfo;
private readonly Dictionary<string, LogContext> m_LogContextMap; // <FileName, LogContext> private readonly Dictionary<string, LogContext> m_LogContextMap; // <FileName, LogContext>
private readonly ReaderWriterLockSlim m_LogListLock; private readonly DirectoryInfo m_LogDirectoryInfo;
private readonly List<string[]> m_LogList; private readonly List<string[]> m_LogList;
private Thread m_Thread; private readonly ReaderWriterLockSlim m_LogListLock;
private bool m_ResetLog;
private bool m_FirstRun = true; private bool m_FirstRun = true;
private static DateTime tillDate = DateTime.Now; private bool m_ResetLog;
private Thread m_Thread;
private DateTime tillDate = DateTime.Now;
public bool VrcClosedGracefully;
// NOTE // NOTE
// FileSystemWatcher() is unreliable // FileSystemWatcher() is unreliable
@@ -102,7 +90,7 @@ namespace VRCX
private void Update() private void Update()
{ {
if (m_ResetLog == true) if (m_ResetLog)
{ {
m_FirstRun = true; m_FirstRun = true;
m_ResetLog = false; m_ResetLog = false;
@@ -121,7 +109,7 @@ namespace VRCX
var deletedNameSet = new HashSet<string>(m_LogContextMap.Keys); var deletedNameSet = new HashSet<string>(m_LogContextMap.Keys);
m_LogDirectoryInfo.Refresh(); m_LogDirectoryInfo.Refresh();
if (m_LogDirectoryInfo.Exists == true) if (m_LogDirectoryInfo.Exists)
{ {
var fileInfos = m_LogDirectoryInfo.GetFiles("output_log_*.txt", SearchOption.TopDirectoryOnly); var fileInfos = m_LogDirectoryInfo.GetFiles("output_log_*.txt", SearchOption.TopDirectoryOnly);
@@ -141,7 +129,7 @@ namespace VRCX
continue; continue;
} }
if (m_LogContextMap.TryGetValue(fileInfo.Name, out LogContext logContext) == true) if (m_LogContextMap.TryGetValue(fileInfo.Name, out var logContext))
{ {
deletedNameSet.Remove(fileInfo.Name); deletedNameSet.Remove(fileInfo.Name);
} }
@@ -168,7 +156,7 @@ namespace VRCX
m_FirstRun = false; m_FirstRun = false;
} }
private void ParseLog(FileInfo fileInfo, LogContext logContext) private void ParseLog(FileInfo fileInfo, LogContext logContext)
{ {
try try
@@ -187,9 +175,17 @@ namespace VRCX
break; break;
} }
if (line.Length == 0)
{
continue;
}
// 2020.10.31 23:36:28 Log - [VRCFlowManagerVRC] Destination fetching: wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd // 2020.10.31 23:36:28 Log - [VRCFlowManagerVRC] Destination fetching: wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd
// 2021.02.03 10:18:58 Log - [DŽDŽDžDžDžDŽDŽDžDžDŽDžDžDžDžDŽDŽDŽDžDžDŽDŽDžDžDžDžDŽDžDžDžDžDŽDŽDŽDŽDŽDžDŽDžDŽDŽDŽDžDžDŽDžDžDž] Destination fetching: wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd // 2021.02.03 10:18:58 Log - [DŽDŽDžDžDžDŽDŽDžDžDŽDžDžDžDžDŽDŽDŽDžDžDŽDŽDžDžDžDžDŽDžDžDžDžDŽDŽDŽDŽDŽDžDŽDžDŽDŽDŽDžDžDŽDžDžDž] Destination fetching: wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd
if (ParseLogUdonException(fileInfo, line))
continue;
if (line.Length <= 36 || if (line.Length <= 36 ||
line[31] != '-') line[31] != '-')
{ {
@@ -198,12 +194,12 @@ namespace VRCX
} }
if (DateTime.TryParseExact( if (DateTime.TryParseExact(
line.Substring(0, 19), line.Substring(0, 19),
"yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss",
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal, DateTimeStyles.AssumeLocal,
out DateTime lineDate out var lineDate
)) ))
{ {
if (DateTime.Compare(lineDate, tillDate) <= 0) if (DateTime.Compare(lineDate, tillDate) <= 0)
{ {
@@ -214,33 +210,31 @@ namespace VRCX
var offset = 34; var offset = 34;
if (line[offset] == '[') if (line[offset] == '[')
{ {
if (ParseLogOnPlayerJoinedOrLeft(fileInfo, logContext, line, offset) == true || if (ParseLogOnPlayerJoinedOrLeft(fileInfo, logContext, line, offset) ||
ParseLogLocation(fileInfo, logContext, line, offset) == true || ParseLogLocation(fileInfo, logContext, line, offset) ||
ParseLogLocationDestination(fileInfo, logContext, line, offset) == true || ParseLogLocationDestination(fileInfo, logContext, line, offset) ||
ParseLogPortalSpawn(fileInfo, logContext, line, offset) == true || ParseLogPortalSpawn(fileInfo, logContext, line, offset) ||
ParseLogNotification(fileInfo, logContext, line, offset) == true || ParseLogNotification(fileInfo, logContext, line, offset) ||
ParseLogAPIRequest(fileInfo, logContext, line, offset) == true || ParseLogAPIRequest(fileInfo, logContext, line, offset) ||
ParseLogJoinBlocked(fileInfo, logContext, line, offset) == true || ParseLogJoinBlocked(fileInfo, logContext, line, offset) ||
ParseLogAvatarPedestalChange(fileInfo, logContext, line, offset) == true || ParseLogAvatarPedestalChange(fileInfo, logContext, line, offset) ||
ParseLogVideoError(fileInfo, logContext, line, offset) == true || ParseLogVideoError(fileInfo, logContext, line, offset) ||
ParseLogVideoChange(fileInfo, logContext, line, offset) == true || ParseLogVideoChange(fileInfo, logContext, line, offset) ||
ParseLogUsharpVideoPlay(fileInfo, logContext, line, offset) == true || ParseLogUsharpVideoPlay(fileInfo, logContext, line, offset) ||
ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) == true || ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) ||
ParseLogWorldVRCX(fileInfo, logContext, line, offset) == true || ParseLogWorldVRCX(fileInfo, logContext, line, offset) ||
ParseLogOnAudioConfigurationChanged(fileInfo, logContext, line, offset) == true || ParseLogOnAudioConfigurationChanged(fileInfo, logContext, line, offset) ||
ParseLogScreenshot(fileInfo, logContext, line, offset) == true) ParseLogScreenshot(fileInfo, logContext, line, offset))
{ {
continue;
} }
} }
else else
{ {
if (ParseLogShaderKeywordsLimit(fileInfo, logContext, line, offset) == true || if (ParseLogShaderKeywordsLimit(fileInfo, logContext, line, offset) ||
ParseLogSDK2VideoPlay(fileInfo, logContext, line, offset) == true || ParseLogSDK2VideoPlay(fileInfo, logContext, line, offset) ||
ParseApplicationQuit(fileInfo, logContext, line, offset) == true || ParseApplicationQuit(fileInfo, logContext, line, offset) ||
ParseOpenVRInit(fileInfo, logContext, line, offset) == true) ParseOpenVRInit(fileInfo, logContext, line, offset))
{ {
continue;
} }
} }
} }
@@ -263,6 +257,7 @@ namespace VRCX
if (MainForm.Instance != null && MainForm.Instance.Browser != null) if (MainForm.Instance != null && MainForm.Instance.Browser != null)
MainForm.Instance.Browser.ExecuteScriptAsync("$app.addGameLogEvent", logLine); MainForm.Instance.Browser.ExecuteScriptAsync("$app.addGameLogEvent", logLine);
} }
m_LogList.Add(item); m_LogList.Add(item);
} }
finally finally
@@ -276,12 +271,12 @@ namespace VRCX
// 2020.10.31 23:36:22 // 2020.10.31 23:36:22
if (DateTime.TryParseExact( if (DateTime.TryParseExact(
line.Substring(0, 19), line.Substring(0, 19),
"yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss",
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal,
out DateTime dt out var dt
) == false) ) == false)
{ {
dt = DateTime.UtcNow; dt = DateTime.UtcNow;
} }
@@ -334,10 +329,11 @@ namespace VRCX
logContext.RecentWorldName logContext.RecentWorldName
}); });
logContext.onJoinPhotonDisplayName = String.Empty; logContext.onJoinPhotonDisplayName = string.Empty;
logContext.LastAudioDevice = String.Empty; logContext.LastAudioDevice = string.Empty;
logContext.LastVideoError = String.Empty; logContext.LastVideoError = string.Empty;
logContext.locationDestination = String.Empty; logContext.locationDestination = string.Empty;
VrcClosedGracefully = false;
return true; return true;
} }
@@ -355,7 +351,7 @@ namespace VRCX
var lineOffset = line.LastIndexOf("] Took screenshot to: "); var lineOffset = line.LastIndexOf("] Took screenshot to: ");
if (lineOffset < 0) if (lineOffset < 0)
return true; return true;
var screenshotPath = line.Substring(lineOffset + 22); var screenshotPath = line.Substring(lineOffset + 22);
AppendLog(new[] { fileInfo.Name, ConvertLogTimeToISO8601(line), "screenshot", screenshotPath }); AppendLog(new[] { fileInfo.Name, ConvertLogTimeToISO8601(line), "screenshot", screenshotPath });
return true; return true;
@@ -377,7 +373,7 @@ namespace VRCX
logContext.locationDestination logContext.locationDestination
}); });
logContext.locationDestination = String.Empty; logContext.locationDestination = string.Empty;
return true; return true;
} }
@@ -481,6 +477,7 @@ namespace VRCX
}); });
return true; return true;
} }
return false; return false;
} }
@@ -491,7 +488,7 @@ namespace VRCX
if (line.Contains("Maximum number (384) of shader global keywords exceeded")) if (line.Contains("Maximum number (384) of shader global keywords exceeded"))
{ {
if (logContext.ShaderKeywordsLimitReached == true) if (logContext.ShaderKeywordsLimitReached)
return true; return true;
AppendLog(new[] AppendLog(new[]
@@ -766,7 +763,7 @@ namespace VRCX
if (pos < 0) if (pos < 0)
return false; return false;
if (!String.IsNullOrEmpty(logContext.onJoinPhotonDisplayName)) if (!string.IsNullOrEmpty(logContext.onJoinPhotonDisplayName))
{ {
var endPos = line.LastIndexOf(" ("); var endPos = line.LastIndexOf(" (");
var photonId = line.Substring(pos + 9, endPos - (pos + 9)); var photonId = line.Substring(pos + 9, endPos - (pos + 9));
@@ -779,7 +776,7 @@ namespace VRCX
logContext.onJoinPhotonDisplayName, logContext.onJoinPhotonDisplayName,
photonId photonId
}); });
logContext.onJoinPhotonDisplayName = String.Empty; logContext.onJoinPhotonDisplayName = string.Empty;
return true; return true;
} }
@@ -830,12 +827,13 @@ namespace VRCX
lineOffset += 3; lineOffset += 3;
var endPos = line.Length - 1; var endPos = line.Length - 1;
var audioDevice = line.Substring(lineOffset, endPos - lineOffset); var audioDevice = line.Substring(lineOffset, endPos - lineOffset);
if (String.IsNullOrEmpty(logContext.LastAudioDevice)) if (string.IsNullOrEmpty(logContext.LastAudioDevice))
{ {
logContext.AudioDeviceChanged = false; logContext.AudioDeviceChanged = false;
logContext.LastAudioDevice = audioDevice; logContext.LastAudioDevice = audioDevice;
return true; return true;
} }
if (!logContext.AudioDeviceChanged || logContext.LastAudioDevice == audioDevice) if (!logContext.AudioDeviceChanged || logContext.LastAudioDevice == audioDevice)
return true; return true;
@@ -856,6 +854,27 @@ namespace VRCX
return false; return false;
} }
private bool ParseLogUdonException(FileInfo fileInfo, string line)
{
// 2022.11.29 04:27:33 Error - [UdonBehaviour] An exception occurred during Udon execution, this UdonBehaviour will be halted.
// VRC.Udon.VM.UdonVMException: An exception occurred in an UdonVM, execution will be halted. --->VRC.Udon.VM.UdonVMException: An exception occurred during EXTERN to 'VRCSDKBaseVRCPlayerApi.__get_displayName__SystemString'. --->System.NullReferenceException: Object reference not set to an instance of an object.
var lineOffset = line.IndexOf(" ---> VRC.Udon.VM.UdonVMException: ");
if (lineOffset < 0)
return false;
var data = line.Substring(lineOffset);
AppendLog(new[]
{
fileInfo.Name,
ConvertLogTimeToISO8601(line),
"udon-exception",
data
});
return true;
}
private bool ParseApplicationQuit(FileInfo fileInfo, LogContext logContext, string line, int offset) private bool ParseApplicationQuit(FileInfo fileInfo, LogContext logContext, string line, int offset)
{ {
// 2022.06.12 01:51:46 Log - VRCApplication: OnApplicationQuit at 1603.499 // 2022.06.12 01:51:46 Log - VRCApplication: OnApplicationQuit at 1603.499
@@ -870,6 +889,8 @@ namespace VRCX
"vrc-quit" "vrc-quit"
}); });
VrcClosedGracefully = true;
return true; return true;
} }
@@ -890,12 +911,12 @@ namespace VRCX
return true; return true;
} }
private void ParseDesktopMode(FileInfo fileInfo, string line) private bool ParseDesktopMode(FileInfo fileInfo, string line)
{ {
// XR Device: None // XR Device: None
if (string.Compare(line, 0, " XR Device: None", 0, 19, StringComparison.Ordinal) != 0) if (string.Compare(line, 0, " XR Device: None", 0, 19, StringComparison.Ordinal) != 0)
return; return false;
AppendLog(new[] AppendLog(new[]
{ {
@@ -903,6 +924,8 @@ namespace VRCX
ConvertLogTimeToISO8601(line), ConvertLogTimeToISO8601(line),
"desktop-mode" "desktop-mode"
}); });
return true;
} }
public string[][] Get() public string[][] Get()
@@ -939,5 +962,18 @@ namespace VRCX
return new string[][] { }; return new string[][] { };
} }
private class LogContext
{
public bool AudioDeviceChanged;
public string LastAudioDevice;
public string LastVideoError;
public long Length;
public string locationDestination;
public string onJoinPhotonDisplayName;
public long Position;
public string RecentWorldName;
public bool ShaderKeywordsLimitReached;
}
} }
} }
+62 -2
View File
@@ -5026,6 +5026,7 @@ speechSynthesis.getVoices();
API.currentUser.$online_for = ''; API.currentUser.$online_for = '';
API.currentUser.$offline_for = Date.now(); API.currentUser.$offline_for = Date.now();
this.autoVRChatCacheManagement(); this.autoVRChatCacheManagement();
this.checkIfGameCrashed();
this.ipcTimeout = 0; this.ipcTimeout = 0;
} }
this.lastLocationReset(); this.lastLocationReset();
@@ -9197,7 +9198,8 @@ speechSynthesis.getVoices();
if ( if (
this.debugGameLog && this.debugGameLog &&
gameLog.type !== 'photon-id' && gameLog.type !== 'photon-id' &&
gameLog.type !== 'api-request' gameLog.type !== 'api-request' &&
gameLog.type !== 'udon-exception'
) { ) {
console.log('gameLog:', gameLog); console.log('gameLog:', gameLog);
} }
@@ -9525,6 +9527,15 @@ speechSynthesis.getVoices();
this.isGameNoVR = true; this.isGameNoVR = true;
configRepository.setBool('isGameNoVR', this.isGameNoVR); configRepository.setBool('isGameNoVR', this.isGameNoVR);
break; break;
case 'udon-exception':
console.log('UdonException', gameLog.data);
// var entry = {
// created_at: gameLog.dt,
// type: 'Event',
// data: gameLog.data
// };
// database.addGamelogEventToDatabase(entry);
break;
} }
if (entry) { if (entry) {
this.queueGameLogNoty(entry); this.queueGameLogNoty(entry);
@@ -13060,6 +13071,9 @@ speechSynthesis.getVoices();
$app.data.autoSweepVRChatCache = configRepository.getBool( $app.data.autoSweepVRChatCache = configRepository.getBool(
'VRCX_autoSweepVRChatCache' 'VRCX_autoSweepVRChatCache'
); );
$app.data.relaunchVRChatAfterCrash = configRepository.getBool(
'VRCX_relaunchVRChatAfterCrash'
);
$app.data.vrcQuitFix = configRepository.getBool('VRCX_vrcQuitFix'); $app.data.vrcQuitFix = configRepository.getBool('VRCX_vrcQuitFix');
$app.data.vrBackgroundEnabled = configRepository.getBool( $app.data.vrBackgroundEnabled = configRepository.getBool(
'VRCX_vrBackgroundEnabled' 'VRCX_vrBackgroundEnabled'
@@ -13180,6 +13194,10 @@ speechSynthesis.getVoices();
'VRCX_autoSweepVRChatCache', 'VRCX_autoSweepVRChatCache',
this.autoSweepVRChatCache this.autoSweepVRChatCache
); );
configRepository.setBool(
'VRCX_relaunchVRChatAfterCrash',
this.relaunchVRChatAfterCrash
);
configRepository.setBool('VRCX_vrcQuitFix', this.vrcQuitFix); configRepository.setBool('VRCX_vrcQuitFix', this.vrcQuitFix);
configRepository.setBool( configRepository.setBool(
'VRCX_vrBackgroundEnabled', 'VRCX_vrBackgroundEnabled',
@@ -17738,9 +17756,29 @@ speechSynthesis.getVoices();
args.push('--no-vr'); args.push('--no-vr');
} }
if (vrcLaunchPathOverride) { if (vrcLaunchPathOverride) {
AppApi.StartGameFromPath(vrcLaunchPathOverride, args.join(' ')); AppApi.StartGameFromPath(
vrcLaunchPathOverride,
args.join(' ')
).then((result) => {
if (!result) {
this.$message({
message:
'Failed to launch VRChat, invalid custom path set',
type: 'error'
});
} else {
this.$message({
message: 'VRChat launched',
type: 'success'
});
}
});
} else { } else {
AppApi.StartGame(args.join(' ')); AppApi.StartGame(args.join(' '));
this.$message({
message: 'VRChat launched',
type: 'success'
});
} }
D.visible = false; D.visible = false;
}; };
@@ -20689,6 +20727,28 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.checkIfGameCrashed = function () {
if (!this.relaunchVRChatAfterCrash) {
return;
}
var lastLocation = this.lastLocation.location;
AppApi.VrcClosedGracefully().then((result) => {
console.log(result, lastLocation);
if (result || !this.isRealInstance(lastLocation)) {
return;
}
var entry = {
created_at: new Date().toJSON(),
type: 'Event',
data: 'VRChat crashed, attempting to rejoin last instance'
};
database.addGamelogEventToDatabase(entry);
this.queueGameLogNoty(entry);
this.addGameLog(entry);
this.launchGame(lastLocation);
});
};
$app.data.VRChatUsedCacheSize = ''; $app.data.VRChatUsedCacheSize = '';
$app.data.VRChatTotalCacheSize = ''; $app.data.VRChatTotalCacheSize = '';
$app.data.VRChatCacheSizeLoading = false; $app.data.VRChatCacheSizeLoading = false;
+9 -5
View File
@@ -1406,15 +1406,14 @@ html
el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") {{ $t('view.settings.advanced.advanced.launch_options') }} el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") {{ $t('view.settings.advanced.advanced.launch_options') }}
el-button(size="small" icon="el-icon-picture" @click="showScreenshotMetadataDialog()") {{ $t('view.settings.advanced.advanced.screenshot_metadata') }} el-button(size="small" icon="el-icon-picture" @click="showScreenshotMetadataDialog()") {{ $t('view.settings.advanced.advanced.screenshot_metadata') }}
div.options-container div.options-container
span.sub-header {{ $t('view.settings.advanced.advanced.pending_offline.header') }}
div.options-container-item
span.name {{ $t('view.settings.advanced.advanced.pending_offline.description') }}
el-button-group(style="display:block")
el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") {{ $t('view.settings.advanced.advanced.pending_offline.set_delay') }}
span.sub-header {{ $t('view.settings.advanced.advanced.primary_password.header') }} span.sub-header {{ $t('view.settings.advanced.advanced.primary_password.header') }}
div.options-container-item div.options-container-item
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.primary_password.description') }} span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.primary_password.description') }}
el-switch(v-model="enablePrimaryPassword" @change="enablePrimaryPasswordChange" :disabled="!loginForm.savedCredentials[API.currentUser.username]") el-switch(v-model="enablePrimaryPassword" @change="enablePrimaryPasswordChange" :disabled="!loginForm.savedCredentials[API.currentUser.username]")
span.sub-header {{ $t('view.settings.advanced.advanced.relaunch_vrchat.header') }}
div.options-container-item
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.relaunch_vrchat.description') }}
el-switch(v-model="relaunchVRChatAfterCrash" @change="saveOpenVROption")
span.sub-header {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.header') }} span.sub-header {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.header') }}
div.options-container-item div.options-container-item
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.description') }} span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.description') }}
@@ -1497,6 +1496,11 @@ html
el-button(size="small" icon="el-icon-time" @click="promptPhotonLobbyTimeoutThreshold" :disabled="!openVR") {{ $t('view.settings.advanced.photon.timeout_hud.timeout_threshold') }} el-button(size="small" icon="el-icon-time" @click="promptPhotonLobbyTimeoutThreshold" :disabled="!openVR") {{ $t('view.settings.advanced.photon.timeout_hud.timeout_threshold') }}
div.options-container div.options-container
span.header {{ $t('view.settings.advanced.advanced.cache_debug.header') }} span.header {{ $t('view.settings.advanced.advanced.cache_debug.header') }}
span.sub-header {{ $t('view.settings.advanced.advanced.pending_offline.header') }}
div.options-container-item
span.name {{ $t('view.settings.advanced.advanced.pending_offline.description') }}
el-button-group(style="display:block")
el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") {{ $t('view.settings.advanced.advanced.pending_offline.set_delay') }}
div.options-container-item div.options-container-item
span.name {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog') }} span.name {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog') }}
el-switch(v-model="gameLogDisabled" @change="disableGameLogDialog") el-switch(v-model="gameLogDisabled" @change="disableGameLogDialog")
+4
View File
@@ -359,6 +359,10 @@
"header": "Primary Password", "header": "Primary Password",
"description": "Encrypt password (disables auto login)" "description": "Encrypt password (disables auto login)"
}, },
"relaunch_vrchat": {
"header": "Relaunch VRChat after crashing",
"description": "Rejoin last instance when VRChat crashes"
},
"vrchat_quit_fix": { "vrchat_quit_fix": {
"header": "VRChat Quit Fix", "header": "VRChat Quit Fix",
"description": "Kill VRChat after exiting game" "description": "Kill VRChat after exiting game"
+4
View File
@@ -71,6 +71,10 @@ class GameLogService {
case 'desktop-mode': case 'desktop-mode':
break; break;
case 'udon-exception':
gameLog.data = args[0];
break;
default: default:
break; break;
} }