@amxts/core 0.1.0 → 0.2.0
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/README.md +18 -23
- package/README.ru.md +19 -22
- package/as/amxts.d.ts +63 -3
- package/as/constants.ts +684 -116
- package/as/entities.ts +1905 -1364
- package/as/events.ts +1694 -905
- package/as/facade.ts +1240 -220
- package/as/fetch.ts +1519 -0
- package/as/flags.ts +159 -145
- package/as/hlds.ts +1071 -0
- package/as/hooks.ts +5226 -5379
- package/as/kit.ts +15 -5
- package/as/lib/check.ts +1 -1
- package/as/natives.ts +2658 -2499
- package/as/remote.ts +39 -15
- package/as/tsconfig.json +6 -2
- package/as/vector.ts +12 -9
- package/includes/order.txt +22 -29
- package/includes/sources.json +0 -8
- package/node_modules/assemblyscript/std/assembly/index.d.ts +20 -11
- package/package.json +29 -7
- package/runtime/deps/assemblyscript/dist/asc.js +86 -16
- package/runtime/deps/assemblyscript/dist/assemblyscript.js +29 -29
- package/runtime/licenses/MPL-2.0.txt +373 -0
- package/runtime/licenses/README.md +5 -1
- package/runtime/licenses/curl-COPYING +22 -0
- package/runtime/licenses/libssh2-COPYING +43 -0
- package/runtime/licenses/mbedTLS-LICENSE +553 -0
- package/runtime/natives.txt +108 -105
- package/runtime/patches/assemblyscript-0.28.20-amxts.patch +752 -296
- package/runtime/patches/wamr-2.4.5-amxts.patch +148 -0
- package/scripts/apply-docs.ts +2 -2
- package/scripts/auto-imports.ts +2 -2
- package/scripts/build-identity.ts +115 -0
- package/scripts/build-wasm.ts +101 -50
- package/scripts/check.ts +17 -3
- package/scripts/client-messages.ts +246 -0
- package/scripts/compile-pool.ts +128 -0
- package/scripts/compile-worker.ts +23 -0
- package/scripts/compile.ts +156 -59
- package/scripts/docker-server.ts +13 -3
- package/scripts/docs/as/amxts.ts +86 -0
- package/scripts/docs/as/facade.ts +688 -188
- package/scripts/docs/as/fetch.ts +805 -0
- package/scripts/docs/entities.ts +43 -144
- package/scripts/docs/events.ts +15 -26
- package/scripts/docs/game.ts +68 -22
- package/scripts/docs/messages.ts +330 -16
- package/scripts/editor-api.ts +101 -0
- package/scripts/hlds-events.ts +370 -0
- package/scripts/includes.ts +12 -10
- package/scripts/player-fields.ts +16 -15
- package/scripts/prebuilt.ts +65 -23
- package/scripts/prepare.ts +39 -28
- package/scripts/project.ts +120 -20
- package/scripts/reapi-events.ts +98 -0
- package/scripts/shared-modules.ts +85 -23
- package/scripts/source-map.ts +242 -0
- package/scripts/system.ts +1 -1
- package/scripts/typed-commands.ts +263 -0
- package/scripts/typed-configs.ts +23 -12
- package/scripts/ui.ts +3 -1
- package/scripts/upgrade-menus.ts +274 -0
- package/scripts/upgrade-names.ts +384 -0
- package/scripts/upgrade.ts +830 -0
- package/src/cli-api.mjs +37 -4
- package/src/system.mjs +74 -3
- package/src/testing/compile.ts +8 -5
- package/src/testing/natives.ts +199 -5
- package/src/testing/network.ts +531 -0
- package/src/testing/server.ts +565 -47
- package/src/testing/tables.ts +25 -0
- package/as/modules/http.ts +0 -184
- package/scripts/docs/as/modules/http.ts +0 -66
package/src/testing/tables.ts
CHANGED
|
@@ -48,6 +48,30 @@ export interface Tables {
|
|
|
48
48
|
stringFields: Set<number>;
|
|
49
49
|
/** Members read with an element index: m_rgpPlayerItems. */
|
|
50
50
|
arrayFields: Set<number>;
|
|
51
|
+
/** An entvar by its offset in entvars_t, as the module's ent_get takes it: its constant, and a vector's component. */
|
|
52
|
+
entvarAt: Map<number, { field: number; component: number }>;
|
|
53
|
+
/** A member by its class and name in the gamedata, as member_slot takes it ("CBasePlayer::m_iAccount"): its constant. */
|
|
54
|
+
memberNamed: Map<string, number>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The entvars by their offset (a vector's components each) and the members by
|
|
59
|
+
* their gamedata name, as the module reads them: the lists as/entities.ts
|
|
60
|
+
* keeps beside its member table.
|
|
61
|
+
*/
|
|
62
|
+
function fieldPlaces(constants: Map<string, number>, entities: string) {
|
|
63
|
+
const entvarAt = new Map<number, { field: number; component: number }>();
|
|
64
|
+
for (const [, name, offset, vector] of entities.matchAll(/^\/\/ (var_\w+) (\d+)( vector)?$/gm)) {
|
|
65
|
+
const field = constants.get(name);
|
|
66
|
+
if (field === undefined) continue;
|
|
67
|
+
for (let component = 0; component < (vector ? 3 : 1); component++) entvarAt.set(Number(offset) + component * 4, { field, component });
|
|
68
|
+
}
|
|
69
|
+
const memberNamed = new Map<string, number>();
|
|
70
|
+
for (const [, className, name, reapi] of entities.matchAll(/^\t"(\w+)", "(\w+)", \/\/ (\w+)$/gm)) {
|
|
71
|
+
const field = constants.get(reapi);
|
|
72
|
+
if (field !== undefined) memberNamed.set(`${className}::${name}`, field);
|
|
73
|
+
}
|
|
74
|
+
return { entvarAt, memberNamed };
|
|
51
75
|
}
|
|
52
76
|
|
|
53
77
|
let cached: Tables | null = null;
|
|
@@ -126,6 +150,7 @@ export function tables(): Tables {
|
|
|
126
150
|
vectorFields: fieldsOf(kind => (kind & 3) === 2),
|
|
127
151
|
stringFields: fieldsOf(kind => (kind & 3) === 3),
|
|
128
152
|
arrayFields: fieldsOf(kind => (kind & 4) !== 0),
|
|
153
|
+
...fieldPlaces(constants, generated('entities.ts')),
|
|
129
154
|
};
|
|
130
155
|
|
|
131
156
|
return cached;
|
package/as/modules/http.ts
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// fetch() over the easy_http module.
|
|
2
|
-
//
|
|
3
|
-
// An extension, not the core: easy_http is a third-party AMX Mod X module
|
|
4
|
-
// (github.com/Next21Team/AmxxEasyHttp), so a plugin imports this file itself -
|
|
5
|
-
// `import { fetch } from "~/modules/http"` - and a server without the module
|
|
6
|
-
// gets one clear line in the log instead of a missing-native error.
|
|
7
|
-
//
|
|
8
|
-
// const response = await fetch("https://example.com/");
|
|
9
|
-
// if (response.ok) console.log(response.text);
|
|
10
|
-
//
|
|
11
|
-
// fetch("https://example.com/")
|
|
12
|
-
// .then((response) => console.log(`${response.status}: ${response.text}`))
|
|
13
|
-
// .catch((error) => console.log(error.message));
|
|
14
|
-
//
|
|
15
|
-
// A real Promise (as/promise.ts): awaited in an async function, or given
|
|
16
|
-
// .then and .catch. `signal` cancels the request, as the Fetch standard's does.
|
|
17
|
-
import { CellBuffer, WideHandler } from "~/facade";
|
|
18
|
-
import {
|
|
19
|
-
LibraryExists, ezhttp_cancel_request, ezhttp_create_options, ezhttp_delete, ezhttp_get,
|
|
20
|
-
ezhttp_get_downloaded_bytes, ezhttp_get_error_code, ezhttp_get_error_message, ezhttp_get_http_code,
|
|
21
|
-
ezhttp_option_set_body, ezhttp_option_set_header, ezhttp_patch, ezhttp_post, ezhttp_put
|
|
22
|
-
} from "~/natives";
|
|
23
|
-
import { LibType_Library } from "~/constants";
|
|
24
|
-
|
|
25
|
-
/** A request's options besides its URL. Every field is optional. */
|
|
26
|
-
export class RequestInit {
|
|
27
|
-
/** The request's method, one of `"GET"` (the default), `"POST"`, `"PUT"`, `"PATCH"`, `"DELETE"`. */
|
|
28
|
-
method?: string = "GET";
|
|
29
|
-
/** The text sent with the request, such as JSON for a POST; empty by default. */
|
|
30
|
-
body?: string = "";
|
|
31
|
-
/** The request's headers, as pairs: `[["Content-Type", "application/json"]]`. */
|
|
32
|
-
headers?: string[][] = [];
|
|
33
|
-
/**
|
|
34
|
-
* A signal that cancels the request; the promise then rejects with an
|
|
35
|
-
* Error named `"AbortError"`. In an async command handler or player event,
|
|
36
|
-
* the player leaving cancels the request too.
|
|
37
|
-
*/
|
|
38
|
-
signal?: AbortSignal | null = null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** The server's response to a request. */
|
|
42
|
-
export class Response {
|
|
43
|
-
constructor(
|
|
44
|
-
/** The response's HTTP status: `200`, `404`, ... */
|
|
45
|
-
public status: number,
|
|
46
|
-
/** The response's body, as text. */
|
|
47
|
-
public text: string
|
|
48
|
-
) {}
|
|
49
|
-
|
|
50
|
-
/** `true` for a 2xx status. */
|
|
51
|
-
get ok() {
|
|
52
|
-
return this.status >= 200 && this.status < 300;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Sends a request. The promise is fulfilled with the response on a later
|
|
58
|
-
* frame, and rejected when there is none - no connection, a bad URL, a
|
|
59
|
-
* timeout, no `easy_http`, or an abort. An HTTP error such as `404` is a
|
|
60
|
-
* response, as in fetch: check `response.ok`.
|
|
61
|
-
*
|
|
62
|
-
* Pawn: `ezhttp_get`, `ezhttp_post` (easy_http)
|
|
63
|
-
*/
|
|
64
|
-
export function fetch(url: string, init: RequestInit = {}): Promise<Response> {
|
|
65
|
-
const promise = __co_promise<Response>();
|
|
66
|
-
|
|
67
|
-
if (LibraryExists("easy_http", LibType_Library) == 0) {
|
|
68
|
-
console.error(`fetch(${url}): the easy_http module is not loaded - add it to modules.ini`);
|
|
69
|
-
__co_reject(promise, new Error("easy_http is not loaded"));
|
|
70
|
-
return promise;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const request = new Request(promise);
|
|
74
|
-
const guard = new __AbortGuard(request, init.signal as AbortSignal | null);
|
|
75
|
-
request.guard = guard;
|
|
76
|
-
const aborted = guard.aborted;
|
|
77
|
-
if (aborted) {
|
|
78
|
-
guard.release();
|
|
79
|
-
__co_reject(promise, aborted);
|
|
80
|
-
return promise;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let options = 0;
|
|
84
|
-
// An optional field reads as `T | undefined`, though a field the literal
|
|
85
|
-
// leaves out holds its default: `||` makes the type plain.
|
|
86
|
-
const body = init.body || "";
|
|
87
|
-
const headers = init.headers || [];
|
|
88
|
-
|
|
89
|
-
if (body.length > 0 || headers.length > 0) {
|
|
90
|
-
options = ezhttp_create_options();
|
|
91
|
-
if (body.length > 0) ezhttp_option_set_body(options, body);
|
|
92
|
-
for (const pair of headers) ezhttp_option_set_header(options, pair[0], pair[1]);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const callback = completeName();
|
|
96
|
-
if (callback.length == 0) {
|
|
97
|
-
guard.release();
|
|
98
|
-
__co_reject(promise, new Error("no callback slot left"));
|
|
99
|
-
return promise;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const method = init.method || "GET";
|
|
103
|
-
let id = 0;
|
|
104
|
-
|
|
105
|
-
if (method == "GET") id = ezhttp_get(url, callback, options);
|
|
106
|
-
else if (method == "POST") id = ezhttp_post(url, callback, options);
|
|
107
|
-
else if (method == "PUT") id = ezhttp_put(url, callback, options);
|
|
108
|
-
else if (method == "PATCH") id = ezhttp_patch(url, callback, options);
|
|
109
|
-
else if (method == "DELETE") id = ezhttp_delete(url, callback, options);
|
|
110
|
-
else {
|
|
111
|
-
guard.release();
|
|
112
|
-
__co_reject(promise, new Error(`easy_http has no ${method}`));
|
|
113
|
-
return promise;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
request.id = id;
|
|
117
|
-
pending.set(id, request);
|
|
118
|
-
return promise;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** A request under way, and what cancels it when a signal aborts. */
|
|
122
|
-
class Request extends __AbortWatch {
|
|
123
|
-
id = 0;
|
|
124
|
-
guard: __AbortGuard | null = null;
|
|
125
|
-
|
|
126
|
-
constructor(public promise: Promise<Response>) {
|
|
127
|
-
super();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
run(reason: Error): void {
|
|
131
|
-
if (!pending.has(this.id)) return;
|
|
132
|
-
pending.delete(this.id);
|
|
133
|
-
ezhttp_cancel_request(this.id);
|
|
134
|
-
this.settled();
|
|
135
|
-
__co_reject(this.promise, reason);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
settled(): void {
|
|
139
|
-
const guard = this.guard;
|
|
140
|
-
if (guard) guard.release();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const pending = new Map<number, Request>();
|
|
145
|
-
|
|
146
|
-
// Must match SLOT_REUSED in runtime/src/module.cpp, and SHAPE_WIDE the facade's.
|
|
147
|
-
const REUSED = 0x10000;
|
|
148
|
-
const SHAPE_WIDE = 1;
|
|
149
|
-
|
|
150
|
-
// @ts-ignore: decorator
|
|
151
|
-
@external("env", "ezhttp_get_data") declare function _getData(request: i32, buffer: i32, length: i32): i32;
|
|
152
|
-
// @ts-ignore: decorator
|
|
153
|
-
@external("env", "slot") declare function _slot(fn: i32, shape: i32, key: string, fallback: i32): i32;
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* The host public that calls onComplete. Not publicFor: that one answers ""
|
|
157
|
-
* after a hot reload so a registration is not made twice, and every request
|
|
158
|
-
* names its callback afresh, so the name is needed every time.
|
|
159
|
-
*/
|
|
160
|
-
function completeName() {
|
|
161
|
-
const handler: WideHandler = onComplete;
|
|
162
|
-
const slot = _slot(handler.index, SHAPE_WIDE, "ezhttp:complete", 0);
|
|
163
|
-
if (slot < 0) return "";
|
|
164
|
-
return `__amxts_cb${slot & (REUSED - 1)}`;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// easy_http calls on_complete(request_id) once, on the frame the answer came in.
|
|
168
|
-
function onComplete(id: number, b: number, c: number, d: number) {
|
|
169
|
-
if (!pending.has(id)) return;
|
|
170
|
-
const request = pending.get(id);
|
|
171
|
-
pending.delete(id);
|
|
172
|
-
request.settled();
|
|
173
|
-
|
|
174
|
-
if (ezhttp_get_error_code(id) != 0) {
|
|
175
|
-
__co_reject(request.promise, new Error(ezhttp_get_error_message(id)));
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// The whole body, however long: the generated ezhttp_get_data stops at 255.
|
|
180
|
-
const size = ezhttp_get_downloaded_bytes(id) + 1;
|
|
181
|
-
const cells = new CellBuffer(size);
|
|
182
|
-
_getData(<i32>id, <i32>cells.address, <i32>size - 1);
|
|
183
|
-
__co_resolve(request.promise, new Response(ezhttp_get_http_code(id), cells.text()));
|
|
184
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// The tooltips of as/modules/http.ts, in both languages: scripts/apply-docs.ts writes the
|
|
2
|
-
// one AMXTS_DOCS_LANG picks into the JSDoc above each element.
|
|
3
|
-
export default {
|
|
4
|
-
'RequestInit': {
|
|
5
|
-
en: `A request's options besides its URL. Every field is optional.`,
|
|
6
|
-
ru: `Настройки запроса помимо URL. Все поля необязательны.`,
|
|
7
|
-
},
|
|
8
|
-
'RequestInit.method': {
|
|
9
|
-
en: `The request's method, one of \`"GET"\` (the default), \`"POST"\`, \`"PUT"\`, \`"PATCH"\`, \`"DELETE"\`.`,
|
|
10
|
-
ru: `Метод запроса, одно из \`"GET"\` (по умолчанию), \`"POST"\`, \`"PUT"\`, \`"PATCH"\`, \`"DELETE"\`.`,
|
|
11
|
-
},
|
|
12
|
-
'RequestInit.body': {
|
|
13
|
-
en: `The text sent with the request, such as JSON for a POST; empty by default.`,
|
|
14
|
-
ru: `Текст, который уходит с запросом, например JSON для POST; по умолчанию пустой.`,
|
|
15
|
-
},
|
|
16
|
-
'RequestInit.headers': {
|
|
17
|
-
en: `The request's headers, as pairs: \`[["Content-Type", "application/json"]]\`.`,
|
|
18
|
-
ru: `Заголовки запроса, парами: \`[["Content-Type", "application/json"]]\`.`,
|
|
19
|
-
},
|
|
20
|
-
'RequestInit.signal': {
|
|
21
|
-
en: `
|
|
22
|
-
A signal that cancels the request; the promise then rejects with an
|
|
23
|
-
Error named \`"AbortError"\`. In an async command handler or player event,
|
|
24
|
-
the player leaving cancels the request too.
|
|
25
|
-
`,
|
|
26
|
-
ru: `
|
|
27
|
-
Сигнал, который отменяет запрос; промис тогда отклоняется с Error с
|
|
28
|
-
именем \`"AbortError"\`. В async-обработчике команды или события игрока
|
|
29
|
-
запрос отменяется и тогда, когда игрок выходит.
|
|
30
|
-
`,
|
|
31
|
-
},
|
|
32
|
-
'Response': {
|
|
33
|
-
en: `The server's response to a request.`,
|
|
34
|
-
ru: `Ответ сервера на запрос.`,
|
|
35
|
-
},
|
|
36
|
-
'Response.status': {
|
|
37
|
-
en: `The response's HTTP status: \`200\`, \`404\`, ...`,
|
|
38
|
-
ru: `HTTP-статус ответа: \`200\`, \`404\`, ...`,
|
|
39
|
-
},
|
|
40
|
-
'Response.text': {
|
|
41
|
-
en: `The response's body, as text.`,
|
|
42
|
-
ru: `Тело ответа, текстом.`,
|
|
43
|
-
},
|
|
44
|
-
'Response.ok': {
|
|
45
|
-
en: `\`true\` for a 2xx status.`,
|
|
46
|
-
ru: `\`true\` при статусе 2xx.`,
|
|
47
|
-
},
|
|
48
|
-
'fetch': {
|
|
49
|
-
en: `
|
|
50
|
-
Sends a request. The promise is fulfilled with the response on a later
|
|
51
|
-
frame, and rejected when there is none - no connection, a bad URL, a
|
|
52
|
-
timeout, no \`easy_http\`, or an abort. An HTTP error such as \`404\` is a
|
|
53
|
-
response, as in fetch: check \`response.ok\`.
|
|
54
|
-
|
|
55
|
-
Pawn: \`ezhttp_get\`, \`ezhttp_post\` (easy_http)
|
|
56
|
-
`,
|
|
57
|
-
ru: `
|
|
58
|
-
Отправляет запрос. Промис выполняется с ответом в одном из следующих
|
|
59
|
-
кадров и отклоняется, если ответа нет: нет соединения, плохой URL,
|
|
60
|
-
таймаут, нет \`easy_http\` или отмена. HTTP-ошибка вроде \`404\` — это ответ,
|
|
61
|
-
как и в fetch: проверяйте \`response.ok\`.
|
|
62
|
-
|
|
63
|
-
Pawn: \`ezhttp_get\`, \`ezhttp_post\` (easy_http)
|
|
64
|
-
`,
|
|
65
|
-
},
|
|
66
|
-
};
|