@quake2ts/server 0.0.739 → 0.0.740
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/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/dist/client.d.ts +0 -51
- package/dist/client.js +0 -100
- package/dist/dedicated.d.ts +0 -72
- package/dist/dedicated.js +0 -1104
- package/dist/index.cjs +0 -1586
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -1543
- package/dist/net/nodeWsDriver.d.ts +0 -16
- package/dist/net/nodeWsDriver.js +0 -122
- package/dist/protocol/player.d.ts +0 -2
- package/dist/protocol/player.js +0 -1
- package/dist/protocol/write.d.ts +0 -7
- package/dist/protocol/write.js +0 -167
- package/dist/protocol.d.ts +0 -17
- package/dist/protocol.js +0 -71
- package/dist/server.d.ts +0 -50
- package/dist/server.js +0 -12
- package/dist/transport.d.ts +0 -7
- package/dist/transport.js +0 -1
- package/dist/transports/websocket.d.ts +0 -11
- package/dist/transports/websocket.js +0 -38
- package/test-results/junit.xml +0 -111
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { NetDriver } from '@quake2ts/shared';
|
|
2
|
-
import WebSocket from 'ws';
|
|
3
|
-
export declare class WebSocketNetDriver implements NetDriver {
|
|
4
|
-
private socket;
|
|
5
|
-
private messageCallback;
|
|
6
|
-
private closeCallback;
|
|
7
|
-
private errorCallback;
|
|
8
|
-
connect(url: string): Promise<void>;
|
|
9
|
-
attach(socket: WebSocket): void;
|
|
10
|
-
disconnect(): void;
|
|
11
|
-
send(data: Uint8Array): void;
|
|
12
|
-
onMessage(callback: (data: Uint8Array) => void): void;
|
|
13
|
-
onClose(callback: () => void): void;
|
|
14
|
-
onError(callback: (error: Error) => void): void;
|
|
15
|
-
isConnected(): boolean;
|
|
16
|
-
}
|
package/dist/net/nodeWsDriver.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
export class WebSocketNetDriver {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.socket = null;
|
|
5
|
-
this.messageCallback = null;
|
|
6
|
-
this.closeCallback = null;
|
|
7
|
-
this.errorCallback = null;
|
|
8
|
-
}
|
|
9
|
-
async connect(url) {
|
|
10
|
-
return new Promise((resolve, reject) => {
|
|
11
|
-
try {
|
|
12
|
-
this.socket = new WebSocket(url);
|
|
13
|
-
this.socket.binaryType = 'arraybuffer';
|
|
14
|
-
this.socket.onopen = () => {
|
|
15
|
-
resolve();
|
|
16
|
-
};
|
|
17
|
-
this.socket.onerror = (event) => {
|
|
18
|
-
const error = new Error('WebSocket connection error ' + event.message);
|
|
19
|
-
if (this.errorCallback) {
|
|
20
|
-
this.errorCallback(error);
|
|
21
|
-
}
|
|
22
|
-
reject(error);
|
|
23
|
-
};
|
|
24
|
-
this.socket.onclose = () => {
|
|
25
|
-
if (this.closeCallback) {
|
|
26
|
-
this.closeCallback();
|
|
27
|
-
}
|
|
28
|
-
this.socket = null;
|
|
29
|
-
};
|
|
30
|
-
this.socket.onmessage = (event) => {
|
|
31
|
-
if (this.messageCallback) {
|
|
32
|
-
if (event.data instanceof ArrayBuffer) {
|
|
33
|
-
this.messageCallback(new Uint8Array(event.data));
|
|
34
|
-
}
|
|
35
|
-
else if (Buffer.isBuffer(event.data)) {
|
|
36
|
-
// ws in Node might return Buffer
|
|
37
|
-
this.messageCallback(new Uint8Array(event.data));
|
|
38
|
-
}
|
|
39
|
-
else if (Array.isArray(event.data)) {
|
|
40
|
-
// Buffer[]
|
|
41
|
-
const totalLength = event.data.reduce((acc, buf) => acc + buf.length, 0);
|
|
42
|
-
const result = new Uint8Array(totalLength);
|
|
43
|
-
let offset = 0;
|
|
44
|
-
for (const buf of event.data) {
|
|
45
|
-
result.set(buf, offset);
|
|
46
|
-
offset += buf.length;
|
|
47
|
-
}
|
|
48
|
-
this.messageCallback(result);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
console.warn('Received non-binary message from server', typeof event.data);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
reject(e);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
// Method to attach an existing socket (server-side incoming connection)
|
|
62
|
-
attach(socket) {
|
|
63
|
-
this.socket = socket;
|
|
64
|
-
this.socket.binaryType = 'arraybuffer';
|
|
65
|
-
this.socket.onclose = () => {
|
|
66
|
-
if (this.closeCallback)
|
|
67
|
-
this.closeCallback();
|
|
68
|
-
this.socket = null;
|
|
69
|
-
};
|
|
70
|
-
this.socket.onerror = (event) => {
|
|
71
|
-
if (this.errorCallback)
|
|
72
|
-
this.errorCallback(new Error(event.message));
|
|
73
|
-
};
|
|
74
|
-
this.socket.onmessage = (event) => {
|
|
75
|
-
if (this.messageCallback) {
|
|
76
|
-
if (event.data instanceof ArrayBuffer) {
|
|
77
|
-
this.messageCallback(new Uint8Array(event.data));
|
|
78
|
-
}
|
|
79
|
-
else if (Buffer.isBuffer(event.data)) {
|
|
80
|
-
this.messageCallback(new Uint8Array(event.data));
|
|
81
|
-
}
|
|
82
|
-
else if (Array.isArray(event.data)) { // ws specific
|
|
83
|
-
// handle fragmentation if necessary, usually it's Buffer[]
|
|
84
|
-
const totalLength = event.data.reduce((acc, buf) => acc + buf.length, 0);
|
|
85
|
-
const result = new Uint8Array(totalLength);
|
|
86
|
-
let offset = 0;
|
|
87
|
-
for (const buf of event.data) {
|
|
88
|
-
result.set(buf, offset);
|
|
89
|
-
offset += buf.length;
|
|
90
|
-
}
|
|
91
|
-
this.messageCallback(result);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
disconnect() {
|
|
97
|
-
if (this.socket) {
|
|
98
|
-
this.socket.close();
|
|
99
|
-
this.socket = null;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
send(data) {
|
|
103
|
-
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
104
|
-
this.socket.send(data);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
console.warn('Attempted to send data on closed or connecting socket');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
onMessage(callback) {
|
|
111
|
-
this.messageCallback = callback;
|
|
112
|
-
}
|
|
113
|
-
onClose(callback) {
|
|
114
|
-
this.closeCallback = callback;
|
|
115
|
-
}
|
|
116
|
-
onError(callback) {
|
|
117
|
-
this.errorCallback = callback;
|
|
118
|
-
}
|
|
119
|
-
isConnected() {
|
|
120
|
-
return this.socket !== null && this.socket.readyState === WebSocket.OPEN;
|
|
121
|
-
}
|
|
122
|
-
}
|
package/dist/protocol/player.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { writePlayerState } from '@quake2ts/shared';
|
package/dist/protocol/write.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { BinaryWriter, ServerCommand } from '@quake2ts/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Writes a server command and its arguments to a BinaryWriter.
|
|
4
|
-
* This handles the serialization of generic arguments passed to multicast/unicast
|
|
5
|
-
* into the specific binary format expected by the protocol.
|
|
6
|
-
*/
|
|
7
|
-
export declare function writeServerCommand(writer: BinaryWriter, event: ServerCommand, ...args: any[]): void;
|
package/dist/protocol/write.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { ServerCommand, TempEntity } from '@quake2ts/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Writes a server command and its arguments to a BinaryWriter.
|
|
4
|
-
* This handles the serialization of generic arguments passed to multicast/unicast
|
|
5
|
-
* into the specific binary format expected by the protocol.
|
|
6
|
-
*/
|
|
7
|
-
export function writeServerCommand(writer, event, ...args) {
|
|
8
|
-
writer.writeByte(event);
|
|
9
|
-
switch (event) {
|
|
10
|
-
case ServerCommand.print: {
|
|
11
|
-
// args: [level: number, text: string]
|
|
12
|
-
const level = args[0];
|
|
13
|
-
const text = args[1];
|
|
14
|
-
writer.writeByte(level);
|
|
15
|
-
writer.writeString(text);
|
|
16
|
-
break;
|
|
17
|
-
}
|
|
18
|
-
case ServerCommand.centerprint: {
|
|
19
|
-
// args: [text: string]
|
|
20
|
-
const text = args[0];
|
|
21
|
-
writer.writeString(text);
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
case ServerCommand.stufftext: {
|
|
25
|
-
// args: [text: string]
|
|
26
|
-
const text = args[0];
|
|
27
|
-
writer.writeString(text);
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
case ServerCommand.sound: {
|
|
31
|
-
// args: [flags, soundNum, volume?, attenuation?, offset?, ent?, pos?]
|
|
32
|
-
const flags = args[0];
|
|
33
|
-
const soundNum = args[1];
|
|
34
|
-
const volume = args[2];
|
|
35
|
-
const attenuation = args[3];
|
|
36
|
-
const offset = args[4];
|
|
37
|
-
const ent = args[5];
|
|
38
|
-
const pos = args[6];
|
|
39
|
-
writer.writeByte(flags);
|
|
40
|
-
writer.writeByte(soundNum);
|
|
41
|
-
if (flags & 1) { // SND_VOLUME
|
|
42
|
-
writer.writeByte(volume || 0);
|
|
43
|
-
}
|
|
44
|
-
if (flags & 2) { // SND_ATTENUATION
|
|
45
|
-
writer.writeByte(attenuation || 0);
|
|
46
|
-
}
|
|
47
|
-
if (flags & 16) { // SND_OFFSET
|
|
48
|
-
writer.writeByte(offset || 0);
|
|
49
|
-
}
|
|
50
|
-
if (flags & 8) { // SND_ENT
|
|
51
|
-
writer.writeShort(ent || 0);
|
|
52
|
-
}
|
|
53
|
-
if (flags & 4) { // SND_POS
|
|
54
|
-
if (pos) {
|
|
55
|
-
writer.writePos(pos);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
writer.writePos({ x: 0, y: 0, z: 0 });
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case ServerCommand.muzzleflash: {
|
|
64
|
-
// args: [entityIndex: number, flashType: number]
|
|
65
|
-
const entIndex = args[0];
|
|
66
|
-
const flashType = args[1];
|
|
67
|
-
writer.writeShort(entIndex);
|
|
68
|
-
writer.writeByte(flashType);
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
case ServerCommand.temp_entity: {
|
|
72
|
-
// args: [type: TempEntity, ...params]
|
|
73
|
-
const type = args[0];
|
|
74
|
-
writer.writeByte(type);
|
|
75
|
-
writeTempEntity(writer, type, args.slice(1));
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
default:
|
|
79
|
-
console.warn(`writeServerCommand: Unhandled command ${event}`);
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function writeTempEntity(writer, type, args) {
|
|
84
|
-
switch (type) {
|
|
85
|
-
case TempEntity.ROCKET_EXPLOSION:
|
|
86
|
-
case TempEntity.GRENADE_EXPLOSION:
|
|
87
|
-
case TempEntity.EXPLOSION1:
|
|
88
|
-
case TempEntity.EXPLOSION2:
|
|
89
|
-
case TempEntity.ROCKET_EXPLOSION_WATER:
|
|
90
|
-
case TempEntity.GRENADE_EXPLOSION_WATER:
|
|
91
|
-
case TempEntity.BFG_EXPLOSION:
|
|
92
|
-
case TempEntity.BFG_BIGEXPLOSION:
|
|
93
|
-
case TempEntity.PLASMA_EXPLOSION:
|
|
94
|
-
case TempEntity.PLAIN_EXPLOSION:
|
|
95
|
-
case TempEntity.TRACKER_EXPLOSION:
|
|
96
|
-
case TempEntity.EXPLOSION1_BIG:
|
|
97
|
-
case TempEntity.EXPLOSION1_NP:
|
|
98
|
-
case TempEntity.EXPLOSION1_NL:
|
|
99
|
-
case TempEntity.EXPLOSION2_NL:
|
|
100
|
-
case TempEntity.BERSERK_SLAM:
|
|
101
|
-
// Format: [pos]
|
|
102
|
-
writer.writePos(args[0]);
|
|
103
|
-
break;
|
|
104
|
-
case TempEntity.BLASTER:
|
|
105
|
-
case TempEntity.FLECHETTE:
|
|
106
|
-
// Format: [pos, dir]
|
|
107
|
-
writer.writePos(args[0]);
|
|
108
|
-
writer.writeDir(args[1]);
|
|
109
|
-
break;
|
|
110
|
-
case TempEntity.RAILTRAIL:
|
|
111
|
-
case TempEntity.DEBUGTRAIL:
|
|
112
|
-
case TempEntity.BUBBLETRAIL:
|
|
113
|
-
case TempEntity.BUBBLETRAIL2:
|
|
114
|
-
case TempEntity.BFG_LASER:
|
|
115
|
-
case TempEntity.LIGHTNING_BEAM:
|
|
116
|
-
case TempEntity.LIGHTNING:
|
|
117
|
-
// Format: [start, end]
|
|
118
|
-
writer.writePos(args[0]);
|
|
119
|
-
writer.writePos(args[1]);
|
|
120
|
-
break;
|
|
121
|
-
case TempEntity.LASER_SPARKS:
|
|
122
|
-
case TempEntity.WELDING_SPARKS:
|
|
123
|
-
case TempEntity.TUNNEL_SPARKS:
|
|
124
|
-
case TempEntity.ELECTRIC_SPARKS:
|
|
125
|
-
case TempEntity.HEATBEAM_SPARKS:
|
|
126
|
-
case TempEntity.HEATBEAM_STEAM:
|
|
127
|
-
case TempEntity.STEAM:
|
|
128
|
-
// Format: [count, pos, dir, color?]
|
|
129
|
-
// Q2: writeByte(count), writePos(start), writeDir(normal), writeByte(skin/color)
|
|
130
|
-
writer.writeByte(args[0]);
|
|
131
|
-
writer.writePos(args[1]);
|
|
132
|
-
writer.writeDir(args[2]);
|
|
133
|
-
writer.writeByte(args[3] || 0);
|
|
134
|
-
break;
|
|
135
|
-
case TempEntity.PARASITE_ATTACK:
|
|
136
|
-
case TempEntity.MEDIC_CABLE_ATTACK:
|
|
137
|
-
// Format: [entIndex, start, end]
|
|
138
|
-
// args[0] is Entity usually
|
|
139
|
-
const ent = args[0];
|
|
140
|
-
writer.writeShort(ent ? ent.index : 0);
|
|
141
|
-
writer.writePos(args[1]);
|
|
142
|
-
writer.writePos(args[2]);
|
|
143
|
-
break;
|
|
144
|
-
case TempEntity.GUNSHOT:
|
|
145
|
-
case TempEntity.BLOOD:
|
|
146
|
-
case TempEntity.SPARKS:
|
|
147
|
-
case TempEntity.BULLET_SPARKS:
|
|
148
|
-
case TempEntity.SCREEN_SPARKS:
|
|
149
|
-
case TempEntity.SHIELD_SPARKS:
|
|
150
|
-
// Format: [pos, dir]
|
|
151
|
-
writer.writePos(args[0]);
|
|
152
|
-
writer.writeDir(args[1]);
|
|
153
|
-
break;
|
|
154
|
-
case TempEntity.SPLASH:
|
|
155
|
-
case TempEntity.POWER_SPLASH:
|
|
156
|
-
case TempEntity.WIDOWSPLASH:
|
|
157
|
-
// Format: [count, pos, dir, color]
|
|
158
|
-
writer.writeByte(args[0]);
|
|
159
|
-
writer.writePos(args[1]);
|
|
160
|
-
writer.writeDir(args[2]);
|
|
161
|
-
writer.writeByte(args[3] || 0);
|
|
162
|
-
break;
|
|
163
|
-
default:
|
|
164
|
-
console.warn(`writeTempEntity: Unhandled TempEntity ${type}`);
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
}
|
package/dist/protocol.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { BinaryStream, UserCommand } from '@quake2ts/shared';
|
|
2
|
-
export interface ClientMessageHandler {
|
|
3
|
-
onMove(checksum: number, lastFrame: number, userCmd: UserCommand): void;
|
|
4
|
-
onUserInfo(info: string): void;
|
|
5
|
-
onStringCmd(cmd: string): void;
|
|
6
|
-
onNop(): void;
|
|
7
|
-
onBad(): void;
|
|
8
|
-
}
|
|
9
|
-
export declare class ClientMessageParser {
|
|
10
|
-
private stream;
|
|
11
|
-
private handler;
|
|
12
|
-
constructor(stream: BinaryStream, handler: ClientMessageHandler);
|
|
13
|
-
parseMessage(): void;
|
|
14
|
-
private parseMove;
|
|
15
|
-
private parseUserInfo;
|
|
16
|
-
private parseStringCmd;
|
|
17
|
-
}
|
package/dist/protocol.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { ClientCommand } from '@quake2ts/shared';
|
|
2
|
-
export class ClientMessageParser {
|
|
3
|
-
constructor(stream, handler) {
|
|
4
|
-
this.stream = stream;
|
|
5
|
-
this.handler = handler;
|
|
6
|
-
}
|
|
7
|
-
parseMessage() {
|
|
8
|
-
while (this.stream.hasMore()) {
|
|
9
|
-
const cmdId = this.stream.readByte();
|
|
10
|
-
if (cmdId === -1)
|
|
11
|
-
break;
|
|
12
|
-
switch (cmdId) {
|
|
13
|
-
case ClientCommand.move:
|
|
14
|
-
this.parseMove();
|
|
15
|
-
break;
|
|
16
|
-
case ClientCommand.userinfo:
|
|
17
|
-
this.parseUserInfo();
|
|
18
|
-
break;
|
|
19
|
-
case ClientCommand.stringcmd:
|
|
20
|
-
this.parseStringCmd();
|
|
21
|
-
break;
|
|
22
|
-
case ClientCommand.nop:
|
|
23
|
-
this.handler.onNop();
|
|
24
|
-
break;
|
|
25
|
-
default:
|
|
26
|
-
console.warn(`Unknown client command: ${cmdId}`);
|
|
27
|
-
this.handler.onBad();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
parseMove() {
|
|
33
|
-
const checksum = this.stream.readByte();
|
|
34
|
-
const lastFrame = this.stream.readLong();
|
|
35
|
-
// Read UserCmd
|
|
36
|
-
// TODO: support delta compression if needed (Q2 uses delta compression for usercmds)
|
|
37
|
-
// For now, assume full UserCmd or implement basic read
|
|
38
|
-
const msec = this.stream.readByte();
|
|
39
|
-
const buttons = this.stream.readByte();
|
|
40
|
-
const angles = {
|
|
41
|
-
x: this.stream.readShort() * (360.0 / 65536.0),
|
|
42
|
-
y: this.stream.readShort() * (360.0 / 65536.0),
|
|
43
|
-
z: this.stream.readShort() * (360.0 / 65536.0),
|
|
44
|
-
};
|
|
45
|
-
const forwardmove = this.stream.readShort();
|
|
46
|
-
const sidemove = this.stream.readShort();
|
|
47
|
-
const upmove = this.stream.readShort();
|
|
48
|
-
const impulse = this.stream.readByte();
|
|
49
|
-
const lightlevel = this.stream.readByte(); // Used for light-based stealth, usually ignored by server logic except for stats
|
|
50
|
-
const userCmd = {
|
|
51
|
-
msec,
|
|
52
|
-
buttons,
|
|
53
|
-
angles,
|
|
54
|
-
forwardmove,
|
|
55
|
-
sidemove,
|
|
56
|
-
upmove,
|
|
57
|
-
impulse,
|
|
58
|
-
lightlevel,
|
|
59
|
-
sequence: 0 // Server doesn't read sequence from packet body in standard protocol, it tracks it
|
|
60
|
-
};
|
|
61
|
-
this.handler.onMove(checksum, lastFrame, userCmd);
|
|
62
|
-
}
|
|
63
|
-
parseUserInfo() {
|
|
64
|
-
const info = this.stream.readString();
|
|
65
|
-
this.handler.onUserInfo(info);
|
|
66
|
-
}
|
|
67
|
-
parseStringCmd() {
|
|
68
|
-
const cmd = this.stream.readString();
|
|
69
|
-
this.handler.onStringCmd(cmd);
|
|
70
|
-
}
|
|
71
|
-
}
|
package/dist/server.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { CollisionModel } from "@quake2ts/shared";
|
|
2
|
-
import { EntityState } from "@quake2ts/shared";
|
|
3
|
-
import { Client } from "./client.js";
|
|
4
|
-
/**
|
|
5
|
-
* ServerState corresponds to server_state_t in the original source.
|
|
6
|
-
*/
|
|
7
|
-
export declare enum ServerState {
|
|
8
|
-
Dead = 0,// no map loaded
|
|
9
|
-
Loading = 1,// spawning level edicts
|
|
10
|
-
Game = 2,// actively running
|
|
11
|
-
Cinematic = 3,
|
|
12
|
-
Demo = 4,
|
|
13
|
-
Pic = 5
|
|
14
|
-
}
|
|
15
|
-
export interface Challenge {
|
|
16
|
-
adr: string;
|
|
17
|
-
challenge: number;
|
|
18
|
-
time: number;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* ServerStatic holds the state that is constant across server restarts.
|
|
22
|
-
* Corresponds to server_static_t in the original source.
|
|
23
|
-
*/
|
|
24
|
-
export interface ServerStatic {
|
|
25
|
-
initialized: boolean;
|
|
26
|
-
realTime: number;
|
|
27
|
-
mapCmd: string;
|
|
28
|
-
spawnCount: number;
|
|
29
|
-
clients: (Client | null)[];
|
|
30
|
-
lastHeartbeat: number;
|
|
31
|
-
challenges: Challenge[];
|
|
32
|
-
demoFile?: any;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Server holds the state for the current running server instance.
|
|
36
|
-
* Corresponds to server_t in the original source.
|
|
37
|
-
*/
|
|
38
|
-
export interface Server {
|
|
39
|
-
state: ServerState;
|
|
40
|
-
attractLoop: boolean;
|
|
41
|
-
loadGame: boolean;
|
|
42
|
-
startTime: number;
|
|
43
|
-
time: number;
|
|
44
|
-
frame: number;
|
|
45
|
-
name: string;
|
|
46
|
-
collisionModel: CollisionModel | null;
|
|
47
|
-
configStrings: string[];
|
|
48
|
-
baselines: (EntityState | null)[];
|
|
49
|
-
multicastBuf: Uint8Array;
|
|
50
|
-
}
|
package/dist/server.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ServerState corresponds to server_state_t in the original source.
|
|
3
|
-
*/
|
|
4
|
-
export var ServerState;
|
|
5
|
-
(function (ServerState) {
|
|
6
|
-
ServerState[ServerState["Dead"] = 0] = "Dead";
|
|
7
|
-
ServerState[ServerState["Loading"] = 1] = "Loading";
|
|
8
|
-
ServerState[ServerState["Game"] = 2] = "Game";
|
|
9
|
-
ServerState[ServerState["Cinematic"] = 3] = "Cinematic";
|
|
10
|
-
ServerState[ServerState["Demo"] = 4] = "Demo";
|
|
11
|
-
ServerState[ServerState["Pic"] = 5] = "Pic";
|
|
12
|
-
})(ServerState || (ServerState = {}));
|
package/dist/transport.d.ts
DELETED
package/dist/transport.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { NetworkTransport } from '../transport.js';
|
|
2
|
-
import { NetDriver } from '@quake2ts/shared';
|
|
3
|
-
export declare class WebSocketTransport implements NetworkTransport {
|
|
4
|
-
private wss;
|
|
5
|
-
private connectionCallback;
|
|
6
|
-
private errorCallback;
|
|
7
|
-
listen(port: number): Promise<void>;
|
|
8
|
-
close(): void;
|
|
9
|
-
onConnection(callback: (driver: NetDriver, info?: any) => void): void;
|
|
10
|
-
onError(callback: (error: Error) => void): void;
|
|
11
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { WebSocketServer } from 'ws';
|
|
2
|
-
import { WebSocketNetDriver } from '../net/nodeWsDriver.js';
|
|
3
|
-
export class WebSocketTransport {
|
|
4
|
-
constructor() {
|
|
5
|
-
this.wss = null;
|
|
6
|
-
this.connectionCallback = null;
|
|
7
|
-
this.errorCallback = null;
|
|
8
|
-
}
|
|
9
|
-
async listen(port) {
|
|
10
|
-
return new Promise((resolve) => {
|
|
11
|
-
this.wss = new WebSocketServer({ port });
|
|
12
|
-
this.wss.on('listening', () => resolve());
|
|
13
|
-
this.wss.on('connection', (ws, req) => {
|
|
14
|
-
const driver = new WebSocketNetDriver();
|
|
15
|
-
driver.attach(ws);
|
|
16
|
-
if (this.connectionCallback) {
|
|
17
|
-
this.connectionCallback(driver, req);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
this.wss.on('error', (err) => {
|
|
21
|
-
if (this.errorCallback)
|
|
22
|
-
this.errorCallback(err);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
close() {
|
|
27
|
-
if (this.wss) {
|
|
28
|
-
this.wss.close();
|
|
29
|
-
this.wss = null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
onConnection(callback) {
|
|
33
|
-
this.connectionCallback = callback;
|
|
34
|
-
}
|
|
35
|
-
onError(callback) {
|
|
36
|
-
this.errorCallback = callback;
|
|
37
|
-
}
|
|
38
|
-
}
|
package/test-results/junit.xml
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8" ?>
|
|
2
|
-
<testsuites name="vitest tests" tests="35" failures="0" errors="0" time="20.527">
|
|
3
|
-
<testsuite name="tests/client.test.ts" timestamp="2025-12-25T14:59:08.975Z" hostname="Jonathans-MacBook-Pro.local" tests="1" failures="0" errors="0" skipped="0" time="0.001">
|
|
4
|
-
<testcase classname="tests/client.test.ts" name="Server Client > should initialize with NetChan" time="0.001">
|
|
5
|
-
</testcase>
|
|
6
|
-
</testsuite>
|
|
7
|
-
<testsuite name="tests/connection_flow.test.ts" timestamp="2025-12-25T14:59:08.977Z" hostname="Jonathans-MacBook-Pro.local" tests="1" failures="0" errors="0" skipped="0" time="0.009">
|
|
8
|
-
<testcase classname="tests/connection_flow.test.ts" name="DedicatedServer Connection Flow > should handle "connect" command" time="0.008">
|
|
9
|
-
</testcase>
|
|
10
|
-
</testsuite>
|
|
11
|
-
<testsuite name="tests/dedicated.test.ts" timestamp="2025-12-25T14:59:08.977Z" hostname="Jonathans-MacBook-Pro.local" tests="4" failures="0" errors="0" skipped="0" time="0.103">
|
|
12
|
-
<testcase classname="tests/dedicated.test.ts" name="DedicatedServer > should initialize the game and start the frame loop" time="0.005">
|
|
13
|
-
</testcase>
|
|
14
|
-
<testcase classname="tests/dedicated.test.ts" name="DedicatedServer > should run the main game loop and process client commands" time="0.006">
|
|
15
|
-
</testcase>
|
|
16
|
-
<testcase classname="tests/dedicated.test.ts" name="DedicatedServer > should not process commands for clients that are not active" time="0.004">
|
|
17
|
-
</testcase>
|
|
18
|
-
<testcase classname="tests/dedicated.test.ts" name="DedicatedServer > should compensate for slow frames (drift compensation)" time="0.088">
|
|
19
|
-
</testcase>
|
|
20
|
-
</testsuite>
|
|
21
|
-
<testsuite name="tests/dedicated_trace.test.ts" timestamp="2025-12-25T14:59:08.978Z" hostname="Jonathans-MacBook-Pro.local" tests="2" failures="0" errors="0" skipped="0" time="0.13">
|
|
22
|
-
<testcase classname="tests/dedicated_trace.test.ts" name="DedicatedServer Trace Integration > should invoke CollisionEntityIndex.trace and resolve entity" time="0.074">
|
|
23
|
-
<system-out>
|
|
24
|
-
Starting Dedicated Server on port 27998...
|
|
25
|
-
Loading map test.bsp...
|
|
26
|
-
|
|
27
|
-
Map loaded successfully.
|
|
28
|
-
Server started.
|
|
29
|
-
|
|
30
|
-
</system-out>
|
|
31
|
-
</testcase>
|
|
32
|
-
<testcase classname="tests/dedicated_trace.test.ts" name="DedicatedServer Trace Integration > should fallback to world trace (via entityIndex) if entity trace is further" time="0.056">
|
|
33
|
-
<system-out>
|
|
34
|
-
Starting Dedicated Server on port 27999...
|
|
35
|
-
Loading map test.bsp...
|
|
36
|
-
|
|
37
|
-
Map loaded successfully.
|
|
38
|
-
Server started.
|
|
39
|
-
|
|
40
|
-
</system-out>
|
|
41
|
-
</testcase>
|
|
42
|
-
</testsuite>
|
|
43
|
-
<testsuite name="tests/lag.test.ts" timestamp="2025-12-25T14:59:08.979Z" hostname="Jonathans-MacBook-Pro.local" tests="4" failures="0" errors="0" skipped="0" time="0.043">
|
|
44
|
-
<testcase classname="tests/lag.test.ts" name="Lag Compensation > should record entity history" time="0.035">
|
|
45
|
-
</testcase>
|
|
46
|
-
<testcase classname="tests/lag.test.ts" name="Lag Compensation > should interpolate entity position based on lag" time="0.002">
|
|
47
|
-
</testcase>
|
|
48
|
-
<testcase classname="tests/lag.test.ts" name="Lag Compensation > should handle lag larger than history" time="0.001">
|
|
49
|
-
</testcase>
|
|
50
|
-
<testcase classname="tests/lag.test.ts" name="Lag Compensation > should handle negative lag (extrapolation not supported, clamps to newest)" time="0.004">
|
|
51
|
-
</testcase>
|
|
52
|
-
</testsuite>
|
|
53
|
-
<testsuite name="tests/protocol.test.ts" timestamp="2025-12-25T14:59:08.980Z" hostname="Jonathans-MacBook-Pro.local" tests="4" failures="0" errors="0" skipped="0" time="0.003">
|
|
54
|
-
<testcase classname="tests/protocol.test.ts" name="ClientMessageParser > should parse NOP command" time="0.002">
|
|
55
|
-
</testcase>
|
|
56
|
-
<testcase classname="tests/protocol.test.ts" name="ClientMessageParser > should parse StringCmd" time="0">
|
|
57
|
-
</testcase>
|
|
58
|
-
<testcase classname="tests/protocol.test.ts" name="ClientMessageParser > should parse UserInfo" time="0.001">
|
|
59
|
-
</testcase>
|
|
60
|
-
<testcase classname="tests/protocol.test.ts" name="ClientMessageParser > should parse Move command (UserCmd)" time="0">
|
|
61
|
-
</testcase>
|
|
62
|
-
</testsuite>
|
|
63
|
-
<testsuite name="tests/server-state.test.ts" timestamp="2025-12-25T14:59:08.981Z" hostname="Jonathans-MacBook-Pro.local" tests="1" failures="0" errors="0" skipped="0" time="0.002">
|
|
64
|
-
<testcase classname="tests/server-state.test.ts" name="Server State Structures > Client initialization should set default values correctly" time="0">
|
|
65
|
-
</testcase>
|
|
66
|
-
</testsuite>
|
|
67
|
-
<testsuite name="tests/server.test.ts" timestamp="2025-12-25T14:59:08.981Z" hostname="Jonathans-MacBook-Pro.local" tests="6" failures="0" errors="0" skipped="0" time="0.014">
|
|
68
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should create a server with default options" time="0.001">
|
|
69
|
-
</testcase>
|
|
70
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should initialize WebSocketServer on start" time="0.006">
|
|
71
|
-
</testcase>
|
|
72
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should be able to stop" time="0.002">
|
|
73
|
-
</testcase>
|
|
74
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should fail to start without map" time="0.001">
|
|
75
|
-
</testcase>
|
|
76
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should kick player" time="0">
|
|
77
|
-
</testcase>
|
|
78
|
-
<testcase classname="tests/server.test.ts" name="DedicatedServer > should change map" time="0.004">
|
|
79
|
-
</testcase>
|
|
80
|
-
</testsuite>
|
|
81
|
-
<testsuite name="tests/unit/dedicated_timeout.test.ts" timestamp="2025-12-25T14:59:08.982Z" hostname="Jonathans-MacBook-Pro.local" tests="2" failures="0" errors="0" skipped="0" time="0.01">
|
|
82
|
-
<testcase classname="tests/unit/dedicated_timeout.test.ts" name="DedicatedServer Timeout > should disconnect a client after timeout" time="0.005">
|
|
83
|
-
</testcase>
|
|
84
|
-
<testcase classname="tests/unit/dedicated_timeout.test.ts" name="DedicatedServer Timeout > should NOT disconnect a client if they send messages" time="0.004">
|
|
85
|
-
</testcase>
|
|
86
|
-
</testsuite>
|
|
87
|
-
<testsuite name="tests/protocol/player.test.ts" timestamp="2025-12-25T14:59:08.982Z" hostname="Jonathans-MacBook-Pro.local" tests="3" failures="0" errors="0" skipped="0" time="0.003">
|
|
88
|
-
<testcase classname="tests/protocol/player.test.ts" name="writePlayerState > should write an empty state as just flags (plus statbits)" time="0.002">
|
|
89
|
-
</testcase>
|
|
90
|
-
<testcase classname="tests/protocol/player.test.ts" name="writePlayerState > should correctly round-trip all fields" time="0.001">
|
|
91
|
-
</testcase>
|
|
92
|
-
<testcase classname="tests/protocol/player.test.ts" name="writePlayerState > should ignore stats > 31" time="0">
|
|
93
|
-
</testcase>
|
|
94
|
-
</testsuite>
|
|
95
|
-
<testsuite name="tests/protocol/write.test.ts" timestamp="2025-12-25T14:59:08.983Z" hostname="Jonathans-MacBook-Pro.local" tests="7" failures="0" errors="0" skipped="0" time="0.003">
|
|
96
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes ServerCommand.print" time="0.002">
|
|
97
|
-
</testcase>
|
|
98
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes ServerCommand.muzzleflash" time="0">
|
|
99
|
-
</testcase>
|
|
100
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes TempEntity.ROCKET_EXPLOSION" time="0">
|
|
101
|
-
</testcase>
|
|
102
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes TempEntity.PARASITE_ATTACK" time="0">
|
|
103
|
-
</testcase>
|
|
104
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes ServerCommand.centerprint" time="0">
|
|
105
|
-
</testcase>
|
|
106
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes ServerCommand.stufftext" time="0">
|
|
107
|
-
</testcase>
|
|
108
|
-
<testcase classname="tests/protocol/write.test.ts" name="writeServerCommand > writes ServerCommand.sound" time="0">
|
|
109
|
-
</testcase>
|
|
110
|
-
</testsuite>
|
|
111
|
-
</testsuites>
|