Skip to content

Commit 2da72d5

Browse files
committed
Bug fixes and rc.3 bump
1 parent a7e78a2 commit 2da72d5

File tree

6 files changed

+110
-27
lines changed

6 files changed

+110
-27
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@runejs/common",
3-
"version": "2.0.0-rc.1",
3+
"version": "2.0.0-rc.3",
44
"description": "Common logging, networking, compression, and other functionality for RuneJS applications.",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",

src/buffer/byte-buffer.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ export class ByteBuffer extends Uint8Array {
9090
return Buffer.from(this);
9191
}
9292

93-
public get(type: 'string' | 'STRING'): string;
94-
public get(type: DataType, signed?: Signedness, endian?: Endianness): number;
95-
public get(type: DataType = 'byte', signed: Signedness = 'signed', endian: Endianness = 'be'): number | string {
93+
public get(): number;
94+
public get(type: Extract<DataType, 'string' | 'STRING'>): string;
95+
public get(type: Extract<DataType, 'long' | 'LONG'>, signed?: Signedness, endian?: Endianness): bigint;
96+
public get(type: Exclude<DataType, 'string' | 'STRING' | 'long' | 'LONG'>, signed?: Signedness, endian?: Endianness): number;
97+
public get(type: DataType = 'byte', signed: Signedness = 'signed', endian: Endianness = 'be'): number | bigint | string {
9698
type = ByteBuffer.getType(type);
9799
signed = ByteBuffer.getSignage(signed);
98100
endian = ByteBuffer.getEndianness(endian);
@@ -111,18 +113,24 @@ export class ByteBuffer extends Uint8Array {
111113
const smol = type === 'long' ? 'Big' : '';
112114

113115
this._readerIndex += size;
114-
const methodName = `read${signedChar}${smol}Int${bitLength}${suffix}`;
116+
const methodName = `read${smol}${signedChar}Int${bitLength}${suffix}`;
115117

116118
try {
117-
return this[methodName](readerIndex) as number;
119+
if(type === 'long') {
120+
return this[methodName](readerIndex) as bigint;
121+
} else {
122+
return this[methodName](readerIndex) as number;
123+
}
118124
} catch(error) {
119125
logger.error(`Error reading ${methodName}:`, error);
120126
return null;
121127
}
122128
}
123129
}
124130

125-
public put(value: string, type: 'string' | 'STRING'): ByteBuffer;
131+
public put(value: number): ByteBuffer;
132+
public put(value: string, type: Extract<DataType, 'string' | 'STRING'>): ByteBuffer;
133+
public put(value: bigint, type: Extract<DataType, 'long' | 'LONG'>): ByteBuffer;
126134
public put(value: number | bigint, type?: DataType, endian?: Endianness): ByteBuffer
127135
public put(value: number | bigint | string, type: DataType = 'byte', endian: Endianness = 'be'): ByteBuffer {
128136
const writerIndex = this._writerIndex;
@@ -132,10 +140,8 @@ export class ByteBuffer extends Uint8Array {
132140

133141
if(type === 'smart') {
134142
return this.putSmart(value as number);
135-
} else if(type === 'string') {
136-
if(typeof value === 'string') {
137-
return this.putString(value);
138-
}
143+
} else if(type === 'string' || typeof value === 'string') {
144+
return this.putString(typeof value !== 'string' ? String(value) : value);
139145
} else {
140146
const maxSignedLength = MAX_SIGNED_LENGTHS[type];
141147
const size = BYTE_LENGTH[type];
@@ -253,7 +259,7 @@ export class ByteBuffer extends Uint8Array {
253259
return this;
254260
}
255261

256-
public getSmart(offset: number, signed: Signedness = 'SIGNED'): number {
262+
public getSmart(offset: number, signed: Signedness = 'signed'): number {
257263
const peek = this[offset];
258264

259265
const signedString = ByteBuffer.getSignage(signed);
@@ -265,6 +271,13 @@ export class ByteBuffer extends Uint8Array {
265271
}
266272
}
267273

274+
public clone(): ByteBuffer {
275+
const dataCopy = new ByteBuffer(this.length);
276+
this.copy(dataCopy, 0, 0);
277+
dataCopy.readerIndex = this.readerIndex;
278+
return dataCopy;
279+
}
280+
268281
public readUInt24BE(offset: number): number {
269282
return ((this[offset] & 0xff) << 16) + ((this[offset + 1] & 0xff) << 8) + (this[offset + 2] & 0xff);
270283
}

src/net/socket-server.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
1-
import { createServer, Socket } from 'net';
1+
import { createServer, Server, Socket } from 'net';
22
import { ByteBuffer } from '../buffer';
33
import { logger } from '../logger';
44
import { ConnectionStatus } from './connection-status';
5+
import { setObjectProps } from '../util';
6+
7+
8+
export class SocketServerOptions {
9+
10+
public handshakeRequired: boolean = true;
11+
public noDelay: boolean = true;
12+
public keepAlive: boolean = true;
13+
public timeout: number = 30000;
14+
15+
public constructor(props?: Partial<SocketServerOptions>) {
16+
setObjectProps<SocketServerOptions>(this, props);
17+
}
18+
19+
}
520

621

722
export abstract class SocketServer<T = undefined> {
823

924
public readonly socket: Socket;
25+
public readonly options: SocketServerOptions;
1026

1127
protected _connectionStatus: ConnectionStatus | T = ConnectionStatus.HANDSHAKE;
1228

13-
public constructor(socket: Socket) {
29+
public constructor(socket: Socket);
30+
public constructor(socket: Socket, options: Partial<SocketServerOptions>);
31+
public constructor(socket: Socket, options: SocketServerOptions);
32+
public constructor(socket: Socket, options: Partial<SocketServerOptions> | SocketServerOptions | undefined);
33+
public constructor(socket: Socket, options?: Partial<SocketServerOptions> | SocketServerOptions | undefined) {
1434
this.socket = socket;
35+
this.options = new SocketServerOptions(options);
1536

16-
socket.setNoDelay(true);
17-
socket.setKeepAlive(true);
18-
socket.setTimeout(30000);
37+
socket.setNoDelay(this.options.noDelay);
38+
socket.setKeepAlive(this.options.keepAlive);
39+
socket.setTimeout(this.options.timeout);
40+
41+
if(!this.options.handshakeRequired) {
42+
this._connectionStatus = ConnectionStatus.ACTIVE;
43+
}
1944

2045
socket.on('data', data => {
2146
try {
@@ -41,12 +66,13 @@ export abstract class SocketServer<T = undefined> {
4166
hostName: string,
4267
port: number,
4368
socketServerFactory: (socket: Socket) => T
44-
): void {
45-
createServer(socket => {
69+
): Server {
70+
const server = createServer(socket => {
4671
socketServerFactory(socket);
4772
}).listen(port, hostName);
4873

4974
logger.info(`${ serverName } listening @ ${ hostName }:${ port }.`);
75+
return server;
5076
}
5177

5278
public dataReceived(data: Buffer): void {
@@ -56,7 +82,7 @@ export abstract class SocketServer<T = undefined> {
5682

5783
const byteBuffer = ByteBuffer.fromNodeBuffer(data);
5884

59-
if(this.connectionStatus === ConnectionStatus.HANDSHAKE) {
85+
if(this.options.handshakeRequired && this.connectionStatus === ConnectionStatus.HANDSHAKE) {
6086
if(this.initialHandshake(byteBuffer)) {
6187
this._connectionStatus = ConnectionStatus.ACTIVE;
6288
} else {

src/test.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import { Socket } from 'net';
77
class TestConnectionHandler extends SocketServer {
88

99
public decodeMessage(data: ByteBuffer): void {
10-
logger.info(`Data received:`, data.getString());
10+
logger.info(`Data received:`, data.get('string'));
11+
logger.info(data.get('long').toString());
1112
}
1213

1314
public initialHandshake(data: ByteBuffer): boolean {
14-
logger.info(`Initial handshake:`, data.getString());
15+
logger.info(`Initial handshake:`, data.get('string'));
16+
logger.info(data.get('long').toString());
1517
return true;
1618
}
1719

@@ -24,23 +26,34 @@ class TestConnectionHandler extends SocketServer {
2426
function launchTestServer() {
2527
logger.info('Starting server...');
2628

27-
SocketServer.launch('Test Server', '0.0.0.0', 43594, socket =>
28-
new TestConnectionHandler(socket));
29+
const TEST_PORT = 8000;
30+
31+
const server = SocketServer.launch('Test Server', '0.0.0.0', TEST_PORT, socket =>
32+
new TestConnectionHandler(socket, {
33+
timeout: 300,
34+
keepAlive: false,
35+
handshakeRequired: false
36+
}));
2937

3038
const speakySocket = new Socket();
31-
speakySocket.connect(43594);
39+
speakySocket.connect(TEST_PORT);
3240

3341
setTimeout(() => {
3442
const buffer = new ByteBuffer(200);
3543
buffer.put('hi', 'string');
44+
buffer.put(BigInt('12345'), 'long');
3645
speakySocket.write(buffer.flipWriter());
37-
}, 3000);
46+
}, 1000);
3847

3948
setTimeout(() => {
4049
const buffer = new ByteBuffer(200);
4150
buffer.put('how are you?', 'string');
51+
buffer.put(BigInt('67890'), 'long');
4252
speakySocket.write(buffer.flipWriter());
43-
}, 6000);
53+
}, 2000);
54+
55+
setTimeout(() => speakySocket.destroy(), 3000);
56+
setTimeout(() => server.close(), 4000);
4457
}
4558

4659
launchTestServer();

src/util/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './strings';
22
export * from './numbers';
3+
export * from './objects';

src/util/objects.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
export function setObjectProps<T>(object: T,
2+
objectProps: Map<string, unknown> | Partial<T> | undefined,
3+
ignoreFieldNameCase: boolean = false): void {
4+
if(!objectProps) {
5+
return;
6+
}
7+
8+
const dataKeys = objectProps instanceof Map ? Array.from(objectProps.keys()) :
9+
Object.keys(objectProps ?? {});
10+
const objectKeys = Object.keys(object);
11+
12+
dataKeys.forEach(key => {
13+
const existingKey = objectKeys.find(k => {
14+
if(ignoreFieldNameCase) {
15+
return k.toLowerCase() === key.toLowerCase();
16+
} else {
17+
return k === key;
18+
}
19+
});
20+
21+
if(existingKey) {
22+
const value = objectProps instanceof Map ? objectProps.get(key) : objectProps[key];
23+
if(typeof object[existingKey] === 'number' || /^\d*$/.test(value)) {
24+
object[existingKey] = Number(value);
25+
} else {
26+
object[existingKey] = value;
27+
}
28+
}
29+
});
30+
}

0 commit comments

Comments
 (0)