mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-11 19:03:51 +02:00
322 lines
9.3 KiB
JavaScript
322 lines
9.3 KiB
JavaScript
import Noty from 'noty';
|
|
import utils from '../../classes/utils';
|
|
import { compareUnityVersion } from '../avatar/utils';
|
|
|
|
function getAvailablePlatforms(unityPackages) {
|
|
var isPC = false;
|
|
var isQuest = false;
|
|
var isIos = false;
|
|
if (typeof unityPackages === 'object') {
|
|
for (var unityPackage of unityPackages) {
|
|
if (
|
|
unityPackage.variant &&
|
|
unityPackage.variant !== 'standard' &&
|
|
unityPackage.variant !== 'security'
|
|
) {
|
|
continue;
|
|
}
|
|
if (unityPackage.platform === 'standalonewindows') {
|
|
isPC = true;
|
|
} else if (unityPackage.platform === 'android') {
|
|
isQuest = true;
|
|
} else if (unityPackage.platform === 'ios') {
|
|
isIos = true;
|
|
}
|
|
}
|
|
}
|
|
return { isPC, isQuest, isIos };
|
|
}
|
|
|
|
function downloadAndSaveJson(fileName, data) {
|
|
if (!fileName || !data) {
|
|
return;
|
|
}
|
|
try {
|
|
var link = document.createElement('a');
|
|
link.setAttribute(
|
|
'href',
|
|
`data:application/json;charset=utf-8,${encodeURIComponent(
|
|
JSON.stringify(data, null, 2)
|
|
)}`
|
|
);
|
|
link.setAttribute('download', `${fileName}.json`);
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
} catch {
|
|
new Noty({
|
|
type: 'error',
|
|
text: utils.escapeTag('Failed to download JSON.')
|
|
}).show();
|
|
}
|
|
}
|
|
|
|
async function deleteVRChatCache(ref) {
|
|
var assetUrl = '';
|
|
var variant = '';
|
|
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
|
var unityPackage = ref.unityPackages[i];
|
|
if (
|
|
unityPackage.variant &&
|
|
unityPackage.variant !== 'standard' &&
|
|
unityPackage.variant !== 'security'
|
|
) {
|
|
continue;
|
|
}
|
|
if (
|
|
unityPackage.platform === 'standalonewindows' &&
|
|
compareUnityVersion(unityPackage.unitySortNumber)
|
|
) {
|
|
assetUrl = unityPackage.assetUrl;
|
|
if (unityPackage.variant !== 'standard') {
|
|
variant = unityPackage.variant;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
var id = extractFileId(assetUrl);
|
|
var version = parseInt(extractFileVersion(assetUrl), 10);
|
|
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
|
await AssetBundleManager.DeleteCache(id, version, variant, variantVersion);
|
|
}
|
|
|
|
async function checkVRChatCache(ref) {
|
|
if (!ref.unityPackages) {
|
|
return { Item1: -1, Item2: false, Item3: '' };
|
|
}
|
|
var assetUrl = '';
|
|
var variant = '';
|
|
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
|
var unityPackage = ref.unityPackages[i];
|
|
if (unityPackage.variant && unityPackage.variant !== 'security') {
|
|
continue;
|
|
}
|
|
if (
|
|
unityPackage.platform === 'standalonewindows' &&
|
|
compareUnityVersion(unityPackage.unitySortNumber)
|
|
) {
|
|
assetUrl = unityPackage.assetUrl;
|
|
if (unityPackage.variant !== 'standard') {
|
|
variant = unityPackage.variant;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!assetUrl) {
|
|
assetUrl = ref.assetUrl;
|
|
}
|
|
var id = extractFileId(assetUrl);
|
|
var version = parseInt(extractFileVersion(assetUrl), 10);
|
|
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
|
if (!id || !version) {
|
|
return { Item1: -1, Item2: false, Item3: '' };
|
|
}
|
|
|
|
return AssetBundleManager.CheckVRChatCache(
|
|
id,
|
|
version,
|
|
variant,
|
|
variantVersion
|
|
);
|
|
}
|
|
|
|
function copyToClipboard(text, message = 'Copied successfully!') {
|
|
navigator.clipboard
|
|
.writeText(text)
|
|
.then(() => {
|
|
window.$app.$message({
|
|
message: message,
|
|
type: 'success'
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
console.error('Copy failed:', err);
|
|
window.$app.$message.error('Copy failed!');
|
|
});
|
|
}
|
|
|
|
function getFaviconUrl(resource) {
|
|
if (!resource) {
|
|
return '';
|
|
}
|
|
try {
|
|
const url = new URL(resource);
|
|
return `https://icons.duckduckgo.com/ip2/${url.host}.ico`;
|
|
} catch (err) {
|
|
console.error('Invalid URL:', err);
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function convertFileUrlToImageUrl(url, resolution = 128) {
|
|
if (!url) {
|
|
return '';
|
|
}
|
|
/**
|
|
* possible patterns?
|
|
* /file/file_fileId/version
|
|
* /file/file_fileId/version/
|
|
* /file/file_fileId/version/file
|
|
* /file/file_fileId/version/file/
|
|
*/
|
|
const pattern = /file\/file_([a-f0-9-]+)\/(\d+)(\/file)?\/?$/;
|
|
const match = url.match(pattern);
|
|
|
|
if (match) {
|
|
const fileId = match[1];
|
|
const version = match[2];
|
|
return `https://api.vrchat.cloud/api/1/image/file_${fileId}/${version}/${resolution}`;
|
|
}
|
|
// no match return origin url
|
|
return url;
|
|
}
|
|
|
|
function replaceVrcPackageUrl(url) {
|
|
if (!url) {
|
|
return '';
|
|
}
|
|
return url.replace('https://api.vrchat.cloud/', 'https://vrchat.com/');
|
|
}
|
|
|
|
function getLaunchURL(instance) {
|
|
var L = instance;
|
|
if (L.instanceId) {
|
|
if (L.shortName) {
|
|
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
|
L.worldId
|
|
)}&instanceId=${encodeURIComponent(
|
|
L.instanceId
|
|
)}&shortName=${encodeURIComponent(L.shortName)}`;
|
|
}
|
|
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
|
L.worldId
|
|
)}&instanceId=${encodeURIComponent(L.instanceId)}`;
|
|
}
|
|
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
|
L.worldId
|
|
)}`;
|
|
}
|
|
|
|
function extractFileId(s) {
|
|
var match = String(s).match(/file_[0-9A-Za-z-]+/);
|
|
return match ? match[0] : '';
|
|
}
|
|
|
|
function extractFileVersion(s) {
|
|
var match = /(?:\/file_[0-9A-Za-z-]+\/)([0-9]+)/gi.exec(s);
|
|
return match ? match[1] : '';
|
|
}
|
|
|
|
function extractVariantVersion(url) {
|
|
if (!url) {
|
|
return '0';
|
|
}
|
|
try {
|
|
const params = new URLSearchParams(new URL(url).search);
|
|
const version = params.get('v');
|
|
if (version) {
|
|
return version;
|
|
}
|
|
return '0';
|
|
} catch {
|
|
return '0';
|
|
}
|
|
}
|
|
|
|
export {
|
|
getAvailablePlatforms,
|
|
downloadAndSaveJson,
|
|
deleteVRChatCache,
|
|
checkVRChatCache,
|
|
copyToClipboard,
|
|
getFaviconUrl,
|
|
convertFileUrlToImageUrl,
|
|
replaceVrcPackageUrl,
|
|
getLaunchURL,
|
|
extractFileId,
|
|
extractFileVersion,
|
|
extractVariantVersion
|
|
};
|
|
|
|
// ---------------------- devtools method --------------------------
|
|
|
|
// not window.$app
|
|
window.getBundleLocation = async function (input) {
|
|
const $app = window.$app;
|
|
var assetUrl = input;
|
|
var variant = '';
|
|
if (assetUrl) {
|
|
// continue
|
|
} else if (
|
|
$app.avatarDialog.visible &&
|
|
$app.avatarDialog.ref.unityPackages.length > 0
|
|
) {
|
|
var unityPackages = $app.avatarDialog.ref.unityPackages;
|
|
for (let i = unityPackages.length - 1; i > -1; i--) {
|
|
var unityPackage = unityPackages[i];
|
|
if (
|
|
unityPackage.variant &&
|
|
unityPackage.variant !== 'standard' &&
|
|
unityPackage.variant !== 'security'
|
|
) {
|
|
continue;
|
|
}
|
|
if (
|
|
unityPackage.platform === 'standalonewindows' &&
|
|
compareUnityVersion(unityPackage.unitySortNumber)
|
|
) {
|
|
assetUrl = unityPackage.assetUrl;
|
|
if (unityPackage.variant !== 'standard') {
|
|
variant = unityPackage.variant;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
} else if ($app.avatarDialog.visible && $app.avatarDialog.ref.assetUrl) {
|
|
assetUrl = $app.avatarDialog.ref.assetUrl;
|
|
} else if (
|
|
$app.worldDialog.visible &&
|
|
$app.worldDialog.ref.unityPackages.length > 0
|
|
) {
|
|
var unityPackages = $app.worldDialog.ref.unityPackages;
|
|
for (let i = unityPackages.length - 1; i > -1; i--) {
|
|
var unityPackage = unityPackages[i];
|
|
if (
|
|
unityPackage.platform === 'standalonewindows' &&
|
|
compareUnityVersion(unityPackage.unitySortNumber)
|
|
) {
|
|
assetUrl = unityPackage.assetUrl;
|
|
break;
|
|
}
|
|
}
|
|
} else if ($app.worldDialog.visible && $app.worldDialog.ref.assetUrl) {
|
|
assetUrl = $app.worldDialog.ref.assetUrl;
|
|
}
|
|
if (!assetUrl) {
|
|
return null;
|
|
}
|
|
var fileId = extractFileId(assetUrl);
|
|
var fileVersion = parseInt(extractFileVersion(assetUrl), 10);
|
|
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
|
var assetLocation = await AssetBundleManager.GetVRChatCacheFullLocation(
|
|
fileId,
|
|
fileVersion,
|
|
variant,
|
|
variantVersion
|
|
);
|
|
var cacheInfo = await AssetBundleManager.CheckVRChatCache(
|
|
fileId,
|
|
fileVersion,
|
|
variant,
|
|
variantVersion
|
|
);
|
|
var inCache = false;
|
|
if (cacheInfo.Item1 > 0) {
|
|
inCache = true;
|
|
}
|
|
console.log(`InCache: ${inCache}`);
|
|
var fullAssetLocation = `${assetLocation}\\__data`;
|
|
console.log(fullAssetLocation);
|
|
return fullAssetLocation;
|
|
};
|