ddbot.js-0374 4.1.0 → 4.3.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 ADDED
@@ -0,0 +1,258 @@
1
+ # ddbot.js
2
+
3
+ Библиотека которая оборачивает teeworlds(npm i teeworlds) в более удобный (Для меня лично как минимум.) формат.
4
+
5
+ 0374flop MIT
6
+
7
+ ---
8
+ ## начало
9
+ установка
10
+ ```
11
+ npm i ddbot.js-0374
12
+ ```
13
+
14
+ експорт
15
+ ```ts
16
+ import * as ddbot from 'ddbot.js-0374';
17
+ ```
18
+ ```js
19
+ const ddbot = require('ddbot.js-0374');
20
+ ```
21
+
22
+ простейший пример
23
+ ```ts
24
+ import * as ddbot from '../lib/index.js';
25
+
26
+ const bot = new ddbot.Bot(/* identity, options, custom teeworlds */);
27
+ // if no identity is provided, it will be default 'nameless tee' with default skin
28
+
29
+ bot.on('connect', () => {
30
+ console.log('Connected to server!');
31
+ });
32
+
33
+ bot.on('disconnect', () => {
34
+ console.log('Disconnected from server!');
35
+ });
36
+
37
+ (async () => {
38
+ await bot.connect('45.141.57.22', 8303, 20000); // IP, port, timeout (IP is of ddnet server)
39
+ bot.bot_client?.game.Say('DDNet!'); // from teeworlds
40
+ setTimeout(async () => {
41
+ await bot.disconnect();
42
+ process.exit(0);
43
+ }, 5000); // 5 sec
44
+
45
+ process.on('SIGINT', async () => { // on Ctrl+C
46
+ await bot.disconnect();
47
+ process.exit(0);
48
+ });
49
+ })();
50
+ ```
51
+
52
+ ## Документация
53
+
54
+ ### Bot
55
+
56
+ ```ts
57
+ const bot = new ddbot.Bot(identity?, options?, customTeeworlds?);
58
+ ```
59
+
60
+ #### методы
61
+
62
+ **bot.connect(addr, port?, timeout?)** - подключится к серверу. возвращает `Promise<ConnectionInfo>`.
63
+
64
+ **bot.disconnect()** - отключится от сервера. возвращает `Promise<ConnectionInfo | null>`.
65
+
66
+ **bot.send_input(input)** - отправить инпут (движение, прицел, и тд).
67
+
68
+ **bot.change_identity(identity)** - сменить скин/имя/клан и тд.
69
+
70
+ **bot.destroy()** - полностью уничтожить бота, очищает все listeners.
71
+
72
+ #### геттеры
73
+
74
+ **bot.bot_client** - оригинальный клиент teeworlds. может быть `null` если не подключен. (Proxie)
75
+
76
+ **bot.bot_identity** - текущий identity бота.
77
+
78
+ **bot.OwnID** - clientId бота на сервере. `undefined` если не подключен.
79
+
80
+ #### события
81
+
82
+ **connect** - подключился. `(info: ConnectionInfo)`
83
+
84
+ **disconnect** - отключился. `(reason: string | null, info: ConnectionInfo)`
85
+
86
+ **error** - когда у бота ошибка `(...args: any[])`, (Почти не изпользуеться)
87
+
88
+ ...остальные события проксируються из [teeworlds](https://github.com/swarfeya/teeworlds-library-ts/)
89
+
90
+ ---
91
+ ### Модули
92
+
93
+ Модули это отдельные куски функционала которые можно подключить к боту.
94
+ ```ts
95
+ const chat = new ddbot.StandardModules.Chat(bot); // bot уже должен быть инициализирован! (не обязательно подключен)
96
+ chat.start();
97
+ ```
98
+
99
+ ---
100
+
101
+ #### Chat
102
+
103
+ > Слушает message, и дедублирует сообщения.
104
+ (из-за udp, они дублируються чтобы оно дошло, ведь там нет гарантии доставки.)
105
+
106
+ ```ts
107
+ const chat = new ddbot.StandardModules.Chat(bot);
108
+ chat.start(interval?, cooldown?);
109
+ ```
110
+
111
+ `interval` - как часто чиститься кеш дубликатов (ms, default: 1000)
112
+ `cooldown` - минимальная задержка между исходящими сообщениями (ms, default: 1000)
113
+
114
+ **chat.send(text, team?, priority?)** - добавить сообщение в очередь на отправку.
115
+
116
+ события:
117
+
118
+ **anychat** - любое сообщение `(msg, author, text, team, client_id)`
119
+
120
+ **chat** - сообщение от игрока `(msg, author, text, team, client_id)`
121
+
122
+ **systemchat** - системное сообщение `(msg, text)`
123
+
124
+ **queued** - сообщение добавлено в очередь `({ text, team, queueSize })`
125
+
126
+ **sent** - сообщение отправлено `({ text, team, queueSize })`
127
+
128
+ ---
129
+
130
+ #### PlayerList
131
+
132
+ > Просто сканирует всех игроков от client_id = 0, до 64.
133
+ (Зделано чтобы быстро получить весь список игроков и для отслеживания заходов/выходов игроков.)
134
+
135
+ ```ts
136
+ const playerlist = new ddbot.StandardModules.PlayerList(bot);
137
+ playerlist.start(maxclients?);
138
+ ```
139
+ ```ts
140
+ interface PlayerData {
141
+ client_id: number;
142
+ clientInfo: Types.SnapshotItemTypes.ClientInfo;
143
+ playerInfo: Types.SnapshotItemTypes.PlayerInfo;
144
+ character: Types.SnapshotItemTypes.Character | null;
145
+ DDNetCharacter: Types.SnapshotItemTypes.DDNetCharacter | null;
146
+ }
147
+ ```
148
+
149
+ `maxclients` - максимальное количество игроков (default: 64)
150
+
151
+ **playerlist.list** - список всех игроков `[client_id, PlayerData][]`
152
+
153
+ **playerlist.getPlayer(client_id)** - получить игрока по id. `PlayerData | null`
154
+
155
+ **playerlist.getPlayerCount()** - количество игроков онлайн
156
+
157
+ события:
158
+
159
+ **player_joined** - игрок зашел `({ client_id, name, playerData })`
160
+
161
+ **player_left** - игрок вышел `({ client_id, name, playerData })`
162
+
163
+ ---
164
+
165
+ #### Reconnect
166
+
167
+ > Автоматически переподключает бота при дисконнекте. Умно считает задержку в зависимости от причины. (причины добыты експерементально с оф севреров)
168
+ ```ts
169
+ const reconnect = new ddbot.StandardModules.Reconnect(bot);
170
+ reconnect.start(maxAttempts?, randomDelay?);
171
+ ```
172
+
173
+ `maxAttempts` - максимальное количество попыток реконнекта (-1 для бесконечного, default: -1)
174
+ `randomDelay` - добавлять рандомную задержку к базовой (default: true)
175
+
176
+ события:
177
+
178
+ **reconnecting** - начинает переподключаться `({ attempt, delay, reason, ConnectionInfo })`
179
+
180
+ **reconnected** - успешно переподключился `({ addr, port })`
181
+
182
+ **reconnect_failed** - не смог переподключиться `(reason)`
183
+
184
+ ---
185
+
186
+ #### Snap
187
+
188
+ > Слушает snapshot события и даёт удобные события поверх них. (зделаны не все)
189
+ ```ts
190
+ const snap = new ddbot.StandardModules.Snap(bot);
191
+ snap.start();
192
+ ```
193
+
194
+ **snap.isFrozen** - заморожен ли бот прямо сейчас
195
+
196
+ **Snap.angleshot(character)** - статичный метод, возвращает вектор прицела персонажа `{ x, y } | null`
197
+
198
+ события:
199
+
200
+ **hammerhitme** - кто-то ударил молотком по боту (или просто рядом, и пощитало не правильно) `(hit, client_id)`
201
+
202
+ **fire** - кто-то выстрелил рядом `(sound, client_id)`
203
+
204
+ **frozen** - бот заморозился
205
+
206
+ **unfrozen** - бот разморозился
207
+
208
+ ---
209
+
210
+ ### BaseModule
211
+
212
+ > Базовый класс для своих модулей.
213
+ ```ts
214
+ import { BaseModule } from 'ddbot.js-0374';
215
+
216
+ class MyModule extends BaseModule {
217
+ constructor(bot) {
218
+ super(bot, { moduleName: 'MyModule' });
219
+ }
220
+
221
+ _start() {
222
+ this.bot.on('connect', () => {
223
+ console.log('connected!');
224
+ });
225
+ }
226
+
227
+ _stop() {
228
+ // cleanup
229
+ }
230
+ }
231
+
232
+ const myModule = new MyModule(bot);
233
+ myModule.start();
234
+ ```
235
+
236
+ `moduleName` - имя модуля (для ошибок)
237
+ `offonDisconnect` - автоматически вызывать `destroy()` при дисконнекте (default: true)
238
+
239
+ **module.start(...args)** - запустить модуль, вызывает `_start(...args)`
240
+
241
+ **module.stop()** - остановить модуль, вызывает `_stop()`
242
+
243
+ **module.destroy()** - полностью уничтожить модуль, очищает все listeners
244
+
245
+ **module.isRunning** - запущен ли модуль
246
+
247
+ ---
248
+
249
+ ### DDUtils
250
+
251
+ **DDUtils.DefaultIdentity(name?)** - возвращает дефолтный identity `Identity`, если имени нет, то 'nameless tee'
252
+
253
+ **DDUtils.connectionInfo()** - возвращает дефолтный `ConnectionInfo`,
254
+ 'ConnectionInfo = {
255
+ addr: 'string', port: 8303
256
+ }'
257
+
258
+ **DDUtils.reconstructPlayerInput(char, ddnetChar?, tick?)** - реконструирует инпут игрока из snapshot. NOT FULL. `Types.SnapshotItemTypes.PlayerInput`
package/docs/test.js ADDED
@@ -0,0 +1,3 @@
1
+ const ddbot = require('../lib/index.js');
2
+
3
+ const bot = new ddbot.Bot();
package/docs/test.ts ADDED
@@ -0,0 +1,26 @@
1
+ import * as ddbot from '../lib/index.js';
2
+
3
+ const bot = new ddbot.Bot(/* identity, options, custom teeworlds */);
4
+ // if no identity is provided, it will be default 'nameless tee' with default skin
5
+
6
+ bot.on('connect', () => {
7
+ console.log('Connected to server!');
8
+ });
9
+
10
+ bot.on('disconnect', () => {
11
+ console.log('Disconnected from server!');
12
+ });
13
+
14
+ (async () => {
15
+ await bot.connect('45.141.57.22', 8303, 20000); // IP, port, timeout (IP is of ddnet server)
16
+ bot.bot_client?.game.Say('DDNet!'); // from teeworlds
17
+ setTimeout(async () => {
18
+ await bot.disconnect();
19
+ process.exit(0);
20
+ }, 5000); // 5 sec
21
+
22
+ process.on('SIGINT', async () => { // on Ctrl+C
23
+ await bot.disconnect();
24
+ process.exit(0);
25
+ });
26
+ })();
@@ -2,6 +2,7 @@ import { Client } from 'teeworlds';
2
2
  import { EventEmitter } from 'events';
3
3
  import * as Types from '../types.js';
4
4
  interface BotEvents {
5
+ error: (...args: any[]) => void;
5
6
  connect: (info: Types.ConnectionInfo) => void;
6
7
  disconnect: (reason: string | null, info: Types.ConnectionInfo) => void;
7
8
  broadcast: (message: string) => void;
@@ -16,6 +17,13 @@ interface BotEvents {
16
17
  kill: (kill: Types.SnapshotItemTypes.iKillMsg) => void;
17
18
  snapshot: (items: Types.DeltaItem[]) => void;
18
19
  map_change: (message: Types.SnapshotItemTypes.iMapChange) => void;
20
+ map_details: (message: {
21
+ map_name: string;
22
+ map_sha256: Buffer;
23
+ map_crc: number;
24
+ map_size: number;
25
+ map_url: string;
26
+ }) => void;
19
27
  motd: (message: string) => void;
20
28
  message: (message: Types.SnapshotItemTypes.iMessage) => void;
21
29
  teams: (teams: Array<number>) => void;
@@ -51,6 +59,7 @@ export declare class Bot extends EventEmitter {
51
59
  * @param CustomTeeworlds Custom teeworlds
52
60
  */
53
61
  constructor(identity?: Types.SnapshotItemTypes.Identity, options?: Types.SnapshotItemTypes.iOptions, CustomTeeworlds?: typeof import('teeworlds'));
62
+ private error;
54
63
  /**
55
64
  * Get bot identity
56
65
  */
package/lib/core/core.js CHANGED
@@ -1,10 +1,53 @@
1
1
  "use strict";
2
- import { Client } from 'teeworlds';
3
- import * as Teeworlds from 'teeworlds';
4
- import { EventEmitter } from 'events';
5
- import * as DDUtils from './ddutils.js';
6
- import * as Types from '../types.js';
7
- export class Bot extends EventEmitter {
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Bot = void 0;
37
+ const Teeworlds = __importStar(require("teeworlds"));
38
+ const events_1 = require("events");
39
+ function DefaultIdentity(name = 'nameless tee') {
40
+ return {
41
+ name: name,
42
+ clan: "",
43
+ skin: "default",
44
+ use_custom_color: 0,
45
+ color_body: 0,
46
+ color_feet: 0,
47
+ country: 0
48
+ };
49
+ }
50
+ class Bot extends events_1.EventEmitter {
8
51
  teeworlds;
9
52
  client = null;
10
53
  _clientProxy = null;
@@ -28,9 +71,11 @@ export class Bot extends EventEmitter {
28
71
  super();
29
72
  this.teeworlds = CustomTeeworlds;
30
73
  this.options = options;
31
- this.identity = DDUtils.IsValidIdentity(identity)
32
- ? identity
33
- : DDUtils.DefaultIdentity('nameless tee');
74
+ this.identity = identity ? identity : DefaultIdentity('nameless tee');
75
+ }
76
+ error(...err) {
77
+ //console.error(err);
78
+ this.emit('error', ...err);
34
79
  }
35
80
  /**
36
81
  * Get bot identity
@@ -66,7 +111,7 @@ export class Bot extends EventEmitter {
66
111
  }
67
112
  }
68
113
  catch (e) {
69
- console.error('Error during clean:', e);
114
+ this.error('Error during clean:', e);
70
115
  }
71
116
  }
72
117
  /**
@@ -125,6 +170,10 @@ export class Bot extends EventEmitter {
125
170
  }, timeout);
126
171
  this.once('connect', onConnect);
127
172
  this.once('disconnect', onDisconnect);
173
+ if (!this.client) {
174
+ reject(new Error('Client not created'));
175
+ return;
176
+ }
128
177
  this.client.connect();
129
178
  });
130
179
  }
@@ -140,7 +189,7 @@ export class Bot extends EventEmitter {
140
189
  await this.client.Disconnect();
141
190
  }
142
191
  catch (e) {
143
- console.error('Error during disconnect:', e);
192
+ this.error('Error during disconnect:', e);
144
193
  }
145
194
  this.status.connect.connected = false;
146
195
  info = { addr: this.status.addr, port: this.status.port };
@@ -157,7 +206,7 @@ export class Bot extends EventEmitter {
157
206
  this.identity =
158
207
  typeof identity === 'object' && identity !== null
159
208
  ? { ...this.identity, ...identity }
160
- : DDUtils.DefaultIdentity(this.identity.name);
209
+ : DefaultIdentity(this.identity.name);
161
210
  if (this.client && this.status.connect.connected) {
162
211
  this.client.game.ChangePlayerInfo(this.identity);
163
212
  }
@@ -198,6 +247,7 @@ export class Bot extends EventEmitter {
198
247
  this.client.on('kill', (msg) => this.emit('kill', msg));
199
248
  this.client.on('snapshot', (msg) => this.emit('snapshot', msg));
200
249
  this.client.on('map_change', (msg) => this.emit('map_change', msg));
250
+ this.client.on('map_details', (msg) => this.emit('map_details', msg));
201
251
  this.client.on('motd', (msg) => this.emit('motd', msg));
202
252
  this.client.on('message', (msg) => this.emit('message', msg));
203
253
  this.client.on('teams', (msg) => this.emit('teams', msg));
@@ -208,7 +258,7 @@ export class Bot extends EventEmitter {
208
258
  */
209
259
  setup_snapshot_events() {
210
260
  if (!this.client?.SnapshotUnpacker) {
211
- console.warn('SnapshotUnpacker not available yet');
261
+ this.error('SnapshotUnpacker not available yet');
212
262
  return;
213
263
  }
214
264
  this.client.SnapshotUnpacker.removeAllListeners();
@@ -275,4 +325,5 @@ export class Bot extends EventEmitter {
275
325
  return super.off(event, listener);
276
326
  }
277
327
  }
278
- export default Bot;
328
+ exports.Bot = Bot;
329
+ exports.default = Bot;
@@ -30,4 +30,7 @@ export declare function IsValidInput(input: unknown): input is Input;
30
30
  export declare function random(min: number, max: number): number;
31
31
  export declare function connectionInfo(): ConnectionInfo;
32
32
  import type { SnapshotItemTypes } from '../types.js';
33
+ /**
34
+ * NOT FULL. baze.
35
+ */
33
36
  export declare function reconstructPlayerInput(char: SnapshotItemTypes.Character, ddnetChar?: SnapshotItemTypes.DDNetCharacter | null, tick?: number | null): SnapshotItemTypes.PlayerInput;
@@ -1,4 +1,13 @@
1
- export function DefaultIdentity(name = 'nameless tee') {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultIdentity = DefaultIdentity;
4
+ exports.IsValidIdentity = IsValidIdentity;
5
+ exports.IsValidClient = IsValidClient;
6
+ exports.IsValidInput = IsValidInput;
7
+ exports.random = random;
8
+ exports.connectionInfo = connectionInfo;
9
+ exports.reconstructPlayerInput = reconstructPlayerInput;
10
+ function DefaultIdentity(name = 'nameless tee') {
2
11
  return {
3
12
  name: name,
4
13
  clan: "",
@@ -9,7 +18,7 @@ export function DefaultIdentity(name = 'nameless tee') {
9
18
  country: 0
10
19
  };
11
20
  }
12
- export function IsValidIdentity(identity) {
21
+ function IsValidIdentity(identity) {
13
22
  if (!identity || typeof identity !== 'object') {
14
23
  return false;
15
24
  }
@@ -60,7 +69,7 @@ export function IsValidIdentity(identity) {
60
69
  }
61
70
  return true;
62
71
  }
63
- export function IsValidClient(client) {
72
+ function IsValidClient(client) {
64
73
  if (!client || typeof client !== 'object') {
65
74
  return false;
66
75
  }
@@ -73,7 +82,7 @@ export function IsValidClient(client) {
73
82
  }
74
83
  return true;
75
84
  }
76
- export function IsValidInput(input) {
85
+ function IsValidInput(input) {
77
86
  if (!input || typeof input !== 'object') {
78
87
  return false;
79
88
  }
@@ -100,16 +109,19 @@ export function IsValidInput(input) {
100
109
  return false;
101
110
  return true;
102
111
  }
103
- export function random(min, max) {
112
+ function random(min, max) {
104
113
  return Math.floor(Math.random() * (max - min + 1)) + min;
105
114
  }
106
- export function connectionInfo() {
115
+ function connectionInfo() {
107
116
  return {
108
117
  addr: 'string',
109
118
  port: 8303
110
119
  };
111
120
  }
112
- export function reconstructPlayerInput(char, ddnetChar = null, tick = null) {
121
+ /**
122
+ * NOT FULL. baze.
123
+ */
124
+ function reconstructPlayerInput(char, ddnetChar = null, tick = null) {
113
125
  const input = {
114
126
  direction: char.character_core.direction,
115
127
  target_x: 0,
@@ -4,7 +4,7 @@ interface BaseModuleOptions {
4
4
  moduleName?: string;
5
5
  offonDisconnect?: boolean;
6
6
  }
7
- declare class BaseModule extends EventEmitter {
7
+ declare class BaseModule<TStartArgs extends unknown[] = []> extends EventEmitter {
8
8
  protected readonly bot: Bot;
9
9
  readonly moduleName: string;
10
10
  isRunning: boolean;
@@ -14,7 +14,7 @@ declare class BaseModule extends EventEmitter {
14
14
  * Запускает модуль, если он ещё не запущен
15
15
  * @param args — аргументы, которые будут переданы в _start
16
16
  */
17
- start(...args: unknown[]): void;
17
+ start(...args: TStartArgs): void;
18
18
  /**
19
19
  * Останавливает модуль, если он запущен
20
20
  */
@@ -23,7 +23,7 @@ declare class BaseModule extends EventEmitter {
23
23
  * Метод, который нужно переопределить в наследниках
24
24
  * Здесь происходит основная логика запуска
25
25
  */
26
- protected _start(...args: unknown[]): void;
26
+ protected _start(...args: TStartArgs): void;
27
27
  /**
28
28
  * Метод, который нужно переопределить в наследниках
29
29
  * Здесь происходит очистка при остановке
@@ -1,5 +1,7 @@
1
- import { EventEmitter } from 'events';
2
- class BaseModule extends EventEmitter {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const events_1 = require("events");
4
+ class BaseModule extends events_1.EventEmitter {
3
5
  bot;
4
6
  moduleName;
5
7
  isRunning = false;
@@ -62,4 +64,4 @@ class BaseModule extends EventEmitter {
62
64
  this.removeAllListeners();
63
65
  }
64
66
  }
65
- export default BaseModule;
67
+ exports.default = BaseModule;
@@ -0,0 +1,7 @@
1
+ import type * as Types from './types.js';
2
+ export declare function DefaultIdentity(name?: string): Types.SnapshotItemTypes.Identity;
3
+ export declare function connectionInfo(): Types.ConnectionInfo;
4
+ /**
5
+ * NOT FULL. baze.
6
+ */
7
+ export declare function reconstructPlayerInput(char: Types.SnapshotItemTypes.Character, ddnetChar?: Types.SnapshotItemTypes.DDNetCharacter | null, tick?: number | null): Types.SnapshotItemTypes.PlayerInput;
package/lib/ddutils.js ADDED
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultIdentity = DefaultIdentity;
4
+ exports.connectionInfo = connectionInfo;
5
+ exports.reconstructPlayerInput = reconstructPlayerInput;
6
+ function DefaultIdentity(name = 'nameless tee') {
7
+ return {
8
+ name: name,
9
+ clan: "",
10
+ skin: "default",
11
+ use_custom_color: 0,
12
+ color_body: 0,
13
+ color_feet: 0,
14
+ country: 0
15
+ };
16
+ }
17
+ function connectionInfo() {
18
+ return {
19
+ addr: 'string',
20
+ port: 8303
21
+ };
22
+ }
23
+ /**
24
+ * NOT FULL. baze.
25
+ */
26
+ function reconstructPlayerInput(char, ddnetChar = null, tick = null) {
27
+ const input = {
28
+ direction: char.character_core.direction,
29
+ target_x: 0,
30
+ target_y: -1,
31
+ jump: 0,
32
+ fire: 0,
33
+ hook: 0,
34
+ player_flags: char.player_flags || 0,
35
+ wanted_weapon: char.weapon,
36
+ next_weapon: 0,
37
+ prev_weapon: 0
38
+ };
39
+ if (ddnetChar && (ddnetChar.m_TargetX !== 0 || ddnetChar.m_TargetY !== 0)) {
40
+ input.target_x = ddnetChar.m_TargetX;
41
+ input.target_y = ddnetChar.m_TargetY;
42
+ }
43
+ else {
44
+ const angleRad = (char.character_core.angle / 256.0) * Math.PI / 128.0;
45
+ input.target_x = Math.cos(angleRad) * 256;
46
+ input.target_y = Math.sin(angleRad) * 256;
47
+ }
48
+ if (input.target_x === 0 && input.target_y === 0) {
49
+ input.target_y = -1;
50
+ }
51
+ const hookActive = char.character_core.hook_state !== 0 ||
52
+ char.character_core.hooked_player !== -1;
53
+ input.hook = hookActive ? 1 : 0;
54
+ const jumped = char.character_core.jumped;
55
+ const grounded = Math.abs(char.character_core.vel_y) < 1 && jumped === 0;
56
+ input.jump = jumped > 0 && !grounded ? 1 : 0;
57
+ const isNinja = ddnetChar != null && (ddnetChar.m_Flags & 0x20) !== 0;
58
+ input.wanted_weapon = isNinja ? 5 : char.weapon;
59
+ const isAutofireWeapon = [2, 3, 4].includes(input.wanted_weapon);
60
+ const isJetpackGun = input.wanted_weapon === 1 && ddnetChar?.m_Flags != null;
61
+ input.fire = isAutofireWeapon || isJetpackGun ? 0 : 0; // без tick всегда 0
62
+ return input;
63
+ }
package/lib/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import { Bot } from './core/core.js';
2
- import * as DDUtils from './core/ddutils.js';
3
2
  import BaseModule from './core/module.js';
4
- import BotManager from './manager.js';
5
3
  import Chat from './modules/chat.js';
6
4
  import PlayerList from './modules/playerlist.js';
7
5
  import Reconnect from './modules/reconnect.js';
8
6
  import Snap from './modules/snap.js';
7
+ import * as DDUtils from './ddutils.js';
9
8
  import * as Types from './types.js';
10
9
  declare const StandardModules: {
11
10
  Chat: typeof Chat;
@@ -13,4 +12,4 @@ declare const StandardModules: {
13
12
  Reconnect: typeof Reconnect;
14
13
  Snap: typeof Snap;
15
14
  };
16
- export { Bot, Types, DDUtils, BaseModule, BotManager, StandardModules, };
15
+ export { Bot, Types, DDUtils, BaseModule, StandardModules, };
package/lib/index.js CHANGED
@@ -1,16 +1,58 @@
1
- import { Bot } from './core/core.js';
2
- import * as DDUtils from './core/ddutils.js';
3
- import BaseModule from './core/module.js';
4
- import BotManager from './manager.js';
5
- import Chat from './modules/chat.js';
6
- import PlayerList from './modules/playerlist.js';
7
- import Reconnect from './modules/reconnect.js';
8
- import Snap from './modules/snap.js';
9
- import * as Types from './types.js';
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.StandardModules = exports.BaseModule = exports.DDUtils = exports.Types = exports.Bot = void 0;
40
+ const core_js_1 = require("./core/core.js");
41
+ Object.defineProperty(exports, "Bot", { enumerable: true, get: function () { return core_js_1.Bot; } });
42
+ const module_js_1 = __importDefault(require("./core/module.js"));
43
+ exports.BaseModule = module_js_1.default;
44
+ const chat_js_1 = __importDefault(require("./modules/chat.js"));
45
+ const playerlist_js_1 = __importDefault(require("./modules/playerlist.js"));
46
+ const reconnect_js_1 = __importDefault(require("./modules/reconnect.js"));
47
+ const snap_js_1 = __importDefault(require("./modules/snap.js"));
48
+ const DDUtils = __importStar(require("./ddutils.js"));
49
+ exports.DDUtils = DDUtils;
50
+ const Types = __importStar(require("./types.js"));
51
+ exports.Types = Types;
10
52
  const StandardModules = {
11
- Chat,
12
- PlayerList,
13
- Reconnect,
14
- Snap,
53
+ Chat: chat_js_1.default,
54
+ PlayerList: playerlist_js_1.default,
55
+ Reconnect: reconnect_js_1.default,
56
+ Snap: snap_js_1.default,
15
57
  };
16
- export { Bot, Types, DDUtils, BaseModule, BotManager, StandardModules, };
58
+ exports.StandardModules = StandardModules;
package/lib/manager.js CHANGED
@@ -1,7 +1,8 @@
1
- import { Bot } from './core/core.js';
2
- import { EventEmitter } from 'events';
3
- import * as Types from './types.js';
4
- class BotManager extends EventEmitter {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_js_1 = require("./core/core.js");
4
+ const events_1 = require("events");
5
+ class BotManager extends events_1.EventEmitter {
5
6
  bots = new Map();
6
7
  names = new Set();
7
8
  constructor() {
@@ -80,7 +81,7 @@ class BotManager extends EventEmitter {
80
81
  return uniqueName;
81
82
  }
82
83
  createBot(...config) {
83
- const bot = new Bot(...config);
84
+ const bot = new core_js_1.Bot(...config);
84
85
  const id = this.createUniqueName();
85
86
  this.botevents(id, bot);
86
87
  this.bots.set(id, bot);
@@ -133,4 +134,4 @@ class BotManager extends EventEmitter {
133
134
  }
134
135
  }
135
136
  }
136
- export default BotManager;
137
+ exports.default = BotManager;
@@ -16,7 +16,7 @@ interface ChatEvents {
16
16
  queueSize: number;
17
17
  }) => void;
18
18
  }
19
- declare class Chat extends BaseModule {
19
+ declare class Chat extends BaseModule<[interval?: number, cooldown?: number]> {
20
20
  private chatinterval;
21
21
  private sendinterval;
22
22
  private readonly chatset;
@@ -37,7 +37,6 @@ declare class Chat extends BaseModule {
37
37
  private _processQueue;
38
38
  protected _start(interval?: number, cooldown?: number): void;
39
39
  protected _stop(): void;
40
- destroy(): void;
41
40
  on<K extends keyof ChatEvents>(event: K, listener: ChatEvents[K]): this;
42
41
  once<K extends keyof ChatEvents>(event: K, listener: ChatEvents[K]): this;
43
42
  emit<K extends keyof ChatEvents>(event: K, ...args: Parameters<ChatEvents[K]>): boolean;
@@ -1,6 +1,10 @@
1
- import BaseModule from '../core/module.js';
2
- import * as Types from '../types.js';
3
- class Chat extends BaseModule {
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const module_js_1 = __importDefault(require("../core/module.js"));
7
+ class Chat extends module_js_1.default {
4
8
  chatinterval = null;
5
9
  sendinterval = null;
6
10
  chatset = new Set();
@@ -8,26 +12,21 @@ class Chat extends BaseModule {
8
12
  lastSentTime = 0;
9
13
  cooldown = 1000;
10
14
  chatlistener = (msg) => {
11
- try {
12
- const msgraw = msg;
13
- const text = String(msgraw?.message ?? '');
14
- const client_id = msgraw.client_id ?? -1;
15
- const team = msgraw.team ?? 0;
16
- const autormsg = msgraw?.author?.ClientInfo?.name ?? null;
17
- const key = `${client_id}:${text}:${team}`;
18
- if (this.chatset.has(key))
19
- return;
20
- this.chatset.add(key);
21
- this.emit('anychat', msgraw, autormsg, text, team, client_id);
22
- if (autormsg) {
23
- this.emit('chat', msgraw, autormsg, text, team, client_id);
24
- }
25
- else {
26
- this.emit('systemchat', msgraw, text);
27
- }
15
+ const msgraw = msg;
16
+ const text = String(msgraw?.message ?? '');
17
+ const client_id = msgraw.client_id ?? -1;
18
+ const team = msgraw.team ?? 0;
19
+ const autormsg = msgraw?.author?.ClientInfo?.name ?? null;
20
+ const key = `${client_id}:${text}:${team}`;
21
+ if (this.chatset.has(key))
22
+ return;
23
+ this.chatset.add(key);
24
+ this.emit('anychat', msgraw, autormsg, text, team, client_id);
25
+ if (autormsg) {
26
+ this.emit('chat', msgraw, autormsg, text, team, client_id);
28
27
  }
29
- catch (e) {
30
- console.error(`[${this.moduleName}] chat listener error:`, e);
28
+ else {
29
+ this.emit('systemchat', msgraw, text);
31
30
  }
32
31
  };
33
32
  constructor(bot) {
@@ -102,9 +101,6 @@ class Chat extends BaseModule {
102
101
  this.sendinterval = null;
103
102
  }
104
103
  }
105
- destroy() {
106
- super.destroy();
107
- }
108
104
  on(event, listener) {
109
105
  return super.on(event, listener);
110
106
  }
@@ -118,4 +114,4 @@ class Chat extends BaseModule {
118
114
  return super.off(event, listener);
119
115
  }
120
116
  }
121
- export default Chat;
117
+ exports.default = Chat;
@@ -8,7 +8,7 @@ interface PlayerData {
8
8
  character: Types.SnapshotItemTypes.Character | null;
9
9
  DDNetCharacter: Types.SnapshotItemTypes.DDNetCharacter | null;
10
10
  }
11
- declare class PlayerList extends BaseModule {
11
+ declare class PlayerList extends BaseModule<[maxclients?: number]> {
12
12
  constructor(bot: Bot);
13
13
  private client;
14
14
  private maxclients;
@@ -1,8 +1,13 @@
1
- import BaseModule from '../core/module.js';
2
- class PlayerList extends BaseModule {
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const module_js_1 = __importDefault(require("../core/module.js"));
7
+ class PlayerList extends module_js_1.default {
3
8
  constructor(bot) {
4
9
  super(bot, { moduleName: 'PlayerList', offonDisconnect: false });
5
- this.client = this.bot.bot_client;
10
+ this.client = this.bot.bot_client; // тута короче же прокси, так что ето работает
6
11
  }
7
12
  client;
8
13
  maxclients = 64;
@@ -75,4 +80,4 @@ class PlayerList extends BaseModule {
75
80
  this.previousMap.clear();
76
81
  }
77
82
  }
78
- export default PlayerList;
83
+ exports.default = PlayerList;
@@ -7,7 +7,7 @@ export interface ReconnectingInfo {
7
7
  reason: string | null;
8
8
  ConnectionInfo: Types.ConnectionInfo;
9
9
  }
10
- declare class Reconnect extends BaseModule {
10
+ declare class Reconnect extends BaseModule<[maxAttempts?: number, randomDelay?: boolean]> {
11
11
  private maxAttempts;
12
12
  private randomDelay;
13
13
  private currentAttempts;
@@ -1,6 +1,10 @@
1
- import BaseModule from '../core/module.js';
2
- import * as Types from '../types.js';
3
- class Reconnect extends BaseModule {
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const module_js_1 = __importDefault(require("../core/module.js"));
7
+ class Reconnect extends module_js_1.default {
4
8
  maxAttempts = -1;
5
9
  randomDelay = true;
6
10
  currentAttempts = 0;
@@ -82,4 +86,4 @@ class Reconnect extends BaseModule {
82
86
  }
83
87
  }
84
88
  }
85
- export default Reconnect;
89
+ exports.default = Reconnect;
@@ -1,6 +1,10 @@
1
- import BaseModule from '../core/module.js';
2
- import * as Types from '../types.js';
3
- class Snap extends BaseModule {
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const module_js_1 = __importDefault(require("../core/module.js"));
7
+ class Snap extends module_js_1.default {
4
8
  _isFrozen = false;
5
9
  hammerHitlistener = (hit) => {
6
10
  if (this.bot.OwnID === undefined)
@@ -31,7 +35,7 @@ class Snap extends BaseModule {
31
35
  }
32
36
  }
33
37
  };
34
- ffs();
38
+ ffs(); // in future snapshot can be biger, so we just make new functions. блять идите нахуй со своим англиским, я не знаю но я стараюсь идите нахуй
35
39
  };
36
40
  constructor(bot) {
37
41
  super(bot, { moduleName: 'Snap', offonDisconnect: false });
@@ -42,7 +46,7 @@ class Snap extends BaseModule {
42
46
  const distanceY = Math.abs(y1 - y2);
43
47
  return distanceX <= TILE && distanceY <= TILE;
44
48
  }
45
- static whoareWithinTile(x, y, list, ignoreClients = []) {
49
+ static whoareWithinTile(x, y, list = [], ignoreClients = []) {
46
50
  for (const character of list) {
47
51
  const character_core = character?.character_core;
48
52
  if (!character_core)
@@ -69,8 +73,6 @@ class Snap extends BaseModule {
69
73
  return this._isFrozen;
70
74
  }
71
75
  _start() {
72
- if (!this.bot.status.connect.connected)
73
- return;
74
76
  this.bot.on('snapshot', this.snapslistener);
75
77
  this.bot.on('hammerhit', this.hammerHitlistener);
76
78
  this.bot.on('sound_world', this.firelistener);
@@ -81,4 +83,4 @@ class Snap extends BaseModule {
81
83
  this.bot.off('sound_world', this.firelistener);
82
84
  }
83
85
  }
84
- export default Snap;
86
+ exports.default = Snap;
package/lib/types.js CHANGED
@@ -1,4 +1,2 @@
1
- /**
2
- * Типы из библиотеки teeworlds
3
- */
4
- export {};
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -3,11 +3,11 @@
3
3
  "teeworlds": "^2.5.11"
4
4
  },
5
5
  "name": "ddbot.js-0374",
6
- "version": "4.1.0",
6
+ "version": "4.3.0",
7
7
  "description": "ddbot.js — это Node.js проект для автоматизации и управления ботами.",
8
- "main": "./index.js",
8
+ "main": "./lib/index.js",
9
9
  "scripts": {
10
- "build": "tsc && tsc index.ts --outDir . --skipLibCheck",
10
+ "build": "tsc",
11
11
  "prepublishOnly": "npm run build"
12
12
  },
13
13
  "repository": {
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "author": "0374flop",
26
26
  "license": "MIT",
27
- "type": "module",
27
+ "type": "commonjs",
28
28
  "bugs": {
29
29
  "url": "https://github.com/0374flop/ddbot.js/issues"
30
30
  },
File without changes
package/index.js DELETED
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var ddbot = require("./lib/index");
4
- exports.default = ddbot;