返回提交历史
Modified
config-vanilla.json
+12
-0
Modified
src/controllers/custom/addCurrencyController.ts
+14
-5
Modified
src/controllers/custom/addItemsController.ts
+5
-1
Modified
src/controllers/custom/configController.ts
+1
-13
Modified
src/controllers/custom/importController.ts
+9
-5
Modified
src/controllers/custom/setAccountCheatController.ts
+12
-10
Modified
src/services/configService.ts
+12
-0
Modified
src/services/loginService.ts
+31
-2
Modified
src/services/wsService.ts
+19
-1
Modified
static/webui/index.html
+89
-89
Modified
static/webui/script.js
+20
-1
XFEstudio/XFESpaceNinjaServer
feat(webui): initial permission system (#3820)
Closes #3749 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3820 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
5bf7aaba
代码差异
11 个文件
+224
-127
@@ -31,6 +31,18 @@
31
31
"webui": {
32
32
"enabled": true,
33
33
"adminOnly": false,
34
"nonAdminPermissions": {
35
"*": true,
36
"addCredits": true,
37
"addPlatinum": true,
38
"addEndo": true,
39
"addRegalAya": true,
40
"import": true,
41
"toggleCheat": {
42
"*": true,
43
"skipAllDialogue": true
44
}
45
},
34
46
"defaultLanguage": "en"
35
47
},
36
48
"unfaithfulBugFixes": {
@@ -1,28 +1,30 @@
1
1
import type { RequestHandler } from "express";
2
import { getAccountIdForRequest } from "../../services/loginService.ts";
2
import { getAccountForRequest, hasPermission } from "../../services/loginService.ts";
3
3
import { addFusionPoints, getInventory } from "../../services/inventoryService.ts";
4
4
import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
5
5
import { GuildPermission } from "../../types/guildTypes.ts";
6
6
import { broadcastInventoryUpdate } from "../../services/wsService.ts";
7
7
8
8
export const addCurrencyController: RequestHandler = async (req, res) => {
9
const accountId = await getAccountIdForRequest(req);
9
const account = await getAccountForRequest(req);
10
10
const request = req.body as IAddCurrencyRequest;
11
11
let projection = request.currency as string;
12
12
if (request.currency.startsWith("Vault")) projection = "GuildId";
13
const inventory = await getInventory(accountId, projection);
13
const inventory = await getInventory(account._id, projection);
14
14
if (request.currency == "FusionPoints") {
15
15
addFusionPoints(inventory, request.delta);
16
16
} else if (request.currency == "VaultRegularCredits" || request.currency == "VaultPremiumCredits") {
17
17
const guild = await getGuildForRequestEx(req, inventory);
18
if (await hasGuildPermission(guild, accountId, GuildPermission.Treasurer)) {
18
if (await hasGuildPermission(guild, account._id, GuildPermission.Treasurer)) {
19
19
guild[request.currency] ??= 0;
20
20
guild[request.currency]! += request.delta;
21
21
await guild.save();
22
22
res.json(guild[request.currency]);
23
23
}
24
24
} else {
25
inventory[request.currency] += request.delta;
25
if (hasPermission(account, currencyToPermission[request.currency])) {
26
inventory[request.currency] += request.delta;
27
}
26
28
}
27
29
if (!request.currency.startsWith("Vault")) {
28
30
await inventory.save();
@@ -41,3 +43,10 @@ interface IAddCurrencyRequest {
41
43
| "VaultPremiumCredits";
42
44
delta: number;
43
45
}
46
47
const currencyToPermission: Record<string, string> = {
48
RegularCredits: "addCredits",
49
PremiumCredits: "addPlatinum",
50
FusionPoints: "addEndo",
51
PrimeTokens: "addRegalAya"
52
};
@@ -1,4 +1,4 @@
1
import { getAccountForRequest } from "../../services/loginService.ts";
1
import { getAccountForRequest, hasPermission } from "../../services/loginService.ts";
2
2
import { getInventory, addItem } from "../../services/inventoryService.ts";
3
3
import type { RequestHandler } from "express";
4
4
import { broadcastInventoryUpdate } from "../../services/wsService.ts";
@@ -6,6 +6,10 @@ import { logger } from "../../utils/logger.ts";
6
6
7
7
export const addItemsController: RequestHandler = async (req, res) => {
8
8
const account = await getAccountForRequest(req);
9
if (!hasPermission(account, "addItems")) {
10
res.status(500).send(`Permission denied`).end();
11
return;
12
}
9
13
const requests = req.body as IAddItemRequest[];
10
14
const inventory = await getInventory(account._id);
11
15
for (const request of requests) {
@@ -1,5 +1,5 @@
1
1
import type { RequestHandler } from "express";
2
import { config } from "../../services/configService.ts";
2
import { configIdToIndexable } from "../../services/configService.ts";
3
3
import { syncConfigWithDatabase } from "../../services/configWatcherService.ts";
4
4
import { getAccountForRequest, isAdministrator } from "../../services/loginService.ts";
5
5
import { saveConfig } from "../../services/configWriterService.ts";
@@ -37,15 +37,3 @@ export const setConfigController: RequestHandler = async (req, res) => {
37
37
res.status(401).end();
38
38
}
39
39
};
40
41
const configIdToIndexable = (id: string): [Record<string, boolean | string | number | undefined>, string] => {
42
let obj = config as unknown as Record<string, never>;
43
const arr = id.split(".");
44
while (arr.length > 1) {
45
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
46
obj[arr[0]] ??= {} as never;
47
obj = obj[arr[0]];
48
arr.splice(0, 1);
49
}
50
return [obj, arr[0]];
51
};
@@ -1,7 +1,7 @@
1
1
import { importInventory, importLoadOutPresets, importPersonalRooms } from "../../services/importService.ts";
2
2
import { ensureUserHasFounderHonoria, getInventory } from "../../services/inventoryService.ts";
3
3
import { getLoadout } from "../../services/loadoutService.ts";
4
import { getAccountIdForRequest } from "../../services/loginService.ts";
4
import { getAccountForRequest, hasPermission } from "../../services/loginService.ts";
5
5
import { getPersonalRooms } from "../../services/personalRoomsService.ts";
6
6
import { broadcastInventoryUpdate } from "../../services/wsService.ts";
7
7
import type { IInventoryClient } from "../../types/inventoryTypes/inventoryTypes.ts";
@@ -9,12 +9,16 @@ import type { IGetShipResponse } from "../../types/personalRoomsTypes.ts";
9
9
import type { RequestHandler } from "express";
10
10
11
11
export const importController: RequestHandler = async (req, res) => {
12
const accountId = await getAccountIdForRequest(req);
12
const account = await getAccountForRequest(req);
13
if (!hasPermission(account, "import")) {
14
res.status(500).send(`Permission denied`).end();
15
return;
16
}
13
17
const request = req.body as IImportRequest;
14
18
15
19
let anyKnownKey = false;
16
20
try {
17
const inventory = await getInventory(accountId);
21
const inventory = await getInventory(account._id);
18
22
importInventory(inventory, request.inventory);
19
23
if (inventory.isModified()) {
20
24
anyKnownKey = true;
@@ -25,7 +29,7 @@ export const importController: RequestHandler = async (req, res) => {
25
29
}
26
30
27
31
if ("LoadOutPresets" in request.inventory && request.inventory.LoadOutPresets) {
28
const loadout = await getLoadout(accountId);
32
const loadout = await getLoadout(account._id);
29
33
importLoadOutPresets(loadout, request.inventory.LoadOutPresets);
30
34
if (loadout.isModified()) {
31
35
anyKnownKey = true;
@@ -38,7 +42,7 @@ export const importController: RequestHandler = async (req, res) => {
38
42
"Apartment" in request.inventory ||
39
43
"TailorShop" in request.inventory
40
44
) {
41
const personalRooms = await getPersonalRooms(accountId);
45
const personalRooms = await getPersonalRooms(account._id);
42
46
importPersonalRooms(personalRooms, request.inventory);
43
47
if (personalRooms.isModified()) {
44
48
anyKnownKey = true;
@@ -1,5 +1,5 @@
1
1
import { getInventory } from "../../services/inventoryService.ts";
2
import { getAccountIdForRequest } from "../../services/loginService.ts";
2
import { getAccountForRequest, hasPermission } from "../../services/loginService.ts";
3
3
import { sendWsBroadcastEx, sendWsBroadcastTo } from "../../services/wsService.ts";
4
4
import {
5
5
accountCheatBooleans,
@@ -14,11 +14,14 @@ import { lockCheats } from "../../services/cheatsService.ts";
14
14
import { Inventory } from "../../models/inventoryModels/inventoryModel.ts";
15
15
16
16
export const setAccountCheatController: RequestHandler = async (req, res) => {
17
const account = await getAccountForRequest(req);
18
17
19
const payload = req.body as ISetAccountCheatRequest;
18
if (
19
accountCheatBooleans.indexOf(payload.key as TAccountCheatBooleanKey) == -1 &&
20
accountCheatNumbers.indexOf(payload.key as TAccountCheatNumberKey) == -1
21
) {
20
if (accountCheatBooleans.indexOf(payload.key as TAccountCheatBooleanKey) != -1) {
21
if (!hasPermission(account, `toggleCheat.${payload.key}`)) {
22
throw new Error(`Permission denied`);
23
}
24
} else if (accountCheatNumbers.indexOf(payload.key as TAccountCheatNumberKey) == -1) {
22
25
throw new Error(`unexpected setAccountCheat key: ${payload.key}`);
23
26
}
24
27
if (payload.value == undefined) {
@@ -26,11 +29,10 @@ export const setAccountCheatController: RequestHandler = async (req, res) => {
26
29
return;
27
30
}
28
31
29
const accountId = await getAccountIdForRequest(req);
30
32
const meta = payload.value ? lockCheats[payload.key] : undefined;
31
33
32
34
if (meta) {
33
const inventory = await getInventory(accountId, `${payload.key} ${meta.projection}`);
35
const inventory = await getInventory(account._id, `${payload.key} ${meta.projection}`);
34
36
inventory[payload.key] = payload.value as never;
35
37
if (!meta.isInventoryInIdealState(inventory)) {
36
38
res.send("retroactivable");
@@ -39,7 +41,7 @@ export const setAccountCheatController: RequestHandler = async (req, res) => {
39
41
} else {
40
42
await Inventory.updateOne(
41
43
{
42
accountOwnerId: accountId
44
accountOwnerId: account._id
43
45
},
44
46
{
45
47
[payload.key]: payload.value
@@ -60,9 +62,9 @@ export const setAccountCheatController: RequestHandler = async (req, res) => {
60
62
"skipAllPopups"
61
63
].indexOf(payload.key) != -1
62
64
) {
63
sendWsBroadcastTo(accountId, { update_inventory: true, sync_inventory: true });
65
sendWsBroadcastTo(account._id.toString(), { update_inventory: true, sync_inventory: true });
64
66
} else {
65
sendWsBroadcastEx({ update_inventory: true }, accountId, parseInt(String(req.query.wsid)));
67
sendWsBroadcastEx({ update_inventory: true }, account._id.toString(), parseInt(String(req.query.wsid)));
66
68
}
67
69
};
68
70
@@ -248,6 +248,18 @@ export const getReflexiveAddress = (request: Request): { myAddress: string; myUr
248
248
return { myAddress, myUrlBase };
249
249
};
250
250
251
export const configIdToIndexable = (id: string): [Record<string, boolean | string | number | undefined>, string] => {
252
let obj = config as unknown as Record<string, never>;
253
const arr = id.split(".");
254
while (arr.length > 1) {
255
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
256
obj[arr[0]] ??= {} as never;
257
obj = obj[arr[0]];
258
arr.splice(0, 1);
259
}
260
return [obj, arr[0]];
261
};
262
251
263
export interface IWebServerParams {
252
264
address: string;
253
265
httpPort: number;
@@ -6,7 +6,7 @@ import type { Document, Types } from "mongoose";
6
6
import { Loadout, type TLoadoutDatabaseDocument } from "../models/inventoryModels/loadoutModel.ts";
7
7
import { PersonalRooms } from "../models/personalRoomsModel.ts";
8
8
import type { Request } from "express";
9
import { config } from "./configService.ts";
9
import { config, configIdToIndexable } from "./configService.ts";
10
10
import { createStats } from "./statsService.ts";
11
11
import { crc32 } from "node:zlib";
12
12
import crypto from "node:crypto";
@@ -135,7 +135,36 @@ export const getAccountIdForRequest = async (req: Request): Promise<string> => {
135
135
};
136
136
137
137
export const isAdministrator = (account: Pick<TAccountDocument, "DisplayName">): boolean => {
138
return config.administratorNames?.indexOf(account.DisplayName) != -1;
138
return (config.administratorNames?.indexOf(account.DisplayName) ?? -1) != -1;
139
};
140
141
export const hasPermission = (account: Pick<TAccountDocument, "DisplayName">, perm: string): boolean => {
142
if (!isAdministrator(account)) {
143
{
144
const [obj, idx] = configIdToIndexable(`webui.nonAdminPermissions.${perm}`);
145
if (typeof obj[idx] == "boolean") {
146
return obj[idx];
147
}
148
}
149
150
const arr = perm.split(".");
151
arr.pop();
152
while (arr.length > 1) {
153
const [obj, idx] = configIdToIndexable(`webui.nonAdminPermissions.${arr.join(".")}.*`);
154
if (typeof obj[idx] == "boolean") {
155
return obj[idx];
156
}
157
arr.pop();
158
}
159
160
{
161
const [obj, idx] = configIdToIndexable(`webui.nonAdminPermissions.*`);
162
if (typeof obj[idx] == "boolean") {
163
return obj[idx];
164
}
165
}
166
}
167
return true;
139
168
};
140
169
141
170
export const getOriginalPlatform = (account: TAccountDocument): number => {
@@ -8,6 +8,7 @@ import {
8
8
createNonce,
9
9
getAccountForQuery,
10
10
getUsernameFromEmail,
11
hasPermission,
11
12
isAdministrator,
12
13
isCorrectPassword
13
14
} from "./loginService.ts";
@@ -72,6 +73,7 @@ interface IWsMsgFromClient {
72
73
password: string;
73
74
possessing?: string;
74
75
isRegister: boolean;
76
allPermissions: string[];
75
77
};
76
78
auth_game?:
77
79
| {
@@ -84,6 +86,7 @@ interface IWsMsgFromClient {
84
86
};
85
87
logout?: boolean;
86
88
sync_inventory?: boolean;
89
allPermissions?: string[];
87
90
}
88
91
89
92
export interface IWsMsgToClientCommon {
@@ -102,6 +105,7 @@ export interface IWsMsgToClientWebui extends IWsMsgToClientCommon {
102
105
DisplayName: string;
103
106
Nonce: number;
104
107
};
108
permissions?: string[];
105
109
auth_fail?: "bad login" | "bad register" | "admin only" | "registered but admin only";
106
110
nonce_updated?: boolean;
107
111
update_inventory?: boolean;
@@ -176,7 +180,10 @@ const wsOnConnect = (ws: WebSocket, req: http.IncomingMessage): void => {
176
180
DisplayName: accessedAccount.DisplayName,
177
181
Nonce: account.Nonce
178
182
},
179
have_game_ws: haveGameWs(accessedAccount.id)
183
have_game_ws: haveGameWs(accessedAccount.id),
184
permissions: data.auth.allPermissions.filter(perm =>
185
hasPermission(accessedAccount, perm)
186
)
180
187
} satisfies IWsMsgToClient)
181
188
);
182
189
} else {
@@ -233,6 +240,17 @@ const wsOnConnect = (ws: WebSocket, req: http.IncomingMessage): void => {
233
240
sendWsBroadcastToGame(accountId, { sync_inventory: true });
234
241
}
235
242
}
243
if (data.allPermissions) {
244
const accountId = (ws as IWsCustomData).accountId;
245
if (accountId && !(ws as IWsCustomData).isGame) {
246
const account = (await Account.findById(accountId))!;
247
ws.send(
248
JSON.stringify({
249
permissions: data.allPermissions.filter(perm => hasPermission(account, perm))
250
} satisfies IWsMsgToClient)
251
);
252
}
253
}
236
254
} catch (e) {
237
255
logError(e as Error, `processing websocket message`);
238
256
}
@@ -113,7 +113,7 @@
113
113
<form class="card-body input-group" onsubmit="doAcquireCountItems('miscitems');return false;">
114
114
<input class="form-control" id="miscitems-count" type="number" value="1" />
115
115
<input class="form-control w-50" id="acquire-type-miscitems" list="datalist-miscitems" autocomplete="off" />
116
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
116
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
117
117
</form>
118
118
</div>
119
119
<div class="tab-pane" id="typeName-tab-content">
@@ -122,7 +122,7 @@
122
122
<div class="input-group">
123
123
<input class="form-control" id="typeName-count" type="number" value="1" />
124
124
<input class="form-control w-50" id="typeName-type" />
125
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
125
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
126
126
</div>
127
127
</form>
128
128
</div>
@@ -137,7 +137,7 @@
137
137
<p class="card-text" id="RegularCredits-owned"></p>
138
138
<form class="input-group" onsubmit="doAddCurrency('RegularCredits');return false;">
139
139
<input class="form-control" id="RegularCredits-delta" type="number" value="1000000" />
140
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
140
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addCredits"></button>
141
141
</form>
142
142
</div>
143
143
</div>
@@ -149,7 +149,7 @@
149
149
<p class="card-text" id="PremiumCredits-owned"></p>
150
150
<form class="input-group" onsubmit="doAddCurrency('PremiumCredits');return false;">
151
151
<input class="form-control" id="PremiumCredits-delta" type="number" value="100" />
152
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
152
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addPlatinum"></button>
153
153
</form>
154
154
</div>
155
155
</div>
@@ -161,7 +161,7 @@
161
161
<p class="card-text" id="FusionPoints-owned"></p>
162
162
<form class="input-group" onsubmit="doAddCurrency('FusionPoints');return false;">
163
163
<input class="form-control" id="FusionPoints-delta" type="number" value="1000" />
164
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
164
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addEndo"></button>
165
165
</form>
166
166
</div>
167
167
</div>
@@ -173,7 +173,7 @@
173
173
<p class="card-text" id="PrimeTokens-owned"></p>
174
174
<form class="input-group" onsubmit="doAddCurrency('PrimeTokens');return false;">
175
175
<input class="form-control" id="PrimeTokens-delta" type="number" value="1" />
176
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
176
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addRegalAya"></button>
177
177
</form>
178
178
</div>
179
179
</div>
@@ -186,7 +186,7 @@
186
186
<div class="card-body d-flex flex-column">
187
187
<form class="input-group mb-3" onsubmit="doAcquireEquipment('Suits');return false;">
188
188
<input class="form-control" id="acquire-type-Suits" list="datalist-Suits" autocomplete="off" />
189
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
189
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
190
190
</form>
191
191
<div class="overflow-auto">
192
192
<table class="table table-hover w-100">
@@ -202,7 +202,7 @@
202
202
<div class="card-body d-flex flex-column">
203
203
<form class="input-group mb-3" onsubmit="handleModularSelection('LongGuns');return false;">
204
204
<input class="form-control" id="acquire-type-LongGuns" list="datalist-LongGuns" autocomplete="off" />
205
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
205
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
206
206
</form>
207
207
<form class="input-group mb-3 d-none" id="modular-LongGuns">
208
208
<input class="form-control" id="acquire-type-LongGuns-GUN_BARREL" list="datalist-ModularParts-GUN_BARREL" autocomplete="off" />
@@ -225,7 +225,7 @@
225
225
<div class="card-body d-flex flex-column">
226
226
<form class="input-group mb-3" onsubmit="handleModularSelection('Pistols');return false;">
227
227
<input class="form-control" id="acquire-type-Pistols" list="datalist-Pistols" autocomplete="off" />
228
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
228
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
229
229
</form>
230
230
<form class="input-group mb-3 d-none" id="modular-Pistols">
231
231
<input class="form-control" id="acquire-type-Pistols-GUN_BARREL" list="datalist-ModularParts-GUN_BARREL" autocomplete="off" />
@@ -246,7 +246,7 @@
246
246
<div class="card-body d-flex flex-column">
247
247
<form class="input-group mb-3" onsubmit="handleModularSelection('Melee');return false;">
248
248
<input class="form-control" id="acquire-type-Melee" list="datalist-Melee" autocomplete="off" />
249
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
249
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
250
250
</form>
251
251
<form class="input-group mb-3 d-none" id="modular-Melee">
252
252
<input class="form-control" id="acquire-type-Melee-BLADE" list="datalist-ModularParts-BLADE" autocomplete="off" />
@@ -269,7 +269,7 @@
269
269
<div class="card-body d-flex flex-column">
270
270
<form class="input-group mb-3" onsubmit="doAcquireEquipment('SpaceSuits');return false;">
271
271
<input class="form-control" id="acquire-type-SpaceSuits" list="datalist-SpaceSuits" autocomplete="off" />
272
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
272
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
273
273
</form>
274
274
<div class="overflow-auto">
275
275
<table class="table table-hover w-100">
@@ -285,7 +285,7 @@
285
285
<div class="card-body d-flex flex-column">
286
286
<form class="input-group mb-3" onsubmit="doAcquireEquipment('SpaceGuns');return false;">
287
287
<input class="form-control" id="acquire-type-SpaceGuns" list="datalist-SpaceGuns" autocomplete="off" />
288
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
288
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
289
289
</form>
290
290
<div class="overflow-auto">
291
291
<table class="table table-hover w-100">
@@ -303,7 +303,7 @@
303
303
<div class="card-body d-flex flex-column">
304
304
<form class="input-group mb-3" onsubmit="doAcquireEquipment('SpaceMelee');return false;">
305
305
<input class="form-control" id="acquire-type-SpaceMelee" list="datalist-SpaceMelee" autocomplete="off" />
306
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
306
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
307
307
</form>
308
308
<div class="overflow-auto">
309
309
<table class="table table-hover w-100">
@@ -319,7 +319,7 @@
319
319
<div class="card-body d-flex flex-column">
320
320
<form class="input-group mb-3" onsubmit="doAcquireEquipment('MechSuits');return false;">
321
321
<input class="form-control" id="acquire-type-MechSuits" list="datalist-MechSuits" autocomplete="off" />
322
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
322
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
323
323
</form>
324
324
<div class="overflow-auto">
325
325
<table class="table table-hover w-100">
@@ -337,7 +337,7 @@
337
337
<div class="card-body d-flex flex-column">
338
338
<form class="input-group mb-3" onsubmit="doAcquireEquipment('Sentinels');return false;">
339
339
<input class="form-control" id="acquire-type-Sentinels" list="datalist-Sentinels" autocomplete="off" />
340
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
340
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
341
341
</form>
342
342
<div class="overflow-auto">
343
343
<table class="table table-hover w-100">
@@ -353,7 +353,7 @@
353
353
<div class="card-body d-flex flex-column">
354
354
<form class="input-group mb-3" onsubmit="handleModularSelection('MoaPets');return false;">
355
355
<input class="form-control" id="acquire-type-MoaPets" list="datalist-MoaPets" autocomplete="off" />
356
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
356
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
357
357
</form>
358
358
<form class="input-group mb-3 d-none" id="modular-MoaPets-Moa">
359
359
<input class="form-control" id="acquire-type-MoaPets-MOA_ENGINE" list="datalist-ModularParts-MOA_ENGINE" autocomplete="off" />
@@ -383,7 +383,7 @@
383
383
<div class="card-body d-flex flex-column">
384
384
<form class="input-group mb-3" onsubmit="handleModularSelection('KubrowPets');return false;">
385
385
<input class="form-control" id="acquire-type-KubrowPets" list="datalist-KubrowPets" autocomplete="off" />
386
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
386
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
387
387
</form>
388
388
<form class="input-group mb-3 d-none" id="modular-KubrowPets-Catbrow">
389
389
<input class="form-control" id="acquire-type-KubrowPets-CATBROW_ANTIGEN" list="datalist-ModularParts-CATBROW_ANTIGEN" autocomplete="off" />
@@ -407,7 +407,7 @@
407
407
<div class="card-body d-flex flex-column">
408
408
<form class="input-group mb-3" onsubmit="doAcquireEquipment('SentinelWeapons');return false;">
409
409
<input class="form-control" id="acquire-type-SentinelWeapons" list="datalist-SentinelWeapons" autocomplete="off" />
410
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
410
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
411
411
</form>
412
412
<div class="overflow-auto">
413
413
<table class="table table-hover w-100">
@@ -425,7 +425,7 @@
425
425
<div class="card-body d-flex flex-column">
426
426
<form class="input-group mb-3" onsubmit="handleModularSelection('OperatorAmps');return false;">
427
427
<input class="form-control" id="acquire-type-OperatorAmps" list="datalist-OperatorAmps" autocomplete="off" />
428
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
428
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
429
429
</form>
430
430
<form class="input-group mb-3 d-none" id="modular-OperatorAmps">
431
431
<input class="form-control" id="acquire-type-OperatorAmps-AMP_OCULUS" list="datalist-ModularParts-AMP_OCULUS" autocomplete="off" />
@@ -449,7 +449,7 @@
449
449
<input class="form-control" id="acquire-type-Hoverboards-HB_ENGINE" list="datalist-ModularParts-HB_ENGINE" autocomplete="off" />
450
450
<input class="form-control" id="acquire-type-Hoverboards-HB_FRONT" list="datalist-ModularParts-HB_FRONT" autocomplete="off" />
451
451
<input class="form-control" id="acquire-type-Hoverboards-HB_JET" list="datalist-ModularParts-HB_JET" autocomplete="off" />
452
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
452
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
453
453
</form>
454
454
<div class="overflow-auto">
455
455
<table class="table table-hover w-100">
@@ -467,7 +467,7 @@
467
467
<div class="card-body d-flex flex-column">
468
468
<form class="input-group mb-3" onsubmit="doAcquireEquipment('QuestKeys');return false;">
469
469
<input class="form-control" id="acquire-type-QuestKeys" list="datalist-QuestKeys" autocomplete="off" />
470
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
470
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
471
471
</form>
472
472
<div class="overflow-auto">
473
473
<table class="table table-hover w-100">
@@ -483,7 +483,7 @@
483
483
<div class="card-body d-flex flex-column">
484
484
<form class="input-group mb-3" onsubmit="doAcquireEvolution();return false;">
485
485
<input class="form-control" id="acquire-type-EvolutionProgress" list="datalist-EvolutionProgress" autocomplete="off" />
486
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
486
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
487
487
</form>
488
488
<div class="overflow-auto">
489
489
<table class="table table-hover w-100">
@@ -501,7 +501,7 @@
501
501
<div class="card-body d-flex flex-column">
502
502
<form class="input-group mb-3" onsubmit="doAcquireBooster();return false;">
503
503
<input class="form-control" id="acquire-type-Boosters" list="datalist-Boosters" autocomplete="off" />
504
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
504
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
505
505
</form>
506
506
<div class="overflow-auto">
507
507
<table class="table table-hover w-100">
@@ -517,7 +517,7 @@
517
517
<div class="card-body d-flex flex-column">
518
518
<form class="input-group mb-3" onsubmit="doAcquireEquipment('FlavourItems');return false;">
519
519
<input class="form-control" id="acquire-type-FlavourItems" list="datalist-FlavourItems" autocomplete="off" />
520
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
520
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
521
521
</form>
522
522
<div class="overflow-auto">
523
523
<table class="table table-hover w-100">
@@ -536,7 +536,7 @@
536
536
<form class="input-group mb-3" onsubmit="doAcquireCountItems('ShipDecorations');return false;">
537
537
<input class="form-control" id="ShipDecorations-count" type="number" value="1" />
538
538
<input class="form-control w-50" id="acquire-type-ShipDecorations" list="datalist-ShipDecorations" autocomplete="off" />
539
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
539
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
540
540
</form>
541
541
<div class="overflow-auto">
542
542
<table class="table table-hover w-100">
@@ -552,7 +552,7 @@
552
552
<div class="card-body d-flex flex-column">
553
553
<form class="input-group mb-3" onsubmit="doAcquireEquipment('WeaponSkins');return false;">
554
554
<input class="form-control" id="acquire-type-WeaponSkins" list="datalist-WeaponSkins" autocomplete="off" />
555
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
555
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
556
556
</form>
557
557
<div class="overflow-auto">
558
558
<table class="table table-hover w-100">
@@ -588,7 +588,7 @@
588
588
<p class="card-text" id="VaultRegularCredits-owned"></p>
589
589
<form id="vaultRegularCredits-form" class="input-group d-none" onsubmit="doAddCurrency('VaultRegularCredits');return false;">
590
590
<input class="form-control" id="VaultRegularCredits-delta" type="number" value="1000000" />
591
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
591
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
592
592
</form>
593
593
</div>
594
594
</div>
@@ -600,7 +600,7 @@
600
600
<p class="card-text" id="VaultPremiumCredits-owned"></p>
601
601
<form id="vaultPremiumCredits-form" class="input-group d-none" onsubmit="doAddCurrency('VaultPremiumCredits');return false;">
602
602
<input class="form-control" id="VaultPremiumCredits-delta" type="number" value="100" />
603
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
603
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
604
604
</form>
605
605
</div>
606
606
</div>
@@ -613,7 +613,7 @@
613
613
<div class="card-body d-flex flex-column">
614
614
<form id="techProjects-form" class="input-group mb-3 d-none" onsubmit="addGuildTechProject();return false;">
615
615
<input class="form-control" id="acquire-type-TechProjects" list="datalist-TechProjects" autocomplete="off" />
616
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
616
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
617
617
</form>
618
618
<div class="overflow-auto">
619
619
<table class="table table-hover w-100">
@@ -629,7 +629,7 @@
629
629
<div class="card-body d-flex flex-column">
630
630
<form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultDecoRecipes');return false;">
631
631
<input class="form-control" id="acquire-type-VaultDecoRecipes" list="datalist-VaultDecoRecipes" autocomplete="off" />
632
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
632
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
633
633
</form>
634
634
<div class="overflow-auto">
635
635
<table class="table table-hover w-100">
@@ -648,7 +648,7 @@
648
648
<form id="vaultMiscItems-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultMiscItems');return false;">
649
649
<input class="form-control" id="VaultMiscItems-count" type="number" value="1" />
650
650
<input class="form-control w-50" id="acquire-type-VaultMiscItems" list="datalist-VaultMiscItems" autocomplete="off" />
651
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
651
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
652
652
</form>
653
653
<div class="overflow-auto">
654
654
<table class="table table-hover w-100">
@@ -665,7 +665,7 @@
665
665
<form id="vaultShipDecorations-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultShipDecorations');return false;">
666
666
<input class="form-control" id="VaultShipDecorations-count" type="number" value="1" />
667
667
<input class="form-control w-50" id="acquire-type-VaultShipDecorations" list="datalist-ShipDecorations" autocomplete="off" />
668
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
668
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
669
669
</form>
670
670
<div class="overflow-auto">
671
671
<table class="table table-hover w-100">
@@ -704,27 +704,27 @@
704
704
<h5 class="card-header" data-loc="guildView_cheats"></h5>
705
705
<div class="card-body" id="guild-cheats">
706
706
<div class="form-check">
707
<input class="form-check-input" type="checkbox" id="noDojoRoomBuildStage" />
707
<input class="form-check-input" type="checkbox" id="noDojoRoomBuildStage" data-enabling-permission="toggleCheat.noDojoRoomBuildStage" />
708
708
<label class="form-check-label" for="noDojoRoomBuildStage" data-loc="cheats_noDojoRoomBuildStage"></label>
709
709
</div>
710
710
<div class="form-check">
711
<input class="form-check-input" type="checkbox" id="fastDojoRoomDestruction" />
711
<input class="form-check-input" type="checkbox" id="fastDojoRoomDestruction" data-enabling-permission="toggleCheat.fastDojoRoomDestruction" />
712
712
<label class="form-check-label" for="fastDojoRoomDestruction" data-loc="cheats_fastDojoRoomDestruction"></label>
713
713
</div>
714
714
<div class="form-check">
715
<input class="form-check-input" type="checkbox" id="noDojoDecoBuildStage" />
715
<input class="form-check-input" type="checkbox" id="noDojoDecoBuildStage" data-enabling-permission="toggleCheat.noDojoDecoBuildStage" />
716
716
<label class="form-check-label" for="noDojoDecoBuildStage" data-loc="cheats_noDojoDecoBuildStage"></label>
717
717
</div>
718
718
<div class="form-check">
719
<input class="form-check-input" type="checkbox" id="noDojoResearchCosts" />
719
<input class="form-check-input" type="checkbox" id="noDojoResearchCosts" data-enabling-permission="toggleCheat.noDojoResearchCosts" />
720
720
<label class="form-check-label" for="noDojoResearchCosts" data-loc="cheats_noDojoResearchCosts"></label>
721
721
</div>
722
722
<div class="form-check">
723
<input class="form-check-input" type="checkbox" id="noDojoResearchTime" />
723
<input class="form-check-input" type="checkbox" id="noDojoResearchTime" data-enabling-permission="toggleCheat.noDojoResearchTime" />
724
724
<label class="form-check-label" for="noDojoResearchTime" data-loc="cheats_noDojoResearchTime"></label>
725
725
</div>
726
726
<div class="form-check">
727
<input class="form-check-input" type="checkbox" id="fastClanAscension" />
727
<input class="form-check-input" type="checkbox" id="fastClanAscension" data-enabling-permission="toggleCheat.fastClanAscension" />
728
728
<label class="form-check-label" for="fastClanAscension" data-loc="cheats_fastClanAscension"></label>
729
729
</div>
730
730
</div>
@@ -754,7 +754,7 @@
754
754
<input type="number" id="archon-crystal-add-count" min="1" max="10000" value="1" class="form-control" style="max-width:100px" />
755
755
<span class="input-group-text">x</span>
756
756
<input class="form-control" list="datalist-archonCrystalUpgrades" autocomplete="off" />
757
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
757
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
758
758
</form>
759
759
<table class="table table-hover w-100">
760
760
<tbody id="crystals-list"></tbody>
@@ -884,7 +884,7 @@
884
884
<option value="PlayerMeleeWeaponRandomModRare">PlayerMeleeWeaponRandomModRare</option>
885
885
</select>
886
886
<textarea id="addriven-fingerprint" class="form-control mb-3" data-loc-placeholder="mods_fingerprint"></textarea>
887
<button class="btn btn-primary" style="margin-right: 5px" type="submit" data-loc="general_addButton"></button>
887
<button class="btn btn-primary" style="margin-right: 5px" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
888
888
<a href="riven-tool/" target="_blank" data-loc="mods_fingerprintHelp"></a>
889
889
</form>
890
890
</div>
@@ -904,8 +904,8 @@
904
904
<form class="input-group mb-3" onsubmit="doAcquireMod();return false;">
905
905
<input class="form-control" id="mod-count" type="number" value="1"/>
906
906
<input class="form-control w-50" id="mod-to-acquire" list="datalist-mods" autocomplete="off" />
907
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
908
<button class="btn btn-success" onclick="window.maxed=true" data-loc="mods_addMax"></button>
907
<button class="btn btn-primary" type="submit" data-loc="general_addButton" data-enabling-permission="addItems"></button>
908
<button class="btn btn-success" onclick="window.maxed=true" data-loc="mods_addMax" data-enabling-permission="addItems"></button>
909
909
</form>
910
910
<table class="table table-hover w-100">
911
911
<tbody id="mods-list"></tbody>
@@ -915,9 +915,9 @@
915
915
<div class="card">
916
916
<h5 class="card-header" data-loc="general_bulkActions"></h5>
917
917
<div class="card-body d-flex flex-wrap gap-2">
918
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_addMissingUnrankedMods"></button>
918
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_addMissingUnrankedMods" data-enabling-permission="addItems"></button>
919
919
<button class="btn btn-danger" onclick="doRemoveUnrankedMods();" data-loc="mods_removeUnranked"></button>
920
<button class="btn btn-primary" onclick="doAddMissingMaxRankMods();" data-loc="mods_addMissingMaxRankMods"></button>
920
<button class="btn btn-primary" onclick="doAddMissingMaxRankMods();" data-loc="mods_addMissingMaxRankMods" data-enabling-permission="addItems"></button>
921
921
</div>
922
922
</div>
923
923
</div>
@@ -930,179 +930,179 @@
930
930
<h5 class="card-header" data-loc="cheats_account"></h5>
931
931
<div class="card-body" id="account-cheats">
932
932
<div class="form-check">
933
<input class="form-check-input" type="checkbox" id="skipAllDialogue" />
933
<input class="form-check-input" type="checkbox" id="skipAllDialogue" data-enabling-permission="toggleCheat.skipAllDialogue" />
934
934
<label class="form-check-label" for="skipAllDialogue" data-loc="cheats_skipAllDialogue"></label>
935
935
</div>
936
936
<div class="form-check">
937
<input class="form-check-input" type="checkbox" id="skipAllPopups" />
937
<input class="form-check-input" type="checkbox" id="skipAllPopups" data-enabling-permission="toggleCheat.skipAllPopups" />
938
938
<label class="form-check-label" for="skipAllPopups" data-loc="cheats_skipAllPopups"></label>
939
939
</div>
940
940
<div class="form-check">
941
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" />
941
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" data-enabling-permission="toggleCheat.dontSubtractPurchaseCreditCost" />
942
942
<label class="form-check-label" for="dontSubtractPurchaseCreditCost" data-loc="cheats_dontSubtractPurchaseCreditCost"></label>
943
943
</div>
944
944
<div class="form-check">
945
<input class="form-check-input" type="checkbox" id="dontSubtractPurchasePlatinumCost" />
945
<input class="form-check-input" type="checkbox" id="dontSubtractPurchasePlatinumCost" data-enabling-permission="toggleCheat.dontSubtractPurchasePlatinumCost" />
946
946
<label class="form-check-label" for="dontSubtractPurchasePlatinumCost" data-loc="cheats_dontSubtractPurchasePlatinumCost"></label>
947
947
</div>
948
948
<div class="form-check">
949
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseItemCost" />
949
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseItemCost" data-enabling-permission="toggleCheat.dontSubtractPurchaseItemCost" />
950
950
<label class="form-check-label" for="dontSubtractPurchaseItemCost" data-loc="cheats_dontSubtractPurchaseItemCost"></label>
951
951
</div>
952
952
<div class="form-check">
953
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseStandingCost" />
953
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseStandingCost" data-enabling-permission="toggleCheat.dontSubtractPurchaseStandingCost" />
954
954
<label class="form-check-label" for="dontSubtractPurchaseStandingCost" data-loc="cheats_dontSubtractPurchaseStandingCost"></label>
955
955
</div>
956
956
<div class="form-check">
957
<input class="form-check-input" type="checkbox" id="dontSubtractKuvaForRivens" />
957
<input class="form-check-input" type="checkbox" id="dontSubtractKuvaForRivens" data-enabling-permission="toggleCheat.dontSubtractKuvaForRivens" />
958
958
<label class="form-check-label" for="dontSubtractKuvaForRivens" data-loc="cheats_dontSubtractKuvaForRivens"></label>
959
959
</div>
960
960
<div class="form-check">
961
<input class="form-check-input" type="checkbox" id="dontSubtractVoidTraces" />
961
<input class="form-check-input" type="checkbox" id="dontSubtractVoidTraces" data-enabling-permission="toggleCheat.dontSubtractVoidTraces" />
962
962
<label class="form-check-label" for="dontSubtractVoidTraces" data-loc="cheats_dontSubtractVoidTraces"></label>
963
963
</div>
964
964
<div class="form-check">
965
<input class="form-check-input" type="checkbox" id="dontSubtractConsumables" />
965
<input class="form-check-input" type="checkbox" id="dontSubtractConsumables" data-enabling-permission="toggleCheat.dontSubtractConsumables" />
966
966
<label class="form-check-label" for="dontSubtractConsumables" data-loc="cheats_dontSubtractConsumables"></label>
967
967
</div>
968
968
<div class="form-check">
969
<input class="form-check-input" type="checkbox" id="dontSubtractKeys" />
969
<input class="form-check-input" type="checkbox" id="dontSubtractKeys" data-enabling-permission="toggleCheat.dontSubtractKeys" />
970
970
<label class="form-check-label" for="dontSubtractKeys" data-loc="cheats_dontSubtractKeys"></label>
971
971
</div>
972
972
<div class="form-check">
973
<input class="form-check-input" type="checkbox" id="infiniteCredits" />
973
<input class="form-check-input" type="checkbox" id="infiniteCredits" data-enabling-permission="toggleCheat.infiniteCredits" />
974
974
<label class="form-check-label" for="infiniteCredits" data-loc="cheats_infiniteCredits"></label>
975
975
</div>
976
976
<div class="form-check">
977
<input class="form-check-input" type="checkbox" id="infinitePlatinum" />
977
<input class="form-check-input" type="checkbox" id="infinitePlatinum" data-enabling-permission="toggleCheat.infinitePlatinum" />
978
978
<label class="form-check-label" for="infinitePlatinum" data-loc="cheats_infinitePlatinum"></label>
979
979
</div>
980
980
<div class="form-check">
981
<input class="form-check-input" type="checkbox" id="infiniteEndo" />
981
<input class="form-check-input" type="checkbox" id="infiniteEndo" data-enabling-permission="toggleCheat.infiniteEndo" />
982
982
<label class="form-check-label" for="infiniteEndo" data-loc="cheats_infiniteEndo"></label>
983
983
</div>
984
984
<div class="form-check">
985
<input class="form-check-input" type="checkbox" id="infiniteRegalAya" />
985
<input class="form-check-input" type="checkbox" id="infiniteRegalAya" data-enabling-permission="toggleCheat.infiniteRegalAya" />
986
986
<label class="form-check-label" for="infiniteRegalAya" data-loc="cheats_infiniteRegalAya"></label>
987
987
</div>
988
988
<div class="form-check">
989
<input class="form-check-input" type="checkbox" id="infiniteTrades" />
989
<input class="form-check-input" type="checkbox" id="infiniteTrades" data-enabling-permission="toggleCheat.infiniteTrades" />
990
990
<label class="form-check-label" for="infiniteTrades" data-loc="cheats_infiniteTrades"></label>
991
991
</div>
992
992
<div class="form-check">
993
<input class="form-check-input" type="checkbox" id="infiniteGifts" />
993
<input class="form-check-input" type="checkbox" id="infiniteGifts" data-enabling-permission="toggleCheat.infiniteGifts" />
994
994
<label class="form-check-label" for="infiniteGifts" data-loc="cheats_infiniteGifts"></label>
995
995
</div>
996
996
<div class="form-check">
997
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
997
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" data-enabling-permission="toggleCheat.infiniteHelminthMaterials" />
998
998
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
999
999
</div>
1000
1000
<div class="form-check">
1001
<input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" />
1001
<input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" data-enabling-permission="toggleCheat.universalPolarityEverywhere" />
1002
1002
<label class="form-check-label" for="universalPolarityEverywhere" data-loc="cheats_universalPolarityEverywhere"></label>
1003
1003
</div>
1004
1004
<div class="form-check">
1005
<input class="form-check-input" type="checkbox" id="unlockDoubleCapacityPotatoesEverywhere" />
1005
<input class="form-check-input" type="checkbox" id="unlockDoubleCapacityPotatoesEverywhere" data-enabling-permission="toggleCheat.unlockDoubleCapacityPotatoesEverywhere" />
1006
1006
<label class="form-check-label" for="unlockDoubleCapacityPotatoesEverywhere" data-loc="cheats_unlockDoubleCapacityPotatoesEverywhere"></label>
1007
1007
</div>
1008
1008
<div class="form-check">
1009
<input class="form-check-input" type="checkbox" id="unlockExilusEverywhere" />
1009
<input class="form-check-input" type="checkbox" id="unlockExilusEverywhere" data-enabling-permission="toggleCheat.unlockExilusEverywhere" />
1010
1010
<label class="form-check-label" for="unlockExilusEverywhere" data-loc="cheats_unlockExilusEverywhere"></label>
1011
1011
</div>
1012
1012
<div class="form-check">
1013
<input class="form-check-input" type="checkbox" id="unlockArcanesEverywhere" />
1013
<input class="form-check-input" type="checkbox" id="unlockArcanesEverywhere" data-enabling-permission="toggleCheat.unlockArcanesEverywhere" />
1014
1014
<label class="form-check-label" for="unlockArcanesEverywhere" data-loc="cheats_unlockArcanesEverywhere"></label>
1015
1015
</div>
1016
1016
<div class="form-check">
1017
<input class="form-check-input" type="checkbox" id="alertsRepeatable" />
1017
<input class="form-check-input" type="checkbox" id="alertsRepeatable" data-enabling-permission="toggleCheat.alertsRepeatable" />
1018
1018
<label class="form-check-label" for="alertsRepeatable" data-loc="cheats_alertsRepeatable"></label>
1019
1019
</div>
1020
1020
<div class="form-check">
1021
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
1021
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" data-enabling-permission="toggleCheat.syndicateMissionsRepeatable" />
1022
1022
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>
1023
1023
</div>
1024
1024
<div class="form-check">
1025
<input class="form-check-input" type="checkbox" id="instantFinishRivenChallenge" />
1025
<input class="form-check-input" type="checkbox" id="instantFinishRivenChallenge" data-enabling-permission="toggleCheat.instantFinishRivenChallenge" />
1026
1026
<label class="form-check-label" for="instantFinishRivenChallenge" data-loc="cheats_instantFinishRivenChallenge"></label>
1027
1027
</div>
1028
1028
<div class="form-check">
1029
<input class="form-check-input" type="checkbox" id="noDailyStandingLimits" />
1029
<input class="form-check-input" type="checkbox" id="noDailyStandingLimits" data-enabling-permission="toggleCheat.noDailyStandingLimits" />
1030
1030
<label class="form-check-label" for="noDailyStandingLimits" data-loc="cheats_noDailyStandingLimits"></label>
1031
1031
</div>
1032
1032
<div class="form-check">
1033
<input class="form-check-input" type="checkbox" id="noDailyFocusLimit" />
1033
<input class="form-check-input" type="checkbox" id="noDailyFocusLimit" data-enabling-permission="toggleCheat.noDailyFocusLimit" />
1034
1034
<label class="form-check-label" for="noDailyFocusLimit" data-loc="cheats_noDailyFocusLimit"></label>
1035
1035
</div>
1036
1036
<div class="form-check">
1037
<input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" />
1037
<input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" data-enabling-permission="toggleCheat.noArgonCrystalDecay" />
1038
1038
<label class="form-check-label" for="noArgonCrystalDecay" data-loc="cheats_noArgonCrystalDecay"></label>
1039
1039
</div>
1040
1040
<div class="form-check">
1041
<input class="form-check-input" type="checkbox" id="noMasteryRankUpCooldown" />
1041
<input class="form-check-input" type="checkbox" id="noMasteryRankUpCooldown" data-enabling-permission="toggleCheat.noMasteryRankUpCooldown" />
1042
1042
<label class="form-check-label" for="noMasteryRankUpCooldown" data-loc="cheats_noMasteryRankUpCooldown"></label>
1043
1043
</div>
1044
1044
<div class="form-check">
1045
<input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
1045
<input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" data-enabling-permission="toggleCheat.noVendorPurchaseLimits" />
1046
1046
<label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
1047
1047
</div>
1048
1048
<div class="form-check">
1049
<input class="form-check-input" type="checkbox" id="noNodeEntryFees" />
1049
<input class="form-check-input" type="checkbox" id="noNodeEntryFees" data-enabling-permission="toggleCheat.noNodeEntryFees" />
1050
1050
<label class="form-check-label" for="noNodeEntryFees" data-loc="cheats_noNodeEntryFees"></label>
1051
1051
</div>
1052
1052
<div class="form-check">
1053
<input class="form-check-input" type="checkbox" id="noDeathMarks" />
1053
<input class="form-check-input" type="checkbox" id="noDeathMarks" data-enabling-permission="toggleCheat.noDeathMarks" />
1054
1054
<label class="form-check-label" for="noDeathMarks" data-loc="cheats_noDeathMarks"></label>
1055
1055
</div>
1056
1056
<div class="form-check">
1057
<input class="form-check-input" type="checkbox" id="noNemesis" />
1057
<input class="form-check-input" type="checkbox" id="noNemesis" data-enabling-permission="toggleCheat.noNemesis" />
1058
1058
<label class="form-check-label" for="noNemesis" data-loc="cheats_noNemesis"></label>
1059
1059
</div>
1060
1060
<div class="form-check">
1061
<input class="form-check-input" type="checkbox" id="noKimCooldowns" />
1061
<input class="form-check-input" type="checkbox" id="noKimCooldowns" data-enabling-permission="toggleCheat.noKimCooldowns" />
1062
1062
<label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
1063
1063
</div>
1064
1064
<div class="form-check">
1065
<input class="form-check-input" type="checkbox" id="noBlessingCooldown" />
1065
<input class="form-check-input" type="checkbox" id="noBlessingCooldown" data-enabling-permission="toggleCheat.noBlessingCooldown" />
1066
1066
<label class="form-check-label" for="noBlessingCooldown" data-loc="cheats_noBlessingCooldown"></label>
1067
1067
</div>
1068
1068
<div class="form-check">
1069
<input class="form-check-input" type="checkbox" id="noResourceExtractorDronesDamage" />
1069
<input class="form-check-input" type="checkbox" id="noResourceExtractorDronesDamage" data-enabling-permission="toggleCheat.noResourceExtractorDronesDamage" />
1070
1070
<label class="form-check-label" for="noResourceExtractorDronesDamage" data-loc="cheats_noResourceExtractorDronesDamage"></label>
1071
1071
</div>
1072
1072
<div class="form-check">
1073
<input class="form-check-input" type="checkbox" id="instantResourceExtractorDrones" />
1073
<input class="form-check-input" type="checkbox" id="instantResourceExtractorDrones" data-enabling-permission="toggleCheat.instantResourceExtractorDrones" />
1074
1074
<label class="form-check-label" for="instantResourceExtractorDrones" data-loc="cheats_instantResourceExtractorDrones"></label>
1075
1075
</div>
1076
1076
<div class="form-check">
1077
<input class="form-check-input" type="checkbox" id="claimingBlueprintRefundsIngredients" />
1077
<input class="form-check-input" type="checkbox" id="claimingBlueprintRefundsIngredients" data-enabling-permission="toggleCheat.claimingBlueprintRefundsIngredients" />
1078
1078
<label class="form-check-label" for="claimingBlueprintRefundsIngredients" data-loc="cheats_claimingBlueprintRefundsIngredients"></label>
1079
1079
</div>
1080
1080
<div class="form-check">
1081
<input class="form-check-input" type="checkbox" id="missionsCanGiveAllRelics" />
1081
<input class="form-check-input" type="checkbox" id="missionsCanGiveAllRelics" data-enabling-permission="toggleCheat.missionsCanGiveAllRelics" />
1082
1082
<label class="form-check-label" for="missionsCanGiveAllRelics" data-loc="cheats_missionsCanGiveAllRelics"></label>
1083
1083
</div>
1084
1084
<div class="form-check">
1085
<input class="form-check-input" type="checkbox" id="exceptionalRelicsAlwaysGiveBronzeReward" />
1085
<input class="form-check-input" type="checkbox" id="exceptionalRelicsAlwaysGiveBronzeReward" data-enabling-permission="toggleCheat.exceptionalRelicsAlwaysGiveBronzeReward" />
1086
1086
<label class="form-check-label" for="exceptionalRelicsAlwaysGiveBronzeReward" data-loc="cheats_exceptionalRelicsAlwaysGiveBronzeReward"></label>
1087
1087
</div>
1088
1088
<div class="form-check">
1089
<input class="form-check-input" type="checkbox" id="flawlessRelicsAlwaysGiveSilverReward" />
1089
<input class="form-check-input" type="checkbox" id="flawlessRelicsAlwaysGiveSilverReward" data-enabling-permission="toggleCheat.flawlessRelicsAlwaysGiveSilverReward" />
1090
1090
<label class="form-check-label" for="flawlessRelicsAlwaysGiveSilverReward" data-loc="cheats_flawlessRelicsAlwaysGiveSilverReward"></label>
1091
1091
</div>
1092
1092
<div class="form-check">
1093
<input class="form-check-input" type="checkbox" id="radiantRelicsAlwaysGiveGoldReward" />
1093
<input class="form-check-input" type="checkbox" id="radiantRelicsAlwaysGiveGoldReward" data-enabling-permission="toggleCheat.radiantRelicsAlwaysGiveGoldReward" />
1094
1094
<label class="form-check-label" for="radiantRelicsAlwaysGiveGoldReward" data-loc="cheats_radiantRelicsAlwaysGiveGoldReward"></label>
1095
1095
</div>
1096
1096
<div class="form-check">
1097
<input class="form-check-input" type="checkbox" id="disableDailyTribute" />
1097
<input class="form-check-input" type="checkbox" id="disableDailyTribute" data-enabling-permission="toggleCheat.disableDailyTribute" />
1098
1098
<label class="form-check-label" for="disableDailyTribute" data-loc="cheats_disableDailyTribute"></label>
1099
1099
</div>
1100
1100
<div class="form-check">
1101
<input class="form-check-input" type="checkbox" id="incrementDailyTributeBy50" />
1101
<input class="form-check-input" type="checkbox" id="incrementDailyTributeBy50" data-enabling-permission="toggleCheat.incrementDailyTributeBy50" />
1102
1102
<label class="form-check-label" for="incrementDailyTributeBy50" data-loc="cheats_incrementDailyTributeBy50"></label>
1103
1103
</div>
1104
1104
<div class="form-check">
1105
<input class="form-check-input" type="checkbox" id="finishInvasionsInOneMission" />
1105
<input class="form-check-input" type="checkbox" id="finishInvasionsInOneMission" data-enabling-permission="toggleCheat.finishInvasionsInOneMission" />
1106
1106
<label class="form-check-label" for="finishInvasionsInOneMission" data-loc="cheats_finishInvasionsInOneMission"></label>
1107
1107
</div>
1108
1108
<form class="form-group mt-2" onsubmit="doChangeSupportedSyndicate(); return false;">
@@ -1699,7 +1699,7 @@
1699
1699
<span data-loc="import_importNote2"></span>
1700
1700
</p>
1701
1701
<textarea class="form-control" id="import-inventory" style="height: calc(100vh - 300px)"></textarea>
1702
<button class="btn btn-primary mt-3" onclick="doImport();" data-loc="import_submit"></button>
1702
<button class="btn btn-primary mt-3" onclick="doImport();" data-loc="import_submit" data-enabling-permission="import"></button>
1703
1703
<p class="mt-3 mb-1" data-loc="import_samples"></p>
1704
1704
<ul>
1705
1705
<li><a href="#" onclick="event.preventDefault();setImportSample('maxFocus');" data-loc="import_samples_maxFocus"></a></li>
@@ -8,6 +8,14 @@
8
8
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
9
9
/* eslint-disable @typescript-eslint/explicit-function-return-type */
10
10
11
const allPermissions = [];
12
document.querySelectorAll("[data-enabling-permission]").forEach(elm => {
13
const perm = elm.getAttribute("data-enabling-permission");
14
if (allPermissions.indexOf(perm) == -1) {
15
allPermissions.push(perm);
16
}
17
});
18
11
19
let auth_pending = false,
12
20
ws_is_open = false,
13
21
wsid = 0,
@@ -21,7 +29,8 @@ const sendAuth = isRegister => {
21
29
email: localStorage.getItem("email").toLowerCase(),
22
30
password: wp.encSync(localStorage.getItem("password")),
23
31
possessing: localStorage.getItem("possessing"),
24
isRegister
32
isRegister,
33
allPermissions
25
34
}
26
35
})
27
36
);
@@ -85,6 +94,15 @@ function openWebSocket() {
85
94
refreshServerConfig();
86
95
}
87
96
}
97
if ("permissions" in msg) {
98
for (const perm of allPermissions) {
99
const granted = msg.permissions.indexOf(perm) != -1;
100
//console.log(`Permission ${perm} was ${granted ? 'granted' : 'denied'}`);
101
document.querySelectorAll(`[data-enabling-permission='${perm}']`).forEach(elm => {
102
elm.disabled = !granted;
103
});
104
}
105
}
88
106
if ("auth_fail" in msg) {
89
107
auth_pending = false;
90
108
if (localStorage.getItem("possessing")) {
@@ -148,6 +166,7 @@ function refreshServerConfig() {
148
166
if (single.getCurrentPath() == "/webui/cheats" || single.getCurrentPath() == "/webui/admin") {
149
167
single.loadRoute(single.getCurrentPath());
150
168
}
169
ws.send(JSON.stringify({ allPermissions }));
151
170
}
152
171
153
172
function doAccountSwitch(to_route) {