Random fixes

This commit is contained in:
Natsumi
2025-10-20 13:22:22 +11:00
parent b4cafe2f3d
commit 97ef396ec9
16 changed files with 79 additions and 22 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ namespace VRCX
var output = new Dictionary<string, Dictionary<string, object>>(); var output = new Dictionary<string, Dictionary<string, object>>();
using var regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\VRChat\VRChat"); using var regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\VRChat\VRChat");
if (regKey == null) if (regKey == null)
throw new Exception("Nothing to backup."); throw new Exception("Failed to get VRC registry data");
var keys = regKey.GetValueNames(); var keys = regKey.GetValueNames();
+20
View File
@@ -24,6 +24,26 @@ namespace VRCX
var fileName = Path.GetFileNameWithoutExtension(path); var fileName = Path.GetFileNameWithoutExtension(path);
if (!File.Exists(path) || !path.EndsWith(".png") || !fileName.StartsWith("VRChat_")) if (!File.Exists(path) || !path.EndsWith(".png") || !fileName.StartsWith("VRChat_"))
return string.Empty; return string.Empty;
// check if file is in use and we have permission to write
var success = false;
for (var i = 0; i < 10; i++)
{
try
{
using (File.Open(path, FileMode.Append, FileAccess.Write, FileShare.None))
{
success = true;
break;
}
}
catch (IOException)
{
Thread.Sleep(1000);
}
}
if (!success)
return string.Empty;
if (changeFilename) if (changeFilename)
{ {
+2 -2
View File
@@ -14,7 +14,6 @@ namespace VRCX
public partial class AppApi public partial class AppApi
{ {
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private static readonly MD5 _hasher = MD5.Create();
public void Init() public void Init()
{ {
@@ -30,7 +29,8 @@ namespace VRCX
public int GetColourFromUserID(string userId) public int GetColourFromUserID(string userId)
{ {
var hash = _hasher.ComputeHash(Encoding.UTF8.GetBytes(userId)); using var hasher = MD5.Create();
var hash = hasher.ComputeHash(Encoding.UTF8.GetBytes(userId));
return (hash[3] << 8) | hash[4]; return (hash[3] << 8) | hash[4];
} }
+12 -2
View File
@@ -30,19 +30,24 @@ namespace VRCX
_steamPath = Path.Join(_homeDirectory, ".local/share/Steam"); _steamPath = Path.Join(_homeDirectory, ".local/share/Steam");
var flatpakSteamPath = Path.Join(_homeDirectory, ".var/app/com.valvesoftware.Steam/.local/share/Steam"); var flatpakSteamPath = Path.Join(_homeDirectory, ".var/app/com.valvesoftware.Steam/.local/share/Steam");
if (!Directory.Exists(_steamPath) && Directory.Exists(flatpakSteamPath)) if (!IsValidSteamPath(_steamPath) && IsValidSteamPath(flatpakSteamPath))
{ {
logger.Info("Flatpak Steam detected."); logger.Info("Flatpak Steam detected.");
_steamPath = flatpakSteamPath; _steamPath = flatpakSteamPath;
} }
var legacySteamPath = Path.Join(_homeDirectory, ".steam/steam"); var legacySteamPath = Path.Join(_homeDirectory, ".steam/steam");
if (!Directory.Exists(_steamPath) && Directory.Exists(legacySteamPath)) if (!IsValidSteamPath(_steamPath) && IsValidSteamPath(legacySteamPath))
{ {
logger.Info("Legacy Steam path detected."); logger.Info("Legacy Steam path detected.");
_steamPath = legacySteamPath; _steamPath = legacySteamPath;
} }
if (!IsValidSteamPath(_steamPath))
{
logger.Error("No valid Steam library found.");
}
var libraryFoldersVdfPath = Path.Join(_steamPath, "config/libraryfolders.vdf"); var libraryFoldersVdfPath = Path.Join(_steamPath, "config/libraryfolders.vdf");
var vrcLibraryPath = GetLibraryWithAppId(libraryFoldersVdfPath, vrchatAppid); var vrcLibraryPath = GetLibraryWithAppId(libraryFoldersVdfPath, vrchatAppid);
if (string.IsNullOrEmpty(vrcLibraryPath)) if (string.IsNullOrEmpty(vrcLibraryPath))
@@ -55,6 +60,11 @@ namespace VRCX
_vrcAppDataPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/LocalLow/VRChat/VRChat"); _vrcAppDataPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/LocalLow/VRChat/VRChat");
_vrcCrashesPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/Local/Temp/VRChat/VRChat/Crashes"); _vrcCrashesPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/Local/Temp/VRChat/VRChat/Crashes");
} }
private static bool IsValidSteamPath(string path)
{
return File.Exists(Path.Join(path, "config/libraryfolders.vdf"));
}
private static string? GetLibraryWithAppId(string libraryFoldersVdfPath, string appId) private static string? GetLibraryWithAppId(string libraryFoldersVdfPath, string appId)
{ {
@@ -611,10 +611,10 @@ namespace VRCX
public string GetVRChatRegistryJson() public string GetVRChatRegistryJson()
{ {
var registry = new Dictionary<string, Dictionary<string, object>>(); var registry = new Dictionary<string, Dictionary<string, object>>();
string regCommand = "query \"HKEY_CURRENT_USER\\SOFTWARE\\VRChat\\VRChat\""; const string regCommand = "query \"HKEY_CURRENT_USER\\SOFTWARE\\VRChat\\VRChat\"";
var queryResult = GetWineRegCommand(regCommand); var queryResult = GetWineRegCommand(regCommand);
if (queryResult == null) if (queryResult == null)
return null; throw new Exception("Failed to get VRC registry data");
var lines = queryResult.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) var lines = queryResult.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Where(line => .Where(line =>
+1 -1
View File
@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputPath>..\build\Cef\</OutputPath> <OutputPath>..\build\Cef\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
@@ -32,6 +31,7 @@
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<!-- Fix fail fast exception --> <!-- Fix fail fast exception -->
<CETCompat>false</CETCompat> <CETCompat>false</CETCompat>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WarningLevel>0</WarningLevel> <WarningLevel>0</WarningLevel>
</PropertyGroup> </PropertyGroup>
+1 -1
View File
@@ -185,7 +185,7 @@
const friendsInCurrentInstance = lastLocation.value.friendList; const friendsInCurrentInstance = lastLocation.value.friendList;
for (const friend of friendsInCurrentInstance.values()) { for (const friend of friendsInCurrentInstance.values()) {
const ctx = friends.value.get(friend.userId); const ctx = friends.value.get(friend.userId);
if (typeof ctx.ref === 'undefined') { if (typeof ctx?.ref === 'undefined') {
continue; continue;
} }
D.friendsInInstance.push(ctx); D.friendsInInstance.push(ctx);
+1 -1
View File
@@ -594,7 +594,7 @@
const friendsInCurrentInstance = lastLocation.value.friendList; const friendsInCurrentInstance = lastLocation.value.friendList;
for (const friend of friendsInCurrentInstance.values()) { for (const friend of friendsInCurrentInstance.values()) {
const ctx = friends.value.get(friend.userId); const ctx = friends.value.get(friend.userId);
if (typeof ctx.ref === 'undefined') { if (typeof ctx?.ref === 'undefined') {
continue; continue;
} }
D.friendsInInstance.push(ctx); D.friendsInInstance.push(ctx);
@@ -249,7 +249,7 @@
style="margin-left: 5px" style="margin-left: 5px"
@click="showBioDialog"></el-button> @click="showBioDialog"></el-button>
</div> </div>
<div v-if="translationApi" style="float: right"> <div v-if="translationApi && userDialog.ref.bio" style="float: right">
<el-button type="text" size="small" style="margin-left: 5px" @click="translateBio" <el-button type="text" size="small" style="margin-left: 5px" @click="translateBio"
><i class="ri-translate-2"></i ><i class="ri-translate-2"></i
></el-button> ></el-button>
+1 -1
View File
@@ -364,7 +364,7 @@ export const useInstanceStore = defineStore('Instance', () => {
} }
if ( if (
userStore.userDialog.visible && userStore.userDialog.visible &&
userStore.userDialog.ref?.$location.tag === ref.id userStore.userDialog.ref?.$location?.tag === ref.id
) { ) {
userStore.applyUserDialogLocation(); userStore.applyUserDialogLocation();
} }
+14 -5
View File
@@ -397,6 +397,10 @@ export const useVrcxStore = defineStore('Vrcx', () => {
location.worldId, location.worldId,
advancedSettingsStore.screenshotHelperModifyFilename advancedSettingsStore.screenshotHelperModifyFilename
); );
if (!newPath) {
console.error('Failed to add screenshot metadata', path);
return;
}
console.log('Screenshot metadata added', newPath); console.log('Screenshot metadata added', newPath);
} }
if (advancedSettingsStore.screenshotHelperCopyToClipboard) { if (advancedSettingsStore.screenshotHelperCopyToClipboard) {
@@ -618,11 +622,16 @@ export const useVrcxStore = defineStore('Vrcx', () => {
async function backupVrcRegistry(name) { async function backupVrcRegistry(name) {
let regJson; let regJson;
if (WINDOWS) { try {
regJson = await AppApi.GetVRChatRegistry(); if (WINDOWS) {
} else { regJson = await AppApi.GetVRChatRegistry();
regJson = await AppApi.GetVRChatRegistryJson(); } else {
regJson = JSON.parse(regJson); regJson = await AppApi.GetVRChatRegistryJson();
regJson = JSON.parse(regJson);
}
} catch (e) {
console.error('Failed to get VRChat registry for backup:', e);
return;
} }
const newBackup = { const newBackup = {
name, name,
+18
View File
@@ -200,6 +200,15 @@ export const useVRCXUpdaterStore = defineStore('VRCXUpdater', () => {
} finally { } finally {
checkingForVRCXUpdate.value = false; checkingForVRCXUpdate.value = false;
} }
if (response.status !== 200) {
ElMessage({
message: t('message.vrcx_updater.failed', {
message: `${response.status} ${response.data}`
}),
type: 'error'
});
return;
}
pendingVRCXUpdate.value = false; pendingVRCXUpdate.value = false;
const json = JSON.parse(response.data); const json = JSON.parse(response.data);
if (AppDebug.debugWebRequests) { if (AppDebug.debugWebRequests) {
@@ -263,6 +272,15 @@ export const useVRCXUpdaterStore = defineStore('VRCXUpdater', () => {
} finally { } finally {
checkingForVRCXUpdate.value = false; checkingForVRCXUpdate.value = false;
} }
if (response.status !== 200) {
ElMessage({
message: t('message.vrcx_updater.failed', {
message: `${response.status} ${response.data}`
}),
type: 'error'
});
return;
}
const json = JSON.parse(response.data); const json = JSON.parse(response.data);
if (AppDebug.debugWebRequests) { if (AppDebug.debugWebRequests) {
console.log(json, response); console.log(json, response);
@@ -170,7 +170,7 @@
t(props.isLocalFavorite ? 'view.favorite.copy_tooltip' : 'view.favorite.move_tooltip') t(props.isLocalFavorite ? 'view.favorite.copy_tooltip' : 'view.favorite.move_tooltip')
); );
const smallThumbnail = computed( const smallThumbnail = computed(
() => localFavFakeRef.value.thumbnailImageUrl.replace('256', '128') || localFavFakeRef.value.thumbnailImageUrl () => localFavFakeRef.value.thumbnailImageUrl?.replace('256', '128') || localFavFakeRef.value.thumbnailImageUrl
); );
const favoriteGroupName = computed(() => { const favoriteGroupName = computed(() => {
if (typeof props.group === 'string') { if (typeof props.group === 'string') {
@@ -68,6 +68,6 @@
defineEmits(['click']); defineEmits(['click']);
const smallThumbnail = computed(() => { const smallThumbnail = computed(() => {
return props.favorite.thumbnailImageUrl.replace('256', '128') || props.favorite.thumbnailImageUrl; return props.favorite.thumbnailImageUrl?.replace('256', '128') || props.favorite.thumbnailImageUrl;
}); });
</script> </script>
@@ -162,7 +162,7 @@
); );
const smallThumbnail = computed(() => { const smallThumbnail = computed(() => {
const url = localFavFakeRef.value.thumbnailImageUrl.replace('256', '128'); const url = localFavFakeRef.value.thumbnailImageUrl?.replace('256', '128');
return url || localFavFakeRef.value.thumbnailImageUrl; return url || localFavFakeRef.value.thumbnailImageUrl;
}); });
+2 -2
View File
@@ -670,7 +670,7 @@
} }
function setProfilePicOverride(fileId) { function setProfilePicOverride(fileId) {
if (!currentUser.value.$isVRCPlus) { if (!isLocalUserVrcPlusSupporter.value) {
ElMessage({ ElMessage({
message: 'VRCPlus required', message: 'VRCPlus required',
type: 'error' type: 'error'
@@ -773,7 +773,7 @@
} }
function setVRCPlusIcon(fileId) { function setVRCPlusIcon(fileId) {
if (!currentUser.value.$isVRCPlus) { if (!isLocalUserVrcPlusSupporter.value) {
ElMessage({ ElMessage({
message: 'VRCPlus required', message: 'VRCPlus required',
type: 'error' type: 'error'