@libertytools/libertyjs 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +32 -27
- package/readme.md +363 -358
- package/src/index.js +308 -308
package/src/index.js
CHANGED
|
@@ -1,309 +1,309 @@
|
|
|
1
|
-
export default class LibertyJS {
|
|
2
|
-
#SERVER_KEY;
|
|
3
|
-
#PRIVATE_SERVER_API;
|
|
4
|
-
#useWebhook;
|
|
5
|
-
#WEBHOOK_URL;
|
|
6
|
-
#WEBHOOK_TOKEN;
|
|
7
|
-
#rateLimits;
|
|
8
|
-
#resStatus;
|
|
9
|
-
|
|
10
|
-
constructor({
|
|
11
|
-
SERVER_KEY,
|
|
12
|
-
PRIVATE_SERVER_API = "https://api.policeroleplay.community/v2/",
|
|
13
|
-
WEBHOOK_URL,
|
|
14
|
-
WEBHOOK_TOKEN
|
|
15
|
-
} = {}) {
|
|
16
|
-
if (!SERVER_KEY) {
|
|
17
|
-
throw new Error("[LibertyJS]: SERVER_KEY is required");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
this.#SERVER_KEY = SERVER_KEY;
|
|
21
|
-
this.#PRIVATE_SERVER_API = PRIVATE_SERVER_API;
|
|
22
|
-
|
|
23
|
-
if (WEBHOOK_URL && !WEBHOOK_TOKEN) {
|
|
24
|
-
throw new Error("[LibertyJS]: WEBHOOK_TOKEN is required if you are using a webhook");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.#useWebhook = Boolean(WEBHOOK_URL && WEBHOOK_TOKEN);
|
|
28
|
-
|
|
29
|
-
if (WEBHOOK_URL && WEBHOOK_TOKEN) {
|
|
30
|
-
this.#WEBHOOK_URL = WEBHOOK_URL;
|
|
31
|
-
this.#WEBHOOK_TOKEN = WEBHOOK_TOKEN;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this.#rateLimits = {
|
|
35
|
-
get: { limit: null, remaining: null, reset: null },
|
|
36
|
-
post: { limit: null, remaining: null, reset: null }
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
this.#resStatus = {
|
|
40
|
-
forbiddenErrors: 0
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
#wait(seconds) {
|
|
45
|
-
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async #fetchAPI(url, options = {}) {
|
|
49
|
-
if (!this.#SERVER_KEY) {
|
|
50
|
-
return {
|
|
51
|
-
error: "invalid_env",
|
|
52
|
-
message: "[LibertyJS]: SERVER_KEY was not provided in a .env file"
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (this.#resStatus.forbiddenErrors >= 2) {
|
|
57
|
-
return {
|
|
58
|
-
error: "forbidden",
|
|
59
|
-
message: "[LibertyJS]: Received a 403 error 2 times, suspending API calls as the server key may be invalid"
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const isPRC = url.startsWith("https://api.policeroleplay.community/");
|
|
64
|
-
const method = (options.method || "GET").toUpperCase();
|
|
65
|
-
|
|
66
|
-
const headers = { ...(options.headers || {}) };
|
|
67
|
-
|
|
68
|
-
let body = options.body;
|
|
69
|
-
if (method === "POST" && body !== undefined) {
|
|
70
|
-
headers["Content-Type"] = "application/json";
|
|
71
|
-
body = typeof body === "string" ? body : JSON.stringify(body);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (isPRC) {
|
|
75
|
-
headers["server-key"] = this.#SERVER_KEY;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const currentTime = Math.floor(Date.now() / 1000);
|
|
79
|
-
|
|
80
|
-
const handleRateLimit = async (rl) => {
|
|
81
|
-
if (rl.reset && rl.remaining === 0 && currentTime < rl.reset) {
|
|
82
|
-
const seconds = Math.max(0, rl.reset - currentTime);
|
|
83
|
-
console.log(`[LibertyJS]: Rate limited (${method}). Waiting ${seconds}s`);
|
|
84
|
-
await this.#wait(seconds);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
if (isPRC) {
|
|
89
|
-
if (method === "GET") await handleRateLimit(this.#rateLimits.get);
|
|
90
|
-
if (method === "POST") await handleRateLimit(this.#rateLimits.post);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const res = await fetch(url, {
|
|
94
|
-
...options,
|
|
95
|
-
method,
|
|
96
|
-
headers,
|
|
97
|
-
body
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
let data;
|
|
101
|
-
try {
|
|
102
|
-
data = await res.json();
|
|
103
|
-
} catch {
|
|
104
|
-
data = null;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (!res.ok) {
|
|
108
|
-
if (res.status === 403 && isPRC) {
|
|
109
|
-
this.#resStatus.forbiddenErrors++;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
error: "api-error",
|
|
114
|
-
message: `[LibertyJS]: Encountered an error while attempting to fetch ${url}`,
|
|
115
|
-
apiResponse: data
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (isPRC) {
|
|
120
|
-
const target = method === "GET"
|
|
121
|
-
? this.#rateLimits.get
|
|
122
|
-
: this.#rateLimits.post;
|
|
123
|
-
|
|
124
|
-
target.reset = Number(res.headers.get("X-RateLimit-Reset"));
|
|
125
|
-
target.limit = Number(res.headers.get("X-RateLimit-Limit"));
|
|
126
|
-
target.remaining = Number(res.headers.get("X-RateLimit-Remaining"));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return data;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async getPrivateServerAPI(options = [], includeInvalid = false) {
|
|
133
|
-
const valid = [
|
|
134
|
-
"Players",
|
|
135
|
-
"Staff",
|
|
136
|
-
"JoinLogs",
|
|
137
|
-
"Queue",
|
|
138
|
-
"KillLogs",
|
|
139
|
-
"CommandLogs",
|
|
140
|
-
"ModCalls",
|
|
141
|
-
"EmergencyCalls",
|
|
142
|
-
"Vehicles"
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
if (!Array.isArray(options)) {
|
|
146
|
-
console.error("[LibertyJS.getPrivateServerAPI]: Options must be an array");
|
|
147
|
-
return {
|
|
148
|
-
error: "invalid_input",
|
|
149
|
-
message: "[LibertyJS.getPrivateServerAPI]: Options must be an array"
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const params = [];
|
|
154
|
-
const invalidOptions = [];
|
|
155
|
-
|
|
156
|
-
for (const opt of options) {
|
|
157
|
-
if (valid.includes(opt)) {
|
|
158
|
-
params.push(`${opt}=true`);
|
|
159
|
-
} else {
|
|
160
|
-
console.log(`[LibertyJS]: Invalid option "${String(opt)}"`);
|
|
161
|
-
invalidOptions.push(opt);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const query = params.length ? `?${params.join("&")}` : "";
|
|
166
|
-
const url = this.#PRIVATE_SERVER_API + "server" + query;
|
|
167
|
-
|
|
168
|
-
if (!includeInvalid) {
|
|
169
|
-
return await this.#fetchAPI(url);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return {
|
|
173
|
-
data: await this.#fetchAPI(url),
|
|
174
|
-
invalidOptions
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async sendPrivateServerCommand(options = []) {
|
|
179
|
-
const url = this.#PRIVATE_SERVER_API + "server/command";
|
|
180
|
-
|
|
181
|
-
const valid = {
|
|
182
|
-
":wanted": ["Player"],
|
|
183
|
-
":time": ["Number"],
|
|
184
|
-
":stopfire": [],
|
|
185
|
-
":respawn": ["Player"],
|
|
186
|
-
":tp": ["Player", "Player"],
|
|
187
|
-
":startnearfire": ["String"],
|
|
188
|
-
":jail": ["Player"],
|
|
189
|
-
":pt": ["Number"],
|
|
190
|
-
":h": ["String"],
|
|
191
|
-
":m": ["String"],
|
|
192
|
-
":pm": ["Player", "String"],
|
|
193
|
-
":refresh": ["Player"],
|
|
194
|
-
":bring": ["Player"],
|
|
195
|
-
":heal": ["Player"],
|
|
196
|
-
":kick": ["Player", "String"],
|
|
197
|
-
":startfire": ["String"],
|
|
198
|
-
":unwanted": ["Player"],
|
|
199
|
-
":prty": ["Number"],
|
|
200
|
-
":stopdumpsterfire": [],
|
|
201
|
-
":helper": ["Player/UserId"],
|
|
202
|
-
":shutdown": [],
|
|
203
|
-
":weather": ["String"],
|
|
204
|
-
":unmod": ["Player/UserId"],
|
|
205
|
-
":unloadlayout": ["String"],
|
|
206
|
-
":unban": ["String"],
|
|
207
|
-
":mod": ["Player/UserId"],
|
|
208
|
-
":ban": ["Player/UserId"],
|
|
209
|
-
":unhelper": ["Player/UserId"],
|
|
210
|
-
":log": ["String"],
|
|
211
|
-
":kill": ["Player"],
|
|
212
|
-
":unadmin": ["Player/UserId"],
|
|
213
|
-
":admin": ["Player/UserId"],
|
|
214
|
-
":loadlayout": ["String"]
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
if (!Array.isArray(options)) {
|
|
218
|
-
console.error("[LibertyJS.sendPrivateServerCommand]: Options must be an array");
|
|
219
|
-
return {
|
|
220
|
-
error: "invalid_input",
|
|
221
|
-
message: "[LibertyJS.sendPrivateServerCommand]: Options must be an array"
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (options.length === 0) {
|
|
226
|
-
console.error("[LibertyJS.sendPrivateServerCommand]: Options must have at least one item");
|
|
227
|
-
return {
|
|
228
|
-
error: "invalid_input",
|
|
229
|
-
message: "[LibertyJS.sendPrivateServerCommand]: Options must have at least one item"
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const commands = [];
|
|
234
|
-
|
|
235
|
-
for (const cmd of options) {
|
|
236
|
-
if (!cmd.startsWith(":")) continue;
|
|
237
|
-
|
|
238
|
-
const parts = cmd.trim().split(" ");
|
|
239
|
-
const name = parts[0];
|
|
240
|
-
const args = parts.slice(1);
|
|
241
|
-
const schema = valid[name];
|
|
242
|
-
|
|
243
|
-
if (!schema) {
|
|
244
|
-
console.error(`[LibertyJS]: Unsupported command "${name}"`);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const validArgs =
|
|
249
|
-
(schema.at(-1) === "String" && args.length >= schema.length) ||
|
|
250
|
-
(schema.at(-1) !== "String" && args.length === schema.length);
|
|
251
|
-
|
|
252
|
-
if (validArgs) {
|
|
253
|
-
commands.push(cmd);
|
|
254
|
-
} else {
|
|
255
|
-
console.log(`[LibertyJS]: "${name}" requires ${schema.length}${schema.at(-1) === "String" ? "+" : ""} args`);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let successes = 0;
|
|
260
|
-
let failures = 0;
|
|
261
|
-
const failureReasons = [];
|
|
262
|
-
|
|
263
|
-
for (const command of commands) {
|
|
264
|
-
const res = await this.#fetchAPI(url, {
|
|
265
|
-
method: "POST",
|
|
266
|
-
body: command
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
if (!res?.error) {
|
|
270
|
-
successes++;
|
|
271
|
-
} else {
|
|
272
|
-
failures++;
|
|
273
|
-
failureReasons.push({
|
|
274
|
-
command,
|
|
275
|
-
apiResponse: res.apiResponse
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return { successes, failures, failureReasons };
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
webhook = {
|
|
284
|
-
status: async () => {
|
|
285
|
-
if (!this.#useWebhook) {
|
|
286
|
-
return {
|
|
287
|
-
error: "webhook_disabled",
|
|
288
|
-
message: "[LibertyJS.webhook.status]: Webhook is not configured"
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const url = `${this.#WEBHOOK_URL}health`;
|
|
293
|
-
|
|
294
|
-
return await this.#fetchAPI(url, { method: "GET" });
|
|
295
|
-
},
|
|
296
|
-
events: async () => {
|
|
297
|
-
if (!this.#useWebhook) {
|
|
298
|
-
return {
|
|
299
|
-
error: "webhook_disabled",
|
|
300
|
-
message: "[LibertyJS.webhook.events]: Webhook is not configured"
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const url = `${this.#WEBHOOK_URL}webhook/${this.#WEBHOOK_TOKEN}/events`;
|
|
305
|
-
|
|
306
|
-
return await this.#fetchAPI(url, { method: "GET" });
|
|
307
|
-
}
|
|
308
|
-
};
|
|
1
|
+
export default class LibertyJS {
|
|
2
|
+
#SERVER_KEY;
|
|
3
|
+
#PRIVATE_SERVER_API;
|
|
4
|
+
#useWebhook;
|
|
5
|
+
#WEBHOOK_URL;
|
|
6
|
+
#WEBHOOK_TOKEN;
|
|
7
|
+
#rateLimits;
|
|
8
|
+
#resStatus;
|
|
9
|
+
|
|
10
|
+
constructor({
|
|
11
|
+
SERVER_KEY,
|
|
12
|
+
PRIVATE_SERVER_API = "https://api.policeroleplay.community/v2/",
|
|
13
|
+
WEBHOOK_URL,
|
|
14
|
+
WEBHOOK_TOKEN
|
|
15
|
+
} = {}) {
|
|
16
|
+
if (!SERVER_KEY) {
|
|
17
|
+
throw new Error("[LibertyJS]: SERVER_KEY is required");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.#SERVER_KEY = SERVER_KEY;
|
|
21
|
+
this.#PRIVATE_SERVER_API = PRIVATE_SERVER_API;
|
|
22
|
+
|
|
23
|
+
if (WEBHOOK_URL && !WEBHOOK_TOKEN) {
|
|
24
|
+
throw new Error("[LibertyJS]: WEBHOOK_TOKEN is required if you are using a webhook");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.#useWebhook = Boolean(WEBHOOK_URL && WEBHOOK_TOKEN);
|
|
28
|
+
|
|
29
|
+
if (WEBHOOK_URL && WEBHOOK_TOKEN) {
|
|
30
|
+
this.#WEBHOOK_URL = WEBHOOK_URL;
|
|
31
|
+
this.#WEBHOOK_TOKEN = WEBHOOK_TOKEN;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.#rateLimits = {
|
|
35
|
+
get: { limit: null, remaining: null, reset: null },
|
|
36
|
+
post: { limit: null, remaining: null, reset: null }
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
this.#resStatus = {
|
|
40
|
+
forbiddenErrors: 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#wait(seconds) {
|
|
45
|
+
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async #fetchAPI(url, options = {}) {
|
|
49
|
+
if (!this.#SERVER_KEY) {
|
|
50
|
+
return {
|
|
51
|
+
error: "invalid_env",
|
|
52
|
+
message: "[LibertyJS]: SERVER_KEY was not provided in a .env file"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (this.#resStatus.forbiddenErrors >= 2) {
|
|
57
|
+
return {
|
|
58
|
+
error: "forbidden",
|
|
59
|
+
message: "[LibertyJS]: Received a 403 error 2 times, suspending API calls as the server key may be invalid"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const isPRC = url.startsWith("https://api.policeroleplay.community/");
|
|
64
|
+
const method = (options.method || "GET").toUpperCase();
|
|
65
|
+
|
|
66
|
+
const headers = { ...(options.headers || {}) };
|
|
67
|
+
|
|
68
|
+
let body = options.body;
|
|
69
|
+
if (method === "POST" && body !== undefined) {
|
|
70
|
+
headers["Content-Type"] = "application/json";
|
|
71
|
+
body = typeof body === "string" ? body : JSON.stringify(body);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isPRC) {
|
|
75
|
+
headers["server-key"] = this.#SERVER_KEY;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
79
|
+
|
|
80
|
+
const handleRateLimit = async (rl) => {
|
|
81
|
+
if (rl.reset && rl.remaining === 0 && currentTime < rl.reset) {
|
|
82
|
+
const seconds = Math.max(0, rl.reset - currentTime);
|
|
83
|
+
console.log(`[LibertyJS]: Rate limited (${method}). Waiting ${seconds}s`);
|
|
84
|
+
await this.#wait(seconds);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (isPRC) {
|
|
89
|
+
if (method === "GET") await handleRateLimit(this.#rateLimits.get);
|
|
90
|
+
if (method === "POST") await handleRateLimit(this.#rateLimits.post);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const res = await fetch(url, {
|
|
94
|
+
...options,
|
|
95
|
+
method,
|
|
96
|
+
headers,
|
|
97
|
+
body
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
let data;
|
|
101
|
+
try {
|
|
102
|
+
data = await res.json();
|
|
103
|
+
} catch {
|
|
104
|
+
data = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
if (res.status === 403 && isPRC) {
|
|
109
|
+
this.#resStatus.forbiddenErrors++;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
error: "api-error",
|
|
114
|
+
message: `[LibertyJS]: Encountered an error while attempting to fetch ${url}`,
|
|
115
|
+
apiResponse: data
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (isPRC) {
|
|
120
|
+
const target = method === "GET"
|
|
121
|
+
? this.#rateLimits.get
|
|
122
|
+
: this.#rateLimits.post;
|
|
123
|
+
|
|
124
|
+
target.reset = Number(res.headers.get("X-RateLimit-Reset"));
|
|
125
|
+
target.limit = Number(res.headers.get("X-RateLimit-Limit"));
|
|
126
|
+
target.remaining = Number(res.headers.get("X-RateLimit-Remaining"));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return data;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async getPrivateServerAPI(options = [], includeInvalid = false) {
|
|
133
|
+
const valid = [
|
|
134
|
+
"Players",
|
|
135
|
+
"Staff",
|
|
136
|
+
"JoinLogs",
|
|
137
|
+
"Queue",
|
|
138
|
+
"KillLogs",
|
|
139
|
+
"CommandLogs",
|
|
140
|
+
"ModCalls",
|
|
141
|
+
"EmergencyCalls",
|
|
142
|
+
"Vehicles"
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
if (!Array.isArray(options)) {
|
|
146
|
+
console.error("[LibertyJS.getPrivateServerAPI]: Options must be an array");
|
|
147
|
+
return {
|
|
148
|
+
error: "invalid_input",
|
|
149
|
+
message: "[LibertyJS.getPrivateServerAPI]: Options must be an array"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const params = [];
|
|
154
|
+
const invalidOptions = [];
|
|
155
|
+
|
|
156
|
+
for (const opt of options) {
|
|
157
|
+
if (valid.includes(opt)) {
|
|
158
|
+
params.push(`${opt}=true`);
|
|
159
|
+
} else {
|
|
160
|
+
console.log(`[LibertyJS]: Invalid option "${String(opt)}"`);
|
|
161
|
+
invalidOptions.push(opt);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const query = params.length ? `?${params.join("&")}` : "";
|
|
166
|
+
const url = this.#PRIVATE_SERVER_API + "server" + query;
|
|
167
|
+
|
|
168
|
+
if (!includeInvalid) {
|
|
169
|
+
return await this.#fetchAPI(url);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
data: await this.#fetchAPI(url),
|
|
174
|
+
invalidOptions
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async sendPrivateServerCommand(options = []) {
|
|
179
|
+
const url = this.#PRIVATE_SERVER_API + "server/command";
|
|
180
|
+
|
|
181
|
+
const valid = {
|
|
182
|
+
":wanted": ["Player"],
|
|
183
|
+
":time": ["Number"],
|
|
184
|
+
":stopfire": [],
|
|
185
|
+
":respawn": ["Player"],
|
|
186
|
+
":tp": ["Player", "Player"],
|
|
187
|
+
":startnearfire": ["String"],
|
|
188
|
+
":jail": ["Player"],
|
|
189
|
+
":pt": ["Number"],
|
|
190
|
+
":h": ["String"],
|
|
191
|
+
":m": ["String"],
|
|
192
|
+
":pm": ["Player", "String"],
|
|
193
|
+
":refresh": ["Player"],
|
|
194
|
+
":bring": ["Player"],
|
|
195
|
+
":heal": ["Player"],
|
|
196
|
+
":kick": ["Player", "String"],
|
|
197
|
+
":startfire": ["String"],
|
|
198
|
+
":unwanted": ["Player"],
|
|
199
|
+
":prty": ["Number"],
|
|
200
|
+
":stopdumpsterfire": [],
|
|
201
|
+
":helper": ["Player/UserId"],
|
|
202
|
+
":shutdown": [],
|
|
203
|
+
":weather": ["String"],
|
|
204
|
+
":unmod": ["Player/UserId"],
|
|
205
|
+
":unloadlayout": ["String"],
|
|
206
|
+
":unban": ["String"],
|
|
207
|
+
":mod": ["Player/UserId"],
|
|
208
|
+
":ban": ["Player/UserId"],
|
|
209
|
+
":unhelper": ["Player/UserId"],
|
|
210
|
+
":log": ["String"],
|
|
211
|
+
":kill": ["Player"],
|
|
212
|
+
":unadmin": ["Player/UserId"],
|
|
213
|
+
":admin": ["Player/UserId"],
|
|
214
|
+
":loadlayout": ["String"]
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (!Array.isArray(options)) {
|
|
218
|
+
console.error("[LibertyJS.sendPrivateServerCommand]: Options must be an array");
|
|
219
|
+
return {
|
|
220
|
+
error: "invalid_input",
|
|
221
|
+
message: "[LibertyJS.sendPrivateServerCommand]: Options must be an array"
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (options.length === 0) {
|
|
226
|
+
console.error("[LibertyJS.sendPrivateServerCommand]: Options must have at least one item");
|
|
227
|
+
return {
|
|
228
|
+
error: "invalid_input",
|
|
229
|
+
message: "[LibertyJS.sendPrivateServerCommand]: Options must have at least one item"
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const commands = [];
|
|
234
|
+
|
|
235
|
+
for (const cmd of options) {
|
|
236
|
+
if (!cmd.startsWith(":")) continue;
|
|
237
|
+
|
|
238
|
+
const parts = cmd.trim().split(" ");
|
|
239
|
+
const name = parts[0];
|
|
240
|
+
const args = parts.slice(1);
|
|
241
|
+
const schema = valid[name];
|
|
242
|
+
|
|
243
|
+
if (!schema) {
|
|
244
|
+
console.error(`[LibertyJS]: Unsupported command "${name}"`);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const validArgs =
|
|
249
|
+
(schema.at(-1) === "String" && args.length >= schema.length) ||
|
|
250
|
+
(schema.at(-1) !== "String" && args.length === schema.length);
|
|
251
|
+
|
|
252
|
+
if (validArgs) {
|
|
253
|
+
commands.push(cmd);
|
|
254
|
+
} else {
|
|
255
|
+
console.log(`[LibertyJS]: "${name}" requires ${schema.length}${schema.at(-1) === "String" ? "+" : ""} args`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let successes = 0;
|
|
260
|
+
let failures = 0;
|
|
261
|
+
const failureReasons = [];
|
|
262
|
+
|
|
263
|
+
for (const command of commands) {
|
|
264
|
+
const res = await this.#fetchAPI(url, {
|
|
265
|
+
method: "POST",
|
|
266
|
+
body: command
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
if (!res?.error) {
|
|
270
|
+
successes++;
|
|
271
|
+
} else {
|
|
272
|
+
failures++;
|
|
273
|
+
failureReasons.push({
|
|
274
|
+
command,
|
|
275
|
+
apiResponse: res.apiResponse
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return { successes, failures, failureReasons };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
webhook = {
|
|
284
|
+
status: async () => {
|
|
285
|
+
if (!this.#useWebhook) {
|
|
286
|
+
return {
|
|
287
|
+
error: "webhook_disabled",
|
|
288
|
+
message: "[LibertyJS.webhook.status]: Webhook is not configured"
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const url = `${this.#WEBHOOK_URL}health`;
|
|
293
|
+
|
|
294
|
+
return await this.#fetchAPI(url, { method: "GET" });
|
|
295
|
+
},
|
|
296
|
+
events: async () => {
|
|
297
|
+
if (!this.#useWebhook) {
|
|
298
|
+
return {
|
|
299
|
+
error: "webhook_disabled",
|
|
300
|
+
message: "[LibertyJS.webhook.events]: Webhook is not configured"
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const url = `${this.#WEBHOOK_URL}webhook/${this.#WEBHOOK_TOKEN}/events`;
|
|
305
|
+
|
|
306
|
+
return await this.#fetchAPI(url, { method: "GET" });
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
309
|
}
|