mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 06:43:51 +02:00
refactor: app.js (#1291)
* refactor: frontend * Fix avatar gallery sort * Update .NET dependencies * Update npm dependencies electron v37.1.0 * bulkRefreshFriends * fix dark theme * Remove crowdin * Fix config.json dialog not updating * VRCX log file fixes & add Cef log * Remove SharedVariable, fix startup * Revert init theme change * Logging date not working? Fix WinformThemer designer error * Add Cef request hander, no more escaping main page * clean * fix * fix * clean * uh * Apply thememode at startup, fixes random user colours * Split database into files * Instance info remove empty lines * Open external VRC links with VRCX * Electron fixes * fix userdialog style * ohhhh * fix store * fix store * fix: load all group members after kicking a user * fix: world dialog favorite button style * fix: Clear VRCX Cache Timer input value * clean * Fix VR overlay * Fix VR overlay 2 * Fix Discord discord rich presence for RPC worlds * Clean up age verified user tags * Fix playerList being occupied after program reload * no `this` * Fix login stuck loading * writable: false * Hide dialogs on logout * add flush sync option * rm LOGIN event * rm LOGOUT event * remove duplicate event listeners * remove duplicate event listeners * clean * remove duplicate event listeners * clean * fix theme style * fix t * clearable * clean * fix ipcEvent * Small changes * Popcorn Palace support * Remove checkActiveFriends * Clean up * Fix dragEnterCef * Block API requests when not logged in * Clear state on login & logout * Fix worldDialog instances not updating * use <script setup> * Fix avatar change event, CheckGameRunning at startup * Fix image dragging * fix * Remove PWI * fix updateLoop * add webpack-dev-server to dev environment * rm unnecessary chunks * use <script setup> * webpack-dev-server changes * use <script setup> * use <script setup> * Fix UGC text size * Split login event * t * use <script setup> * fix * Update .gitignore and enable checkJs in jsconfig * fix i18n t * use <script setup> * use <script setup> * clean * global types * fix * use checkJs for debugging * Add watchState for login watchers * fix .vue template * type fixes * rm Vue.filter * Cef v138.0.170, VC++ 2022 * Settings fixes * Remove 'USER:CURRENT' * clean up 2FA callbacks * remove userApply * rm i18n import * notification handling to use notification store methods * refactor favorite handling to use favorite store methods and clean up event emissions * refactor moderation handling to use dedicated functions for player moderation events * refactor friend handling to use dedicated functions for friend events * Fix program startup, move lang init * Fix friend state * Fix status change error * Fix user notes diff * fix * rm group event * rm auth event * rm avatar event * clean * clean * getUser * getFriends * getFavoriteWorlds, getFavoriteAvatars * AvatarGalleryUpload btn style & package.json update * Fix friend requests * Apply user * Apply world * Fix note diff * Fix VR overlay * Fixes * Update build scripts * Apply avatar * Apply instance * Apply group * update hidden VRC+ badge * Fix sameInstance "private" * fix 502/504 API errors * fix 502/504 API errors * clean * Fix friend in same instance on orange showing twice in friends list * Add back in broken friend state repair methods * add types --------- Co-authored-by: Natsumi <cmcooper123@hotmail.com>
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
import utils from '../../classes/utils';
|
||||
|
||||
function storeAvatarImage(args) {
|
||||
const refCreatedAt = args.json.versions[0];
|
||||
const fileCreatedAt = refCreatedAt.created_at;
|
||||
const fileId = args.params.fileId;
|
||||
let avatarName = '';
|
||||
const imageName = args.json.name;
|
||||
const avatarNameRegex = /Avatar - (.*) - Image -/gi.exec(imageName);
|
||||
if (avatarNameRegex) {
|
||||
avatarName = utils.replaceBioSymbols(avatarNameRegex[1]);
|
||||
}
|
||||
const ownerId = args.json.ownerId;
|
||||
const avatarInfo = {
|
||||
ownerId,
|
||||
avatarName,
|
||||
fileCreatedAt
|
||||
};
|
||||
window.API.cachedAvatarNames.set(fileId, avatarInfo);
|
||||
return avatarInfo;
|
||||
}
|
||||
|
||||
function parseAvatarUrl(avatar) {
|
||||
const url = new URL(avatar);
|
||||
const urlPath = url.pathname;
|
||||
if (urlPath.substring(5, 13) === '/avatar/') {
|
||||
const avatarId = urlPath.substring(13);
|
||||
return avatarId;
|
||||
}
|
||||
// return void 0;
|
||||
}
|
||||
|
||||
function getPlatformInfo(unityPackages) {
|
||||
var pc = {};
|
||||
var android = {};
|
||||
var ios = {};
|
||||
if (typeof unityPackages === 'object') {
|
||||
for (var unityPackage of unityPackages) {
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (unityPackage.platform === 'standalonewindows') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
pc.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
pc = unityPackage;
|
||||
} else if (unityPackage.platform === 'android') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
android.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
android = unityPackage;
|
||||
} else if (unityPackage.platform === 'ios') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
ios.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
ios = unityPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { pc, android, ios };
|
||||
}
|
||||
|
||||
function compareUnityVersion(unitySortNumber) {
|
||||
if (!window.API.cachedConfig.sdkUnityVersion) {
|
||||
console.error('No cachedConfig.sdkUnityVersion');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2022.3.6f1 2022 03 06 000
|
||||
// 2019.4.31f1 2019 04 31 000
|
||||
// 5.3.4p1 5 03 04 010
|
||||
// 2019.4.31f1c1 is a thing
|
||||
var array = window.API.cachedConfig.sdkUnityVersion.split('.');
|
||||
if (array.length < 3) {
|
||||
console.error('Invalid cachedConfig.sdkUnityVersion');
|
||||
return false;
|
||||
}
|
||||
var currentUnityVersion = array[0];
|
||||
currentUnityVersion += array[1].padStart(2, '0');
|
||||
var indexFirstLetter = array[2].search(/[a-zA-Z]/);
|
||||
if (indexFirstLetter > -1) {
|
||||
currentUnityVersion += array[2]
|
||||
.substr(0, indexFirstLetter)
|
||||
.padStart(2, '0');
|
||||
currentUnityVersion += '0';
|
||||
var letter = array[2].substr(indexFirstLetter, 1);
|
||||
if (letter === 'p') {
|
||||
currentUnityVersion += '1';
|
||||
} else {
|
||||
// f
|
||||
currentUnityVersion += '0';
|
||||
}
|
||||
currentUnityVersion += '0';
|
||||
} else {
|
||||
// just in case
|
||||
currentUnityVersion += '000';
|
||||
}
|
||||
// just in case
|
||||
currentUnityVersion = currentUnityVersion.replace(/\D/g, '');
|
||||
|
||||
if (parseInt(unitySortNumber, 10) <= parseInt(currentUnityVersion, 10)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export {
|
||||
storeAvatarImage,
|
||||
parseAvatarUrl,
|
||||
getPlatformInfo,
|
||||
compareUnityVersion
|
||||
};
|
||||
@@ -1,164 +0,0 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import configRepository from '../../service/config';
|
||||
|
||||
function useModerationTable() {
|
||||
const groupInvitesModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupJoinRequestsModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupBlockedModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupLogsModerationTable = reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['description'], value: '' }],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupBansModerationTable = reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['$displayName'], value: '' }],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupMemberModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
|
||||
async function initializePageSize() {
|
||||
try {
|
||||
const tablePageSize = await configRepository.getInt(
|
||||
'VRCX_tablePageSize',
|
||||
15
|
||||
);
|
||||
groupMemberModerationTable.pageSize = tablePageSize;
|
||||
groupBansModerationTable.pageSize = tablePageSize;
|
||||
groupLogsModerationTable.pageSize = tablePageSize;
|
||||
groupInvitesModerationTable.pageSize = tablePageSize;
|
||||
groupJoinRequestsModerationTable.pageSize = tablePageSize;
|
||||
groupBlockedModerationTable.pageSize = tablePageSize;
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize table page size:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function deselectGroupMember(userId) {
|
||||
const deselectInTable = (tableData) => {
|
||||
if (userId) {
|
||||
const row = tableData.find((item) => item.userId === userId);
|
||||
if (row) {
|
||||
row.$selected = false;
|
||||
}
|
||||
} else {
|
||||
tableData.forEach((row) => {
|
||||
if (row.$selected) {
|
||||
row.$selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
deselectInTable(groupMemberModerationTable.data);
|
||||
deselectInTable(groupBansModerationTable.data);
|
||||
deselectInTable(groupInvitesModerationTable.data);
|
||||
deselectInTable(groupJoinRequestsModerationTable.data);
|
||||
deselectInTable(groupBlockedModerationTable.data);
|
||||
}
|
||||
|
||||
return {
|
||||
groupInvitesModerationTable,
|
||||
groupJoinRequestsModerationTable,
|
||||
groupBlockedModerationTable,
|
||||
groupLogsModerationTable,
|
||||
groupBansModerationTable,
|
||||
groupMemberModerationTable,
|
||||
initializePageSize,
|
||||
deselectGroupMember
|
||||
};
|
||||
}
|
||||
|
||||
function useSelectedUsers() {
|
||||
const selectedUsers = reactive({});
|
||||
// computed not working here hmm
|
||||
const selectedUsersArray = ref([]);
|
||||
|
||||
function groupMemberModerationTableSelectionChange(row) {
|
||||
if (row.$selected && !selectedUsers[row.userId]) {
|
||||
setSelectedUsers(row.userId, row);
|
||||
} else if (!row.$selected && selectedUsers[row.userId]) {
|
||||
deselectedUsers(row.userId);
|
||||
}
|
||||
}
|
||||
|
||||
function deselectedUsers(userId, isAll = false) {
|
||||
if (isAll) {
|
||||
for (const id in selectedUsers) {
|
||||
if (Object.prototype.hasOwnProperty.call(selectedUsers, id)) {
|
||||
delete selectedUsers[id];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Object.prototype.hasOwnProperty.call(selectedUsers, userId)) {
|
||||
delete selectedUsers[userId];
|
||||
}
|
||||
}
|
||||
selectedUsersArray.value = Object.values(selectedUsers);
|
||||
}
|
||||
|
||||
function setSelectedUsers(usersId, user) {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
selectedUsers[usersId] = user;
|
||||
selectedUsersArray.value = Object.values(selectedUsers);
|
||||
}
|
||||
return {
|
||||
selectedUsers,
|
||||
selectedUsersArray,
|
||||
groupMemberModerationTableSelectionChange,
|
||||
deselectedUsers,
|
||||
setSelectedUsers
|
||||
};
|
||||
}
|
||||
|
||||
export { useModerationTable, useSelectedUsers };
|
||||
@@ -1,14 +0,0 @@
|
||||
function hasGroupPermission(ref, permission) {
|
||||
if (
|
||||
ref &&
|
||||
ref.myMember &&
|
||||
ref.myMember.permissions &&
|
||||
(ref.myMember.permissions.includes('*') ||
|
||||
ref.myMember.permissions.includes(permission))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export { hasGroupPermission };
|
||||
@@ -1,168 +0,0 @@
|
||||
import { instanceRequest } from '../../api';
|
||||
|
||||
// TODO: launch, invite, refresh, etc. buttons, better to split into one component
|
||||
function refreshInstancePlayerCount(instance) {
|
||||
const L = parseLocation(instance);
|
||||
if (L.isRealInstance) {
|
||||
instanceRequest.getInstance({
|
||||
worldId: L.worldId,
|
||||
instanceId: L.instanceId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function isRealInstance(instanceId) {
|
||||
if (!instanceId) {
|
||||
return false;
|
||||
}
|
||||
switch (instanceId) {
|
||||
case ':':
|
||||
case 'offline':
|
||||
case 'offline:offline':
|
||||
case 'private':
|
||||
case 'private:private':
|
||||
case 'traveling':
|
||||
case 'traveling:traveling':
|
||||
case instanceId.startsWith('local'):
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function displayLocation(location, worldName, groupName) {
|
||||
var text = worldName;
|
||||
var L = parseLocation(location);
|
||||
if (L.isOffline) {
|
||||
text = 'Offline';
|
||||
} else if (L.isPrivate) {
|
||||
text = 'Private';
|
||||
} else if (L.isTraveling) {
|
||||
text = 'Traveling';
|
||||
} else if (L.worldId) {
|
||||
if (groupName) {
|
||||
text = `${worldName} ${L.accessTypeName}(${groupName})`;
|
||||
} else if (L.instanceId) {
|
||||
text = `${worldName} ${L.accessTypeName}`;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
function parseLocation(tag) {
|
||||
var _tag = String(tag || '');
|
||||
var ctx = {
|
||||
tag: _tag,
|
||||
isOffline: false,
|
||||
isPrivate: false,
|
||||
isTraveling: false,
|
||||
isRealInstance: false,
|
||||
worldId: '',
|
||||
instanceId: '',
|
||||
instanceName: '',
|
||||
accessType: '',
|
||||
accessTypeName: '',
|
||||
region: '',
|
||||
shortName: '',
|
||||
userId: null,
|
||||
hiddenId: null,
|
||||
privateId: null,
|
||||
friendsId: null,
|
||||
groupId: null,
|
||||
groupAccessType: null,
|
||||
canRequestInvite: false,
|
||||
strict: false,
|
||||
ageGate: false
|
||||
};
|
||||
if (_tag === 'offline' || _tag === 'offline:offline') {
|
||||
ctx.isOffline = true;
|
||||
} else if (_tag === 'private' || _tag === 'private:private') {
|
||||
ctx.isPrivate = true;
|
||||
} else if (_tag === 'traveling' || _tag === 'traveling:traveling') {
|
||||
ctx.isTraveling = true;
|
||||
} else if (!_tag.startsWith('local')) {
|
||||
ctx.isRealInstance = true;
|
||||
var sep = _tag.indexOf(':');
|
||||
// technically not part of instance id, but might be there when coping id from url so why not support it
|
||||
var shortNameQualifier = '&shortName=';
|
||||
var shortNameIndex = _tag.indexOf(shortNameQualifier);
|
||||
if (shortNameIndex >= 0) {
|
||||
ctx.shortName = _tag.substr(
|
||||
shortNameIndex + shortNameQualifier.length
|
||||
);
|
||||
_tag = _tag.substr(0, shortNameIndex);
|
||||
}
|
||||
if (sep >= 0) {
|
||||
ctx.worldId = _tag.substr(0, sep);
|
||||
ctx.instanceId = _tag.substr(sep + 1);
|
||||
ctx.instanceId.split('~').forEach((s, i) => {
|
||||
if (i) {
|
||||
var A = s.indexOf('(');
|
||||
var Z = A >= 0 ? s.lastIndexOf(')') : -1;
|
||||
var key = Z >= 0 ? s.substr(0, A) : s;
|
||||
var value = A < Z ? s.substr(A + 1, Z - A - 1) : '';
|
||||
if (key === 'hidden') {
|
||||
ctx.hiddenId = value;
|
||||
} else if (key === 'private') {
|
||||
ctx.privateId = value;
|
||||
} else if (key === 'friends') {
|
||||
ctx.friendsId = value;
|
||||
} else if (key === 'canRequestInvite') {
|
||||
ctx.canRequestInvite = true;
|
||||
} else if (key === 'region') {
|
||||
ctx.region = value;
|
||||
} else if (key === 'group') {
|
||||
ctx.groupId = value;
|
||||
} else if (key === 'groupAccessType') {
|
||||
ctx.groupAccessType = value;
|
||||
} else if (key === 'strict') {
|
||||
ctx.strict = true;
|
||||
} else if (key === 'ageGate') {
|
||||
ctx.ageGate = true;
|
||||
}
|
||||
} else {
|
||||
ctx.instanceName = s;
|
||||
}
|
||||
});
|
||||
ctx.accessType = 'public';
|
||||
if (ctx.privateId !== null) {
|
||||
if (ctx.canRequestInvite) {
|
||||
// InvitePlus
|
||||
ctx.accessType = 'invite+';
|
||||
} else {
|
||||
// InviteOnly
|
||||
ctx.accessType = 'invite';
|
||||
}
|
||||
ctx.userId = ctx.privateId;
|
||||
} else if (ctx.friendsId !== null) {
|
||||
// FriendsOnly
|
||||
ctx.accessType = 'friends';
|
||||
ctx.userId = ctx.friendsId;
|
||||
} else if (ctx.hiddenId !== null) {
|
||||
// FriendsOfGuests
|
||||
ctx.accessType = 'friends+';
|
||||
ctx.userId = ctx.hiddenId;
|
||||
} else if (ctx.groupId !== null) {
|
||||
// Group
|
||||
ctx.accessType = 'group';
|
||||
}
|
||||
ctx.accessTypeName = ctx.accessType;
|
||||
if (ctx.groupAccessType !== null) {
|
||||
if (ctx.groupAccessType === 'public') {
|
||||
ctx.accessTypeName = 'groupPublic';
|
||||
} else if (ctx.groupAccessType === 'plus') {
|
||||
ctx.accessTypeName = 'groupPlus';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.worldId = _tag;
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export {
|
||||
refreshInstancePlayerCount,
|
||||
isRealInstance,
|
||||
displayLocation,
|
||||
parseLocation
|
||||
};
|
||||
@@ -1,236 +0,0 @@
|
||||
const getOptions = (optionTypes) => {
|
||||
const optionMap = {
|
||||
Off: { label: 'Off', textKey: 'dialog.shared_feed_filters.off' },
|
||||
On: { label: 'On', textKey: 'dialog.shared_feed_filters.on' },
|
||||
VIP: {
|
||||
label: 'VIP',
|
||||
textKey: 'dialog.shared_feed_filters.favorite'
|
||||
},
|
||||
Friends: {
|
||||
label: 'Friends',
|
||||
textKey: 'dialog.shared_feed_filters.friends'
|
||||
},
|
||||
Everyone: {
|
||||
label: 'Everyone',
|
||||
textKey: 'dialog.shared_feed_filters.everyone'
|
||||
}
|
||||
};
|
||||
return optionTypes.map((type) => optionMap[type]);
|
||||
};
|
||||
|
||||
function feedFiltersOptions() {
|
||||
const baseOptions = [
|
||||
{
|
||||
key: 'OnPlayerJoining',
|
||||
name: 'OnPlayerJoining',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'OnPlayerJoined',
|
||||
name: 'OnPlayerJoined',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'OnPlayerLeft',
|
||||
name: 'OnPlayerLeft',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'Online',
|
||||
name: 'Online',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'Offline',
|
||||
name: 'Offline',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'GPS',
|
||||
name: 'GPS',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'Status',
|
||||
name: 'Status',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'invite',
|
||||
name: 'Invite',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'requestInvite',
|
||||
name: 'Request Invite',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'inviteResponse',
|
||||
name: 'Invite Response',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'requestInviteResponse',
|
||||
name: 'Request Invite Response',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'friendRequest',
|
||||
name: 'Friend Request',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'Friend',
|
||||
name: 'New Friend',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'Unfriend',
|
||||
name: 'Unfriend',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'DisplayName',
|
||||
name: 'Display Name Change',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'TrustLevel',
|
||||
name: 'Trust Level Change',
|
||||
options: getOptions(['Off', 'VIP', 'Friends'])
|
||||
},
|
||||
{
|
||||
key: 'groupChange',
|
||||
name: 'Group Change',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip:
|
||||
"When you've left or been kicked from a group, group name changed, group owner changed, role added/removed"
|
||||
},
|
||||
{
|
||||
key: 'group.announcement',
|
||||
name: 'Group Announcement',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'group.informative',
|
||||
name: 'Group Join',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip: 'When your request to join a group has been approved'
|
||||
},
|
||||
{
|
||||
key: 'group.invite',
|
||||
name: 'Group Invite',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip: 'When someone invites you to join a group'
|
||||
},
|
||||
{
|
||||
key: 'group.joinRequest',
|
||||
name: 'Group Join Request',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip:
|
||||
"When someone requests to join a group you're a moderator for"
|
||||
},
|
||||
{
|
||||
key: 'group.transfer',
|
||||
name: 'Group Transfer Request',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'group.queueReady',
|
||||
name: 'Instance Queue Ready',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'instance.closed',
|
||||
name: 'Instance Closed',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip:
|
||||
"When the instance you're in has been closed preventing anyone from joining"
|
||||
},
|
||||
{
|
||||
key: 'VideoPlay',
|
||||
name: 'Video Play',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip: 'Requires VRCX YouTube API option enabled',
|
||||
tooltipIcon: 'el-icon-warning'
|
||||
},
|
||||
{
|
||||
key: 'Event',
|
||||
name: 'Miscellaneous Events',
|
||||
options: getOptions(['Off', 'On']),
|
||||
tooltip:
|
||||
'Misc event from VRC game log: VRC crash auto rejoin, shader keyword limit, joining instance blocked by master, error loading video, audio device changed, error joining instance, kicked from instance, VRChat failing to start OSC server, etc...'
|
||||
},
|
||||
{
|
||||
key: 'External',
|
||||
name: 'External App',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{
|
||||
key: 'BlockedOnPlayerJoined',
|
||||
name: 'Blocked Player Joins',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'BlockedOnPlayerLeft',
|
||||
name: 'Blocked Player Leaves',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'MutedOnPlayerJoined',
|
||||
name: 'Muted Player Joins',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'MutedOnPlayerLeft',
|
||||
name: 'Muted Player Leaves',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'AvatarChange',
|
||||
name: 'Lobby Avatar Change',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
}
|
||||
];
|
||||
|
||||
const photonFeedFiltersOptions = [
|
||||
{
|
||||
key: 'PortalSpawn',
|
||||
name: 'Portal Spawn',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{
|
||||
key: 'ChatBoxMessage',
|
||||
name: 'Lobby ChatBox Message',
|
||||
options: getOptions(['Off', 'VIP', 'Friends', 'Everyone'])
|
||||
},
|
||||
{ key: 'Blocked', name: 'Blocked', options: getOptions(['Off', 'On']) },
|
||||
{
|
||||
key: 'Unblocked',
|
||||
name: 'Unblocked',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
{ key: 'Muted', name: 'Muted', options: getOptions(['Off', 'On']) },
|
||||
{ key: 'Unmuted', name: 'Unmuted', options: getOptions(['Off', 'On']) }
|
||||
];
|
||||
|
||||
const notyFeedFiltersOptions = baseOptions;
|
||||
|
||||
const wristFeedFiltersOptions = [
|
||||
{
|
||||
key: 'Location',
|
||||
name: 'Self Location',
|
||||
options: getOptions(['Off', 'On'])
|
||||
},
|
||||
...baseOptions
|
||||
];
|
||||
|
||||
return {
|
||||
notyFeedFiltersOptions,
|
||||
wristFeedFiltersOptions,
|
||||
photonFeedFiltersOptions
|
||||
};
|
||||
}
|
||||
|
||||
export { feedFiltersOptions };
|
||||
@@ -1,424 +0,0 @@
|
||||
const openSourceSoftwareLicenses = [
|
||||
{
|
||||
name: 'animate.css',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Daniel Eden
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'CefSharp',
|
||||
licenseText: `// Copyright © The CefSharp Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the name CefSharp nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`
|
||||
},
|
||||
{
|
||||
name: 'DiscordRichPresence',
|
||||
licenseText: `MIT License
|
||||
|
||||
Copyright (c) 2018 Lachee
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'element',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-present ElemeFE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'librsync.net',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Brad Dodson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'Newtonsoft.Json',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2007 James Newton-King
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'normalize',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright © Nicolas Gallagher and Jonathan Neal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'noty',
|
||||
licenseText: `Copyright (c) 2012 Nedim Arabacı
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'OpenVR SDK',
|
||||
licenseText: `Copyright (c) 2015, Valve Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`
|
||||
},
|
||||
{
|
||||
name: 'Twemoji',
|
||||
licenseText: `MIT License
|
||||
|
||||
Copyright (c) 2021 Twitter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'SharpDX',
|
||||
licenseText: `Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'vue',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-present, Yuxi (Evan) You
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'vue-data-tables',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Leon Zhang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'vue-lazyload',
|
||||
licenseText: `The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Awe
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'Encode Sans Font (from Dark Vanilla)',
|
||||
licenseText: `SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
Copyright (c) 2020 June 20, Impallari Type, Andres Torresi, Jacques Le Bailly
|
||||
(https://fonts.google.com/specimen/Encode+Sans),
|
||||
with Reserved Font Name: Encode Sans.
|
||||
|
||||
PREAMBLE:
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development
|
||||
of collaborative font projects, to support the font creation efforts of academic
|
||||
and linguistic communities, and to provide a free and open framework in which
|
||||
fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed
|
||||
freely as long as they are not sold by themselves. The fonts, including any
|
||||
derivative works, can be bundled, embedded, redistributed and/or sold with any
|
||||
software provided that any reserved names are not used by derivative works.
|
||||
The fonts and derivatives, however, cannot be released under any other type of
|
||||
license. The requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
the Font Software, to use, study, copy, merge, embed, modify, redistribute, and
|
||||
sell modified and unmodified copies of the Font Software, subject to the
|
||||
following conditions:
|
||||
|
||||
1. Neither the Font Software nor any of its individual components, in Original or
|
||||
Modified Versions, may be sold by itself.
|
||||
|
||||
2. Original or Modified Versions of the Font Software may be bundled, redistributed
|
||||
and/or sold with any software, provided that each copy contains the above copyright
|
||||
notice and this license. These can be included either as stand-alone text files,
|
||||
human-readable headers or in the appropriate machine-readable metadata fields within
|
||||
text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3. No Modified Version of the Font Software may use the Reserved Font Name(s) unless
|
||||
explicit written permission is granted by the corresponding Copyright Holder. This
|
||||
restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4. The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall
|
||||
not be used to promote, endorse or advertise any Modified Version, except to
|
||||
acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with
|
||||
their explicit written permission.
|
||||
|
||||
5. The Font Software, modified or unmodified, in part or in whole, must be distributed
|
||||
entirely under this license, and must not be distributed under any other license.
|
||||
The requirement for fonts to remain under this license does not apply to any document
|
||||
created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR
|
||||
OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
|
||||
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||
DEALINGS IN THE FONT SOFTWARE.`
|
||||
},
|
||||
{
|
||||
name: 'Apache ECharts',
|
||||
licenseText: `Apache License 2.0
|
||||
|
||||
Copyright 2017-2025 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (https://www.apache.org/).`
|
||||
},
|
||||
{
|
||||
name: 'dayjs',
|
||||
licenseText: `MIT License
|
||||
|
||||
Copyright (c) 2018-present, iamkun
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.`
|
||||
}
|
||||
];
|
||||
|
||||
export { openSourceSoftwareLicenses };
|
||||
@@ -1,16 +0,0 @@
|
||||
const VRChatScreenshotResolutions = [
|
||||
{ name: '1280x720 (720p)', width: 1280, height: 720 },
|
||||
{ name: '1920x1080 (1080p Default)', width: '', height: '' },
|
||||
{ name: '2560x1440 (1440p)', width: 2560, height: 1440 },
|
||||
{ name: '3840x2160 (4K)', width: 3840, height: 2160 }
|
||||
];
|
||||
|
||||
const VRChatCameraResolutions = [
|
||||
{ name: '1280x720 (720p)', width: 1280, height: 720 },
|
||||
{ name: '1920x1080 (1080p Default)', width: '', height: '' },
|
||||
{ name: '2560x1440 (1440p)', width: 2560, height: 1440 },
|
||||
{ name: '3840x2160 (4K)', width: 3840, height: 2160 },
|
||||
{ name: '7680x4320 (8K)', width: 7680, height: 4320 }
|
||||
];
|
||||
|
||||
export { VRChatScreenshotResolutions, VRChatCameraResolutions };
|
||||
@@ -1,17 +0,0 @@
|
||||
function getVRChatResolution(res) {
|
||||
switch (res) {
|
||||
case '1280x720':
|
||||
return '1280x720 (720p)';
|
||||
case '1920x1080':
|
||||
return '1920x1080 (1080p)';
|
||||
case '2560x1440':
|
||||
return '2560x1440 (2K)';
|
||||
case '3840x2160':
|
||||
return '3840x2160 (4K)';
|
||||
case '7680x4320':
|
||||
return '7680x4320 (8K)';
|
||||
}
|
||||
return `${res} (Custom)`;
|
||||
}
|
||||
|
||||
export { getVRChatResolution };
|
||||
@@ -1,106 +0,0 @@
|
||||
const photonEmojis = [
|
||||
'Angry',
|
||||
'Blushing',
|
||||
'Crying',
|
||||
'Frown',
|
||||
'Hand Wave',
|
||||
'Hang Ten',
|
||||
'In Love',
|
||||
'Jack O Lantern',
|
||||
'Kiss',
|
||||
'Laugh',
|
||||
'Skull',
|
||||
'Smile',
|
||||
'Spooky Ghost',
|
||||
'Stoic',
|
||||
'Sunglasses',
|
||||
'Thinking',
|
||||
'Thumbs Down',
|
||||
'Thumbs Up',
|
||||
'Tongue Out',
|
||||
'Wow',
|
||||
'Arrow Point',
|
||||
"Can't see",
|
||||
'Hourglass',
|
||||
'Keyboard',
|
||||
'No Headphones',
|
||||
'No Mic',
|
||||
'Portal',
|
||||
'Shush',
|
||||
'Bats',
|
||||
'Cloud',
|
||||
'Fire',
|
||||
'Snow Fall',
|
||||
'Snowball',
|
||||
'Splash',
|
||||
'Web',
|
||||
'Beer',
|
||||
'Candy',
|
||||
'Candy Cane',
|
||||
'Candy Corn',
|
||||
'Champagne',
|
||||
'Drink',
|
||||
'Gingerbread',
|
||||
'Ice Cream',
|
||||
'Pineapple',
|
||||
'Pizza',
|
||||
'Tomato',
|
||||
'Beachball',
|
||||
'Coal',
|
||||
'Confetti',
|
||||
'Gift',
|
||||
'Gifts',
|
||||
'Life Ring',
|
||||
'Mistletoe',
|
||||
'Money',
|
||||
'Neon Shades',
|
||||
'Sun Lotion',
|
||||
'Boo',
|
||||
'Broken Heart',
|
||||
'Exclamation',
|
||||
'Go',
|
||||
'Heart',
|
||||
'Music Note',
|
||||
'Question',
|
||||
'Stop',
|
||||
'Zzz'
|
||||
];
|
||||
|
||||
const photonEventType = [
|
||||
'MeshVisibility',
|
||||
'AnimationFloat',
|
||||
'AnimationBool',
|
||||
'AnimationTrigger',
|
||||
'AudioTrigger',
|
||||
'PlayAnimation',
|
||||
'SendMessage',
|
||||
'SetParticlePlaying',
|
||||
'TeleportPlayer',
|
||||
'RunConsoleCommand',
|
||||
'SetGameObjectActive',
|
||||
'SetWebPanelURI',
|
||||
'SetWebPanelVolume',
|
||||
'SpawnObject',
|
||||
'SendRPC',
|
||||
'ActivateCustomTrigger',
|
||||
'DestroyObject',
|
||||
'SetLayer',
|
||||
'SetMaterial',
|
||||
'AddHealth',
|
||||
'AddDamage',
|
||||
'SetComponentActive',
|
||||
'AnimationInt',
|
||||
'AnimationIntAdd',
|
||||
'AnimationIntSubtract',
|
||||
'AnimationIntMultiply',
|
||||
'AnimationIntDivide',
|
||||
'AddVelocity',
|
||||
'SetVelocity',
|
||||
'AddAngularVelocity',
|
||||
'SetAngularVelocity',
|
||||
'AddForce',
|
||||
'SetUIText',
|
||||
'CallUdonMethod'
|
||||
];
|
||||
|
||||
export { photonEmojis, photonEventType };
|
||||
@@ -1,341 +0,0 @@
|
||||
import Noty from 'noty';
|
||||
import utils from '../../classes/utils';
|
||||
import { compareUnityVersion } from '../avatar/utils';
|
||||
import {
|
||||
displayLocation,
|
||||
isRealInstance,
|
||||
parseLocation
|
||||
} from '../instance/utils';
|
||||
import {
|
||||
getPrintFileName,
|
||||
getPrintLocalDate,
|
||||
isFriendOnline
|
||||
} from '../user/utils';
|
||||
|
||||
function getAvailablePlatforms(unityPackages) {
|
||||
var isPC = false;
|
||||
var isQuest = false;
|
||||
var isIos = false;
|
||||
if (typeof unityPackages === 'object') {
|
||||
for (var unityPackage of unityPackages) {
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (unityPackage.platform === 'standalonewindows') {
|
||||
isPC = true;
|
||||
} else if (unityPackage.platform === 'android') {
|
||||
isQuest = true;
|
||||
} else if (unityPackage.platform === 'ios') {
|
||||
isIos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { isPC, isQuest, isIos };
|
||||
}
|
||||
|
||||
function downloadAndSaveJson(fileName, data) {
|
||||
if (!fileName || !data) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var link = document.createElement('a');
|
||||
link.setAttribute(
|
||||
'href',
|
||||
`data:application/json;charset=utf-8,${encodeURIComponent(
|
||||
JSON.stringify(data, null, 2)
|
||||
)}`
|
||||
);
|
||||
link.setAttribute('download', `${fileName}.json`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
} catch {
|
||||
new Noty({
|
||||
type: 'error',
|
||||
text: utils.escapeTag('Failed to download JSON.')
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteVRChatCache(ref) {
|
||||
var assetUrl = '';
|
||||
var variant = '';
|
||||
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = ref.unityPackages[i];
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (unityPackage.variant !== 'standard') {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var id = extractFileId(assetUrl);
|
||||
var version = parseInt(extractFileVersion(assetUrl), 10);
|
||||
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
||||
await AssetBundleManager.DeleteCache(id, version, variant, variantVersion);
|
||||
}
|
||||
|
||||
async function checkVRChatCache(ref) {
|
||||
if (!ref.unityPackages) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
var assetUrl = '';
|
||||
var variant = '';
|
||||
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = ref.unityPackages[i];
|
||||
if (unityPackage.variant && unityPackage.variant !== 'security') {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (unityPackage.variant !== 'standard') {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var id = extractFileId(assetUrl);
|
||||
var version = parseInt(extractFileVersion(assetUrl), 10);
|
||||
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
||||
if (!id || !version) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
|
||||
return AssetBundleManager.CheckVRChatCache(
|
||||
id,
|
||||
version,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
}
|
||||
|
||||
function copyToClipboard(text, message = 'Copied successfully!') {
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
window.$app.$message({
|
||||
message: message,
|
||||
type: 'success'
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Copy failed:', err);
|
||||
window.$app.$message.error('Copy failed!');
|
||||
});
|
||||
}
|
||||
|
||||
function getFaviconUrl(resource) {
|
||||
if (!resource) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
const url = new URL(resource);
|
||||
return `https://icons.duckduckgo.com/ip2/${url.host}.ico`;
|
||||
} catch (err) {
|
||||
console.error('Invalid URL:', err);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function convertFileUrlToImageUrl(url, resolution = 128) {
|
||||
if (!url) {
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* possible patterns?
|
||||
* /file/file_fileId/version
|
||||
* /file/file_fileId/version/
|
||||
* /file/file_fileId/version/file
|
||||
* /file/file_fileId/version/file/
|
||||
*/
|
||||
const pattern = /file\/file_([a-f0-9-]+)\/(\d+)(\/file)?\/?$/;
|
||||
const match = url.match(pattern);
|
||||
|
||||
if (match) {
|
||||
const fileId = match[1];
|
||||
const version = match[2];
|
||||
return `https://api.vrchat.cloud/api/1/image/file_${fileId}/${version}/${resolution}`;
|
||||
}
|
||||
// no match return origin url
|
||||
return url;
|
||||
}
|
||||
|
||||
function replaceVrcPackageUrl(url) {
|
||||
if (!url) {
|
||||
return '';
|
||||
}
|
||||
return url.replace('https://api.vrchat.cloud/', 'https://vrchat.com/');
|
||||
}
|
||||
|
||||
function getLaunchURL(instance) {
|
||||
var L = instance;
|
||||
if (L.instanceId) {
|
||||
if (L.shortName) {
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}&instanceId=${encodeURIComponent(
|
||||
L.instanceId
|
||||
)}&shortName=${encodeURIComponent(L.shortName)}`;
|
||||
}
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}&instanceId=${encodeURIComponent(L.instanceId)}`;
|
||||
}
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}`;
|
||||
}
|
||||
|
||||
function extractFileId(s) {
|
||||
var match = String(s).match(/file_[0-9A-Za-z-]+/);
|
||||
return match ? match[0] : '';
|
||||
}
|
||||
|
||||
function extractFileVersion(s) {
|
||||
var match = /(?:\/file_[0-9A-Za-z-]+\/)([0-9]+)/gi.exec(s);
|
||||
return match ? match[1] : '';
|
||||
}
|
||||
|
||||
function extractVariantVersion(url) {
|
||||
if (!url) {
|
||||
return '0';
|
||||
}
|
||||
try {
|
||||
const params = new URLSearchParams(new URL(url).search);
|
||||
const version = params.get('v');
|
||||
if (version) {
|
||||
return version;
|
||||
}
|
||||
return '0';
|
||||
} catch {
|
||||
return '0';
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------- devtool method --------------------------
|
||||
|
||||
async function getBundleLocation(input) {
|
||||
const $app = window.$app;
|
||||
var assetUrl = input;
|
||||
var variant = '';
|
||||
if (assetUrl) {
|
||||
// continue
|
||||
} else if (
|
||||
$app.avatarDialog.visible &&
|
||||
$app.avatarDialog.ref.unityPackages.length > 0
|
||||
) {
|
||||
var unityPackages = $app.avatarDialog.ref.unityPackages;
|
||||
for (let i = unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = unityPackages[i];
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (unityPackage.variant !== 'standard') {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
$app.worldDialog.visible &&
|
||||
$app.worldDialog.ref.unityPackages.length > 0
|
||||
) {
|
||||
var unityPackages = $app.worldDialog.ref.unityPackages;
|
||||
for (let i = unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = unityPackages[i];
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!assetUrl) {
|
||||
return null;
|
||||
}
|
||||
var fileId = extractFileId(assetUrl);
|
||||
var fileVersion = parseInt(extractFileVersion(assetUrl), 10);
|
||||
var variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
||||
var assetLocation = await AssetBundleManager.GetVRChatCacheFullLocation(
|
||||
fileId,
|
||||
fileVersion,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
var cacheInfo = await AssetBundleManager.CheckVRChatCache(
|
||||
fileId,
|
||||
fileVersion,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
var inCache = false;
|
||||
if (cacheInfo.Item1 > 0) {
|
||||
inCache = true;
|
||||
}
|
||||
console.log(`InCache: ${inCache}`);
|
||||
var fullAssetLocation = `${assetLocation}\\__data`;
|
||||
console.log(fullAssetLocation);
|
||||
return fullAssetLocation;
|
||||
}
|
||||
|
||||
const _utils = {
|
||||
getAvailablePlatforms,
|
||||
deleteVRChatCache,
|
||||
checkVRChatCache,
|
||||
getLaunchURL,
|
||||
extractFileId,
|
||||
extractFileVersion,
|
||||
extractVariantVersion,
|
||||
isRealInstance,
|
||||
displayLocation,
|
||||
parseLocation,
|
||||
getPrintFileName,
|
||||
getPrintLocalDate,
|
||||
isFriendOnline
|
||||
};
|
||||
|
||||
export {
|
||||
getAvailablePlatforms,
|
||||
downloadAndSaveJson,
|
||||
deleteVRChatCache,
|
||||
checkVRChatCache,
|
||||
copyToClipboard,
|
||||
getFaviconUrl,
|
||||
convertFileUrlToImageUrl,
|
||||
replaceVrcPackageUrl,
|
||||
getLaunchURL,
|
||||
extractFileId,
|
||||
extractFileVersion,
|
||||
extractVariantVersion,
|
||||
getBundleLocation,
|
||||
_utils
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
const emojiAnimationStyleUrl =
|
||||
'https://assets.vrchat.com/www/images/emoji-previews/';
|
||||
|
||||
const emojiAnimationStyleList = {
|
||||
Aura: 'Preview_B2-Aura.gif',
|
||||
Bats: 'Preview_B2-Fall_Bats.gif',
|
||||
Bees: 'Preview_B2-Bees.gif',
|
||||
Bounce: 'Preview_B2-Bounce.gif',
|
||||
Cloud: 'Preview_B2-Cloud.gif',
|
||||
Confetti: 'Preview_B2-Winter_Confetti.gif',
|
||||
Crying: 'Preview_B2-Crying.gif',
|
||||
Dislike: 'Preview_B2-Dislike.gif',
|
||||
Fire: 'Preview_B2-Fire.gif',
|
||||
Idea: 'Preview_B2-Idea.gif',
|
||||
Lasers: 'Preview_B2-Lasers.gif',
|
||||
Like: 'Preview_B2-Like.gif',
|
||||
Magnet: 'Preview_B2-Magnet.gif',
|
||||
Mistletoe: 'Preview_B2-Winter_Mistletoe.gif',
|
||||
Money: 'Preview_B2-Money.gif',
|
||||
Noise: 'Preview_B2-Noise.gif',
|
||||
Orbit: 'Preview_B2-Orbit.gif',
|
||||
Pizza: 'Preview_B2-Pizza.gif',
|
||||
Rain: 'Preview_B2-Rain.gif',
|
||||
Rotate: 'Preview_B2-Rotate.gif',
|
||||
Shake: 'Preview_B2-Shake.gif',
|
||||
Snow: 'Preview_B2-Spin.gif',
|
||||
Snowball: 'Preview_B2-Winter_Snowball.gif',
|
||||
Spin: 'Preview_B2-Spin.gif',
|
||||
Splash: 'Preview_B2-SummerSplash.gif',
|
||||
Stop: 'Preview_B2-Stop.gif',
|
||||
ZZZ: 'Preview_B2-ZZZ.gif'
|
||||
};
|
||||
|
||||
export { emojiAnimationStyleUrl, emojiAnimationStyleList };
|
||||
@@ -1,73 +0,0 @@
|
||||
// vrchat to famfamfam language mappings
|
||||
const languageMappings = {
|
||||
eng: 'us',
|
||||
kor: 'kr',
|
||||
rus: 'ru',
|
||||
spa: 'es',
|
||||
por: 'pt',
|
||||
zho: 'cn',
|
||||
deu: 'de',
|
||||
jpn: 'jp',
|
||||
fra: 'fr',
|
||||
swe: 'se',
|
||||
nld: 'nl',
|
||||
pol: 'pl',
|
||||
dan: 'dk',
|
||||
nor: 'no',
|
||||
ita: 'it',
|
||||
tha: 'th',
|
||||
fin: 'fi',
|
||||
hun: 'hu',
|
||||
ces: 'cz',
|
||||
tur: 'tr',
|
||||
ara: 'ae',
|
||||
ron: 'ro',
|
||||
vie: 'vn',
|
||||
ukr: 'ua',
|
||||
ase: 'us',
|
||||
bfi: 'gb',
|
||||
dse: 'nl',
|
||||
fsl: 'fr',
|
||||
jsl: 'jp',
|
||||
kvk: 'kr',
|
||||
|
||||
mlt: 'mt',
|
||||
ind: 'id',
|
||||
hrv: 'hr',
|
||||
heb: 'he',
|
||||
afr: 'af',
|
||||
ben: 'be',
|
||||
bul: 'bg',
|
||||
cmn: 'cn',
|
||||
cym: 'cy',
|
||||
ell: 'el',
|
||||
est: 'et',
|
||||
fil: 'ph',
|
||||
gla: 'gd',
|
||||
gle: 'ga',
|
||||
hin: 'hi',
|
||||
hmn: 'cn',
|
||||
hye: 'hy',
|
||||
isl: 'is',
|
||||
lav: 'lv',
|
||||
lit: 'lt',
|
||||
ltz: 'lb',
|
||||
mar: 'hi',
|
||||
mkd: 'mk',
|
||||
msa: 'my',
|
||||
sco: 'gd',
|
||||
slk: 'sk',
|
||||
slv: 'sl',
|
||||
tel: 'hi',
|
||||
mri: 'nz',
|
||||
wuu: 'cn',
|
||||
yue: 'cn',
|
||||
tws: 'cn',
|
||||
asf: 'au',
|
||||
nzs: 'nz',
|
||||
gsg: 'de',
|
||||
epo: 'eo',
|
||||
tok: 'tok'
|
||||
};
|
||||
|
||||
export { languageMappings };
|
||||
@@ -1,16 +0,0 @@
|
||||
const userDialogGroupSortingOptions = {
|
||||
alphabetical: {
|
||||
name: 'dialog.user.groups.sorting.alphabetical',
|
||||
value: 'alphabetical'
|
||||
},
|
||||
members: {
|
||||
name: 'dialog.user.groups.sorting.members',
|
||||
value: 'members'
|
||||
},
|
||||
inGame: {
|
||||
name: 'dialog.user.groups.sorting.in_game',
|
||||
value: 'inGame'
|
||||
}
|
||||
};
|
||||
|
||||
export { userDialogGroupSortingOptions };
|
||||
@@ -1,89 +0,0 @@
|
||||
import { languageMappings } from './constants/language';
|
||||
|
||||
function userOnlineForTimestamp(ctx) {
|
||||
if (ctx.ref.state === 'online' && ctx.ref.$online_for) {
|
||||
return ctx.ref.$online_for;
|
||||
} else if (ctx.ref.state === 'active' && ctx.ref.$active_for) {
|
||||
return ctx.ref.$active_for;
|
||||
} else if (ctx.ref.$offline_for) {
|
||||
return ctx.ref.$offline_for;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function languageClass(language) {
|
||||
const style = {};
|
||||
const mapping = languageMappings[language];
|
||||
if (typeof mapping !== 'undefined') {
|
||||
style[mapping] = true;
|
||||
} else {
|
||||
style.unknown = true;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
function getPrintFileName(print) {
|
||||
const authorName = print.authorName;
|
||||
// fileDate format: 2024-11-03_16-14-25.757
|
||||
const createdAt = getPrintLocalDate(print);
|
||||
const fileNameDate = createdAt
|
||||
.toISOString()
|
||||
.replace(/:/g, '-')
|
||||
.replace(/T/g, '_')
|
||||
.replace(/Z/g, '');
|
||||
const fileName = `${authorName}_${fileNameDate}_${print.id}.png`;
|
||||
return fileName;
|
||||
}
|
||||
|
||||
function getEmojiFileName(emoji) {
|
||||
if (emoji.frames) {
|
||||
const loopStyle = emoji.loopStyle || 'linear';
|
||||
return `${emoji.name}_${emoji.animationStyle}animationStyle_${emoji.frames}frames_${emoji.framesOverTime}fps_${loopStyle}loopStyle.png`;
|
||||
} else {
|
||||
return `${emoji.name}_${emoji.animationStyle}animationStyle.png`;
|
||||
}
|
||||
}
|
||||
|
||||
function getPrintLocalDate(print) {
|
||||
if (print.createdAt) {
|
||||
const createdAt = new Date(print.createdAt);
|
||||
// cursed convert to local time
|
||||
createdAt.setMinutes(
|
||||
createdAt.getMinutes() - createdAt.getTimezoneOffset()
|
||||
);
|
||||
return createdAt;
|
||||
}
|
||||
if (print.timestamp) {
|
||||
return new Date(print.timestamp);
|
||||
}
|
||||
|
||||
const createdAt = new Date();
|
||||
// cursed convert to local time
|
||||
createdAt.setMinutes(
|
||||
createdAt.getMinutes() - createdAt.getTimezoneOffset()
|
||||
);
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
function isFriendOnline(friend) {
|
||||
if (typeof friend === 'undefined' || typeof friend.ref === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
if (friend.state === 'online') {
|
||||
return true;
|
||||
}
|
||||
if (friend.state !== 'online' && friend.ref.location !== 'private') {
|
||||
// wat
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export {
|
||||
userOnlineForTimestamp,
|
||||
languageClass,
|
||||
getPrintFileName,
|
||||
getPrintLocalDate,
|
||||
getEmojiFileName,
|
||||
isFriendOnline
|
||||
};
|
||||
Reference in New Issue
Block a user