diff --git a/AppApi.cs b/AppApi.cs index 83d7d5d7..d1d75a5b 100644 --- a/AppApi.cs +++ b/AppApi.cs @@ -317,7 +317,7 @@ namespace VRCX public bool StartGameFromPath(string path, string arguments) { if (!path.EndsWith(".exe")) - path = Path.Combine(path, "start_protected_game.exe"); + path = Path.Combine(path, "launch.exe"); if (!File.Exists(path)) return false; diff --git a/LogWatcher.cs b/LogWatcher.cs index 3b94d439..ddfeb89b 100644 --- a/LogWatcher.cs +++ b/LogWatcher.cs @@ -242,7 +242,8 @@ namespace VRCX ParseLogScreenshot(fileInfo, logContext, line, offset) || ParseLogStringDownload(fileInfo, logContext, line, offset) || ParseLogImageDownload(fileInfo, logContext, line, offset) || - ParseVoteKick(fileInfo, logContext, line, offset)) + ParseVoteKick(fileInfo, logContext, line, offset) || + ParseFailedToJoin(fileInfo, logContext, line, offset)) { } } @@ -1083,6 +1084,23 @@ namespace VRCX }); return true; } + + private bool ParseFailedToJoin(FileInfo fileInfo, LogContext logContext, string line, int offset) + { + // 2023.09.01 10:42:19 Warning - [Behaviour] Failed to join instance 'wrld_78eb6b52-fd5a-4954-ba28-972c92c8cc77:82384~hidden(usr_a9bf892d-b447-47ce-a572-20c83dbfffd8)~region(eu)' due to 'That instance is using an outdated version of VRChat. You won't be able to join them until they update!' + + if (string.Compare(line, offset, "[Behaviour] Failed to join instance ", 0, 36, StringComparison.Ordinal) != 0) + return false; + + AppendLog(new[] + { + fileInfo.Name, + ConvertLogTimeToISO8601(line), + "event", + line.Substring(offset + 36) + }); + return true; + } public string[][] Get() { diff --git a/html/src/app.js b/html/src/app.js index d9be5806..6013d8cf 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -9648,6 +9648,12 @@ speechSynthesis.getVoices(); return true; } return false; + case 'StringLoad': + case 'ImageLoad': + if (String(row.resourceUrl).toUpperCase().includes(value)) { + return true; + } + return false; } return true; }; @@ -10499,8 +10505,7 @@ speechSynthesis.getVoices(); 'Moderation', 'Camera', 'SpawnEmoji', - 'MasterMigrate', - 'PhotonBot' + 'MasterMigrate' ]; $app.methods.photonEventTableFilterChange = function () { @@ -10758,7 +10763,8 @@ speechSynthesis.getVoices(); canModerateInstance: user.canModerateInstance, groupOnNameplate: user.groupOnNameplate, showGroupBadgeToOthers: user.showGroupBadgeToOthers, - showSocialRank: user.showSocialRank + showSocialRank: user.showSocialRank, + useImpostorAsFallback: user.useImpostorAsFallback }); this.photonUserJoin(id, user, gameLogDate); } @@ -10789,13 +10795,13 @@ speechSynthesis.getVoices(); this.photonLobbyJointime.set(id, { joinTime: Date.parse(gameLogDate), hasInstantiated, - inVRMode: user.user.inVRMode, - avatarEyeHeight: user.user.avatarEyeHeight, - canModerateInstance: user.user.canModerateInstance, - groupOnNameplate: user.user.groupOnNameplate, - showGroupBadgeToOthers: - user.user.showGroupBadgeToOthers, - showSocialRank: user.user.showSocialRank + inVRMode: user.inVRMode, + avatarEyeHeight: user.avatarEyeHeight, + canModerateInstance: user.canModerateInstance, + groupOnNameplate: user.groupOnNameplate, + showGroupBadgeToOthers: user.showGroupBadgeToOthers, + showSocialRank: user.showSocialRank, + useImpostorAsFallback: user.useImpostorAsFallback }); this.photonUserJoin(id, user, gameLogDate); } @@ -10828,7 +10834,8 @@ speechSynthesis.getVoices(); canModerateInstance: user.canModerateInstance, groupOnNameplate: user.groupOnNameplate, showGroupBadgeToOthers: user.showGroupBadgeToOthers, - showSocialRank: user.showSocialRank + showSocialRank: user.showSocialRank, + useImpostorAsFallback: user.useImpostorAsFallback }); break; case 255: @@ -10876,18 +10883,15 @@ speechSynthesis.getVoices(); groupOnNameplate: data.Parameters[249].groupOnNameplate, showGroupBadgeToOthers: data.Parameters[249].showGroupBadgeToOthers, - showSocialRank: data.Parameters[249].showSocialRank + showSocialRank: data.Parameters[249].showSocialRank, + useImpostorAsFallback: + data.Parameters[249].useImpostorAsFallback }); this.photonUserJoin( data.Parameters[254], data.Parameters[249], gameLogDate ); - this.checkPhotonBotJoin( - data.Parameters[254], - data.Parameters[249], - gameLogDate - ); this.startLobbyWatcherLoop(); break; case 254: @@ -11355,39 +11359,6 @@ speechSynthesis.getVoices(); } }; - $app.methods.checkPhotonBotJoin = function (photonId, data, gameLogDate) { - var text = ''; - var platforms = []; - if (typeof this.currentInstanceWorld.ref.unityPackages === 'object') { - for (var unityPackage of this.currentInstanceWorld.ref - .unityPackages) { - platforms.push(unityPackage.platform); - } - } - if (data.avatarEyeHeight < 0) { - text = 'Photon bot has joined, invalid avatarEyeHeight'; - } - if (text) { - this.addEntryPhotonEvent({ - photonId, - text, - type: 'PhotonBot', - color: 'yellow', - created_at: gameLogDate - }); - var entry = { - created_at: new Date().toJSON(), - type: 'Event', - data: `${text} - ${this.getDisplayNameFromPhotonId( - photonId - )} (${this.getUserIdFromPhotonId(photonId)})` - }; - this.queueGameLogNoty(entry); - this.addGameLog(entry); - database.addGamelogEventToDatabase(entry); - } - }; - $app.methods.parsePhotonUser = async function ( photonId, user, @@ -11523,6 +11494,7 @@ speechSynthesis.getVoices(); } else { platform = 'Desktop'; } + this.photonUserSusieCheck(photonId, user, gameLogDate); this.checkVRChatCache(avatar).then((cacheInfo) => { var inCache = false; if (cacheInfo.Item1 > 0) { @@ -11540,6 +11512,34 @@ speechSynthesis.getVoices(); }); }; + $app.methods.photonUserSusieCheck = function (photonId, user, gameLogDate) { + var text = ''; + if (typeof user.modTag !== 'undefined') { + text = `Moderator has joined ${user.modTag}`; + } else if (user.isInvisible) { + text = 'User joined invisible'; + } + if (text) { + this.addEntryPhotonEvent({ + photonId, + text, + type: 'Event', + color: 'yellow', + created_at: gameLogDate + }); + var entry = { + created_at: new Date().toJSON(), + type: 'Event', + data: `${text} - ${this.getDisplayNameFromPhotonId( + photonId + )} (${this.getUserIdFromPhotonId(photonId)})` + }; + this.queueGameLogNoty(entry); + this.addGameLog(entry); + database.addGamelogEventToDatabase(entry); + } + }; + $app.methods.photonUserLeave = function (photonId, gameLogDate) { if (!this.photonLobbyCurrent.has(photonId)) { return; @@ -15288,13 +15288,12 @@ speechSynthesis.getVoices(); this.showGroupDialog(groupId); return true; } - } else if ( - input.startsWith('https://vrc.group/') || - /^[A-Za-z0-9]{3,6}\.[0-9]{4}$/g.test(input) - ) { + } else if (input.startsWith('https://vrc.group/')) { var shortCode = input.substring(18); this.showGroupDialogShortCode(shortCode); return true; + } else if (/^[A-Za-z0-9]{3,6}\.[0-9]{4}$/g.test(input)) { + this.showGroupDialogShortCode(input); } else if ( input.substring(0, 4) === 'usr_' || /^[A-Za-z0-9]{10}$/g.test(input) @@ -16946,7 +16945,11 @@ speechSynthesis.getVoices(); } var map = new Map(); for (var ref of API.cachedWorlds.values()) { - if (ref.authorId === D.id) { + if ( + ref.authorId === D.id && + (ref.authorId === API.currentUser.id || + ref.releaseStatus === 'public') + ) { API.cachedWorlds.delete(ref.id); } } @@ -23993,7 +23996,8 @@ speechSynthesis.getVoices(); canModerateInstance: user.canModerateInstance, groupOnNameplate: user.groupOnNameplate, showGroupBadgeToOthers: user.showGroupBadgeToOthers, - showSocialRank: user.showSocialRank + showSocialRank: user.showSocialRank, + useImpostorAsFallback: user.useImpostorAsFallback }); } } @@ -27414,7 +27418,7 @@ speechSynthesis.getVoices(); groupId: '', groupName: '', userId: '', - userIds: '', + userIds: [], userObject: {} }; @@ -27445,8 +27449,7 @@ speechSynthesis.getVoices(); API.getCachedUser({ userId }).then((args) => { D.userObject = args.ref; }); - // D.userIds = [userId]; - D.userIds = userId; + D.userIds = [userId]; } }; @@ -27455,7 +27458,7 @@ speechSynthesis.getVoices(); }); $app.methods.sendGroupInvite = function () { - this.$confirm('Continue? Invite To Group', 'Confirm', { + this.$confirm('Continue? Invite User(s) To Group', 'Confirm', { confirmButtonText: 'Confirm', cancelButtonText: 'Cancel', type: 'info', @@ -27465,25 +27468,22 @@ speechSynthesis.getVoices(); return; } D.loading = true; - // no fun allowed - // var inviteLoop = () => { - // if (D.userIds.length > 0) { - // var receiverUserId = D.userIds.shift(); - // API.sendGroupInvite({ - // groupId: D.groupId, - // userId: receiverUserId - // }).finally(inviteLoop); - // } else { - // D.loading = false; - // } - // }; - var receiverUserId = D.userIds; - API.sendGroupInvite({ - groupId: D.groupId, - userId: receiverUserId - }).finally(() => { - D.loading = false; - }); + var inviteLoop = () => { + if (D.userIds.length === 0) { + D.loading = false; + return; + } + var receiverUserId = D.userIds.shift(); + API.sendGroupInvite({ + groupId: D.groupId, + userId: receiverUserId + }) + .then(inviteLoop) + .catch(() => { + D.loading = false; + }); + }; + inviteLoop(); } }); }; @@ -27851,6 +27851,10 @@ speechSynthesis.getVoices(); var fileId = extractFileId(assetUrl); var version = parseInt(extractFileVersion(assetUrl), 10); if (!fileId || !version) { + this.$message({ + message: 'File Analysis unavailable', + type: 'error' + }); return; } API.getFileAnalysis({ fileId, version }); diff --git a/html/src/index.pug b/html/src/index.pug index cef6dc6f..5e913b45 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -672,6 +672,11 @@ html .detail span.name {{ $t('dialog.world.info.youtube_preview') }} span.extra https://www.youtube.com/watch?v={{ worldDialog.ref.previewYoutubeId }} + .x-friend-item(style="width:100%;cursor:default") + .detail + span.name {{ $t('dialog.world.info.author_tags') }} + span.extra(v-if="worldDialog.ref.tags?.length > 0") {{ worldDialog.ref.tags.filter(tag => tag.startsWith('author_tag')).map(tag => tag.replace('author_tag_', '')).join(', ') }} + span.extra(v-else) - .x-friend-item(style="cursor:default") .detail span.name {{ $t('dialog.world.info.players') }} @@ -2115,7 +2120,7 @@ html //- dialog: Gallery/VRCPlusIcons el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="galleryDialog" :visible.sync="galleryDialogVisible" :title="$t('dialog.gallery_icons.header')" width="100%") - span(style="padding-bottom:10px") {{ $t('dialog.gallery_icons.description') }} (4:3) + span(style="padding-bottom:10px") {{ $t('dialog.gallery_icons.description') }} br br el-tabs(type="card") @@ -2165,7 +2170,7 @@ html span.name(v-text="styleName" style="margin-right:100px") br .x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in emojiTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default") - .vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url") + .vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" style="cursor:default") img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url") div(style="display:inline-block;margin:5px") span {{ image.animationStyle }} @@ -2489,7 +2494,7 @@ html img(v-lazy="group.iconUrl") .detail span.name(v-text="group.name") - el-select(v-model="inviteGroupDialog.userIds" clearable :placeholder="$t('dialog.invite_to_group.choose_friends_placeholder')" filterable :disabled="inviteGroupDialog.loading" style="width:100%;margin-top:15px") + el-select(v-model="inviteGroupDialog.userIds" multiple clearable :placeholder="$t('dialog.invite_to_group.choose_friends_placeholder')" filterable :disabled="inviteGroupDialog.loading" style="width:100%;margin-top:15px") el-option-group(v-if="inviteGroupDialog.userId" :label="$t('dialog.invite_to_group.selected_users')") el-option.x-friend-item(:key="inviteGroupDialog.userObject.id" :label="inviteGroupDialog.userObject.displayName" :value="inviteGroupDialog.userObject.id" style="height:auto") template(v-if="inviteGroupDialog.userObject.id") diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json index 82e3e729..8e102b67 100644 --- a/html/src/localization/strings/en.json +++ b/html/src/localization/strings/en.json @@ -681,6 +681,7 @@ "copy_url": "Copy URL", "copy_name": "Copy Name", "youtube_preview": "Youtube Preview", + "author_tags": "Author Tags", "players": "Players", "favorites": "Favorites", "visits": "Visits", @@ -1061,7 +1062,7 @@ }, "invite_to_group": { "header": "Invite To Group", - "description": "Don't spam invite users, inviting too many users to a group is known to cause a ban.", + "description": "Don't spam invite users, you'll get rate limited.", "choose_group_placeholder": "Choose Group", "groups": "Groups", "choose_friends_placeholder": "Choose Friends", diff --git a/html/src/mixins/tabs/playerList.pug b/html/src/mixins/tabs/playerList.pug index a60d399b..0282bfb5 100644 --- a/html/src/mixins/tabs/playerList.pug +++ b/html/src/mixins/tabs/playerList.pug @@ -237,6 +237,7 @@ mixin playerListTab() span(v-else) {{ scope.row.ref.last_platform }} template(v-if="scope.row.inVRMode !== null") span(v-if="scope.row.inVRMode") VR + span(v-else-if="scope.row.ref.last_platform === 'android' || scope.row.ref.last_platform === 'ios'") M span(v-else) D el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="displayName" sortable="custom") template(v-once #default="scope")