This repository has been archived by the owner on Apr 3, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
BaseCluster.ts
74 lines (60 loc) · 2.31 KB
/
BaseCluster.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import type { GatewaySendPayload } from 'discord-api-types/v9';
import { EventEmitter } from 'events';
import { ClusterNode, ClusterNodeOptions } from '../ClusterNode';
import type { Player } from '../core/Player';
import type { VoiceServerUpdate, VoiceStateUpdate } from './BaseNode';
export interface ClusterFilter {
(node: ClusterNode, guildID: string): boolean;
}
export interface ClusterSend {
(guildID: string, packet: GatewaySendPayload): unknown;
}
export abstract class BaseCluster extends EventEmitter {
public abstract send: ClusterSend;
public abstract filter: ClusterFilter;
public readonly nodes: ClusterNode[] = [];
public constructor(options?: ClusterNodeOptions[]) {
super();
if (options) this.spawn(options);
}
public connect() {
return Promise.all(this.nodes.map((node) => node.connect()));
}
public spawn(options: ClusterNodeOptions): ClusterNode;
public spawn(options: ClusterNodeOptions[]): ClusterNode[];
public spawn(options: ClusterNodeOptions | ClusterNodeOptions[]): ClusterNode | ClusterNode[] {
if (Array.isArray(options)) return options.map((opt) => this.spawn(opt));
const node = new ClusterNode(this, options);
this.nodes.push(node);
return node;
}
public sort(): ClusterNode[] {
return this.nodes
.filter((n) => n.connected)
.sort((a, b) => {
// sort by overall system cpu load
if (!a.stats || !b.stats) return -1;
return (
(a.stats.cpu ? a.stats.cpu.systemLoad / a.stats.cpu.cores : 0) - (b.stats.cpu ? b.stats.cpu.systemLoad / b.stats.cpu.cores : 0)
);
});
}
public getNode(guildID: string): ClusterNode {
let node = this.nodes.find((node) => node.players.has(guildID));
if (!node) node = this.sort().find((node) => this.filter(node, guildID));
if (node) return node;
throw new Error('unable to find appropriate node; please check your filter');
}
public has(guildID: string): boolean {
return this.nodes.some((node) => node.players.has(guildID));
}
public get(guildID: string): Player<ClusterNode> {
return this.getNode(guildID).players.get(guildID);
}
public voiceStateUpdate(state: VoiceStateUpdate): Promise<boolean> {
return this.getNode(state.guild_id!).voiceStateUpdate(state);
}
public voiceServerUpdate(server: VoiceServerUpdate): Promise<boolean> {
return this.getNode(server.guild_id).voiceServerUpdate(server);
}
}