AssetBundleCacher 1

This commit is contained in:
Natsumi
2021-05-17 13:33:02 +12:00
parent 4b62ba08a9
commit 8f503d582c
3 changed files with 132 additions and 39 deletions
+41 -3
View File
@@ -32,6 +32,8 @@ namespace VRCX
public static bool DownloadCanceled; public static bool DownloadCanceled;
public static string AssetId; public static string AssetId;
public static string AssetVersion; public static string AssetVersion;
public static int AssetSize;
public static string AssetMd5;
public static WebClient client; public static WebClient client;
public static Process process; public static Process process;
@@ -81,7 +83,7 @@ namespace VRCX
return -1; return -1;
} }
public void DownloadCacheFile(string url, string id, int version, string AppVersion, string cacheDir) public void DownloadCacheFile(string cacheDir, string url, string id, int version, int sizeInBytes, string md5, string AppVersion)
{ {
if (!File.Exists(Path.Combine(Program.BaseDirectory, "AssetBundleCacher\\AssetBundleCacher.exe"))) if (!File.Exists(Path.Combine(Program.BaseDirectory, "AssetBundleCacher\\AssetBundleCacher.exe")))
{ {
@@ -121,6 +123,8 @@ namespace VRCX
DownloadProgress = -12; DownloadProgress = -12;
return; return;
} }
AssetSize = sizeInBytes;
AssetMd5 = md5;
AssetId = GetAssetId(id); AssetId = GetAssetId(id);
AssetVersion = GetAssetVersion(version); AssetVersion = GetAssetVersion(version);
var DownloadTempLocation = Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId); var DownloadTempLocation = Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId);
@@ -172,11 +176,38 @@ namespace VRCX
return; return;
} }
DownloadProgress = -1; DownloadProgress = -1;
if (!File.Exists(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId)))
{
DownloadProgress = -15;
return;
}
FileInfo data = new FileInfo(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId));
if (data.Length != AssetSize)
{
DownloadProgress = -15;
return;
}
using (var stream = File.OpenRead(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId)))
{
byte[] md5AsBytes = MD5.Create().ComputeHash(stream);
var md5 = System.Convert.ToBase64String(md5AsBytes);
if (md5 != AssetMd5)
{
DownloadProgress = -15;
return;
}
}
process = new Process(); process = new Process();
process.StartInfo.FileName = Path.Combine(Program.BaseDirectory, "AssetBundleCacher\\AssetBundleCacher.exe"); process.StartInfo.FileName = Path.Combine(Program.BaseDirectory, "AssetBundleCacher\\AssetBundleCacher.exe");
process.StartInfo.Arguments = AssetBundleCacherArgs; process.StartInfo.Arguments = AssetBundleCacherArgs;
process.Start(); process.Start();
process.WaitForExit(1000 * 60 * 2); //2mins process.WaitForExit(1000 * 60 * 2); //2mins
if (process.ExitCode != 0)
{
DownloadProgress = -13;
return;
}
if (DownloadCanceled) if (DownloadCanceled)
{ {
if (File.Exists(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId))) if (File.Exists(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId)))
@@ -209,7 +240,7 @@ namespace VRCX
File.Delete(Path.Combine(VRChatCacheLocation, "Cache-WindowsPlayer", "__info")); File.Delete(Path.Combine(VRChatCacheLocation, "Cache-WindowsPlayer", "__info"));
File.Move(Path.Combine(AssetBundleCacherTemp, "__info"), Path.Combine(VRChatCacheLocation, "Cache-WindowsPlayer", "__info")); File.Move(Path.Combine(AssetBundleCacherTemp, "__info"), Path.Combine(VRChatCacheLocation, "Cache-WindowsPlayer", "__info"));
Directory.Delete(Path.Combine(VRChatCacheLocation, "AssetBundleCacher\\Cache", AssetId), true); Directory.Delete(Path.Combine(VRChatCacheLocation, "AssetBundleCacher\\Cache", AssetId), true);
File.Delete(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId)); //File.Delete(Path.Combine(VRChatCacheLocation, "AssetBundleCacher", AssetId));
} }
catch catch
{ {
@@ -219,7 +250,14 @@ namespace VRCX
DownloadProgress = -3; DownloadProgress = -3;
} }
public void DeleteCache(string cacheDir) public void DeleteCache(string cacheDir, string id, int version)
{
var FullLocation = GetVRChatCacheLocation(id, version, cacheDir);
if (Directory.Exists(FullLocation))
Directory.Delete(FullLocation, true);
}
public void DeleteAllCache(string cacheDir)
{ {
var cachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat\Cache-WindowsPlayer"; var cachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat\Cache-WindowsPlayer";
if (cacheDir != String.Empty && Directory.Exists(cacheDir)) if (cacheDir != String.Empty && Directory.Exists(cacheDir))
+81 -34
View File
@@ -6866,6 +6866,8 @@ speechSynthesis.getVoices();
$app.data.notificationTimeout = configRepository.getString('VRCX_notificationTimeout'); $app.data.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
$app.data.worldAutoCacheInvite = configRepository.getString('VRCX_worldAutoCacheInvite'); $app.data.worldAutoCacheInvite = configRepository.getString('VRCX_worldAutoCacheInvite');
$app.data.worldAutoCacheGPS = configRepository.getString('VRCX_worldAutoCacheGPS'); $app.data.worldAutoCacheGPS = configRepository.getString('VRCX_worldAutoCacheGPS');
$app.data.worldAutoCacheInviteFilter = configRepository.getBool('VRCX_worldAutoCacheInviteFilter');
$app.data.worldAutoCacheGPSFilter = configRepository.getBool('VRCX_worldAutoCacheGPSFilter');
var saveOpenVROption = function () { var saveOpenVROption = function () {
configRepository.setBool('openVR', this.openVR); configRepository.setBool('openVR', this.openVR);
configRepository.setBool('openVRAlways', this.openVRAlways); configRepository.setBool('openVRAlways', this.openVRAlways);
@@ -6881,6 +6883,8 @@ speechSynthesis.getVoices();
configRepository.setBool('displayVRCPlusIconsAsAvatar', this.displayVRCPlusIconsAsAvatar); configRepository.setBool('displayVRCPlusIconsAsAvatar', this.displayVRCPlusIconsAsAvatar);
configRepository.setString('VRCX_worldAutoCacheInvite', this.worldAutoCacheInvite); configRepository.setString('VRCX_worldAutoCacheInvite', this.worldAutoCacheInvite);
configRepository.setString('VRCX_worldAutoCacheGPS', this.worldAutoCacheGPS); configRepository.setString('VRCX_worldAutoCacheGPS', this.worldAutoCacheGPS);
configRepository.setBool('VRCX_worldAutoCacheInviteFilter', this.worldAutoCacheInviteFilter);
configRepository.setBool('VRCX_worldAutoCacheGPSFilter', this.worldAutoCacheGPSFilter);
this.updateVRConfigVars(); this.updateVRConfigVars();
}; };
$app.data.TTSvoices = speechSynthesis.getVoices(); $app.data.TTSvoices = speechSynthesis.getVoices();
@@ -6906,6 +6910,8 @@ speechSynthesis.getVoices();
$app.watch.displayVRCPlusIconsAsAvatar = saveOpenVROption; $app.watch.displayVRCPlusIconsAsAvatar = saveOpenVROption;
$app.watch.worldAutoCacheInvite = saveOpenVROption; $app.watch.worldAutoCacheInvite = saveOpenVROption;
$app.watch.worldAutoCacheGPS = saveOpenVROption; $app.watch.worldAutoCacheGPS = saveOpenVROption;
$app.watch.worldAutoCacheInviteFilter = saveOpenVROption;
$app.watch.worldAutoCacheGPSFilter = saveOpenVROption;
$app.watch.notificationTTS = saveNotificationTTS; $app.watch.notificationTTS = saveNotificationTTS;
$app.data.isDarkMode = configRepository.getBool('isDarkMode'); $app.data.isDarkMode = configRepository.getBool('isDarkMode');
$appDarkStyle.disabled = $app.data.isDarkMode === false; $appDarkStyle.disabled = $app.data.isDarkMode === false;
@@ -8318,12 +8324,7 @@ speechSynthesis.getVoices();
D.ref = args.ref; D.ref = args.ref;
D.isFavorite = API.cachedFavoritesByObjectId.has(D.id); D.isFavorite = API.cachedFavoritesByObjectId.has(D.id);
D.rooms = []; D.rooms = [];
this.checkVRChatCache(D.ref).then((cacheSize) => { this.updateVRChatCache();
if (cacheSize > 0) {
D.inCache = true;
D.cacheSize = `${(cacheSize / 1048576).toFixed(2)} MiB`;
}
});
this.applyWorldDialogInstances(); this.applyWorldDialogInstances();
if (args.cache) { if (args.cache) {
API.getWorld(args.params); API.getWorld(args.params);
@@ -11058,6 +11059,22 @@ speechSynthesis.getVoices();
return cacheDirectory; return cacheDirectory;
}; };
// Asset Bundle Cacher
$app.methods.updateVRChatCache = function () {
var D = this.worldDialog;
if (D.visible) {
D.inCache = false;
D.cacheSize = 0;
this.checkVRChatCache(D.ref).then((cacheSize) => {
if (cacheSize > 0) {
D.inCache = true;
D.cacheSize = `${(cacheSize / 1048576).toFixed(2)} MiB`;
}
});
}
};
$app.methods.checkVRChatCache = async function (ref) { $app.methods.checkVRChatCache = async function (ref) {
return await AssetBundleCacher.CheckVRChatCache(ref.id, ref.version, await this.getVRChatCacheDir()); return await AssetBundleCacher.CheckVRChatCache(ref.id, ref.version, await this.getVRChatCacheDir());
}; };
@@ -11075,19 +11092,38 @@ speechSynthesis.getVoices();
} }
}; };
API.getWorldBundles = async function (fileId) {
return this.call(`file/${fileId}`, {
method: 'GET'
}).then((json) => {
var args = {
json
};
return args;
});
};
$app.methods.downloadVRChatCache = async function () { $app.methods.downloadVRChatCache = async function () {
if (this.downloadQueue.size === 0) { if (this.downloadQueue.size === 0) {
return; return;
} }
this.downloadProgress = 0; this.downloadProgress = 0;
this.downloadProgressBarLoading = false; this.downloadIsProcessing = false;
this.downloadInProgress = true; this.downloadInProgress = true;
this.downloadCurrent = this.downloadQueue.values().next().value; this.downloadCurrent = this.downloadQueue.values().next().value;
this.downloadCurrent.id = this.downloadQueue.keys().next().value; this.downloadCurrent.id = this.downloadQueue.keys().next().value;
var { ref, type } = this.downloadCurrent; var { ref, type } = this.downloadCurrent;
this.downloadQueue.delete(ref.id); this.downloadQueue.delete(ref.id);
this.downloadQueueTable.data = Array.from(this.downloadQueue.values()); this.downloadQueueTable.data = Array.from(this.downloadQueue.values());
await AssetBundleCacher.DownloadCacheFile(ref.assetUrl, ref.id, ref.version, appVersion, await this.getVRChatCacheDir());
var fileId = extractFileId(ref.assetUrl);
var args = await API.getWorldBundles(fileId);
var { versions } = args.json;
var version = versions[versions.length - 1];
var { url, md5, sizeInBytes } = version.file;
var cacheDir = await this.getVRChatCacheDir();
console.log('start', ref.name, md5);
await AssetBundleCacher.DownloadCacheFile(cacheDir, url, ref.id, ref.version, sizeInBytes, md5, appVersion);
this.downloadVRChatCacheProgress(); this.downloadVRChatCacheProgress();
}; };
@@ -11128,6 +11164,10 @@ speechSynthesis.getVoices();
if ((this.worldAutoCacheInvite === 'Always') || if ((this.worldAutoCacheInvite === 'Always') ||
((this.worldAutoCacheInvite === 'Game Closed') && (!this.isGameRunning)) || ((this.worldAutoCacheInvite === 'Game Closed') && (!this.isGameRunning)) ||
((this.worldAutoCacheInvite === 'Game Running') && (this.isGameRunning))) { ((this.worldAutoCacheInvite === 'Game Running') && (this.isGameRunning))) {
if ((!this.worldAutoCacheInviteFilter) &&
(!API.cachedFavoritesByObjectId.has(invite.senderUserId))) {
return;
}
this.autoDownloadWorldCache(invite.details.worldId, 'Invite', invite.senderUserId); this.autoDownloadWorldCache(invite.details.worldId, 'Invite', invite.senderUserId);
} }
}; };
@@ -11138,7 +11178,8 @@ speechSynthesis.getVoices();
((this.worldAutoCacheGPS === 'Game Running') && (this.isGameRunning))) { ((this.worldAutoCacheGPS === 'Game Running') && (this.isGameRunning))) {
if ((feed.location === 'offline') || if ((feed.location === 'offline') ||
(feed.location === 'private') || (feed.location === 'private') ||
(!API.cachedFavoritesByObjectId.has(feed.id))) { ((!this.worldAutoCacheGPSFilter) &&
(!API.cachedFavoritesByObjectId.has(feed.id)))) {
return; return;
} }
this.autoDownloadWorldCache(feed.location, 'GPS', feed.id); this.autoDownloadWorldCache(feed.location, 'GPS', feed.id);
@@ -11183,7 +11224,7 @@ speechSynthesis.getVoices();
$app.data.downloadProgress = 0; $app.data.downloadProgress = 0;
$app.data.downloadInProgress = false; $app.data.downloadInProgress = false;
$app.data.downloadProgressBarLoading = false; $app.data.downloadIsProcessing = false;
$app.data.downloadQueue = new Map(); $app.data.downloadQueue = new Map();
$app.data.downloadCurrent = {}; $app.data.downloadCurrent = {};
@@ -11192,19 +11233,11 @@ speechSynthesis.getVoices();
switch (downloadProgress) { switch (downloadProgress) {
case -1: case -1:
this.downloadProgress = 100; this.downloadProgress = 100;
this.downloadProgressBarLoading = true; this.downloadIsProcessing = true;
break; break;
case -3: case -3:
var D = this.worldDialog; if (this.worldDialog.id === this.downloadCurrent.id) {
if ((D.visible) && (D.id === this.downloadCurrent.id)) { this.updateVRChatCache();
D.inCache = false;
D.cacheSize = 0;
this.checkVRChatCache(D.ref).then((cacheSize) => {
if (cacheSize > 0) {
D.inCache = true;
D.cacheSize = `${(cacheSize / 1048576).toFixed(2)} MiB`;
}
});
} }
if (this.downloadCurrent.type === 'manual') { if (this.downloadCurrent.type === 'manual') {
this.$message({ this.$message({
@@ -11254,16 +11287,8 @@ speechSynthesis.getVoices();
this.downloadInProgress = false; this.downloadInProgress = false;
return; return;
case -12: case -12:
var D = this.worldDialog; if (this.worldDialog.id === this.downloadCurrent.id) {
if ((D.visible) && (D.id === this.downloadCurrent.id)) { this.updateVRChatCache();
D.inCache = false;
D.cacheSize = 0;
this.checkVRChatCache(D.ref).then((cacheSize) => {
if (cacheSize > 0) {
D.inCache = true;
D.cacheSize = `${(cacheSize / 1048576).toFixed(2)} MiB`;
}
});
} }
if (this.downloadCurrent.type === 'manual') { if (this.downloadCurrent.type === 'manual') {
this.$message({ this.$message({
@@ -11302,6 +11327,18 @@ speechSynthesis.getVoices();
this.downloadInProgress = false; this.downloadInProgress = false;
this.downloadVRChatCache(); this.downloadVRChatCache();
return; return;
case -15:
this.$message({
message: 'Download failed',
type: 'error'
});
this.downloadCurrent.status = 'Download failed';
this.downloadHistoryTable.data.unshift(this.downloadCurrent);
this.downloadCurrent = {};
this.downloadProgress = 0;
this.downloadInProgress = false;
this.downloadVRChatCache();
return;
default: default:
this.downloadProgress = downloadProgress; this.downloadProgress = downloadProgress;
} }
@@ -11318,7 +11355,7 @@ speechSynthesis.getVoices();
}; };
$app.methods.downloadProgressText = function () { $app.methods.downloadProgressText = function () {
if (this.downloadProgressBarLoading) { if (this.downloadIsProcessing) {
return 'Processing'; return 'Processing';
} }
if (this.downloadProgress >= 0) { if (this.downloadProgress >= 0) {
@@ -11337,13 +11374,23 @@ speechSynthesis.getVoices();
return ''; return '';
}; };
$app.methods.deleteVRChatCache = async function () { $app.methods.deleteVRChatCache = async function (ref) {
await this.readVRChatConfigFile(); await this.readVRChatConfigFile();
var cacheDirectory = ''; var cacheDirectory = '';
if (this.VRChatConfigFile.cache_directory) { if (this.VRChatConfigFile.cache_directory) {
cacheDirectory = this.VRChatConfigFile.cache_directory; cacheDirectory = this.VRChatConfigFile.cache_directory;
} }
await AssetBundleCacher.DeleteCache(cacheDirectory); await AssetBundleCacher.DeleteCache(cacheDirectory, ref.id, ref.version);
this.updateVRChatCache();
};
$app.methods.deleteAllVRChatCache = async function () {
await this.readVRChatConfigFile();
var cacheDirectory = '';
if (this.VRChatConfigFile.cache_directory) {
cacheDirectory = this.VRChatConfigFile.cache_directory;
}
await AssetBundleCacher.DeleteAllCache(cacheDirectory);
this.getVRChatCacheSize(); this.getVRChatCacheSize();
}; };
+10 -2
View File
@@ -859,10 +859,16 @@ html
span.name Download on invite: span.name Download on invite:
br br
toggle-switch(:options="worldCacheToggleSwitchOption" group="worldCacheInviteToggleSwitchOption" v-model="worldAutoCacheInvite" class="toggle-switch") toggle-switch(:options="worldCacheToggleSwitchOption" group="worldCacheInviteToggleSwitchOption" v-model="worldAutoCacheInvite" class="toggle-switch")
div.options-container-item
el-switch(v-model="worldAutoCacheInviteFilter" inactive-text="VIP" active-text="Everyone" :disabled="worldAutoCacheInvite == 'Never'")
br
div.options-container-item div.options-container-item
span.name Download on VIP GPS: span.name Download on VIP GPS:
br br
toggle-switch(:options="worldCacheToggleSwitchOption" group="worldCacheGPSToggleSwitchOption" v-model="worldAutoCacheGPS" class="toggle-switch") toggle-switch(:options="worldCacheToggleSwitchOption" group="worldCacheGPSToggleSwitchOption" v-model="worldAutoCacheGPS" class="toggle-switch")
div.options-container-item
el-switch(v-model="worldAutoCacheGPSFilter" inactive-text="VIP" active-text="Everyone" :disabled="worldAutoCacheGPS == 'Never'")
br
div.options-container-item div.options-container-item
el-button-group el-button-group
el-button(size="small" icon="el-icon-download" @click="showDownloadDialog()") Download History el-button(size="small" icon="el-icon-download" @click="showDownloadDialog()") Download History
@@ -1195,7 +1201,9 @@ html
div(style="margin-top:5px") div(style="margin-top:5px")
span(v-show="worldDialog.ref.name !== worldDialog.ref.description" v-text="worldDialog.ref.description" style="font-size:12px") span(v-show="worldDialog.ref.name !== worldDialog.ref.description" v-text="worldDialog.ref.description" style="font-size:12px")
div(style="flex:none;margin-left:10px") div(style="flex:none;margin-left:10px")
el-button(v-if="!worldDialog.inCache && !downloadQueue.has(worldDialog.id) && downloadCurrent.id !== worldDialog.id" icon="el-icon-download" circle @click="queueCacheDownload(worldDialog.ref, 'Manual')") el-button(v-if="worldDialog.inCache" icon="el-icon-delete" circle @click="deleteVRChatCache(worldDialog.ref)")
el-button(v-else-if="downloadCurrent.id === worldDialog.id || downloadQueue.has(worldDialog.id)" icon="el-icon-loading" circle @click="showDownloadDialog")
el-button(v-else icon="el-icon-download" circle @click="queueCacheDownload(worldDialog.ref, 'Manual')")
el-button(v-if="worldDialog.isFavorite" type="warning" icon="el-icon-star-on" circle @click="worldDialogCommand('Delete Favorite')" style="margin-left:5px") el-button(v-if="worldDialog.isFavorite" type="warning" icon="el-icon-star-on" circle @click="worldDialogCommand('Delete Favorite')" style="margin-left:5px")
el-button(v-else type="default" icon="el-icon-star-off" circle @click="worldDialogCommand('Add Favorite')" style="margin-left:5px") el-button(v-else type="default" icon="el-icon-star-off" circle @click="worldDialogCommand('Add Favorite')" style="margin-left:5px")
el-dropdown(trigger="click" @command="worldDialogCommand" size="small" style="margin-left:5px") el-dropdown(trigger="click" @command="worldDialogCommand" size="small" style="margin-left:5px")
@@ -1505,7 +1513,7 @@ html
el-tooltip(placement="top") el-tooltip(placement="top")
template(#content) template(#content)
span Clear Cache span Clear Cache
el-button(type="default" @click="deleteVRChatCache" :disabled="isGameRunning" size="small" icon="el-icon-delete" circle style="margin-left:5px") el-button(type="default" @click="deleteAllVRChatCache" :disabled="isGameRunning" size="small" icon="el-icon-delete" circle style="margin-left:5px")
br br
div(style="display:inline-block;margin-top:10px" v-for="(item, value) in VRChatConfigList" :key="value") div(style="display:inline-block;margin-top:10px" v-for="(item, value) in VRChatConfigList" :key="value")
span(v-text="item.name" style="word-break:keep-all") span(v-text="item.name" style="word-break:keep-all")