clashofclans.js 3.0.0-dev.392ca4c → 3.0.0-dev.ec60c82
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/dist/client/Client.d.ts +26 -2
- package/dist/client/Client.js +8 -6
- package/dist/client/PollingClient.d.ts +105 -32
- package/dist/client/PollingClient.js +265 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +5 -2
- package/dist/index.mjs +2 -1
- package/dist/rest/RESTManager.d.ts +36 -3
- package/dist/rest/RESTManager.js +35 -29
- package/dist/rest/RequestHandler.d.ts +30 -2
- package/dist/rest/RequestHandler.js +12 -6
- package/dist/struct/Clan.d.ts +1 -1
- package/dist/struct/Player.d.ts +1 -1
- package/dist/struct/Ranking.d.ts +1 -1
- package/dist/struct/Unit.d.ts +0 -2
- package/dist/struct/Unit.js +0 -2
- package/dist/struct/index.js +5 -1
- package/dist/types/index.js +5 -1
- package/dist/types/lib.d.ts +4 -4
- package/dist/util/Constants.d.ts +38 -3
- package/dist/util/Constants.js +11 -2
- package/dist/util/Util.js +2 -2
- package/dist/util/raw.json +1 -1
- package/package.json +6 -59
- package/dist/client/EventManager.d.ts +0 -86
- package/dist/client/EventManager.js +0 -278
package/dist/client/Client.d.ts
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
2
3
|
import { ClanSearchOptions, SearchOptions, ClientOptions, LoginOptions, OverrideOptions } from '../types';
|
|
3
|
-
import { CWLRounds } from '../util/Constants';
|
|
4
|
+
import { CWLRounds, ClientEvents } from '../util/Constants';
|
|
4
5
|
import { RESTManager } from '../rest/RESTManager';
|
|
5
|
-
import { EventEmitter } from 'events';
|
|
6
6
|
import { Util } from '../util/Util';
|
|
7
7
|
import { Clan, ClanMember, ClanWar, ClanWarLog, League, Location, Player, WarLeague, RankedClan, RankedPlayer, Label, SeasonRankedPlayer, GoldPassSeason, ClanWarLeagueGroup } from '../struct';
|
|
8
|
+
interface IClientEvents {
|
|
9
|
+
[ClientEvents.Error]: [error: unknown];
|
|
10
|
+
[ClientEvents.Debug]: [path: string, status: string, message: string];
|
|
11
|
+
}
|
|
12
|
+
export interface Client {
|
|
13
|
+
emit: (<K extends keyof IClientEvents>(event: K, ...args: IClientEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof IClientEvents>, ...args: any[]) => boolean);
|
|
14
|
+
off: (<K extends keyof IClientEvents>(event: K, listener: (...args: IClientEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IClientEvents>, listener: (...args: any[]) => void) => this);
|
|
15
|
+
on: (<K extends keyof IClientEvents>(event: K, listener: (...args: IClientEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IClientEvents>, listener: (...args: any[]) => void) => this);
|
|
16
|
+
once: (<K extends keyof IClientEvents>(event: K, listener: (...args: IClientEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IClientEvents>, listener: (...args: any[]) => void) => this);
|
|
17
|
+
removeAllListeners: (<K extends keyof IClientEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof IClientEvents>) => this);
|
|
18
|
+
/**
|
|
19
|
+
* Emitted for general debugging information.
|
|
20
|
+
* @public
|
|
21
|
+
* @event
|
|
22
|
+
*/
|
|
23
|
+
debug: string;
|
|
24
|
+
/**
|
|
25
|
+
* Emitted when the client encounters an error.
|
|
26
|
+
* @public
|
|
27
|
+
* @event
|
|
28
|
+
*/
|
|
29
|
+
error: string;
|
|
30
|
+
}
|
|
8
31
|
/**
|
|
9
32
|
* Represents Clash of Clans API Client.
|
|
10
33
|
* ```js
|
|
@@ -127,3 +150,4 @@ export declare class Client extends EventEmitter {
|
|
|
127
150
|
/** Get info about gold pass season. */
|
|
128
151
|
getGoldPassSeason(options?: OverrideOptions): Promise<GoldPassSeason>;
|
|
129
152
|
}
|
|
153
|
+
export {};
|
package/dist/client/Client.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Client = void 0;
|
|
4
|
+
const node_events_1 = require("node:events");
|
|
4
5
|
const Constants_1 = require("../util/Constants");
|
|
5
6
|
const HTTPError_1 = require("../rest/HTTPError");
|
|
6
7
|
const RESTManager_1 = require("../rest/RESTManager");
|
|
7
|
-
const events_1 = require("events");
|
|
8
8
|
const Util_1 = require("../util/Util");
|
|
9
9
|
const struct_1 = require("../struct");
|
|
10
10
|
/**
|
|
@@ -14,10 +14,12 @@ const struct_1 = require("../struct");
|
|
|
14
14
|
* const client = new Client({ keys: ['***'] });
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
|
-
class Client extends
|
|
17
|
+
class Client extends node_events_1.EventEmitter {
|
|
18
18
|
constructor(options) {
|
|
19
19
|
super();
|
|
20
|
-
this.rest = new RESTManager_1.RESTManager({ ...options, rejectIfNotValid: true })
|
|
20
|
+
this.rest = new RESTManager_1.RESTManager({ ...options, rejectIfNotValid: true })
|
|
21
|
+
.on(Constants_1.RestEvents.Debug, this.emit.bind(this, Constants_1.RestEvents.Debug))
|
|
22
|
+
.on(Constants_1.RestEvents.Error, this.emit.bind(this, Constants_1.RestEvents.Error));
|
|
21
23
|
}
|
|
22
24
|
/** Contains various general-purpose utility methods. */
|
|
23
25
|
get util() {
|
|
@@ -32,11 +34,11 @@ class Client extends events_1.EventEmitter {
|
|
|
32
34
|
* ```
|
|
33
35
|
*/
|
|
34
36
|
login(options) {
|
|
35
|
-
return this.rest.
|
|
37
|
+
return this.rest.requestHandler.init(options);
|
|
36
38
|
}
|
|
37
39
|
/** Set Clash of Clans API keys. */
|
|
38
40
|
setKeys(keys) {
|
|
39
|
-
this.rest.
|
|
41
|
+
this.rest.requestHandler.setKeys(keys);
|
|
40
42
|
return this;
|
|
41
43
|
}
|
|
42
44
|
/** Search clans by name and/or filtering parameters or get clans by their tags (fetches in parallel). */
|
|
@@ -140,7 +142,7 @@ class Client extends events_1.EventEmitter {
|
|
|
140
142
|
return [await this.getClanWar(clanTag, options)];
|
|
141
143
|
}
|
|
142
144
|
try {
|
|
143
|
-
return this.getLeagueWars(clanTag, options);
|
|
145
|
+
return await this.getLeagueWars(clanTag, options);
|
|
144
146
|
}
|
|
145
147
|
catch (e) {
|
|
146
148
|
if (e instanceof HTTPError_1.HTTPError && [404].includes(e.status)) {
|
|
@@ -2,7 +2,6 @@ import { Clan, ClanWar, Player } from '../struct';
|
|
|
2
2
|
import { ClientOptions } from '../types';
|
|
3
3
|
import { PollingEvents } from '../util/Constants';
|
|
4
4
|
import { Client } from './Client';
|
|
5
|
-
import { PollingEventManager } from './EventManager';
|
|
6
5
|
/**
|
|
7
6
|
* Represents Clash of Clans Polling Event Client.
|
|
8
7
|
* ```js
|
|
@@ -11,11 +10,93 @@ import { PollingEventManager } from './EventManager';
|
|
|
11
10
|
* ```
|
|
12
11
|
*/
|
|
13
12
|
export declare class PollingClient extends Client {
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
private readonly _clanTags;
|
|
14
|
+
private readonly _playerTags;
|
|
15
|
+
private readonly _warTags;
|
|
16
|
+
private readonly _clans;
|
|
17
|
+
private readonly _players;
|
|
18
|
+
private readonly _wars;
|
|
19
|
+
private readonly _pollingEvents;
|
|
20
|
+
inMaintenance: boolean;
|
|
21
|
+
private _maintenanceStartTime;
|
|
16
22
|
constructor(options?: ClientOptions);
|
|
17
|
-
/**
|
|
18
|
-
|
|
23
|
+
/** Initialize the PollingEvent Manager to start pulling the data by polling api. */
|
|
24
|
+
init(): Promise<string[]>;
|
|
25
|
+
/** Add clan tags to clan polling events. */
|
|
26
|
+
addClans(tags: string[] | string): this;
|
|
27
|
+
/** Delete clan tags from clan polling events. */
|
|
28
|
+
deleteClans(tags: string[] | string): this;
|
|
29
|
+
/** Add player tags for player polling events. */
|
|
30
|
+
addPlayers(tags: string[] | string): this;
|
|
31
|
+
/** Delete player tags from player polling events. */
|
|
32
|
+
deletePlayers(tags: string[] | string): this;
|
|
33
|
+
/** Add clan tags for war polling events. */
|
|
34
|
+
addWars(tags: string[] | string): this;
|
|
35
|
+
/** Delete clan tags from war polling events. */
|
|
36
|
+
deleteWars(tags: string[] | string): this;
|
|
37
|
+
/**
|
|
38
|
+
* Set your own custom clan polling event.
|
|
39
|
+
*
|
|
40
|
+
* In order to emit the custom polling event, you must have this filter function that returns a boolean.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```js
|
|
44
|
+
* client.addClans(['#2PP', '#8QU8J9LP']);
|
|
45
|
+
*
|
|
46
|
+
* client.setClanEvent({
|
|
47
|
+
* name: 'clanMemberUpdate',
|
|
48
|
+
* filter: (oldClan, newClan) => {
|
|
49
|
+
* return oldClan.memberCount !== newClan.memberCount;
|
|
50
|
+
* }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* client.on('clanMemberUpdate', (oldClan, newClan) => {
|
|
54
|
+
* console.log(oldClan.memberCount, newClan.memberCount);
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* (async function () {
|
|
58
|
+
* await client.init();
|
|
59
|
+
* })();
|
|
60
|
+
* ```
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
setClanEvent(event: {
|
|
64
|
+
name: string;
|
|
65
|
+
filter: (oldClan: Clan, newClan: Clan) => boolean;
|
|
66
|
+
}): this;
|
|
67
|
+
/**
|
|
68
|
+
* Set your own custom war event.
|
|
69
|
+
*
|
|
70
|
+
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
71
|
+
*/
|
|
72
|
+
setWarEvent(event: {
|
|
73
|
+
name: string;
|
|
74
|
+
filter: (oldWar: ClanWar, newWar: ClanWar) => boolean;
|
|
75
|
+
}): this;
|
|
76
|
+
/**
|
|
77
|
+
* Set your own custom player event.
|
|
78
|
+
*
|
|
79
|
+
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
80
|
+
*/
|
|
81
|
+
setPlayerEvent(event: {
|
|
82
|
+
name: string;
|
|
83
|
+
filter: (oldPlayer: Player, newPlayer: Player) => boolean;
|
|
84
|
+
}): this;
|
|
85
|
+
private maintenanceHandler;
|
|
86
|
+
private seasonEndHandler;
|
|
87
|
+
private clanUpdateHandler;
|
|
88
|
+
private playerUpdateHandler;
|
|
89
|
+
private warUpdateHandler;
|
|
90
|
+
private runClanUpdate;
|
|
91
|
+
private runPlayerUpdate;
|
|
92
|
+
private runWarUpdate;
|
|
93
|
+
}
|
|
94
|
+
export interface PollingClient {
|
|
95
|
+
emit: (<K extends keyof IPollingEvents>(event: K, ...args: IPollingEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof IPollingEvents>, ...args: any[]) => boolean);
|
|
96
|
+
off: (<K extends keyof IPollingEvents>(event: K, listener: (...args: IPollingEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IPollingEvents>, listener: (...args: any[]) => void) => this);
|
|
97
|
+
on: (<K extends keyof IPollingEvents>(event: K, listener: (...args: IPollingEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IPollingEvents>, listener: (...args: any[]) => void) => this);
|
|
98
|
+
once: (<K extends keyof IPollingEvents>(event: K, listener: (...args: IPollingEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IPollingEvents>, listener: (...args: any[]) => void) => this);
|
|
99
|
+
removeAllListeners: (<K extends keyof IPollingEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof IPollingEvents>) => this);
|
|
19
100
|
/**
|
|
20
101
|
* Emits when a new season starts.
|
|
21
102
|
*
|
|
@@ -27,13 +108,13 @@ export declare class PollingClient extends Client {
|
|
|
27
108
|
* @public
|
|
28
109
|
* @event
|
|
29
110
|
*/
|
|
30
|
-
|
|
111
|
+
newSeasonStart: string;
|
|
31
112
|
/**
|
|
32
113
|
* Emits when maintenance break starts in the API.
|
|
33
114
|
* @public
|
|
34
115
|
* @event
|
|
35
116
|
*/
|
|
36
|
-
|
|
117
|
+
maintenanceStart: string;
|
|
37
118
|
/**
|
|
38
119
|
* Emits when maintenance break ends in the API.
|
|
39
120
|
*
|
|
@@ -45,39 +126,31 @@ export declare class PollingClient extends Client {
|
|
|
45
126
|
* @public
|
|
46
127
|
* @event
|
|
47
128
|
*/
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
/** @internal */
|
|
62
|
-
emit<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientPollingEvents>, ...args: CustomEvents[S]): this;
|
|
63
|
-
/** @internal */ emit<S extends string | symbol>(event: Exclude<S, keyof ClientPollingEvents>, ...args: any[]): boolean;
|
|
129
|
+
maintenanceEnd: string;
|
|
130
|
+
/**
|
|
131
|
+
* Emitted for general debugging information.
|
|
132
|
+
* @public
|
|
133
|
+
* @event
|
|
134
|
+
*/
|
|
135
|
+
debug: string;
|
|
136
|
+
/**
|
|
137
|
+
* Emitted when the client encounters an error.
|
|
138
|
+
* @public
|
|
139
|
+
* @event
|
|
140
|
+
*/
|
|
141
|
+
error: string;
|
|
64
142
|
}
|
|
65
|
-
interface
|
|
66
|
-
[PollingEvents.NewSeasonStart]: [id: string];
|
|
67
|
-
[PollingEvents.MaintenanceStart]: [];
|
|
68
|
-
[PollingEvents.MaintenanceEnd]: [duration: number];
|
|
143
|
+
interface IPollingEvents {
|
|
69
144
|
[PollingEvents.ClanLoopStart]: [];
|
|
70
145
|
[PollingEvents.ClanLoopEnd]: [];
|
|
71
146
|
[PollingEvents.PlayerLoopStart]: [];
|
|
72
147
|
[PollingEvents.PlayerLoopEnd]: [];
|
|
73
148
|
[PollingEvents.WarLoopStart]: [];
|
|
74
149
|
[PollingEvents.WarLoopEnd]: [];
|
|
150
|
+
[PollingEvents.NewSeasonStart]: [id: string];
|
|
151
|
+
[PollingEvents.MaintenanceStart]: [];
|
|
152
|
+
[PollingEvents.MaintenanceEnd]: [duration: number];
|
|
75
153
|
[PollingEvents.Error]: [error: unknown];
|
|
76
154
|
[PollingEvents.Debug]: [path: string, status: string, message: string];
|
|
77
155
|
}
|
|
78
|
-
interface CustomEvents {
|
|
79
|
-
[key: `clan${string}`]: [oldClan: Clan, newClan: Clan];
|
|
80
|
-
[key: `war${string}`]: [oldWar: ClanWar, newWar: ClanWar];
|
|
81
|
-
[key: `player${string}`]: [oldPlayer: Player, newPlayer: Player];
|
|
82
|
-
}
|
|
83
156
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PollingClient = void 0;
|
|
4
|
+
const HTTPError_1 = require("../rest/HTTPError");
|
|
4
5
|
const Constants_1 = require("../util/Constants");
|
|
5
6
|
const Client_1 = require("./Client");
|
|
6
|
-
const EventManager_1 = require("./EventManager");
|
|
7
7
|
/**
|
|
8
8
|
* Represents Clash of Clans Polling Event Client.
|
|
9
9
|
* ```js
|
|
@@ -14,12 +14,271 @@ const EventManager_1 = require("./EventManager");
|
|
|
14
14
|
class PollingClient extends Client_1.Client {
|
|
15
15
|
constructor(options) {
|
|
16
16
|
super(options);
|
|
17
|
-
this.
|
|
17
|
+
this._clanTags = new Set();
|
|
18
|
+
this._playerTags = new Set();
|
|
19
|
+
this._warTags = new Set();
|
|
20
|
+
this._clans = new Map();
|
|
21
|
+
this._players = new Map();
|
|
22
|
+
this._wars = new Map();
|
|
23
|
+
this._pollingEvents = {
|
|
24
|
+
clans: [],
|
|
25
|
+
wars: [],
|
|
26
|
+
players: []
|
|
27
|
+
};
|
|
28
|
+
this.inMaintenance = Boolean(false);
|
|
29
|
+
this._maintenanceStartTime = null;
|
|
18
30
|
}
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
/** Initialize the PollingEvent Manager to start pulling the data by polling api. */
|
|
32
|
+
async init() {
|
|
33
|
+
this.seasonEndHandler();
|
|
34
|
+
this.maintenanceHandler();
|
|
35
|
+
this.clanUpdateHandler();
|
|
36
|
+
this.playerUpdateHandler();
|
|
37
|
+
this.warUpdateHandler();
|
|
38
|
+
return Promise.resolve(this.eventNames());
|
|
39
|
+
}
|
|
40
|
+
/** Add clan tags to clan polling events. */
|
|
41
|
+
addClans(tags) {
|
|
42
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
43
|
+
this._clanTags.add(this.util.formatTag(tag));
|
|
44
|
+
}
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
/** Delete clan tags from clan polling events. */
|
|
48
|
+
deleteClans(tags) {
|
|
49
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
50
|
+
const key = this.util.formatTag(tag);
|
|
51
|
+
this._clans.delete(key);
|
|
52
|
+
this._clanTags.delete(key);
|
|
53
|
+
}
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/** Add player tags for player polling events. */
|
|
57
|
+
addPlayers(tags) {
|
|
58
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
59
|
+
this._playerTags.add(this.util.formatTag(tag));
|
|
60
|
+
}
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
/** Delete player tags from player polling events. */
|
|
64
|
+
deletePlayers(tags) {
|
|
65
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
66
|
+
const key = this.util.formatTag(tag);
|
|
67
|
+
this._players.delete(key);
|
|
68
|
+
this._playerTags.delete(key);
|
|
69
|
+
}
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
/** Add clan tags for war polling events. */
|
|
73
|
+
addWars(tags) {
|
|
74
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
75
|
+
this._warTags.add(this.util.formatTag(tag));
|
|
76
|
+
}
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/** Delete clan tags from war polling events. */
|
|
80
|
+
deleteWars(tags) {
|
|
81
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
82
|
+
const key = this.util.formatTag(tag);
|
|
83
|
+
this._wars.delete(`${key}:${1}`);
|
|
84
|
+
this._wars.delete(`${key}:${2}`);
|
|
85
|
+
this._warTags.delete(key);
|
|
86
|
+
}
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Set your own custom clan polling event.
|
|
91
|
+
*
|
|
92
|
+
* In order to emit the custom polling event, you must have this filter function that returns a boolean.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```js
|
|
96
|
+
* client.addClans(['#2PP', '#8QU8J9LP']);
|
|
97
|
+
*
|
|
98
|
+
* client.setClanEvent({
|
|
99
|
+
* name: 'clanMemberUpdate',
|
|
100
|
+
* filter: (oldClan, newClan) => {
|
|
101
|
+
* return oldClan.memberCount !== newClan.memberCount;
|
|
102
|
+
* }
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* client.on('clanMemberUpdate', (oldClan, newClan) => {
|
|
106
|
+
* console.log(oldClan.memberCount, newClan.memberCount);
|
|
107
|
+
* });
|
|
108
|
+
*
|
|
109
|
+
* (async function () {
|
|
110
|
+
* await client.init();
|
|
111
|
+
* })();
|
|
112
|
+
* ```
|
|
113
|
+
* @returns
|
|
114
|
+
*/
|
|
115
|
+
setClanEvent(event) {
|
|
116
|
+
if (!event.name)
|
|
117
|
+
throw new Error('Event name is required.');
|
|
118
|
+
if (typeof event.filter !== 'function')
|
|
119
|
+
throw new Error('Filter function is required.');
|
|
120
|
+
this._pollingEvents.clans.push(event);
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Set your own custom war event.
|
|
125
|
+
*
|
|
126
|
+
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
127
|
+
*/
|
|
128
|
+
setWarEvent(event) {
|
|
129
|
+
if (!event.name)
|
|
130
|
+
throw new Error('Event name is required.');
|
|
131
|
+
if (typeof event.filter !== 'function')
|
|
132
|
+
throw new Error('Filter function is required.');
|
|
133
|
+
this._pollingEvents.wars.push(event);
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Set your own custom player event.
|
|
138
|
+
*
|
|
139
|
+
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
140
|
+
*/
|
|
141
|
+
setPlayerEvent(event) {
|
|
142
|
+
if (!event.name)
|
|
143
|
+
throw new Error('Event name is required.');
|
|
144
|
+
if (typeof event.filter !== 'function')
|
|
145
|
+
throw new Error('Filter function is required.');
|
|
146
|
+
this._pollingEvents.players.push(event);
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
async maintenanceHandler() {
|
|
150
|
+
setTimeout(this.maintenanceHandler.bind(this), 10000).unref();
|
|
151
|
+
try {
|
|
152
|
+
const res = await this.rest.getClans({ maxMembers: Math.floor(Math.random() * 40) + 10, limit: 1 });
|
|
153
|
+
if (res.status === 200 && this.inMaintenance) {
|
|
154
|
+
this.inMaintenance = Boolean(false);
|
|
155
|
+
const duration = Date.now() - this._maintenanceStartTime.getTime();
|
|
156
|
+
this._maintenanceStartTime = null;
|
|
157
|
+
this.emit(Constants_1.PollingEvents.MaintenanceEnd, duration);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (error instanceof HTTPError_1.HTTPError && error.status === 503 && !this.inMaintenance) {
|
|
162
|
+
this.inMaintenance = Boolean(true);
|
|
163
|
+
this._maintenanceStartTime = new Date();
|
|
164
|
+
this.emit(Constants_1.PollingEvents.MaintenanceStart);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
seasonEndHandler() {
|
|
169
|
+
const end = this.util.getSeasonEndTime().getTime() - Date.now();
|
|
170
|
+
// Why this? setTimeout can be up to 24.8 days or 2147483647ms [(2^31 - 1) Max 32bit Integer]
|
|
171
|
+
if (end > 24 * 60 * 60 * 1000) {
|
|
172
|
+
setTimeout(this.seasonEndHandler.bind(this), 60 * 60 * 1000);
|
|
173
|
+
}
|
|
174
|
+
else if (end > 0) {
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
this.emit(Constants_1.PollingEvents.NewSeasonStart, this.util.getSeasonId());
|
|
177
|
+
}, end + 100).unref();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async clanUpdateHandler() {
|
|
181
|
+
this.emit(Constants_1.PollingEvents.ClanLoopStart);
|
|
182
|
+
for (const tag of this._clanTags)
|
|
183
|
+
await this.runClanUpdate(tag);
|
|
184
|
+
this.emit(Constants_1.PollingEvents.ClanLoopEnd);
|
|
185
|
+
setTimeout(this.clanUpdateHandler.bind(this), 10000);
|
|
186
|
+
}
|
|
187
|
+
async playerUpdateHandler() {
|
|
188
|
+
this.emit(Constants_1.PollingEvents.PlayerLoopStart);
|
|
189
|
+
for (const tag of this._playerTags)
|
|
190
|
+
await this.runPlayerUpdate(tag);
|
|
191
|
+
this.emit(Constants_1.PollingEvents.PlayerLoopEnd);
|
|
192
|
+
setTimeout(this.playerUpdateHandler.bind(this), 10000);
|
|
193
|
+
}
|
|
194
|
+
async warUpdateHandler() {
|
|
195
|
+
this.emit(Constants_1.PollingEvents.WarLoopStart);
|
|
196
|
+
for (const tag of this._warTags)
|
|
197
|
+
await this.runWarUpdate(tag);
|
|
198
|
+
this.emit(Constants_1.PollingEvents.WarLoopEnd);
|
|
199
|
+
setTimeout(this.warUpdateHandler.bind(this), 10000);
|
|
200
|
+
}
|
|
201
|
+
async runClanUpdate(tag) {
|
|
202
|
+
if (this.inMaintenance)
|
|
203
|
+
return null;
|
|
204
|
+
const clan = await this.getClan(tag).catch(() => null);
|
|
205
|
+
if (!clan)
|
|
206
|
+
return null;
|
|
207
|
+
const cached = this._clans.get(clan.tag);
|
|
208
|
+
if (!cached)
|
|
209
|
+
return this._clans.set(clan.tag, clan);
|
|
210
|
+
for (const { name, filter } of this._pollingEvents.clans) {
|
|
211
|
+
try {
|
|
212
|
+
if (!(await filter(cached, clan)))
|
|
213
|
+
continue;
|
|
214
|
+
this.emit(name, cached, clan);
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
this.emit(Constants_1.PollingEvents.Error, error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return this._clans.set(clan.tag, clan);
|
|
221
|
+
}
|
|
222
|
+
async runPlayerUpdate(tag) {
|
|
223
|
+
if (this.inMaintenance)
|
|
224
|
+
return null;
|
|
225
|
+
const player = await this.getPlayer(tag).catch(() => null);
|
|
226
|
+
if (!player)
|
|
227
|
+
return null;
|
|
228
|
+
const cached = this._players.get(player.tag);
|
|
229
|
+
if (!cached)
|
|
230
|
+
return this._players.set(player.tag, player);
|
|
231
|
+
for (const { name, filter } of this._pollingEvents.players) {
|
|
232
|
+
try {
|
|
233
|
+
if (!(await filter(cached, player)))
|
|
234
|
+
continue;
|
|
235
|
+
this.emit(name, cached, player);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
this.emit(Constants_1.PollingEvents.Error, error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return this._players.set(player.tag, player);
|
|
242
|
+
}
|
|
243
|
+
async runWarUpdate(tag) {
|
|
244
|
+
if (this.inMaintenance)
|
|
245
|
+
return null;
|
|
246
|
+
const clanWars = await this.getWars(tag).catch(() => null);
|
|
247
|
+
if (!clanWars?.length)
|
|
248
|
+
return null;
|
|
249
|
+
clanWars.forEach(async (war, index) => {
|
|
250
|
+
const key = `${tag}:${index}`;
|
|
251
|
+
const cached = this._wars.get(key);
|
|
252
|
+
if (!cached)
|
|
253
|
+
return this._wars.set(key, war);
|
|
254
|
+
for (const { name, filter } of this._pollingEvents.wars) {
|
|
255
|
+
try {
|
|
256
|
+
if (!(await filter(cached, war)))
|
|
257
|
+
continue;
|
|
258
|
+
this.emit(name, cached, war);
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
this.emit(Constants_1.PollingEvents.Error, error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// check for war end
|
|
265
|
+
if (index === 1 && cached.warTag !== war.warTag) {
|
|
266
|
+
const data = await this.getLeagueWar({ clanTag: tag, round: 'PreviousRound' }).catch(() => null);
|
|
267
|
+
if (data && data.warTag === cached.warTag) {
|
|
268
|
+
for (const { name, filter } of this._pollingEvents.wars) {
|
|
269
|
+
try {
|
|
270
|
+
if (!(await filter(cached, data)))
|
|
271
|
+
continue;
|
|
272
|
+
this.emit(name, cached, data);
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
this.emit(Constants_1.PollingEvents.Error, error);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return this._wars.set(key, war);
|
|
281
|
+
});
|
|
23
282
|
}
|
|
24
283
|
}
|
|
25
284
|
exports.PollingClient = PollingClient;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ export * from './client/PollingClient';
|
|
|
3
3
|
export * from './rest/RESTManager';
|
|
4
4
|
export * from './rest/RequestHandler';
|
|
5
5
|
export * from './rest/HTTPError';
|
|
6
|
-
export * from './client/EventManager';
|
|
7
6
|
export * from './rest/Throttler';
|
|
8
7
|
export * from './util/Util';
|
|
9
8
|
export * from './struct';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -15,7 +19,6 @@ __exportStar(require("./client/PollingClient"), exports);
|
|
|
15
19
|
__exportStar(require("./rest/RESTManager"), exports);
|
|
16
20
|
__exportStar(require("./rest/RequestHandler"), exports);
|
|
17
21
|
__exportStar(require("./rest/HTTPError"), exports);
|
|
18
|
-
__exportStar(require("./client/EventManager"), exports);
|
|
19
22
|
__exportStar(require("./rest/Throttler"), exports);
|
|
20
23
|
__exportStar(require("./util/Util"), exports);
|
|
21
24
|
__exportStar(require("./struct"), exports);
|
package/dist/index.mjs
CHANGED
|
@@ -20,6 +20,7 @@ export const ClanWarLeagueRound = mod.ClanWarLeagueRound;
|
|
|
20
20
|
export const ClanWarLog = mod.ClanWarLog;
|
|
21
21
|
export const ClanWarMember = mod.ClanWarMember;
|
|
22
22
|
export const Client = mod.Client;
|
|
23
|
+
export const ClientEvents = mod.ClientEvents;
|
|
23
24
|
export const DarkElixirSpells = mod.DarkElixirSpells;
|
|
24
25
|
export const DarkElixirTroops = mod.DarkElixirTroops;
|
|
25
26
|
export const DevSiteAPIBaseURL = mod.DevSiteAPIBaseURL;
|
|
@@ -43,7 +44,6 @@ export const NotInWarError = mod.NotInWarError;
|
|
|
43
44
|
export const Player = mod.Player;
|
|
44
45
|
export const PlayerClan = mod.PlayerClan;
|
|
45
46
|
export const PollingClient = mod.PollingClient;
|
|
46
|
-
export const PollingEventManager = mod.PollingEventManager;
|
|
47
47
|
export const PollingEvents = mod.PollingEvents;
|
|
48
48
|
export const PrivateWarLogError = mod.PrivateWarLogError;
|
|
49
49
|
export const QueueThrottler = mod.QueueThrottler;
|
|
@@ -52,6 +52,7 @@ export const RankedClan = mod.RankedClan;
|
|
|
52
52
|
export const RankedPlayer = mod.RankedPlayer;
|
|
53
53
|
export const RawData = mod.RawData;
|
|
54
54
|
export const RequestHandler = mod.RequestHandler;
|
|
55
|
+
export const RestEvents = mod.RestEvents;
|
|
55
56
|
export const Season = mod.Season;
|
|
56
57
|
export const SeasonRankedPlayer = mod.SeasonRankedPlayer;
|
|
57
58
|
export const SiegeMachines = mod.SiegeMachines;
|
|
@@ -1,10 +1,43 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
2
3
|
import { Util } from '../util/Util';
|
|
3
4
|
import { APIClan, APIClanList, APIClanMemberList, APIClanRankingList, APIClanVersusRankingList, APIClanWar, APIClanWarLeagueGroup, APIClanWarLog, APIGoldPassSeason, APILabelList, APILeague, APILeagueList, APILeagueSeasonList, APILocation, APILocationList, APIPlayer, APIPlayerRankingList, APIPlayerSeasonRankingList, APIPlayerVersusRankingList, APIVerifyToken, APIWarLeague, APIWarLeagueList, SearchOptions, ClanSearchOptions, RESTOptions, OverrideOptions, LoginOptions } from '../types';
|
|
5
|
+
import { RestEvents } from '../util/Constants';
|
|
6
|
+
import { RequestHandler } from './RequestHandler';
|
|
7
|
+
export interface IRestEvents {
|
|
8
|
+
[RestEvents.Error]: [error: unknown];
|
|
9
|
+
[RestEvents.Debug]: [path: string, status: number, message: string];
|
|
10
|
+
[RestEvents.RateLimited]: [path: string, status: number, message: string];
|
|
11
|
+
}
|
|
12
|
+
export interface RESTManager {
|
|
13
|
+
emit: (<K extends keyof IRestEvents>(event: K, ...args: IRestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, ...args: any[]) => boolean);
|
|
14
|
+
off: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
15
|
+
on: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
16
|
+
once: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
17
|
+
removeAllListeners: (<K extends keyof IRestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof IRestEvents>) => this);
|
|
18
|
+
/**
|
|
19
|
+
* Emitted for general debugging information.
|
|
20
|
+
* @public
|
|
21
|
+
* @event
|
|
22
|
+
*/
|
|
23
|
+
debug: string;
|
|
24
|
+
/**
|
|
25
|
+
* Emitted when the client encounters an error.
|
|
26
|
+
* @public
|
|
27
|
+
* @event
|
|
28
|
+
*/
|
|
29
|
+
error: string;
|
|
30
|
+
/**
|
|
31
|
+
* Emitted when the client is rate limited.
|
|
32
|
+
* @public
|
|
33
|
+
* @event
|
|
34
|
+
*/
|
|
35
|
+
rateLimited: string;
|
|
36
|
+
}
|
|
4
37
|
/** Represents a REST Manager of the client. */
|
|
5
|
-
export declare class RESTManager {
|
|
38
|
+
export declare class RESTManager extends EventEmitter {
|
|
6
39
|
/** Request Handler for the RESTManager. */
|
|
7
|
-
|
|
40
|
+
requestHandler: RequestHandler;
|
|
8
41
|
constructor(options?: RESTOptions);
|
|
9
42
|
/** Contains various general-purpose utility methods. */
|
|
10
43
|
get util(): typeof Util;
|