mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-24 17:23:50 +02:00
Implement automatic sticker saving (#985)
* Implement automatic sticker saving * Prevent multiple requests for same sticker or print
This commit is contained in:
@@ -592,5 +592,16 @@ namespace VRCX
|
|||||||
|
|
||||||
return await ImageCache.SaveImageToFile(url, filePath);
|
return await ImageCache.SaveImageToFile(url, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> SaveStickerToFile(string url, string path, string fileName)
|
||||||
|
{
|
||||||
|
var folder = Path.Combine(GetVRChatPhotosLocation(), "Stickers", MakeValidFileName(path));
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return await ImageCache.SaveImageToFile(url, filePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,8 @@ namespace VRCX
|
|||||||
ParseFailedToJoin(fileInfo, logContext, line, offset) ||
|
ParseFailedToJoin(fileInfo, logContext, line, offset) ||
|
||||||
ParseInstanceResetWarning(fileInfo, logContext, line, offset) ||
|
ParseInstanceResetWarning(fileInfo, logContext, line, offset) ||
|
||||||
ParseVoteKickInitiation(fileInfo, logContext, line, offset) ||
|
ParseVoteKickInitiation(fileInfo, logContext, line, offset) ||
|
||||||
ParseVoteKickSuccess(fileInfo, logContext, line, offset))
|
ParseVoteKickSuccess(fileInfo, logContext, line, offset) ||
|
||||||
|
ParseStickerSpawn(fileInfo, logContext, line, offset))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1270,6 +1271,32 @@ namespace VRCX
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ParseStickerSpawn(FileInfo fileInfo, LogContext logContext, string line, int offset)
|
||||||
|
{
|
||||||
|
var index = line.IndexOf("[StickersManager] User ");
|
||||||
|
if (index == -1 || !line.Contains("file_") || !line.Contains("spawned sticker"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string info = line.Substring(index + 23);
|
||||||
|
|
||||||
|
var (userId, displayName) = ParseUserInfo(info);
|
||||||
|
|
||||||
|
var fileIdIndex = info.IndexOf("file_");
|
||||||
|
string fileId = info.Substring(fileIdIndex);
|
||||||
|
|
||||||
|
AppendLog(new[]
|
||||||
|
{
|
||||||
|
fileInfo.Name,
|
||||||
|
ConvertLogTimeToISO8601(line),
|
||||||
|
"sticker-spawn",
|
||||||
|
userId,
|
||||||
|
displayName,
|
||||||
|
fileId,
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public string[][] Get()
|
public string[][] Get()
|
||||||
{
|
{
|
||||||
Update();
|
Update();
|
||||||
|
|||||||
@@ -8207,6 +8207,10 @@ speechSynthesis.getVoices();
|
|||||||
'VRCX_saveInstancePrints',
|
'VRCX_saveInstancePrints',
|
||||||
this.saveInstancePrints
|
this.saveInstancePrints
|
||||||
);
|
);
|
||||||
|
await configRepository.setBool(
|
||||||
|
'VRCX_saveInstanceStickers',
|
||||||
|
this.saveInstanceStickers
|
||||||
|
);
|
||||||
VRCXStorage.Set(
|
VRCXStorage.Set(
|
||||||
'VRCX_StartAsMinimizedState',
|
'VRCX_StartAsMinimizedState',
|
||||||
this.isStartAsMinimizedState.toString()
|
this.isStartAsMinimizedState.toString()
|
||||||
@@ -17480,6 +17484,29 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$app.data.stickersCache = [];
|
||||||
|
|
||||||
|
$app.methods.trySaveStickerToFile = async function (displayName, fileId) {
|
||||||
|
if ($app.stickersCache.includes(fileId)) return;
|
||||||
|
$app.stickersCache.push(fileId);
|
||||||
|
if ($app.stickersCache.size > 100) {
|
||||||
|
$app.stickersCache.shift();
|
||||||
|
}
|
||||||
|
var args = await API.call(`file/${fileId}`);
|
||||||
|
var imageUrl = args.versions[1].file.url;
|
||||||
|
var createdAt = args.versions[0].created_at;
|
||||||
|
var path = `${createdAt.slice(0, 7)}`;
|
||||||
|
var fileNameDate = createdAt
|
||||||
|
.replace(/:/g, '-')
|
||||||
|
.replace(/T/g, '_')
|
||||||
|
.replace(/Z/g, '');
|
||||||
|
var fileName = `${displayName}_${fileNameDate}_${fileId}.png`;
|
||||||
|
var status = await AppApi.SaveStickerToFile(imageUrl, path, fileName);
|
||||||
|
if (status) {
|
||||||
|
console.log(`Sticker saved to file: ${path}\\${fileName}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | Prints
|
// #region | Prints
|
||||||
API.$on('LOGIN', function () {
|
API.$on('LOGIN', function () {
|
||||||
@@ -17651,6 +17678,11 @@ speechSynthesis.getVoices();
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$app.data.saveInstanceStickers = await configRepository.getBool(
|
||||||
|
'VRCX_saveInstanceStickers',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
$app.methods.getPrintDate = function (print) {
|
$app.methods.getPrintDate = function (print) {
|
||||||
var createdAt = new Date();
|
var createdAt = new Date();
|
||||||
if (print.createdAt) {
|
if (print.createdAt) {
|
||||||
@@ -17674,7 +17706,14 @@ speechSynthesis.getVoices();
|
|||||||
return fileName;
|
return fileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.data.printCache = [];
|
||||||
|
|
||||||
$app.methods.trySavePrintToFile = async function (printId) {
|
$app.methods.trySavePrintToFile = async function (printId) {
|
||||||
|
if ($app.printCache.includes(printId)) return;
|
||||||
|
$app.printCache.push(printId);
|
||||||
|
if ($app.printCache.length > 100) {
|
||||||
|
$app.printCache.shift();
|
||||||
|
}
|
||||||
var args = await API.getPrint({ printId });
|
var args = await API.getPrint({ printId });
|
||||||
var imageUrl = args.json?.files?.image;
|
var imageUrl = args.json?.files?.image;
|
||||||
if (!imageUrl) {
|
if (!imageUrl) {
|
||||||
|
|||||||
@@ -405,6 +405,13 @@ export default class extends baseClass {
|
|||||||
// };
|
// };
|
||||||
// database.addGamelogEventToDatabase(entry);
|
// database.addGamelogEventToDatabase(entry);
|
||||||
break;
|
break;
|
||||||
|
case 'sticker-spawn':
|
||||||
|
if (!$app.saveInstanceStickers) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.trySaveStickerToFile(gameLog.displayName, gameLog.fileId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (entry) {
|
if (entry) {
|
||||||
// add tag colour
|
// add tag colour
|
||||||
|
|||||||
@@ -441,6 +441,10 @@
|
|||||||
"header_tooltip": "Requires \"--enable-sdk-log-levels\" VRC launch option",
|
"header_tooltip": "Requires \"--enable-sdk-log-levels\" VRC launch option",
|
||||||
"description": "Save spawned prints to your VRChat Pictures folder"
|
"description": "Save spawned prints to your VRChat Pictures folder"
|
||||||
},
|
},
|
||||||
|
"save_instance_stickers_to_file": {
|
||||||
|
"header": "Save Instance Stickers To File",
|
||||||
|
"description": "Save dropped Stickers to your VRChat Pictures folder"
|
||||||
|
},
|
||||||
"remote_database": {
|
"remote_database": {
|
||||||
"header": "Remote Avatar Database",
|
"header": "Remote Avatar Database",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
|
|||||||
@@ -489,6 +489,10 @@ mixin settingsTab()
|
|||||||
div.options-container-item
|
div.options-container-item
|
||||||
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.save_instance_prints_to_file.description') }}
|
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.save_instance_prints_to_file.description') }}
|
||||||
el-switch(v-model="saveInstancePrints" @change="saveVRCXWindowOption")
|
el-switch(v-model="saveInstancePrints" @change="saveVRCXWindowOption")
|
||||||
|
span.sub-header {{ $t('view.settings.advanced.advanced.save_instance_stickers_to_file.header') }}
|
||||||
|
div.options-container-item
|
||||||
|
span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.save_instance_stickers_to_file.description') }}
|
||||||
|
el-switch(v-model="saveInstanceStickers" @change="saveVRCXWindowOption")
|
||||||
//- Advanced | Remote Avatar Database
|
//- Advanced | Remote Avatar Database
|
||||||
div.options-container
|
div.options-container
|
||||||
span.header {{ $t('view.settings.advanced.advanced.remote_database.header') }}
|
span.header {{ $t('view.settings.advanced.advanced.remote_database.header') }}
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ class GameLogService {
|
|||||||
gameLog.data = args[0];
|
gameLog.data = args[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'sticker-spawn':
|
||||||
|
gameLog.userId = args[0];
|
||||||
|
gameLog.displayName = args[1];
|
||||||
|
gameLog.fileId = args[2];
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user