-
Notifications
You must be signed in to change notification settings - Fork 149
Expand file tree
/
Copy pathkillstreaks.js
More file actions
234 lines (205 loc) · 8.82 KB
/
killstreaks.js
File metadata and controls
234 lines (205 loc) · 8.82 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//Plugin by PSG - Ignis - Press Start Gaming
import BasePlugin from './base-plugin.js';
export default class Killstreak extends BasePlugin {
static get description() {
return 'The <code>Killstreak</code> plugin broadcasts when players are on a killstreak.';
}
static get defaultEnabled() {
return false;
}
static get optionsSpecification() {
return {
killstreakThreshold: {
required: false,
description: 'The number of kills required to be on a killstreak.',
default: 10
},
allowChatCommand: {
required: false,
description: 'Allow players to check their current killstreak with a chat command.',
default: false
},
chatCommand: {
required: false,
description: 'Chat Command for Players to see their Current Killstreak.',
default: '!killstreak'
},
cmdCooldown: {
required: false,
description: 'How frequently in minutes a user can use the chat command.',
default: 15
},
broadcastMessages: {
required: false,
description: 'The broadcast messages for each multiple of the killstreak threshold.',
default: [
"${attackerName} is on a 10 Killstreak, keep up the momentum!",
"${attackerName} is on a 20 Killstreak, no one can touch you!",
"${attackerName} is on a 30 Killstreak, you're on a killing spree!",
"${attackerName} is on a 40 Killstreak, the battlefield trembles before you!",
"${attackerName} is on a 50 Killstreak, your enemies are powerless to stop you!",
"${attackerName} is on a 60 Killstreak, leave no survivors!",
"${attackerName} is on a 70 Killstreak, the world quakes in fear!",
"${attackerName} is on a 80 Killstreak, you're a force of nature!",
"${attackerName} is on a 90 Killstreak, the battlefield is your domain!",
"${attackerName} is on a 100 Killstreak, you're a living legend among warriors!",
"${attackerName} is on a 110 Killstreak, you can turn those cheats off now!",
"${attackerName} is on a 120 Killstreak, seriously, turn off the cheats!",
"${attackerName} is on a 130 Killstreak, you're just showing off now!",
"${attackerName} is on a 140 Killstreak, you're a god among mortals!",
"${attackerName} is on a 150 Killstreak, you're a force of nature!",
]
},
buzzkillMessages: {
required: false,
description: 'The broadcast message when a player is killed while on a killstreak.',
default: [
'BUZZKILLER! ${attackerName} deleted ${victimName} who had a Killstreak of ${killstreak}!',
'BUZZKILLER! ${attackerName} deleted ${victimName} who was on a ${killstreak} Killstreak!'
]
}
};
}
constructor(server, options, connectors) {
super(server, options, connectors);
this.trackedKillstreaks = {};
if (this.options.allowChatCommand) {
this.onChatCommand = this.onChatCommand.bind(this);
}
this.onWound = this.onWound.bind(this);
this.onNewGame = this.onNewGame.bind(this);
this.onPlayerDisconnected = this.onPlayerDisconnected.bind(this);
this.onPlayerDied = this.onPlayerDied.bind(this);
}
async mount() {
this.server.on('NEW_GAME', this.onNewGame);
this.server.on('PLAYER_WOUNDED', this.onWound);
this.server.on('PLAYER_DIED', this.onPlayerDied);
this.server.on('PLAYER_DISCONNECTED', this.onPlayerDisconnected);
if (this.options.allowChatCommand) {
this.server.on(`CHAT_COMMAND:${this.options.chatCommand}`, this.onChatCommand);
}
this.verbose(1, 'Killstreaks Plugin was Mounted.');
}
async unmount() {
this.server.removeEventListener('NEW_GAME', this.onNewGame);
this.server.removeEventListener('PLAYER_WOUNDED', this.onWound);
this.server.removeEventListener('PLAYER_DIED', this.onPlayerDied);
this.server.removeEventListener('PLAYER_DISCONNECTED', this.onPlayerDisconnected);
if (this.options.allowChatCommand) {
this.server.removeEventListener(`CHAT_COMMAND:${this.options.chatCommand}`, this.onChatCommand);
}
this.verbose(1, 'Killstreaks Plugin was Unmounted.');
}
async onWound(info) {
if (!info.attacker) return;
if (info.teamkill === true) return;
// Get the attacker's Steam ID
const eosID = info.attackerEOSID;
// Check if this is the first time the attacker has made a killstreak
if (!this.trackedKillstreaks.hasOwnProperty(eosID)) {
// Set the player's initial killstreak to 0
this.trackedKillstreaks[eosID] = 0;
}
// Increment the player's kill streak by 1
this.trackedKillstreaks[eosID] += 1;
// Get the current killstreak index and value for the attacker
let killstreakIndex = this.trackedKillstreaks[eosID];
// Log the current killstreak value for debugging purposes
this.verbose(2, `KillstreakIndex for ${eosID}: ${killstreakIndex}`);
// Check if the attacker has reached the killstreak threshold
if (killstreakIndex % this.options.killstreakThreshold === 0) {
// Get the index of the current killstreak multiple
const multipleIndex = killstreakIndex / this.options.killstreakThreshold;
// Get the message for the current multiple from the config.json file
const messages = this.options.broadcastMessages || [];
const message =
messages[multipleIndex - 1] || `${attackerName} is on a ${killstreakIndex} Killstreak!`;
const broadcastText = this.replaceVariables(message, { attackerName: info.attacker.name });
this.server.rcon.broadcast(broadcastText);
}
}
async onPlayerDied(info) {
if (!info.victim.eosID) return;
// GC Factions to Account for Driods instant death
const gcDroidFactions = [
'Droid Army',
'Droid Army - Lego',
'Droid Army - SpecOps',
'Droid Army - Camo',
'Droid Army - Snow',
'Droid Army - Mech',
'Droid Army - Halloween',
'Droid Army - Geonosis'
];
// If info.victim.squad.teamName is in gcDroidFactions
if (gcDroidFactions.includes(info.victim.squad.teamName)) {
this.verbose(2, `Droid Army Detected: ${info.victim.squad.teamName}`);
// Call the onWound function with the info object
this.onWound(info);
}
const eosID = info.victim.eosID;
// Check if the victim has a killstreak
if (this.trackedKillstreaks.hasOwnProperty(eosID)) {
const killstreak = this.trackedKillstreaks[eosID];
if (killstreak >= this.options.killstreakThreshold) {
const killer = info.attacker;
if (killer) {
const messages = this.options.buzzkillMessages || [];
const message = messages[Math.floor(Math.random() * messages.length)] || 'BUZZKILLER! ${attackerName} deleted ${victimName} who was on a ${killstreak} Killstreak!';
const broadcastText = this.replaceVariables(message, { attackerName: killer.name, victimName: info.victim.name, killstreak: killstreak });
this.server.rcon.broadcast(broadcastText);
}
}
delete this.trackedKillstreaks[eosID];
} else {
delete this.trackedKillstreaks[eosID];
}
this.verbose(2, `KillstreakIndex reset for ${eosID} ${info.victim.name}`);
}
async onPlayerDisconnected(info) {
if (!info.eosID) return;
const eosID = info.eosID;
delete this.trackedKillstreaks[eosID];
}
async onNewGame() {
// Get an array of all the Steam IDs in the trackedKillstreaks object
const eosIDs = Object.keys(this.trackedKillstreaks);
// Loop through the array and delete each key-value pair
for (const eosID of eosIDs) {
delete this.trackedKillstreaks[eosID];
}
}
async onChatCommand(info) {
const currentTime = Date.now();
const lastExecutedTimes = this.lastChatCommandExecutionTimes || {};
const cooldownTime = this.options.cmdCooldown;
const eosID = info.player.eosID;
const lastExecutedTime = lastExecutedTimes[eosID] || 0;
const timeSinceLastExecution = (currentTime - lastExecutedTime) / 1000;
if (timeSinceLastExecution < cooldownTime) {
await this.server.rcon.warn(
eosID,
`Please wait ${Math.ceil(
cooldownTime - timeSinceLastExecution
)} minute(s) before using this command again.`
);
return;
}
const currentKillstreak = this.trackedKillstreaks[eosID] || 0;
await this.server.rcon.warn(
eosID,
`Current Killstreak: ${currentKillstreak}`
);
// Update last execution time
lastExecutedTimes[eosID] = currentTime;
this.lastChatCommandExecutionTimes = lastExecutedTimes;
}
replaceVariables(message, variables) {
for (const [variableName, variableValue] of Object.entries(variables)) {
const placeholder = '${' + variableName + '}';
message = message.replace(placeholder, variableValue);
}
return message;
}
}