@takaro/gameserver 0.0.0-next.0da151e
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 +36 -0
- package/dist/TakaroEmitter.d.ts +30 -0
- package/dist/TakaroEmitter.d.ts.map +1 -0
- package/dist/TakaroEmitter.js +101 -0
- package/dist/TakaroEmitter.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -0
- package/dist/gameservers/7d2d/apiResponses.d.ts +194 -0
- package/dist/gameservers/7d2d/apiResponses.d.ts.map +1 -0
- package/dist/gameservers/7d2d/apiResponses.js +2 -0
- package/dist/gameservers/7d2d/apiResponses.js.map +1 -0
- package/dist/gameservers/7d2d/connectionInfo.d.ts +38 -0
- package/dist/gameservers/7d2d/connectionInfo.d.ts.map +1 -0
- package/dist/gameservers/7d2d/connectionInfo.js +66 -0
- package/dist/gameservers/7d2d/connectionInfo.js.map +1 -0
- package/dist/gameservers/7d2d/emitter.d.ts +32 -0
- package/dist/gameservers/7d2d/emitter.d.ts.map +1 -0
- package/dist/gameservers/7d2d/emitter.js +273 -0
- package/dist/gameservers/7d2d/emitter.js.map +1 -0
- package/dist/gameservers/7d2d/index.d.ts +34 -0
- package/dist/gameservers/7d2d/index.d.ts.map +1 -0
- package/dist/gameservers/7d2d/index.js +304 -0
- package/dist/gameservers/7d2d/index.js.map +1 -0
- package/dist/gameservers/7d2d/itemWorker.d.ts +2 -0
- package/dist/gameservers/7d2d/itemWorker.d.ts.map +1 -0
- package/dist/gameservers/7d2d/itemWorker.js +36 -0
- package/dist/gameservers/7d2d/itemWorker.js.map +1 -0
- package/dist/gameservers/7d2d/items-7d2d.json +25051 -0
- package/dist/gameservers/7d2d/sdtdAPIClient.d.ts +19 -0
- package/dist/gameservers/7d2d/sdtdAPIClient.d.ts.map +1 -0
- package/dist/gameservers/7d2d/sdtdAPIClient.js +57 -0
- package/dist/gameservers/7d2d/sdtdAPIClient.js.map +1 -0
- package/dist/gameservers/generic/connectionInfo.d.ts +16 -0
- package/dist/gameservers/generic/connectionInfo.d.ts.map +1 -0
- package/dist/gameservers/generic/connectionInfo.js +29 -0
- package/dist/gameservers/generic/connectionInfo.js.map +1 -0
- package/dist/gameservers/generic/connectorClient.d.ts +7 -0
- package/dist/gameservers/generic/connectorClient.d.ts.map +1 -0
- package/dist/gameservers/generic/connectorClient.js +60 -0
- package/dist/gameservers/generic/connectorClient.js.map +1 -0
- package/dist/gameservers/generic/emitter.d.ts +13 -0
- package/dist/gameservers/generic/emitter.d.ts.map +1 -0
- package/dist/gameservers/generic/emitter.js +31 -0
- package/dist/gameservers/generic/emitter.js.map +1 -0
- package/dist/gameservers/generic/index.d.ts +36 -0
- package/dist/gameservers/generic/index.d.ts.map +1 -0
- package/dist/gameservers/generic/index.js +170 -0
- package/dist/gameservers/generic/index.js.map +1 -0
- package/dist/gameservers/rust/connectionInfo.d.ts +29 -0
- package/dist/gameservers/rust/connectionInfo.d.ts.map +1 -0
- package/dist/gameservers/rust/connectionInfo.js +51 -0
- package/dist/gameservers/rust/connectionInfo.js.map +1 -0
- package/dist/gameservers/rust/emitter.d.ts +32 -0
- package/dist/gameservers/rust/emitter.d.ts.map +1 -0
- package/dist/gameservers/rust/emitter.js +160 -0
- package/dist/gameservers/rust/emitter.js.map +1 -0
- package/dist/gameservers/rust/index.d.ts +35 -0
- package/dist/gameservers/rust/index.d.ts.map +1 -0
- package/dist/gameservers/rust/index.js +217 -0
- package/dist/gameservers/rust/index.js.map +1 -0
- package/dist/gameservers/rust/items-rust.json +20771 -0
- package/dist/getGame.d.ts +10 -0
- package/dist/getGame.d.ts.map +1 -0
- package/dist/getGame.js +27 -0
- package/dist/getGame.js.map +1 -0
- package/dist/interfaces/GameServer.d.ts +99 -0
- package/dist/interfaces/GameServer.d.ts.map +1 -0
- package/dist/interfaces/GameServer.js +235 -0
- package/dist/interfaces/GameServer.js.map +1 -0
- package/dist/main.d.ts +12 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +12 -0
- package/dist/main.js.map +1 -0
- package/package.json +16 -0
- package/src/TakaroEmitter.ts +146 -0
- package/src/TakaroEmitter.unit.test.ts +201 -0
- package/src/__tests__/gameEventEmitter.test.ts +29 -0
- package/src/config.ts +20 -0
- package/src/gameservers/7d2d/__tests__/7d2dActions.unit.test.ts +96 -0
- package/src/gameservers/7d2d/__tests__/7d2dEventDetection.unit.test.ts +424 -0
- package/src/gameservers/7d2d/apiResponses.ts +213 -0
- package/src/gameservers/7d2d/connectionInfo.ts +46 -0
- package/src/gameservers/7d2d/emitter.ts +334 -0
- package/src/gameservers/7d2d/emitter.unit.test.ts +117 -0
- package/src/gameservers/7d2d/index.ts +367 -0
- package/src/gameservers/7d2d/itemWorker.ts +41 -0
- package/src/gameservers/7d2d/items-7d2d.json +25051 -0
- package/src/gameservers/7d2d/sdtdAPIClient.ts +82 -0
- package/src/gameservers/generic/connectionInfo.ts +19 -0
- package/src/gameservers/generic/connectorClient.ts +73 -0
- package/src/gameservers/generic/emitter.ts +36 -0
- package/src/gameservers/generic/index.ts +193 -0
- package/src/gameservers/rust/__tests__/rustActions.unit.test.ts +141 -0
- package/src/gameservers/rust/connectionInfo.ts +35 -0
- package/src/gameservers/rust/emitter.ts +198 -0
- package/src/gameservers/rust/emitter.unit.test.ts +95 -0
- package/src/gameservers/rust/index.ts +270 -0
- package/src/gameservers/rust/items-rust.json +20771 -0
- package/src/getGame.ts +34 -0
- package/src/interfaces/GameServer.ts +215 -0
- package/src/main.ts +16 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +9 -0
- package/typedoc.json +3 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { logger } from '@takaro/util';
|
|
2
|
+
import EventSource from 'eventsource';
|
|
3
|
+
import { ChatChannel, EventChatMessage, EventEntityKilled, EventLogLine, EventPlayerConnected, EventPlayerDeath, EventPlayerDisconnected, GameEvents, IGamePlayer, } from '@takaro/modules';
|
|
4
|
+
import { TakaroEmitter } from '../../TakaroEmitter.js';
|
|
5
|
+
import { SevenDaysToDie } from './index.js';
|
|
6
|
+
import ms from 'ms';
|
|
7
|
+
/**
|
|
8
|
+
* 7d2d servers can get really spammy with bugged vehicles, buggy mods, etc.
|
|
9
|
+
* This is a list of messages that we don't want to emit events for.
|
|
10
|
+
*/
|
|
11
|
+
const blackListedMessages = [
|
|
12
|
+
'NullReferenceException',
|
|
13
|
+
'Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider',
|
|
14
|
+
'IsMovementBlocked',
|
|
15
|
+
'Particle System is trying to spawn on a mesh with zero surface area',
|
|
16
|
+
'AddDecorationAt',
|
|
17
|
+
'EntityFactory CreateEntity: unknown type',
|
|
18
|
+
'DroneManager',
|
|
19
|
+
'VehicleManager',
|
|
20
|
+
'kinematic body',
|
|
21
|
+
];
|
|
22
|
+
const EventRegexMap = {
|
|
23
|
+
[GameEvents.PLAYER_CONNECTED]: /PlayerSpawnedInWorld \(reason: (JoinMultiplayer|EnterMultiplayer), position: [-\d]+, [-\d]+, [-\d]+\): EntityID=(?<entityId>[-\d]+), PltfmId='(Steam|XBL)_[\w\d]+', CrossId='EOS_[\w\d]+', OwnerID='(Steam|XBL)_\d+', PlayerName='(?<name>.+)'/,
|
|
24
|
+
[GameEvents.PLAYER_DISCONNECTED]: /(Player disconnected: )/,
|
|
25
|
+
[GameEvents.CHAT_MESSAGE]: /Chat \(from '(?<platformId>[\w\d-]+)', entity id '(?<entityId>[-\d]+)', to '(?<channel>\w+)'\): ('(?<playerName>.+)':)?(?<message>.+)/,
|
|
26
|
+
[GameEvents.PLAYER_DEATH]: /GMSG: Player '(?<name1>.+)' died|\[(?:CSMM_Patrons|PrismaCore)\]playerDied: (?<name2>.+) \((?<steamOrXboxId>.+)\) died @ (?<xCoord>[-\d]+) (?<yCoord>[-\d]+) (?<zCoord>[-\d]+)/,
|
|
27
|
+
[GameEvents.ENTITY_KILLED]: /\[(?:CSMM_Patrons|PrismaCore)\]entityKilled: (?<killerName>.+) \((?<steamOrXboxId>.+)\) killed (?<entityType>\w+) (?<entityName>[\w\s\u00C0-\u024F\[\]-]+) with (?<weapon>.+)|Entity (?<entityName2>[\w\s\u00C0-\u024F]+) \d+ killed by (?<killerName2>.+) \d+/,
|
|
28
|
+
};
|
|
29
|
+
export class SevenDaysToDieEmitter extends TakaroEmitter {
|
|
30
|
+
constructor(config) {
|
|
31
|
+
super();
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.SSERegex = /\d+-\d+-\d+T\d+:\d+:\d+ \d+\.\d+ INF (.+)/;
|
|
34
|
+
this.logger = logger('7D2D:SSE');
|
|
35
|
+
this.recentMessages = new Set(); // To track recent messages
|
|
36
|
+
this.lastMessageTimestamp = Date.now();
|
|
37
|
+
this.keepAliveTimeout = ms('5minutes');
|
|
38
|
+
this.boundListener = (data) => this.listener(data);
|
|
39
|
+
this.sdtd = new SevenDaysToDie(config, {});
|
|
40
|
+
}
|
|
41
|
+
isModdedFormat(msg) {
|
|
42
|
+
return msg.includes('[CSMM_Patrons]') || msg.includes('[PrismaCore]');
|
|
43
|
+
}
|
|
44
|
+
get url() {
|
|
45
|
+
if (this.config.useLegacy) {
|
|
46
|
+
return `${this.config.useTls ? 'https' : 'http'}://${this.config.host}/sse/log`;
|
|
47
|
+
}
|
|
48
|
+
return `${this.config.useTls ? 'https' : 'http'}://${this.config.host}/sse/?events=log`;
|
|
49
|
+
}
|
|
50
|
+
async start() {
|
|
51
|
+
this.checkInterval = setInterval(() => {
|
|
52
|
+
if (Date.now() - this.lastMessageTimestamp >= this.keepAliveTimeout) {
|
|
53
|
+
this.logger.warn(`No messages received for ${ms(this.keepAliveTimeout, { long: true })}. Reconnecting...`);
|
|
54
|
+
this.lastMessageTimestamp = Date.now();
|
|
55
|
+
this.stop()
|
|
56
|
+
.then(() => this.start())
|
|
57
|
+
.catch((err) => this.logger.error('Error during reconnection', err));
|
|
58
|
+
}
|
|
59
|
+
}, 5000);
|
|
60
|
+
await Promise.race([
|
|
61
|
+
new Promise((resolve, reject) => {
|
|
62
|
+
this.logger.debug(`Connecting to ${this.config.host}`);
|
|
63
|
+
this.eventSource = new EventSource(this.url, {
|
|
64
|
+
headers: {
|
|
65
|
+
'X-SDTD-API-TOKENNAME': this.config.adminUser,
|
|
66
|
+
'X-SDTD-API-SECRET': this.config.adminToken,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
this.eventSource.addEventListener('logLine', this.boundListener);
|
|
70
|
+
this.eventSource.onerror = (e) => {
|
|
71
|
+
this.logger.error('Event source error', e);
|
|
72
|
+
return reject(e);
|
|
73
|
+
};
|
|
74
|
+
this.eventSource.onopen = () => {
|
|
75
|
+
this.logger.debug('Opened a SSE channel for server');
|
|
76
|
+
return resolve();
|
|
77
|
+
};
|
|
78
|
+
}),
|
|
79
|
+
new Promise((_resolve, reject) => {
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
reject(new Error('Timed out'));
|
|
82
|
+
}, 30000);
|
|
83
|
+
}),
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
async stop() {
|
|
87
|
+
if (this.checkInterval) {
|
|
88
|
+
clearInterval(this.checkInterval);
|
|
89
|
+
}
|
|
90
|
+
this.eventSource.removeEventListener('logLine', this.boundListener);
|
|
91
|
+
this.eventSource.close();
|
|
92
|
+
}
|
|
93
|
+
async parseMessage(logLine) {
|
|
94
|
+
this.logger.silly(`Received message from game server: ${logLine.msg}`);
|
|
95
|
+
if (!logLine.msg || typeof logLine.msg !== 'string') {
|
|
96
|
+
throw new Error('Invalid logLine');
|
|
97
|
+
}
|
|
98
|
+
if (blackListedMessages.some((msg) => logLine.msg.includes(msg))) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (EventRegexMap[GameEvents.PLAYER_CONNECTED].test(logLine.msg)) {
|
|
102
|
+
const data = await this.handlePlayerConnected(logLine);
|
|
103
|
+
await this.emit(GameEvents.PLAYER_CONNECTED, data);
|
|
104
|
+
}
|
|
105
|
+
if (EventRegexMap[GameEvents.PLAYER_DISCONNECTED].test(logLine.msg)) {
|
|
106
|
+
const data = await this.handlePlayerDisconnected(logLine);
|
|
107
|
+
await this.emit(GameEvents.PLAYER_DISCONNECTED, data);
|
|
108
|
+
}
|
|
109
|
+
if (EventRegexMap[GameEvents.CHAT_MESSAGE].test(logLine.msg)) {
|
|
110
|
+
const data = await this.handleChatMessage(logLine);
|
|
111
|
+
if (data)
|
|
112
|
+
await this.emit(GameEvents.CHAT_MESSAGE, data);
|
|
113
|
+
}
|
|
114
|
+
if (EventRegexMap[GameEvents.PLAYER_DEATH].test(logLine.msg)) {
|
|
115
|
+
const data = await this.handlePlayerDeath(logLine);
|
|
116
|
+
if (data)
|
|
117
|
+
await this.emit(GameEvents.PLAYER_DEATH, data);
|
|
118
|
+
}
|
|
119
|
+
if (EventRegexMap[GameEvents.ENTITY_KILLED].test(logLine.msg)) {
|
|
120
|
+
const data = await this.handleEntityKilled(logLine);
|
|
121
|
+
if (data)
|
|
122
|
+
await this.emit(GameEvents.ENTITY_KILLED, data);
|
|
123
|
+
}
|
|
124
|
+
await this.emit(GameEvents.LOG_LINE, new EventLogLine({
|
|
125
|
+
msg: logLine.msg,
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
async handlePlayerConnected(logLine) {
|
|
129
|
+
const nameMatches = /PlayerName='([^']+)/.exec(logLine.msg);
|
|
130
|
+
const platformIdMatches = /PltfmId='(.+)', CrossId=/.exec(logLine.msg);
|
|
131
|
+
const crossIdMatches = /CrossId='(.+)', OwnerID/.exec(logLine.msg);
|
|
132
|
+
const name = nameMatches ? nameMatches[1] : 'Unknown name';
|
|
133
|
+
const platformId = platformIdMatches ? platformIdMatches[1] : null;
|
|
134
|
+
const epicOnlineServicesId = crossIdMatches ? crossIdMatches[1].replace('EOS_', '') : undefined;
|
|
135
|
+
const gameId = epicOnlineServicesId;
|
|
136
|
+
const steamId = platformId && platformId.startsWith('Steam_') ? platformId.replace('Steam_', '') : undefined;
|
|
137
|
+
const xboxLiveId = platformId && platformId.startsWith('XBL_') ? platformId.replace('XBL_', '') : undefined;
|
|
138
|
+
if (!gameId)
|
|
139
|
+
throw new Error('Could not find gameId');
|
|
140
|
+
return new EventPlayerConnected({
|
|
141
|
+
msg: logLine.msg,
|
|
142
|
+
player: new IGamePlayer({
|
|
143
|
+
name,
|
|
144
|
+
gameId,
|
|
145
|
+
steamId,
|
|
146
|
+
xboxLiveId,
|
|
147
|
+
epicOnlineServicesId,
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async handlePlayerDisconnected(logLine) {
|
|
152
|
+
const nameMatch = /PlayerName='([^']+)/.exec(logLine.msg);
|
|
153
|
+
const platformIdMatches = /PltfmId='(.+)', CrossId=/.exec(logLine.msg);
|
|
154
|
+
const crossIdMatches = /CrossId='(.+)', OwnerID/.exec(logLine.msg);
|
|
155
|
+
const name = nameMatch ? nameMatch[1] : 'Unknown name';
|
|
156
|
+
const platformId = platformIdMatches ? platformIdMatches[1] : null;
|
|
157
|
+
const steamId = platformId && platformId.startsWith('Steam_') ? platformId.replace('Steam_', '') : undefined;
|
|
158
|
+
const xboxLiveId = platformId && platformId.startsWith('XBL_') ? platformId.replace('XBL_', '') : undefined;
|
|
159
|
+
const epicOnlineServicesId = crossIdMatches ? crossIdMatches[1].replace('EOS_', '') : undefined;
|
|
160
|
+
const gameId = epicOnlineServicesId;
|
|
161
|
+
if (!gameId)
|
|
162
|
+
throw new Error('Could not find gameId');
|
|
163
|
+
return new EventPlayerDisconnected({
|
|
164
|
+
msg: logLine.msg,
|
|
165
|
+
player: new IGamePlayer({
|
|
166
|
+
name,
|
|
167
|
+
gameId,
|
|
168
|
+
steamId,
|
|
169
|
+
xboxLiveId,
|
|
170
|
+
}),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async handleChatMessage(logLine) {
|
|
174
|
+
const match = EventRegexMap[GameEvents.CHAT_MESSAGE].exec(logLine.msg);
|
|
175
|
+
if (!match)
|
|
176
|
+
throw new Error('Could not parse chat message');
|
|
177
|
+
const { groups } = match;
|
|
178
|
+
if (!groups)
|
|
179
|
+
throw new Error('Could not parse chat message');
|
|
180
|
+
const { platformId, name, message, channel } = groups;
|
|
181
|
+
if (platformId === '-non-player-' && name !== 'Server') {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const trimmedMessage = message.trim();
|
|
185
|
+
if (this.recentMessages.has(trimmedMessage)) {
|
|
186
|
+
return; // Ignore if recently processed
|
|
187
|
+
}
|
|
188
|
+
this.recentMessages.add(trimmedMessage);
|
|
189
|
+
setTimeout(() => this.recentMessages.delete(trimmedMessage), 1000);
|
|
190
|
+
const xboxLiveId = platformId.startsWith('XBL_') ? platformId.replace('XBL_', '') : undefined;
|
|
191
|
+
const steamId = platformId.startsWith('Steam_') ? platformId.replace('Steam_', '') : undefined;
|
|
192
|
+
if (steamId || xboxLiveId) {
|
|
193
|
+
const id = steamId || xboxLiveId || '';
|
|
194
|
+
const player = await this.sdtd.steamIdOrXboxToGameId(id);
|
|
195
|
+
let detectedChannel = ChatChannel.GLOBAL;
|
|
196
|
+
switch (channel) {
|
|
197
|
+
case 'Global':
|
|
198
|
+
detectedChannel = ChatChannel.GLOBAL;
|
|
199
|
+
break;
|
|
200
|
+
case 'Party':
|
|
201
|
+
detectedChannel = ChatChannel.TEAM;
|
|
202
|
+
break;
|
|
203
|
+
case 'Friends':
|
|
204
|
+
detectedChannel = ChatChannel.FRIENDS;
|
|
205
|
+
break;
|
|
206
|
+
default:
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (player) {
|
|
210
|
+
return new EventChatMessage({
|
|
211
|
+
player,
|
|
212
|
+
channel: detectedChannel,
|
|
213
|
+
msg: trimmedMessage.trim(),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async handlePlayerDeath(logLine) {
|
|
219
|
+
if (this.isModdedFormat(logLine.msg) && !this.config.useCPM)
|
|
220
|
+
return;
|
|
221
|
+
if (logLine.msg.includes('GMSG') && this.config.useCPM)
|
|
222
|
+
return;
|
|
223
|
+
const match = EventRegexMap[GameEvents.PLAYER_DEATH].exec(logLine.msg);
|
|
224
|
+
if (!match)
|
|
225
|
+
throw new Error('Could not parse player death message');
|
|
226
|
+
const { groups } = match;
|
|
227
|
+
if (!groups)
|
|
228
|
+
throw new Error('Could not parse player death message');
|
|
229
|
+
const { xCoord, yCoord, zCoord, steamOrXboxId } = groups;
|
|
230
|
+
const player = await this.sdtd.steamIdOrXboxToGameId(steamOrXboxId);
|
|
231
|
+
return new EventPlayerDeath({
|
|
232
|
+
msg: logLine.msg,
|
|
233
|
+
player,
|
|
234
|
+
position: {
|
|
235
|
+
x: parseFloat(xCoord),
|
|
236
|
+
y: parseFloat(yCoord),
|
|
237
|
+
z: parseFloat(zCoord),
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
async handleEntityKilled(logLine) {
|
|
242
|
+
if (this.isModdedFormat(logLine.msg) && !this.config.useCPM)
|
|
243
|
+
return;
|
|
244
|
+
if (logLine.msg.includes('killed by') && this.config.useCPM)
|
|
245
|
+
return;
|
|
246
|
+
const match = EventRegexMap[GameEvents.ENTITY_KILLED].exec(logLine.msg);
|
|
247
|
+
if (!match)
|
|
248
|
+
throw new Error('Could not parse entity killed message');
|
|
249
|
+
const { groups } = match;
|
|
250
|
+
if (!groups)
|
|
251
|
+
throw new Error('Could not parse entity killed message');
|
|
252
|
+
// Extracting the relevant details from the named groups
|
|
253
|
+
const { entityName, entityName2, weapon, steamOrXboxId } = groups;
|
|
254
|
+
const player = await this.sdtd.steamIdOrXboxToGameId(steamOrXboxId);
|
|
255
|
+
// Constructing the EventEntityKilled object with the parsed data
|
|
256
|
+
return new EventEntityKilled({
|
|
257
|
+
msg: logLine.msg,
|
|
258
|
+
entity: entityName || entityName2,
|
|
259
|
+
player,
|
|
260
|
+
weapon: weapon || undefined, // Assuming that 'weapon' might not be present in some log lines
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async listener(data) {
|
|
264
|
+
this.lastMessageTimestamp = Date.now();
|
|
265
|
+
const parsed = JSON.parse(data.data);
|
|
266
|
+
const messageMatch = this.SSERegex.exec(parsed.msg);
|
|
267
|
+
if (messageMatch && messageMatch[1]) {
|
|
268
|
+
parsed.msg = messageMatch[1];
|
|
269
|
+
}
|
|
270
|
+
await this.parseMessage(parsed);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../../src/gameservers/7d2d/emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IGamePlayer, IPosition } from '@takaro/modules';
|
|
2
|
+
import { BanDTO, CommandOutput, IEntityDTO, IGameServer, IItemDTO, IMessageOptsDTO, IPlayerReferenceDTO, TestReachabilityOutputDTO, ILocationDTO } from '../../interfaces/GameServer.js';
|
|
3
|
+
import { SevenDaysToDieEmitter } from './emitter.js';
|
|
4
|
+
import { Settings } from '@takaro/apiclient';
|
|
5
|
+
import { SdtdConnectionInfo } from './connectionInfo.js';
|
|
6
|
+
export declare class SevenDaysToDie implements IGameServer {
|
|
7
|
+
private settings;
|
|
8
|
+
private logger;
|
|
9
|
+
private apiClient;
|
|
10
|
+
connectionInfo: SdtdConnectionInfo;
|
|
11
|
+
constructor(config: SdtdConnectionInfo, settings?: Partial<Settings>);
|
|
12
|
+
getEventEmitter(): SevenDaysToDieEmitter;
|
|
13
|
+
getPlayer(player: IPlayerReferenceDTO): Promise<IGamePlayer | null>;
|
|
14
|
+
getPlayers(): Promise<IGamePlayer[]>;
|
|
15
|
+
steamIdOrXboxToGameId(id: string): Promise<IGamePlayer | undefined>;
|
|
16
|
+
getPlayerLocation(player: IPlayerReferenceDTO): Promise<IPosition | null>;
|
|
17
|
+
giveItem(player: IPlayerReferenceDTO, item: string, amount?: number, quality?: string): Promise<void>;
|
|
18
|
+
testReachability(): Promise<TestReachabilityOutputDTO>;
|
|
19
|
+
executeConsoleCommand(rawCommand: string): Promise<CommandOutput>;
|
|
20
|
+
sendMessage(message: string, opts?: IMessageOptsDTO): Promise<void>;
|
|
21
|
+
teleportPlayer(player: IGamePlayer, x: number, y: number, z: number, _dimension?: string): Promise<void>;
|
|
22
|
+
kickPlayer(player: IPlayerReferenceDTO, reason: string): Promise<void>;
|
|
23
|
+
banPlayer(options: BanDTO): Promise<void>;
|
|
24
|
+
unbanPlayer(player: IPlayerReferenceDTO): Promise<void>;
|
|
25
|
+
listBans(): Promise<BanDTO[]>;
|
|
26
|
+
listItems(): Promise<IItemDTO[]>;
|
|
27
|
+
getPlayerInventory(player: IPlayerReferenceDTO): Promise<IItemDTO[]>;
|
|
28
|
+
shutdown(): Promise<void>;
|
|
29
|
+
getMapInfo(): Promise<import("../../interfaces/GameServer.js").MapInfoDTO>;
|
|
30
|
+
getMapTile(x: number, y: number, z: number): Promise<string>;
|
|
31
|
+
listEntities(): Promise<IEntityDTO[]>;
|
|
32
|
+
listLocations(): Promise<ILocationDTO[]>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gameservers/7d2d/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACL,MAAM,EACN,aAAa,EACb,UAAU,EACV,WAAW,EACX,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,YAAY,EACb,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASzD,qBACa,cAAe,YAAW,WAAW;IAO9C,OAAO,CAAC,QAAQ;IANlB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAgB;IACjC,cAAc,EAAE,kBAAkB,CAAC;gBAGjC,MAAM,EAAE,kBAAkB,EAClB,QAAQ,GAAE,OAAO,CAAC,QAAQ,CAAM;IAM1C,eAAe;IAKT,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAKnE,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IA4BpC,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IASnE,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAezE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxG,gBAAgB,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAwCtD,qBAAqB,CAAC,UAAU,EAAE,MAAM;IAWxC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe;IAqBnD,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAMxF,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM;IAKtD,SAAS,CAAC,OAAO,EAAE,MAAM;IAwCzB,WAAW,CAAC,MAAM,EAAE,mBAAmB;IAKvC,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAsC7B,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IA4BhC,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA6BpE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzB,UAAU;IAIV,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAI1C,YAAY,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIrC,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAG/C"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { errors, logger, traceableClass } from '@takaro/util';
|
|
11
|
+
import { IGamePlayer, IPosition } from '@takaro/modules';
|
|
12
|
+
import { BanDTO, CommandOutput, IItemDTO, TestReachabilityOutputDTO, } from '../../interfaces/GameServer.js';
|
|
13
|
+
import { SevenDaysToDieEmitter } from './emitter.js';
|
|
14
|
+
import { SdtdApiClient } from './sdtdAPIClient.js';
|
|
15
|
+
import { SdtdConnectionInfo } from './connectionInfo.js';
|
|
16
|
+
import { Worker } from 'worker_threads';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import * as url from 'url';
|
|
19
|
+
import { DateTime, Duration } from 'luxon';
|
|
20
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
21
|
+
let SevenDaysToDie = class SevenDaysToDie {
|
|
22
|
+
constructor(config, settings = {}) {
|
|
23
|
+
this.settings = settings;
|
|
24
|
+
this.logger = logger('7D2D');
|
|
25
|
+
this.connectionInfo = config;
|
|
26
|
+
this.apiClient = new SdtdApiClient(this.connectionInfo);
|
|
27
|
+
}
|
|
28
|
+
getEventEmitter() {
|
|
29
|
+
const emitter = new SevenDaysToDieEmitter(this.connectionInfo);
|
|
30
|
+
return emitter;
|
|
31
|
+
}
|
|
32
|
+
async getPlayer(player) {
|
|
33
|
+
const players = await this.getPlayers();
|
|
34
|
+
return players.find((p) => p.gameId === player.gameId) || null;
|
|
35
|
+
}
|
|
36
|
+
async getPlayers() {
|
|
37
|
+
const onlinePlayersRes = await this.apiClient.getOnlinePlayers();
|
|
38
|
+
const players = await Promise.all(onlinePlayersRes.data.map((p) => {
|
|
39
|
+
const data = {
|
|
40
|
+
gameId: p.crossplatformid.replace('EOS_', ''),
|
|
41
|
+
ip: p.ip,
|
|
42
|
+
name: p.name,
|
|
43
|
+
epicOnlineServicesId: p.crossplatformid.replace('EOS_', ''),
|
|
44
|
+
ping: p.ping,
|
|
45
|
+
};
|
|
46
|
+
if (p.steamid.startsWith('XBL_')) {
|
|
47
|
+
data.xboxLiveId = p.steamid.replace('XBL_', '');
|
|
48
|
+
}
|
|
49
|
+
if (p.steamid.startsWith('Steam_')) {
|
|
50
|
+
data.steamId = p.steamid.replace('Steam_', '');
|
|
51
|
+
}
|
|
52
|
+
return new IGamePlayer(data);
|
|
53
|
+
}));
|
|
54
|
+
return players;
|
|
55
|
+
}
|
|
56
|
+
async steamIdOrXboxToGameId(id) {
|
|
57
|
+
if (!id)
|
|
58
|
+
return undefined;
|
|
59
|
+
if (id.startsWith('Steam_'))
|
|
60
|
+
id = id.replace('Steam_', '');
|
|
61
|
+
if (id.startsWith('XBL_'))
|
|
62
|
+
id = id.replace('XBL_', '');
|
|
63
|
+
const players = await this.getPlayers();
|
|
64
|
+
const player = players.find((p) => p.steamId === id || p.epicOnlineServicesId === id || p.xboxLiveId === id);
|
|
65
|
+
return player;
|
|
66
|
+
}
|
|
67
|
+
async getPlayerLocation(player) {
|
|
68
|
+
const locations = await this.apiClient.getPlayersLocation();
|
|
69
|
+
const playerLocation = locations.data.find((location) => location.crossplatformid === `EOS_${player.gameId}`);
|
|
70
|
+
if (!playerLocation) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return new IPosition({
|
|
74
|
+
x: playerLocation.position.x,
|
|
75
|
+
y: playerLocation.position.y,
|
|
76
|
+
z: playerLocation.position.z,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async giveItem(player, item, amount = 1, quality) {
|
|
80
|
+
const command = this.connectionInfo.useCPM
|
|
81
|
+
? `giveplus EOS_${player.gameId} ${item} ${amount} ${quality ? quality + ' 0' : ''}`
|
|
82
|
+
: `give EOS_${player.gameId} ${item} ${amount} ${quality ?? ''}`;
|
|
83
|
+
const res = await this.executeConsoleCommand(command);
|
|
84
|
+
if (this.connectionInfo.useCPM && !res.rawResult.includes('Item(s) given')) {
|
|
85
|
+
this.logger.error('Failed to give item', { player, item, amount, quality, rawResult: res.rawResult });
|
|
86
|
+
if (res.rawResult.includes('does not support quality')) {
|
|
87
|
+
this.logger.warn('Item does not support quality, retrying without quality');
|
|
88
|
+
return this.giveItem(player, item, amount);
|
|
89
|
+
}
|
|
90
|
+
throw new errors.BadRequestError(`Failed to give item. Result: "${res.rawResult}"`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async testReachability() {
|
|
94
|
+
const start = Date.now();
|
|
95
|
+
try {
|
|
96
|
+
const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('Request timed out')), 10000));
|
|
97
|
+
await Promise.all([
|
|
98
|
+
Promise.race([this.apiClient.getStats(), timeout]),
|
|
99
|
+
Promise.race([this.executeConsoleCommand('version'), timeout]),
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
let reason = 'Unexpected error, this might be a bug';
|
|
104
|
+
this.logger.warn('Reachability test requests failed', error);
|
|
105
|
+
if (error instanceof Object && 'details' in error) {
|
|
106
|
+
reason =
|
|
107
|
+
'Did not receive a response, please check that the server is running, the IP/port is correct and that it is not firewalled';
|
|
108
|
+
if (error.details instanceof Object) {
|
|
109
|
+
if ('status' in error.details) {
|
|
110
|
+
if (error.details.status === 403 || error.details.status === 401) {
|
|
111
|
+
reason = 'Unauthorized, please check that the admin user and token are correct';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (error instanceof Object && 'message' in error && error.message === 'Request timed out') {
|
|
117
|
+
reason = 'Request timed out, the server did not respond in the allocated time';
|
|
118
|
+
}
|
|
119
|
+
return new TestReachabilityOutputDTO({
|
|
120
|
+
connectable: false,
|
|
121
|
+
reason,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const end = Date.now();
|
|
125
|
+
return new TestReachabilityOutputDTO({
|
|
126
|
+
connectable: true,
|
|
127
|
+
latency: end - start,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async executeConsoleCommand(rawCommand) {
|
|
131
|
+
const encodedCommand = encodeURIComponent(rawCommand);
|
|
132
|
+
const result = await this.apiClient.executeConsoleCommand(encodedCommand);
|
|
133
|
+
this.logger.debug(`Executed command: "${rawCommand}"`, { rawCommand, result: result.data.result.slice(0, 1000) });
|
|
134
|
+
return new CommandOutput({
|
|
135
|
+
rawResult: result.data.result,
|
|
136
|
+
success: true,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async sendMessage(message, opts) {
|
|
140
|
+
const escapedMessage = message.replaceAll(/"/g, "'");
|
|
141
|
+
let command = `say "${escapedMessage}"`;
|
|
142
|
+
if (opts?.recipient?.gameId) {
|
|
143
|
+
command = `sayplayer "EOS_${opts.recipient.gameId}" "${escapedMessage}"`;
|
|
144
|
+
}
|
|
145
|
+
if (this.connectionInfo.useCPM) {
|
|
146
|
+
const sender = opts?.senderNameOverride || this.settings.serverChatName || 'Takaro';
|
|
147
|
+
command = `say2 "${sender}" "${escapedMessage}"`;
|
|
148
|
+
if (opts?.recipient?.gameId) {
|
|
149
|
+
command = `pm2 "${sender}" "EOS_${opts.recipient.gameId}" "${escapedMessage}"`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
await this.executeConsoleCommand(command);
|
|
153
|
+
}
|
|
154
|
+
async teleportPlayer(player, x, y, z, _dimension) {
|
|
155
|
+
// 7D2D doesn't support dimensions, so we ignore the dimension parameter
|
|
156
|
+
const command = `teleportplayer EOS_${player.gameId} ${x} ${y} ${z}`;
|
|
157
|
+
await this.executeConsoleCommand(command);
|
|
158
|
+
}
|
|
159
|
+
async kickPlayer(player, reason) {
|
|
160
|
+
const command = `kick "EOS_${player.gameId}" "${reason}"`;
|
|
161
|
+
await this.executeConsoleCommand(command);
|
|
162
|
+
}
|
|
163
|
+
async banPlayer(options) {
|
|
164
|
+
// If no expiresAt is provided, assume 'permanent'. 500 years is pretty long ;)
|
|
165
|
+
const expiresAt = options.expiresAt ?? '2521-01-01T00:00:00.000';
|
|
166
|
+
const expiresAtDate = DateTime.fromISO(expiresAt);
|
|
167
|
+
const now = DateTime.local();
|
|
168
|
+
let duration = Duration.fromMillis(expiresAtDate.diff(now).milliseconds);
|
|
169
|
+
let unit = 'minute';
|
|
170
|
+
duration = duration.shiftTo('minutes'); // Convert to minutes
|
|
171
|
+
if (duration.minutes >= 60) {
|
|
172
|
+
unit = 'hour';
|
|
173
|
+
duration = duration.shiftTo('hours'); // Convert to hours
|
|
174
|
+
}
|
|
175
|
+
if (duration.hours >= 24) {
|
|
176
|
+
unit = 'day';
|
|
177
|
+
duration = duration.shiftTo('days'); // Convert to days
|
|
178
|
+
}
|
|
179
|
+
if (duration.days >= 7) {
|
|
180
|
+
unit = 'week';
|
|
181
|
+
duration = duration.shiftTo('weeks'); // Convert to weeks
|
|
182
|
+
}
|
|
183
|
+
if (duration.weeks >= 4) {
|
|
184
|
+
unit = 'month';
|
|
185
|
+
duration = duration.shiftTo('months'); // Convert to months
|
|
186
|
+
}
|
|
187
|
+
if (duration.months >= 12) {
|
|
188
|
+
unit = 'year';
|
|
189
|
+
duration = duration.shiftTo('years'); // Convert to years
|
|
190
|
+
}
|
|
191
|
+
const command = `ban add EOS_${options.player.gameId} ${Math.round(duration.as(unit))} ${unit} "${options.reason}"`;
|
|
192
|
+
await this.executeConsoleCommand(command);
|
|
193
|
+
}
|
|
194
|
+
async unbanPlayer(player) {
|
|
195
|
+
const command = `ban remove EOS_${player.gameId}`;
|
|
196
|
+
await this.executeConsoleCommand(command);
|
|
197
|
+
}
|
|
198
|
+
async listBans() {
|
|
199
|
+
// Execute the console command and get the raw result.
|
|
200
|
+
const bansRes = await this.executeConsoleCommand('ban list');
|
|
201
|
+
// Check if the command was successful and if there is a raw result.
|
|
202
|
+
if (!bansRes.success || !bansRes.rawResult) {
|
|
203
|
+
throw new Error('Failed to retrieve ban list.');
|
|
204
|
+
}
|
|
205
|
+
// Extract and parse the bans from the raw result.
|
|
206
|
+
const banEntries = bansRes.rawResult.split('\n').slice(1); // Skip the header line
|
|
207
|
+
const bans = [];
|
|
208
|
+
for (const entry of banEntries) {
|
|
209
|
+
const match = entry.match(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - (\S+) \(([^)]*)\) - (.*)/);
|
|
210
|
+
// If the entry is valid, extract the details and push to the bans array.
|
|
211
|
+
if (match) {
|
|
212
|
+
const [, date, gameId, _displayName, reason] = match;
|
|
213
|
+
const expiresAt = date.replace(' ', 'T') + '.000Z'; // Keep the time in its original form
|
|
214
|
+
// If the saved ban isn't saved with EOS, we cannot resolve to gameId, so skip these.
|
|
215
|
+
if (!gameId.includes('EOS_'))
|
|
216
|
+
continue;
|
|
217
|
+
bans.push(new BanDTO({
|
|
218
|
+
player: new IGamePlayer({
|
|
219
|
+
gameId: gameId.replace('EOS_', ''),
|
|
220
|
+
epicOnlineServicesId: gameId.replace('EOS_', ''),
|
|
221
|
+
}),
|
|
222
|
+
reason,
|
|
223
|
+
expiresAt,
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return bans;
|
|
228
|
+
}
|
|
229
|
+
async listItems() {
|
|
230
|
+
const itemsRes = await this.executeConsoleCommand('li *');
|
|
231
|
+
const itemLines = itemsRes.rawResult.split('\n').slice(0, -2);
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
const workerPath = path.join(__dirname, 'itemWorker.js');
|
|
234
|
+
const worker = new Worker(workerPath);
|
|
235
|
+
worker.postMessage(itemLines);
|
|
236
|
+
worker.on('message', (parsedItems) => {
|
|
237
|
+
if (parsedItems.error) {
|
|
238
|
+
reject(parsedItems.error);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
resolve(parsedItems);
|
|
242
|
+
}
|
|
243
|
+
worker.terminate();
|
|
244
|
+
});
|
|
245
|
+
worker.on('error', reject);
|
|
246
|
+
worker.on('exit', (code) => {
|
|
247
|
+
if (code !== 0) {
|
|
248
|
+
reject(new Error(`Worker stopped with exit code ${code}`));
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
async getPlayerInventory(player) {
|
|
254
|
+
const inventoryRes = await this.apiClient.getPlayerInventory(`EOS_${player.gameId}`);
|
|
255
|
+
const resp = [];
|
|
256
|
+
const mapSdtdItemToDto = async (item) => {
|
|
257
|
+
if (!item)
|
|
258
|
+
return null;
|
|
259
|
+
return item.quality
|
|
260
|
+
? new IItemDTO({ code: item.name, amount: item.count, quality: item.quality })
|
|
261
|
+
: new IItemDTO({ code: item.name, amount: item.count });
|
|
262
|
+
};
|
|
263
|
+
const dtos = await Promise.all([
|
|
264
|
+
...inventoryRes.data.bag.map(mapSdtdItemToDto),
|
|
265
|
+
...inventoryRes.data.belt.map(mapSdtdItemToDto),
|
|
266
|
+
]);
|
|
267
|
+
const filteredDTOs = dtos.filter((item) => item !== null);
|
|
268
|
+
resp.push(...filteredDTOs);
|
|
269
|
+
for (const slot in inventoryRes.data.equipment) {
|
|
270
|
+
if (Object.prototype.hasOwnProperty.call(inventoryRes.data.equipment, slot)) {
|
|
271
|
+
const element = inventoryRes.data.equipment[slot];
|
|
272
|
+
if (element)
|
|
273
|
+
resp.push(new IItemDTO({ code: element.name, amount: element.count }));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return resp;
|
|
277
|
+
}
|
|
278
|
+
async shutdown() {
|
|
279
|
+
if (this.connectionInfo.useCPM) {
|
|
280
|
+
await this.executeConsoleCommand('shutdownba 0');
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
await this.executeConsoleCommand('shutdown');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async getMapInfo() {
|
|
287
|
+
return this.apiClient.getMapInfo();
|
|
288
|
+
}
|
|
289
|
+
async getMapTile(x, y, z) {
|
|
290
|
+
return this.apiClient.getMapTile(x, y, z);
|
|
291
|
+
}
|
|
292
|
+
async listEntities() {
|
|
293
|
+
throw new errors.NotImplementedError();
|
|
294
|
+
}
|
|
295
|
+
async listLocations() {
|
|
296
|
+
throw new errors.NotImplementedError();
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
SevenDaysToDie = __decorate([
|
|
300
|
+
traceableClass('game:7d2d'),
|
|
301
|
+
__metadata("design:paramtypes", [SdtdConnectionInfo, Object])
|
|
302
|
+
], SevenDaysToDie);
|
|
303
|
+
export { SevenDaysToDie };
|
|
304
|
+
//# sourceMappingURL=index.js.map
|