Add GameLog entries for resource loading (#513)

* add log entries for resource loading

* add config for resource loading
This commit is contained in:
BoatFloater
2023-03-24 23:57:55 +09:00
committed by GitHub
parent 11f1f8063e
commit 3f0a479e1a
9 changed files with 151 additions and 2 deletions

View File

@@ -224,7 +224,9 @@ namespace VRCX
ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) ||
ParseLogWorldVRCX(fileInfo, logContext, line, offset) ||
ParseLogOnAudioConfigurationChanged(fileInfo, logContext, line, offset) ||
ParseLogScreenshot(fileInfo, logContext, line, offset))
ParseLogScreenshot(fileInfo, logContext, line, offset) ||
ParseLogStringDownload(fileInfo, logContext, line, offset) ||
ParseLogImageDownload(fileInfo, logContext, line, offset))
{
}
}
@@ -928,6 +930,40 @@ namespace VRCX
return true;
}
private bool ParseLogStringDownload(FileInfo fileInfo, LogContext logContext, string line, int offset)
{
// 2023.03.23 11:37:21 Log - [String Download] Attempting to load String from URL 'https://pastebin.com/raw/BaW6NL2L'
string check = "] Attempting to load String from URL '";
if (!line.Contains(check))
return false;
var lineOffset = line.LastIndexOf(check);
if (lineOffset < 0)
return true;
var stringData = line.Substring(lineOffset + check.Length);
stringData = stringData.Remove(stringData.Length - 1);
AppendLog(new[] { fileInfo.Name, ConvertLogTimeToISO8601(line), "resource-load", stringData, "string" });
return true;
}
private bool ParseLogImageDownload(FileInfo fileInfo, LogContext logContext, string line, int offset)
{
// 2023.03.23 11:32:25 Log - [Image Download] Attempting to load image from URL 'https://i.imgur.com/lCfUMX0.jpeg'
string check = "] Attempting to load image from URL '";
if (!line.Contains(check))
return false;
var lineOffset = line.LastIndexOf(check);
if (lineOffset < 0)
return true;
var imageData = line.Substring(lineOffset + check.Length);
imageData = imageData.Remove(imageData.Length - 1);
AppendLog(new[] { fileInfo.Name, ConvertLogTimeToISO8601(line), "resource-load", imageData, "image" });
return true;
}
public string[][] Get()
{
Update();

View File

@@ -9378,6 +9378,19 @@ speechSynthesis.getVoices();
this.nowPlaying.offset = parseInt(timestamp, 10);
}
break;
case 'resource-load':
if (!this.logResourceLoad) {
break;
}
var entry = {
created_at: gameLog.dt,
type: gameLog.resourceType === 'string' ? 'StringLoad' : 'ImageLoad',
resourceUrl: gameLog.resourceUrl,
resourceType: gameLog.resourceType,
location
};
database.addGamelogResourceLoadToDatabase(entry);
break;
case 'screenshot':
if (!this.screenshotHelper) {
break;
@@ -13359,6 +13372,10 @@ speechSynthesis.getVoices();
AppApi.ExecuteVrOverlayFunction('updateHudTimeout', '[]');
}
};
$app.data.logResourceLoad = configRepository.getBool('VRCX_logResourceLoad', false);
$app.methods.saveGameLogOptions = function() {
configRepository.setBool('VRCX_logResourceLoad', this.logResourceLoad);
};
// setting defaults
if (!configRepository.getString('VRCX_notificationPosition')) {

View File

@@ -451,7 +451,7 @@ html
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
el-select(v-model="gameLogTable.filter" @change="gameLogTableLookup" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.game_log.filter_placeholder')")
el-option(v-once v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft', 'PortalSpawn', 'Event', 'VideoPlay']" :key="type" :label="type" :value="type")
el-option(v-once v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft', 'PortalSpawn', 'Event', 'VideoPlay', 'StringLoad', 'ImageLoad']" :key="type" :label="type" :value="type")
el-input(v-model="gameLogTable.search" :placeholder="$t('view.game_log.search_placeholder')" @keyup.native.13="gameLogTableLookup" @change="gameLogTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
//- el-tooltip(placement="bottom" content="Reload game log" :disabled="hideTooltips")
//- el-button(type="default" @click="resetGameLog" icon="el-icon-refresh" circle style="flex:none")
@@ -486,6 +486,10 @@ html
span(v-if="scope.row.videoId === 'LSMedia'" v-text="scope.row.videoName")
span.x-link(v-else-if="scope.row.videoName" @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoName")
span.x-link(v-else @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoUrl")
template(v-else-if="scope.row.type === 'ImageLoad'")
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
template(v-else-if="scope.row.type === 'StringLoad'")
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
template(v-else-if="scope.row.type === 'Notification' || scope.row.type === 'OnPlayerJoined' || scope.row.type === 'OnPlayerLeft'")
span.x-link(v-else v-text="scope.row.data")
@@ -1150,6 +1154,12 @@ html
span.name {{ $t("view.settings.general.application.tray") }}
el-switch(v-model="isCloseToTray")
div.options-container
div.options-container
span.header {{ $t("view.settings.general.game_log.header") }}
div.options-container-item
span.name {{ $t("view.settings.general.game_log.resource_load") }}
el-switch(v-model="logResourceLoad" @change="saveGameLogOptions")
div.options-container
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
span.header {{ $t("view.settings.general.legal_notice.header" )}}
div.options-container-item

View File

@@ -202,6 +202,10 @@
"minimized": "Start as minimized state",
"tray": "Close to tray"
},
"game_log": {
"header": "Game Log",
"resource_load": "Log Resource Load entries"
},
"legal_notice": {
"header": "Legal Notice",
"info": "VRCX is an assistant application for VRChat that provides information about and managing friendship. This application makes use of the unofficial VRChat API SDK.",

View File

@@ -201,6 +201,9 @@
"minimized": "최소화 상태로 시작",
"tray": "닫지 않고 트레이로 최소화하기"
},
"game_log": {
"header": "게임 기록"
},
"legal_notice": {
"header": "법적 공지",
"info": "VRCX는 친구 관계에 도움을 줄 만한 정보를 제공하는 보조 프로그램입니다. 비공식 VRChat 응용프로그램 프로그래밍 인터페이스를 사용합니다 (VRCSDK).",

View File

@@ -202,6 +202,9 @@
"minimized": "以最小化的形式启动",
"tray": "最小化到系统托盘"
},
"game_log": {
"header": "游戏日志"
},
"legal_notice": {
"header": "法律声明",
"info": "VRCX 是一个提供VRChat好友管理的辅助应用程序。这个程序使用非官方的 VRChat API (VRCSDK)。",

View File

@@ -202,6 +202,9 @@
"minimized": "以最小化啟動",
"tray": "最小化到系統列"
},
"game_log": {
"header": "遊戲紀錄"
},
"legal_notice": {
"header": "法律聲明",
"info": "VRCX 是一個提供好友管理的輔助應用程式。這個程式使用非官方的 VRChat API (VRCSDK)。",

View File

@@ -56,6 +56,9 @@ class Database {
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS gamelog_video_play (id INTEGER PRIMARY KEY, created_at TEXT, video_url TEXT, video_name TEXT, video_id TEXT, location TEXT, display_name TEXT, user_id TEXT, UNIQUE(created_at, video_url))`
);
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS gamelog_resource_load (id INTEGER PRIMARY KEY, created_at TEXT, resource_url TEXT, resource_type TEXT, location TEXT, UNIQUE(created_at, resource_url))`
);
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS gamelog_event (id INTEGER PRIMARY KEY, created_at TEXT, data TEXT, UNIQUE(created_at, data))`
);
@@ -498,6 +501,17 @@ class Database {
};
gamelogDatabase.unshift(row);
}, `SELECT * FROM gamelog_video_play WHERE created_at >= date('${dateOffset}') ORDER BY id DESC`);
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: dbRow[3] === 'string' ? 'StringLoad' : 'ImageLoad',
resourceUrl: dbRow[2],
resourceType: dbRow[3],
location: dbRow[4]
};
gamelogDatabase.unshift(row);
}, `SELECT * FROM gamelog_resource_load WHERE created_at >= date('${dateOffset}') ORDER BY id DESC`);
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
@@ -621,6 +635,18 @@ class Database {
);
}
addGamelogResourceLoadToDatabase(entry) {
sqliteService.executeNonQuery(
`INSERT OR IGNORE INTO gamelog_resource_load (created_at, resource_url, resource_type, location) VALUES (@created_at, @resource_url, @resource_type, @location)`,
{
'@created_at': entry.created_at,
'@resource_url': entry.resourceUrl,
'@resource_type': entry.resourceType,
'@location': entry.location
}
);
}
addGamelogEventToDatabase(entry) {
sqliteService.executeNonQuery(
`INSERT OR IGNORE INTO gamelog_event (created_at, data) VALUES (@created_at, @data)`,
@@ -816,6 +842,14 @@ class Database {
return size;
}
async getResourceLoadTableSize() {
var size = 0;
await sqliteService.execute((row) => {
size = row[0];
}, `SELECT COUNT(*) FROM gamelog_resource_load`);
return size;
}
async getEventTableSize() {
var size = 0;
await sqliteService.execute((row) => {
@@ -1176,6 +1210,8 @@ class Database {
var portalspawn = true;
var msgevent = true;
var videoplay = true;
var resourceload_string = true;
var resourceload_image = true;
if (filters.length > 0) {
location = false;
onplayerjoined = false;
@@ -1183,6 +1219,8 @@ class Database {
portalspawn = false;
msgevent = false;
videoplay = false;
resourceload_string = false;
resourceload_image = false;
filters.forEach((filter) => {
switch (filter) {
case 'Location':
@@ -1203,6 +1241,12 @@ class Database {
case 'VideoPlay':
videoplay = true;
break;
case 'StringLoad':
resourceload_string = true;
break;
case 'ImageLoad':
resourceload_image = true;
break;
}
});
}
@@ -1286,6 +1330,27 @@ class Database {
gamelogDatabase.unshift(row);
}, `SELECT * FROM gamelog_video_play WHERE video_url LIKE '%${search}%' OR video_name LIKE '%${search}%' OR display_name LIKE '%${search}%' ORDER BY id DESC LIMIT ${Database.maxTableSize}`);
}
if (resourceload_string || resourceload_image) {
var checkString = '';
var checkImage = '';
if (!resourceload_string) {
checkString = `AND resource_type != 'string'`;
}
if (!resourceload_image) {
checkString = `AND resource_type != 'image'`;
}
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: dbRow[3] === 'string' ? 'StringLoad' : 'ImageLoad',
resourceUrl: dbRow[2],
resourceType: dbRow[3],
location: dbRow[4]
};
gamelogDatabase.unshift(row);
}, `SELECT * FROM gamelog_resource_load WHERE resource_url LIKE '%${search}%' ${checkString} ${checkImage} ORDER BY id DESC LIMIT ${Database.maxTableSize}`);
}
var compareByCreatedAt = function (a, b) {
var A = a.created_at;
var B = b.created_at;
@@ -1324,6 +1389,9 @@ class Database {
await sqliteService.execute((dbRow) => {
gamelogDatabase.unshift(dbRow[0]);
}, 'SELECT created_at FROM gamelog_video_play ORDER BY id DESC LIMIT 1');
await sqliteService.execute((dbRow) => {
gamelogDatabase.unshift(dbRow[0]);
}, 'SELECT created_at FROM gamelog_resource_load ORDER BY id DESC LIMIT 1');
if (gamelogDatabase.length > 0) {
gamelogDatabase.sort();
var newDate = gamelogDatabase[gamelogDatabase.length - 1];

View File

@@ -41,6 +41,11 @@ class GameLogService {
gameLog.displayName = args[1];
break;
case 'resource-load':
gameLog.resourceUrl = args[0];
gameLog.resourceType = args[1];
break;
case 'video-sync':
gameLog.timestamp = args[0];
break;