diff --git a/html/src/app.js b/html/src/app.js
index 2e7f5dc8..915c1ce8 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -1458,12 +1458,9 @@ speechSynthesis.getVoices();
//
...json
};
- if (
- !json.isFriend &&
- $app.lastLocation.playerList.has(json.displayName)
- ) {
+ if ($app.lastLocation.playerList.has(json.displayName)) {
+ // update $location_at from instance join time
var player = $app.lastLocation.playerList.get(json.displayName);
- ref.location = 'offline';
ref.$location_at = player.joinTime;
ref.$online_for = player.joinTime;
}
@@ -7512,7 +7509,12 @@ speechSynthesis.getVoices();
if (configRepository.getBool(`friendLogInit_${args.json.id}`)) {
await $app.getFriendLog();
} else {
- await $app.initFriendLog(args.json.id);
+ try {
+ await $app.initFriendLog(args.json.id);
+ } catch (err) {
+ this.logout();
+ throw err;
+ }
}
$app.getAllMemos();
if ($app.randomUserColours) {
@@ -8206,27 +8208,36 @@ speechSynthesis.getVoices();
database.addGamelogLocationToDatabase(entry);
break;
case 'player-joined':
+ var joinTime = Date.parse(gameLog.dt);
var userMap = {
displayName: gameLog.userDisplayName,
userId,
- joinTime: Date.parse(gameLog.dt)
+ joinTime
};
this.lastLocation.playerList.set(
gameLog.userDisplayName,
userMap
);
if (userId) {
- if (this.friends.has(userId)) {
+ var ref = API.cachedUsers.get(userId);
+ if (userId === API.currentUser.id) {
+ // skip
+ } else if (this.friends.has(userId)) {
this.lastLocation.friendList.set(
gameLog.userDisplayName,
userMap
);
- } else {
- var ref = API.cachedUsers.get(userId);
- if (typeof ref !== 'undefined') {
- var joinTime = Date.parse(gameLog.dt);
+ if (
+ ref.location !== this.lastLocation.location &&
+ ref.travelingToLocation !==
+ this.lastLocation.location
+ ) {
+ // fix $location_at with private
ref.$location_at = joinTime;
}
+ } else if (typeof ref !== 'undefined') {
+ // set $location_at to join time if user isn't a friend
+ ref.$location_at = joinTime;
}
}
this.updateVRLastLocation();
@@ -10980,8 +10991,7 @@ speechSynthesis.getVoices();
};
$app.methods.getFriendLog = async function () {
- await database.cleanLegendFromFriendLog(); // fix database spam crap
- await database.fixGameLogTraveling(); // fix past bug with incorrect gameLog locations
+ await this.updateDatabaseVersion();
var friendLogCurrentArray = await database.getFriendLogCurrent();
for (var friend of friendLogCurrentArray) {
this.friendLog.set(friend.userId, friend);
@@ -13572,19 +13582,6 @@ speechSynthesis.getVoices();
if (addUser) {
var ref = API.cachedUsers.get(player.userId);
if (typeof ref !== 'undefined') {
- if (
- !ref.isFriend ||
- ref.location !== this.lastLocation.location
- ) {
- // fix $location_at
- var {joinTime} = this.lastLocation.playerList.get(
- ref.displayName
- );
- if (!joinTime) {
- joinTime = Date.now();
- }
- ref.$location_at = joinTime;
- }
pushUser(ref);
} else {
var {joinTime} = this.lastLocation.playerList.get(
@@ -19905,6 +19902,22 @@ speechSynthesis.getVoices();
database.clearAvatarHistory();
};
+ $app.data.databaseVersion = configRepository.getInt('VRCX_databaseVersion');
+
+ $app.methods.updateDatabaseVersion = async function () {
+ var databaseVersion = 1;
+ if (this.databaseVersion !== databaseVersion) {
+ console.log('Updating database...');
+ await database.cleanLegendFromFriendLog(); // fix friendLog spammed with crap
+ await database.fixGameLogTraveling(); // fix bug with gameLog location being set as traveling
+ await database.fixNegativeGPS(); // fix GPS being a negative value due to VRCX bug with traveling
+ await database.fixBrokenLeaveEntries(); // fix user instance timer being higher than current user location timer
+ this.databaseVersion = databaseVersion;
+ configRepository.setInt('VRCX_databaseVersion', databaseVersion);
+ console.log('Database update complete.');
+ }
+ };
+
$app = new Vue($app);
window.$app = $app;
})();
diff --git a/html/src/index.pug b/html/src/index.pug
index e78e8c1f..00ff44c7 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -1361,9 +1361,11 @@ html
el-tooltip(placement="bottom" content="Refresh friends" :disabled="hideTooltips")
el-button(type="default" @click="API.closeWebSocket(); API.getCurrentUser(); API.refreshFriends()" :loading="API.isRefreshFriendsLoading" size="mini" icon="el-icon-refresh" circle style="margin-right:10px")
.x-friend-list(style="padding-bottom:10px")
- .x-friend-group
+ .x-friend-group(style="padding:5px 0 0")
+ span FRIENDS―{{ onlineFriendCount }}/{{ friends.size }}
+ .x-friend-group(style="padding:10px 0 5px")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroupMe }")
- span.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="margin-left:5px") ME―{{ onlineFriendCount }}/{{ friends.size }}
+ span.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="margin-left:5px") ME
div(v-show="isFriendsGroupMe")
.x-friend-item(:key="API.currentUser.id" @click="showUserDialog(API.currentUser.id)")
.avatar(:class="userStatusClass(API.currentUser)")
@@ -2819,7 +2821,7 @@ html
br
el-button-group(style="padding-bottom:10px;padding-top:10px")
el-button(type="default" size="small" @click="displayPreviousImages('Avatar', 'Change')" icon="el-icon-refresh") Refresh
- el-button(type="default" size="small" @click="uploadAvatarImage" icon="el-icon-upload2") Upload Image (1200x900)
+ el-button(type="default" size="small" @click="uploadAvatarImage" icon="el-icon-upload2") Upload Image
//- el-button(type="default" size="small" @click="deleteAvatarImage" icon="el-icon-delete") Delete Latest Image
br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
@@ -2834,7 +2836,7 @@ html
br
el-button-group(style="padding-bottom:10px;padding-top:10px")
el-button(type="default" size="small" @click="displayPreviousImages('World', 'Change')" icon="el-icon-refresh") Refresh
- el-button(type="default" size="small" @click="uploadWorldImage" icon="el-icon-upload2") Upload Image (1200x900)
+ el-button(type="default" size="small" @click="uploadWorldImage" icon="el-icon-upload2") Upload Image
//- el-button(type="default" size="small" @click="deleteWorldImage" icon="el-icon-delete") Delete Latest Image
br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
diff --git a/html/src/repository/database.js b/html/src/repository/database.js
index a6b29595..ab821c33 100644
--- a/html/src/repository/database.js
+++ b/html/src/repository/database.js
@@ -1565,6 +1565,67 @@ class Database {
);
});
}
+
+ async fixNegativeGPS() {
+ var gpsTables = [];
+ await sqliteService.execute((dbRow) => {
+ gpsTables.push(dbRow[0]);
+ }, `SELECT name FROM sqlite_schema WHERE type='table' AND name LIKE '%_gps'`);
+ gpsTables.forEach((tableName) => {
+ sqliteService.executeNonQuery(
+ `UPDATE ${tableName} SET time = 0 WHERE time < 0`
+ );
+ });
+ }
+
+ async getGameLogInstancesTime() {
+ var instances = new Map();
+ await sqliteService.execute((dbRow) => {
+ var time = 0;
+ var location = dbRow[0];
+ if (dbRow[1]) {
+ time = dbRow[1];
+ }
+ var ref = instances.get(location);
+ if (typeof ref !== 'undefined') {
+ time += ref;
+ }
+ instances.set(location, time);
+ }, 'SELECT location, time FROM gamelog_location');
+ return instances;
+ }
+
+ async getBrokenLeaveEntries() {
+ var instances = await this.getGameLogInstancesTime();
+ var badEntries = [];
+ await sqliteService.execute((dbRow) => {
+ if (typeof dbRow[1] === 'number') {
+ var ref = instances.get(dbRow[0]);
+ if (typeof ref !== 'undefined' && dbRow[1] > ref) {
+ badEntries.push(dbRow[2]);
+ }
+ }
+ }, `SELECT location, time, id FROM gamelog_join_leave WHERE type = 'OnPlayerLeft' AND time > 0`);
+ return badEntries;
+ }
+
+ async fixBrokenLeaveEntries() {
+ var badEntries = await this.getBrokenLeaveEntries();
+ var badEntriesList = '';
+ var count = badEntries.length;
+ badEntries.forEach((entry) => {
+ count--;
+ if (count === 0) {
+ badEntriesList = badEntriesList.concat(entry);
+ } else {
+ badEntriesList = badEntriesList.concat(`${entry}, `);
+ }
+ });
+
+ sqliteService.executeNonQuery(
+ `UPDATE gamelog_join_leave SET time = 0 WHERE id IN (${badEntriesList})`
+ );
+ }
}
var self = new Database();