mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Add GameLog entries for resource loading (#513)
* add log entries for resource loading * add config for resource loading
This commit is contained in:
@@ -224,7 +224,9 @@ namespace VRCX
|
|||||||
ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) ||
|
ParseLogUsharpVideoSync(fileInfo, logContext, line, offset) ||
|
||||||
ParseLogWorldVRCX(fileInfo, logContext, line, offset) ||
|
ParseLogWorldVRCX(fileInfo, logContext, line, offset) ||
|
||||||
ParseLogOnAudioConfigurationChanged(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;
|
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()
|
public string[][] Get()
|
||||||
{
|
{
|
||||||
Update();
|
Update();
|
||||||
|
|||||||
@@ -9378,6 +9378,19 @@ speechSynthesis.getVoices();
|
|||||||
this.nowPlaying.offset = parseInt(timestamp, 10);
|
this.nowPlaying.offset = parseInt(timestamp, 10);
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'screenshot':
|
||||||
if (!this.screenshotHelper) {
|
if (!this.screenshotHelper) {
|
||||||
break;
|
break;
|
||||||
@@ -13359,6 +13372,10 @@ speechSynthesis.getVoices();
|
|||||||
AppApi.ExecuteVrOverlayFunction('updateHudTimeout', '[]');
|
AppApi.ExecuteVrOverlayFunction('updateHudTimeout', '[]');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
$app.data.logResourceLoad = configRepository.getBool('VRCX_logResourceLoad', false);
|
||||||
|
$app.methods.saveGameLogOptions = function() {
|
||||||
|
configRepository.setBool('VRCX_logResourceLoad', this.logResourceLoad);
|
||||||
|
};
|
||||||
|
|
||||||
// setting defaults
|
// setting defaults
|
||||||
if (!configRepository.getString('VRCX_notificationPosition')) {
|
if (!configRepository.getString('VRCX_notificationPosition')) {
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ html
|
|||||||
template(#tool)
|
template(#tool)
|
||||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
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-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-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-tooltip(placement="bottom" content="Reload game log" :disabled="hideTooltips")
|
||||||
//- el-button(type="default" @click="resetGameLog" icon="el-icon-refresh" circle style="flex:none")
|
//- 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(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-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")
|
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'")
|
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")
|
span.x-link(v-else v-text="scope.row.data")
|
||||||
|
|
||||||
@@ -1150,6 +1154,12 @@ html
|
|||||||
span.name {{ $t("view.settings.general.application.tray") }}
|
span.name {{ $t("view.settings.general.application.tray") }}
|
||||||
el-switch(v-model="isCloseToTray")
|
el-switch(v-model="isCloseToTray")
|
||||||
div.options-container
|
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")
|
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
|
||||||
span.header {{ $t("view.settings.general.legal_notice.header" )}}
|
span.header {{ $t("view.settings.general.legal_notice.header" )}}
|
||||||
div.options-container-item
|
div.options-container-item
|
||||||
|
|||||||
@@ -202,6 +202,10 @@
|
|||||||
"minimized": "Start as minimized state",
|
"minimized": "Start as minimized state",
|
||||||
"tray": "Close to tray"
|
"tray": "Close to tray"
|
||||||
},
|
},
|
||||||
|
"game_log": {
|
||||||
|
"header": "Game Log",
|
||||||
|
"resource_load": "Log Resource Load entries"
|
||||||
|
},
|
||||||
"legal_notice": {
|
"legal_notice": {
|
||||||
"header": "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.",
|
"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.",
|
||||||
|
|||||||
@@ -201,6 +201,9 @@
|
|||||||
"minimized": "최소화 상태로 시작",
|
"minimized": "최소화 상태로 시작",
|
||||||
"tray": "닫지 않고 트레이로 최소화하기"
|
"tray": "닫지 않고 트레이로 최소화하기"
|
||||||
},
|
},
|
||||||
|
"game_log": {
|
||||||
|
"header": "게임 기록"
|
||||||
|
},
|
||||||
"legal_notice": {
|
"legal_notice": {
|
||||||
"header": "법적 공지",
|
"header": "법적 공지",
|
||||||
"info": "VRCX는 친구 관계에 도움을 줄 만한 정보를 제공하는 보조 프로그램입니다. 비공식 VRChat 응용프로그램 프로그래밍 인터페이스를 사용합니다 (VRCSDK).",
|
"info": "VRCX는 친구 관계에 도움을 줄 만한 정보를 제공하는 보조 프로그램입니다. 비공식 VRChat 응용프로그램 프로그래밍 인터페이스를 사용합니다 (VRCSDK).",
|
||||||
|
|||||||
@@ -202,6 +202,9 @@
|
|||||||
"minimized": "以最小化的形式启动",
|
"minimized": "以最小化的形式启动",
|
||||||
"tray": "最小化到系统托盘"
|
"tray": "最小化到系统托盘"
|
||||||
},
|
},
|
||||||
|
"game_log": {
|
||||||
|
"header": "游戏日志"
|
||||||
|
},
|
||||||
"legal_notice": {
|
"legal_notice": {
|
||||||
"header": "法律声明",
|
"header": "法律声明",
|
||||||
"info": "VRCX 是一个提供VRChat好友管理的辅助应用程序。这个程序使用非官方的 VRChat API (VRCSDK)。",
|
"info": "VRCX 是一个提供VRChat好友管理的辅助应用程序。这个程序使用非官方的 VRChat API (VRCSDK)。",
|
||||||
|
|||||||
@@ -202,6 +202,9 @@
|
|||||||
"minimized": "以最小化啟動",
|
"minimized": "以最小化啟動",
|
||||||
"tray": "最小化到系統列"
|
"tray": "最小化到系統列"
|
||||||
},
|
},
|
||||||
|
"game_log": {
|
||||||
|
"header": "遊戲紀錄"
|
||||||
|
},
|
||||||
"legal_notice": {
|
"legal_notice": {
|
||||||
"header": "法律聲明",
|
"header": "法律聲明",
|
||||||
"info": "VRCX 是一個提供好友管理的輔助應用程式。這個程式使用非官方的 VRChat API (VRCSDK)。",
|
"info": "VRCX 是一個提供好友管理的輔助應用程式。這個程式使用非官方的 VRChat API (VRCSDK)。",
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ class Database {
|
|||||||
await sqliteService.executeNonQuery(
|
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))`
|
`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(
|
await sqliteService.executeNonQuery(
|
||||||
`CREATE TABLE IF NOT EXISTS gamelog_event (id INTEGER PRIMARY KEY, created_at TEXT, data TEXT, UNIQUE(created_at, data))`
|
`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);
|
gamelogDatabase.unshift(row);
|
||||||
}, `SELECT * FROM gamelog_video_play WHERE created_at >= date('${dateOffset}') ORDER BY id DESC`);
|
}, `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) => {
|
await sqliteService.execute((dbRow) => {
|
||||||
var row = {
|
var row = {
|
||||||
rowId: dbRow[0],
|
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) {
|
addGamelogEventToDatabase(entry) {
|
||||||
sqliteService.executeNonQuery(
|
sqliteService.executeNonQuery(
|
||||||
`INSERT OR IGNORE INTO gamelog_event (created_at, data) VALUES (@created_at, @data)`,
|
`INSERT OR IGNORE INTO gamelog_event (created_at, data) VALUES (@created_at, @data)`,
|
||||||
@@ -816,6 +842,14 @@ class Database {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getResourceLoadTableSize() {
|
||||||
|
var size = 0;
|
||||||
|
await sqliteService.execute((row) => {
|
||||||
|
size = row[0];
|
||||||
|
}, `SELECT COUNT(*) FROM gamelog_resource_load`);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
async getEventTableSize() {
|
async getEventTableSize() {
|
||||||
var size = 0;
|
var size = 0;
|
||||||
await sqliteService.execute((row) => {
|
await sqliteService.execute((row) => {
|
||||||
@@ -1176,6 +1210,8 @@ class Database {
|
|||||||
var portalspawn = true;
|
var portalspawn = true;
|
||||||
var msgevent = true;
|
var msgevent = true;
|
||||||
var videoplay = true;
|
var videoplay = true;
|
||||||
|
var resourceload_string = true;
|
||||||
|
var resourceload_image = true;
|
||||||
if (filters.length > 0) {
|
if (filters.length > 0) {
|
||||||
location = false;
|
location = false;
|
||||||
onplayerjoined = false;
|
onplayerjoined = false;
|
||||||
@@ -1183,6 +1219,8 @@ class Database {
|
|||||||
portalspawn = false;
|
portalspawn = false;
|
||||||
msgevent = false;
|
msgevent = false;
|
||||||
videoplay = false;
|
videoplay = false;
|
||||||
|
resourceload_string = false;
|
||||||
|
resourceload_image = false;
|
||||||
filters.forEach((filter) => {
|
filters.forEach((filter) => {
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
case 'Location':
|
case 'Location':
|
||||||
@@ -1203,6 +1241,12 @@ class Database {
|
|||||||
case 'VideoPlay':
|
case 'VideoPlay':
|
||||||
videoplay = true;
|
videoplay = true;
|
||||||
break;
|
break;
|
||||||
|
case 'StringLoad':
|
||||||
|
resourceload_string = true;
|
||||||
|
break;
|
||||||
|
case 'ImageLoad':
|
||||||
|
resourceload_image = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1286,6 +1330,27 @@ class Database {
|
|||||||
gamelogDatabase.unshift(row);
|
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}`);
|
}, `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 compareByCreatedAt = function (a, b) {
|
||||||
var A = a.created_at;
|
var A = a.created_at;
|
||||||
var B = b.created_at;
|
var B = b.created_at;
|
||||||
@@ -1324,6 +1389,9 @@ class Database {
|
|||||||
await sqliteService.execute((dbRow) => {
|
await sqliteService.execute((dbRow) => {
|
||||||
gamelogDatabase.unshift(dbRow[0]);
|
gamelogDatabase.unshift(dbRow[0]);
|
||||||
}, 'SELECT created_at FROM gamelog_video_play ORDER BY id DESC LIMIT 1');
|
}, '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) {
|
if (gamelogDatabase.length > 0) {
|
||||||
gamelogDatabase.sort();
|
gamelogDatabase.sort();
|
||||||
var newDate = gamelogDatabase[gamelogDatabase.length - 1];
|
var newDate = gamelogDatabase[gamelogDatabase.length - 1];
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ class GameLogService {
|
|||||||
gameLog.displayName = args[1];
|
gameLog.displayName = args[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'resource-load':
|
||||||
|
gameLog.resourceUrl = args[0];
|
||||||
|
gameLog.resourceType = args[1];
|
||||||
|
break;
|
||||||
|
|
||||||
case 'video-sync':
|
case 'video-sync':
|
||||||
gameLog.timestamp = args[0];
|
gameLog.timestamp = args[0];
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user