improve gamelog sql

This commit is contained in:
pa
2026-01-29 15:49:37 +09:00
parent 949c64d17b
commit 48c1dd98fa
5 changed files with 366 additions and 147 deletions

View File

@@ -663,24 +663,31 @@ const gameLog = {
return gamelogDatabase;
},
/**
* Lookup the game log database for a specific search term
* @param {string} search The search term
* @param {Array} filters The filters to apply
* @param {Array} [vipList] The list of VIP users
* @returns {Promise<any[]>} The game log data
*/
async lookupGameLogDatabase(
search,
filters,
vipList,
maxEntries = dbVars.maxTableSize
) {
search = search.replaceAll("'", "''");
if (search.startsWith('wrld_') || search.startsWith('grp_')) {
return this.getGameLogByLocation(search, filters);
}
const baseColumns = [
'id',
'created_at',
'type',
'display_name',
'location',
'user_id',
'time',
'world_id',
'world_name',
'group_name',
'instance_id',
'video_url',
'video_name',
'video_id',
'resource_url',
'resource_type',
'data',
'message'
].join(', ');
let vipQuery = '';
if (vipList.length > 0) {
vipQuery = 'AND user_id IN (';
@@ -692,15 +699,15 @@ const gameLog = {
}
vipQuery += ')';
}
var location = true;
var onplayerjoined = true;
var onplayerleft = true;
var portalspawn = true;
var msgevent = true;
var external = true;
var videoplay = true;
var resourceload_string = true;
var resourceload_image = true;
let location = true;
let onplayerjoined = true;
let onplayerleft = true;
let portalspawn = true;
let msgevent = true;
let external = true;
let videoplay = true;
let resourceload_string = true;
let resourceload_image = true;
if (filters.length > 0) {
location = false;
onplayerjoined = false;
@@ -743,24 +750,14 @@ const gameLog = {
}
});
}
var gamelogDatabase = [];
const selects = [];
if (location) {
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: 'Location',
location: dbRow[2],
worldId: dbRow[3],
worldName: dbRow[4],
time: dbRow[5],
groupName: dbRow[6]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_location WHERE world_name LIKE '%${search}%' OR group_name LIKE '%${search}%' ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, 'Location' AS type, NULL AS display_name, location, NULL AS user_id, time, world_id, world_name, group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_location ORDER BY id DESC LIMIT @perTable)`
);
}
if (onplayerjoined || onplayerleft) {
var query = '';
let query = '';
if (!onplayerjoined || !onplayerleft) {
if (onplayerjoined) {
query = "AND type = 'OnPlayerJoined'";
@@ -768,110 +765,331 @@ const gameLog = {
query = "AND type = 'OnPlayerLeft'";
}
}
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: dbRow[2],
displayName: dbRow[3],
location: dbRow[4],
userId: dbRow[5],
time: dbRow[6]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_join_leave WHERE (display_name LIKE '%${search}%' AND user_id != '${dbVars.userId}') ${vipQuery} ${query} ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, type, display_name, location, user_id, time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_join_leave WHERE 1=1 ${vipQuery} ${query} ORDER BY id DESC LIMIT @perTable)`
);
}
if (portalspawn) {
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: 'PortalSpawn',
displayName: dbRow[2],
location: dbRow[3],
userId: dbRow[4],
instanceId: dbRow[5],
worldName: dbRow[6]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_portal_spawn WHERE (display_name LIKE '%${search}%' OR world_name LIKE '%${search}%') ${vipQuery} ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, 'PortalSpawn' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, world_name, NULL AS group_name, instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_portal_spawn WHERE 1=1 ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (msgevent) {
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: 'Event',
data: dbRow[2]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_event WHERE data LIKE '%${search}%' ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, 'Event' AS type, NULL AS display_name, NULL AS location, NULL AS user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, data, NULL AS message FROM gamelog_event ORDER BY id DESC LIMIT @perTable)`
);
}
if (external) {
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: 'External',
message: dbRow[2],
displayName: dbRow[3],
userId: dbRow[4],
location: dbRow[5]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_external WHERE (display_name LIKE '%${search}%' OR message LIKE '%${search}%') ${vipQuery} ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, 'External' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, message FROM gamelog_external WHERE 1=1 ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (videoplay) {
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: 'VideoPlay',
videoUrl: dbRow[2],
videoName: dbRow[3],
videoId: dbRow[4],
location: dbRow[5],
displayName: dbRow[6],
userId: dbRow[7]
};
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_video_play WHERE (video_url LIKE '%${search}%' OR video_name LIKE '%${search}%' OR display_name LIKE '%${search}%') ${vipQuery} ORDER BY id DESC LIMIT ${maxEntries}`);
selects.push(
`SELECT * FROM (SELECT id, created_at, 'VideoPlay' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, video_url, video_name, video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_video_play WHERE 1=1 ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (resourceload_string || resourceload_image) {
var checkString = '';
var checkImage = '';
let checkString = '';
let checkImage = '';
if (!resourceload_string) {
checkString = `AND resource_type != 'StringLoad'`;
}
if (!resourceload_image) {
checkString = `AND resource_type != 'ImageLoad'`;
}
await sqliteService.execute((dbRow) => {
var row = {
selects.push(
`SELECT * FROM (SELECT id, created_at, resource_type AS type, NULL AS display_name, location, NULL AS user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, resource_url, resource_type, NULL AS data, NULL AS message FROM gamelog_resource_load WHERE 1=1 ${checkString} ${checkImage} ORDER BY id DESC LIMIT @perTable)`
);
}
if (selects.length === 0) {
return [];
}
const gamelogDatabase = [];
const args = {
'@limit': maxEntries,
'@perTable': maxEntries
};
await sqliteService.execute(
(dbRow) => {
const row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: dbRow[3],
resourceUrl: dbRow[2],
location: dbRow[4]
type: dbRow[2]
};
switch (dbRow[2]) {
case 'Location':
row.location = dbRow[4];
row.worldId = dbRow[7];
row.worldName = dbRow[8];
row.time = dbRow[6];
row.groupName = dbRow[9];
break;
case 'OnPlayerJoined':
case 'OnPlayerLeft':
row.displayName = dbRow[3];
row.location = dbRow[4];
row.userId = dbRow[5];
row.time = dbRow[6];
break;
case 'PortalSpawn':
row.displayName = dbRow[3];
row.location = dbRow[4];
row.userId = dbRow[5];
row.instanceId = dbRow[10];
row.worldName = dbRow[8];
break;
case 'VideoPlay':
row.videoUrl = dbRow[11];
row.videoName = dbRow[12];
row.videoId = dbRow[13];
row.location = dbRow[4];
row.displayName = dbRow[3];
row.userId = dbRow[5];
break;
case 'Event':
row.data = dbRow[16];
break;
case 'External':
row.message = dbRow[17];
row.displayName = dbRow[3];
row.userId = dbRow[5];
row.location = dbRow[4];
break;
case 'StringLoad':
case 'ImageLoad':
row.resourceUrl = dbRow[14];
row.location = dbRow[4];
break;
}
gamelogDatabase.push(row);
}, `SELECT * FROM gamelog_resource_load WHERE resource_url LIKE '%${search}%' ${checkString} ${checkImage} ORDER BY id DESC LIMIT ${maxEntries}`);
},
`SELECT ${baseColumns} FROM (${selects.join(' UNION ALL ')}) ORDER BY created_at DESC, id DESC LIMIT @limit`,
args
);
return gamelogDatabase;
},
/**
* Lookup the game log database for a specific search term
* @param {string} search The search term
* @param {Array} filters The filters to apply
* @param {Array} [vipList] The list of VIP users
* @returns {Promise<any[]>} The game log data
*/
async searchGameLogDatabase(
search,
filters,
vipList,
maxEntries = dbVars.maxTableSize
) {
if (search.startsWith('wrld_') || search.startsWith('grp_')) {
return this.getGameLogByLocation(search, filters);
}
var compareByCreatedAt = function (a, b) {
var A = a.created_at;
var B = b.created_at;
if (A < B) {
return -1;
let vipQuery = '';
const vipArgs = {};
if (vipList.length > 0) {
const vipPlaceholders = [];
vipList.forEach((vip, i) => {
const key = `@vip_${i}`;
vipArgs[key] = vip;
vipPlaceholders.push(key);
});
vipQuery = `AND user_id IN (${vipPlaceholders.join(', ')})`;
}
let location = true;
let onplayerjoined = true;
let onplayerleft = true;
let portalspawn = true;
let msgevent = true;
let external = true;
let videoplay = true;
let resourceload_string = true;
let resourceload_image = true;
if (filters.length > 0) {
location = false;
onplayerjoined = false;
onplayerleft = false;
portalspawn = false;
msgevent = false;
external = false;
videoplay = false;
resourceload_string = false;
resourceload_image = false;
filters.forEach((filter) => {
switch (filter) {
case 'Location':
location = true;
break;
case 'OnPlayerJoined':
onplayerjoined = true;
break;
case 'OnPlayerLeft':
onplayerleft = true;
break;
case 'PortalSpawn':
portalspawn = true;
break;
case 'Event':
msgevent = true;
break;
case 'External':
external = true;
break;
case 'VideoPlay':
videoplay = true;
break;
case 'StringLoad':
resourceload_string = true;
break;
case 'ImageLoad':
resourceload_image = true;
break;
}
});
}
const searchLike = `%${search}%`;
const selects = [];
const baseColumns = [
'id',
'created_at',
'type',
'display_name',
'location',
'user_id',
'time',
'world_id',
'world_name',
'group_name',
'instance_id',
'video_url',
'video_name',
'video_id',
'resource_url',
'resource_type',
'data',
'message'
].join(', ');
if (location) {
selects.push(
`SELECT * FROM (SELECT id, created_at, 'Location' AS type, NULL AS display_name, location, NULL AS user_id, time, world_id, world_name, group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_location WHERE (world_name LIKE @searchLike OR group_name LIKE @searchLike) ORDER BY id DESC LIMIT @perTable)`
);
}
if (onplayerjoined || onplayerleft) {
let query = '';
if (!onplayerjoined || !onplayerleft) {
if (onplayerjoined) {
query = "AND type = 'OnPlayerJoined'";
} else if (onplayerleft) {
query = "AND type = 'OnPlayerLeft'";
}
}
if (A > B) {
return 1;
selects.push(
`SELECT * FROM (SELECT id, created_at, type, display_name, location, user_id, time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_join_leave WHERE (display_name LIKE @searchLike AND user_id != '${dbVars.userId}') ${vipQuery} ${query} ORDER BY id DESC LIMIT @perTable)`
);
}
if (portalspawn) {
selects.push(
`SELECT * FROM (SELECT id, created_at, 'PortalSpawn' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, world_name, NULL AS group_name, instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_portal_spawn WHERE (display_name LIKE @searchLike OR world_name LIKE @searchLike) ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (msgevent) {
selects.push(
`SELECT * FROM (SELECT id, created_at, 'Event' AS type, NULL AS display_name, NULL AS location, NULL AS user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, data, NULL AS message FROM gamelog_event WHERE data LIKE @searchLike ORDER BY id DESC LIMIT @perTable)`
);
}
if (external) {
selects.push(
`SELECT * FROM (SELECT id, created_at, 'External' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, message FROM gamelog_external WHERE (display_name LIKE @searchLike OR message LIKE @searchLike) ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (videoplay) {
selects.push(
`SELECT * FROM (SELECT id, created_at, 'VideoPlay' AS type, display_name, location, user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, video_url, video_name, video_id, NULL AS resource_url, NULL AS resource_type, NULL AS data, NULL AS message FROM gamelog_video_play WHERE (video_url LIKE @searchLike OR video_name LIKE @searchLike OR display_name LIKE @searchLike) ${vipQuery} ORDER BY id DESC LIMIT @perTable)`
);
}
if (resourceload_string || resourceload_image) {
let checkString = '';
let checkImage = '';
if (!resourceload_string) {
checkString = `AND resource_type != 'StringLoad'`;
}
return 0;
if (!resourceload_image) {
checkString = `AND resource_type != 'ImageLoad'`;
}
selects.push(
`SELECT * FROM (SELECT id, created_at, resource_type AS type, NULL AS display_name, location, NULL AS user_id, NULL AS time, NULL AS world_id, NULL AS world_name, NULL AS group_name, NULL AS instance_id, NULL AS video_url, NULL AS video_name, NULL AS video_id, resource_url, resource_type, NULL AS data, NULL AS message FROM gamelog_resource_load WHERE resource_url LIKE @searchLike ${checkString} ${checkImage} ORDER BY id DESC LIMIT @perTable)`
);
}
if (selects.length === 0) {
return [];
}
const gamelogDatabase = [];
const args = {
'@searchLike': searchLike,
'@limit': maxEntries,
'@perTable': maxEntries,
...vipArgs
};
gamelogDatabase.sort(compareByCreatedAt);
if (gamelogDatabase.length > maxEntries) {
gamelogDatabase.splice(0, gamelogDatabase.length - maxEntries);
}
await sqliteService.execute(
(dbRow) => {
const type = dbRow[2];
const row = {
rowId: dbRow[0],
created_at: dbRow[1],
type
};
switch (type) {
case 'Location':
row.location = dbRow[4];
row.worldId = dbRow[7];
row.worldName = dbRow[8];
row.time = dbRow[6];
row.groupName = dbRow[9];
break;
case 'OnPlayerJoined':
case 'OnPlayerLeft':
row.displayName = dbRow[3];
row.location = dbRow[4];
row.userId = dbRow[5];
row.time = dbRow[6];
break;
case 'PortalSpawn':
row.displayName = dbRow[3];
row.location = dbRow[4];
row.userId = dbRow[5];
row.instanceId = dbRow[10];
row.worldName = dbRow[8];
break;
case 'VideoPlay':
row.videoUrl = dbRow[11];
row.videoName = dbRow[12];
row.videoId = dbRow[13];
row.location = dbRow[4];
row.displayName = dbRow[3];
row.userId = dbRow[5];
break;
case 'Event':
row.data = dbRow[16];
break;
case 'External':
row.message = dbRow[17];
row.displayName = dbRow[3];
row.userId = dbRow[5];
row.location = dbRow[4];
break;
case 'StringLoad':
case 'ImageLoad':
row.resourceUrl = dbRow[14];
row.location = dbRow[4];
break;
}
gamelogDatabase.push(row);
},
`SELECT ${baseColumns} FROM (${selects.join(' UNION ALL ')}) ORDER BY created_at DESC, id DESC LIMIT @limit`,
args
);
return gamelogDatabase;
},