-
Notifications
You must be signed in to change notification settings - Fork 1
/
polyfill.js
159 lines (129 loc) · 4.42 KB
/
polyfill.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 fvtt-shared-library Rui Pinheiro
'use strict';
import { ERRORS } from '../errors/errors.js';
// game.user.data polyfill, so it can be used before 'ready'
export const game_user_data = function(return_null=false) {
// Try game.user.data first
const orig_game_user_data = globalThis.game?.user?.data;
if(orig_game_user_data)
return orig_game_user_data;
// Grab the user ID
const userid = globalThis.game?.userId ?? globalThis.game?.data?.userId;
if(!userid) {
if(return_null)
return null;
throw new ERRORS.internal("Unable to obtain the current user ID");
}
// Find user in game.data.users
const user_data = globalThis.game?.data?.users?.find((x) => { return x._id == userid });
if(!user_data) {
if(return_null)
return null;
throw new ERRORS.internal("Unable to obtain the current user data object");
}
// Done
return user_data;
}
// game.user.can polyfill, so it can be used before 'ready'
export const game_user_can = function(action, return_null=false) {
// Try game.user.can first
const orig_game_user_can = globalThis.game?.user?.can;
if(orig_game_user_can)
return orig_game_user_can.call(game.user, action);
// Obtain game.user.data
const user_data = game_user_data(return_null);
if(!user_data)
return null;
// Check if user is GM
if(user_data.role === 4)
return true;
// Check if the action is in the per-user permissions
if(action in user_data.permissions) return user_data.permissions[action];
// Otherwise, check the role's permissions
const game_permissions_str = globalThis.game?.data?.settings?.find((x) => { return x.key === 'core.permissions'});
if(game_permissions_str?.value) {
const game_permissions = JSON.parse(game_permissions_str.value);
const rolePerms = game_permissions[action];
if(rolePerms && rolePerms.includes(user_data.role))
return true;
}
return false;
}
// game.user.isGM polyfill, so it can be used before 'ready'
export const game_user_isGM = function(return_null=false) {
// Try game.user.isGM first
const orig_game_user_isGM = globalThis.game?.user?.isGM;
if(orig_game_user_isGM !== undefined)
return orig_game_user_isGM;
// Obtain game.user.data
const user_data = game_user_data(return_null);
if(!user_data)
return null;
// Done
return user_data.role === 4;
}
// Polyfill to get the Foundry version
export const game_release_display = function(return_null=true) {
const display =
globalThis.game?.release?.display ??
globalThis.game?.version ??
globalThis.game?.data?.version ??
null
;
if(!return_null && display === null)
throw new ERRORS.internal("Unable to obtain the Foundry display version");
return display;
}
export const game_version = function(return_null=true) {
const version =
globalThis.game?.version ??
globalThis.game?.release?.version ??
globalThis.game?.data?.version ??
null
;
if(!return_null && version === null)
throw new ERRORS.internal("Unable to obtain the Foundry version");
return version;
}
// Polyfill to get module settings (allows accessing settings before 'init' if they are client-scoped)
export const game_settings_get = function(namespace, key, always_fallback=false, return_null=true) {
// Try game.settings.get first
try {
const orig_game_settings_get = globalThis.game?.settings?.get;
if(orig_game_settings_get)
return orig_game_settings_get.call(game.settings, namespace, key);
}
catch(e) {
if(!always_fallback)
throw e;
}
// Access localStorage to get the client-scoped version of the setting
const storage_key = `${namespace}.${key}`;
try {
const data = globalThis.localStorage?.[storage_key];
if(data === undefined || data === null) {
if(return_null)
return null;
throw new ERRORS.internal(`Unable to obtain the setting '${storage_key}'`);
}
// Parse the localStorage data the same way as Core does
const json_data = JSON.parse(data)
if(json_data === undefined || json_data === null) {
if(return_null)
return null;
throw new ERRORS.internal(`Unable to obtain the setting '${storage_key}'`);
}
// Done
return json_data;
}
catch(e) {
if(return_null)
return null;
throw new ERRORS.internal(`Unable to obtain the setting '${storage_key}' due to exception in polyfill:`, e);
}
}
// Polyfill to support FVTT<12 and FVTT>=12
export const isNewerVersion = function(...args) {
return foundry?.utils?.isNewerVersion?.(...args) ?? globalThis.isNewerVersion(...args);
}