Skip to content

Commit 94692dc

Browse files
committed
fix: can connect
1 parent d2a5db7 commit 94692dc

File tree

8 files changed

+199
-26
lines changed

8 files changed

+199
-26
lines changed

libs/@rustymotors/binary/src/lib/BinaryMember.ts

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function addAlignementPadding(buffer: Uint8Array, alignment: number): Uin
6767
*/
6868
export function verifyAlignment(buffer: Uint8Array, alignment: number) {
6969
if (buffer.length % alignment !== 0) {
70-
throw new Error(`Buffer size is not aligned to ${alignment}`);
70+
throw new Error(`Buffer size is not aligned to ${alignment}, got ${buffer.length}`);
7171
}
7272
}
7373

@@ -92,10 +92,6 @@ export class BinaryMember {
9292
this.value = v;
9393
}
9494
get() {
95-
if (this.shouldPad) {
96-
verifyAlignment(this.value, BINARY_ALIGNMENT);
97-
return this.value;
98-
}
9995
return this.value;
10096
}
10197
size() {
@@ -156,6 +152,46 @@ export class Uint32_t extends BinaryMember {
156152
const byte3 = this.value[3] || 0;
157153
return byte0 | byte1 | byte2 | byte3;
158154
}
155+
156+
setInt(value: number, endian: "LE" | "BE" = "LE") {
157+
if (value < 0 || value > 0xffffffff) {
158+
throw new Error(`Value ${value} is not a 32-bit integer`);
159+
}
160+
161+
if (endian === "BE") {
162+
this.setBE(value);
163+
} else {
164+
this.setLE(value);
165+
}
166+
}
167+
168+
/**
169+
* Sets the value of the binary member to a 32-bit little-endian integer.
170+
*
171+
* @param {number} value - The 32-bit little-endian integer value to set.
172+
*/
173+
setLE(value: number) {
174+
this.value = new Uint8Array([
175+
value & 0xff,
176+
(value >> 8) & 0xff,
177+
(value >> 16) & 0xff,
178+
(value >> 24) & 0xff,
179+
]);
180+
}
181+
182+
/**
183+
* Sets the value of the binary member to a 32-bit big-endian integer.
184+
*
185+
* @param {number} value - The 32-bit big-endian integer value to set.
186+
*/
187+
setBE(value: number) {
188+
this.value = new Uint8Array([
189+
(value >> 24) & 0xff,
190+
(value >> 16) & 0xff,
191+
(value >> 8) & 0xff,
192+
value & 0xff,
193+
]);
194+
}
159195
}
160196

161197
export class Uint8_tArray extends BinaryMember {
@@ -216,6 +252,15 @@ export class CString extends BinaryMember {
216252
override size(): number {
217253
return this.value.length + 4;
218254
}
255+
256+
/**
257+
* Returns the string as a sequence of characters without the null terminator.
258+
* @returns {string} The string as a sequence of characters.
259+
*/
260+
override toString(): string {
261+
return this.value.toString();
262+
}
263+
219264
}
220265

221266

libs/@rustymotors/roomserver/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"dependencies": {
66
"@mikro-orm/core": "^6.4.7",
77
"@rustymotors/binary": "workspace:^",
8+
"rusty-motors-database": "workspace:1.0.0-next.0",
9+
"rusty-motors-gateway": "workspace:1.0.0-next.0",
810
"rusty-motors-shared": "workspace:1.0.0-next.0",
911
"rusty-motors-shared-packets": "workspace:1.0.0-next.0",
1012
"tslib": "^2.8.1"

libs/@rustymotors/roomserver/src/lib/LoginRequest.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,12 @@ export class LoginRequest implements PacketBody {
7474
toHexString(): string {
7575
return this.serialize().toString();
7676
}
77+
78+
get customerNumber(): number {
79+
return this._customerNumber.getBE();
80+
}
81+
82+
get userInfo(): UserInfo {
83+
return this._userInfo;
84+
}
7785
}

libs/@rustymotors/roomserver/src/lib/MessageNumberMap.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22
export const MessageNumberMap: Record<number, string> = {
33
0x0100: "NPS_LOGIN",
44
0x0101: "NPS_GET_USER_LIST",
5+
0x0120: "NPS_LOGIN_RESPONSE",
56
};
67

7-
export type MessageName = keyof typeof MessageNumberMap;
8+
export type MessageNumber = keyof typeof MessageNumberMap;
9+
10+
export type MessageName = typeof MessageNumberMap[MessageNumber];
11+
12+
export function getMessageName(messageNumber: MessageNumber): string {
13+
const messageName = MessageNumberMap[messageNumber];
14+
if (!messageName) {
15+
throw new Error(`Unknown message number: ${messageNumber}`);
16+
}
17+
return messageName;
18+
}
19+
20+
/**
21+
* Rturns the message number for the given message name
22+
* @param messageName
23+
* @returns {number | undefined}
24+
*/
25+
export function getMessageNumber(messageName: MessageName): number {
26+
for (const [key, value] of Object.entries(MessageNumberMap)) {
27+
if (value === messageName) {
28+
return parseInt(key);
29+
}
30+
}
31+
throw new Error(`Unknown message name: ${messageName}`);
32+
}

libs/@rustymotors/roomserver/src/lib/RoomServer.ts

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
import { BytableMessage } from '@rustymotors/binary';
2-
import { getServerLogger, ServiceResponse, type ServerLogger } from 'rusty-motors-shared';
3-
import { MessageNumberMap } from './MessageNumberMap.js';
2+
import { databaseManager } from "rusty-motors-database";
3+
import {
4+
createCommandEncryptionPair,
5+
createDataEncryptionPair,
6+
} from "rusty-motors-gateway";
7+
import {
8+
addEncryption,
9+
fetchStateFromDatabase,
10+
getEncryption,
11+
getServerLogger,
12+
McosEncryption,
13+
SerializedBufferOld,
14+
ServiceResponse,
15+
type ServerLogger,
16+
} from "rusty-motors-shared";
17+
import { getMessageNumber, MessageNumberMap } from "./MessageNumberMap.js";
418
import { LoginRequest } from './LoginRequest.js';
19+
import { UserData } from './UserData.js';
520

621
export class RoomServer {
722
private _id: number;
@@ -10,12 +25,14 @@ export class RoomServer {
1025
private _port: number;
1126
private log: ServerLogger;
1227

28+
private usersData = new Map<number, UserData>();
29+
1330
constructor({ id, name, ip, port }: { id: number, name: string, ip: string, port: number }) {
1431
this._name = name;
1532
this._id = id;
1633
this.log = getServerLogger(name, 'roomserver');
1734
this._ip = ip;
18-
this._port = port;
35+
this._port = port;
1936
}
2037

2138
async receivePacket({
@@ -53,28 +70,98 @@ export class RoomServer {
5370
}
5471
}
5572
private async handleLogin({ connectionId, packet }: { connectionId: string, packet: BytableMessage }): Promise<ServiceResponse> {
56-
const log = getServerLogger("RoomServer.handleLogin");
73+
const log = this.log.child({ connectionId, loggerName: "handlers/_npsRequestGameConnectServer" });
5774

5875
try {
5976
log.debug({ connectionId, packet: packet.toHexString() }, "Handling NPS_LOGIN");
6077

6178
const getServerInfoRequest = new LoginRequest();
6279
getServerInfoRequest.deserialize(packet.getBody());
6380

64-
log.debug({ connectionId, getServerInfoRequest }, "Received NPS_LOGIN");
81+
82+
const customerId = getServerInfoRequest.customerNumber;
83+
const userId = getServerInfoRequest.userInfo.userId;
84+
85+
log.debug(
86+
{ connectionId, customerId: customerId , userId: userId },
87+
"Connecting to game server",
88+
);
89+
90+
const state = fetchStateFromDatabase();
91+
92+
const existingEncryption = getEncryption(
93+
state,
94+
connectionId,
95+
);
96+
97+
if (!existingEncryption) {
98+
// Set the encryption keys on the lobby connection
99+
const keys =
100+
await databaseManager.fetchSessionKeyByCustomerId(
101+
customerId,
102+
);
103+
104+
if (keys === undefined) {
105+
throw Error("Error fetching session keys!");
106+
}
107+
108+
// We have the session keys, set them on the connection
109+
const newCommandEncryptionPair =
110+
createCommandEncryptionPair(keys.sessionKey);
111+
112+
const newDataEncryptionPair =
113+
createDataEncryptionPair(keys.sessionKey);
114+
115+
const newEncryption = new McosEncryption({
116+
connectionId,
117+
commandEncryptionPair: newCommandEncryptionPair,
118+
dataEncryptionPair: newDataEncryptionPair,
119+
});
120+
121+
addEncryption(state, newEncryption).save();
122+
}
123+
124+
const userInfo = getServerInfoRequest.userInfo
125+
126+
const userData = userInfo.userData;
127+
128+
this.usersData.set(userId, userData);
129+
130+
const response = new BytableMessage();
131+
response.header.setMessageId(
132+
getMessageNumber("NPS_LOGIN_RESPONSE"),
133+
);
134+
response.header.setMessageVersion(0);
135+
response.setSerializeOrder([
136+
{ name: "userId", field: "Dword" },
137+
{ name: "userName", field: "Container" },
138+
{ name: "userData", field: "Buffer" },
139+
]);
140+
141+
response.setFieldValueByName("userId", userInfo.userId);
142+
response.setFieldValueByName("userName", userInfo.userName);
143+
response.setFieldValueByName("userData", Buffer.from(userData.get()));
144+
145+
146+
log.debug(
147+
{ connectionId, response: response.toHexString() },
148+
"Sending NPS_LOGIN_RESPONSE",
149+
);
150+
151+
return {
152+
connectionId,
153+
messages: [response],
154+
};
155+
65156

66157
} catch (error: any) {
67-
log.error({ connectionId, error }, `Error handling NPS_LOGIN: ${(error as Error).message}`);
158+
log.error({ connectionId, error }, `Error handling NPS_LOGIN: ${(error as Error).message}`);
68159
return {
69160
connectionId,
70161
messages: [],
71162
};
72163

73164
}
74-
return {
75-
connectionId,
76-
messages: [],
77-
};
78165
}
79166

80167
get id() {

libs/@rustymotors/roomserver/src/lib/UserInfo.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
BinaryMember,
33
Uint32_t,
44
CString,
5-
Uint8_tArray,
65
} from "@rustymotors/binary";
76
import { UserData } from "./UserData.js";
87

@@ -59,27 +58,27 @@ export class UserInfo extends BinaryMember {
5958
return this._userId.size() + this._userName.size() + this._userData.size();
6059
}
6160

62-
get userId(): Uint32_t {
63-
return this._userId;
61+
get userId(): number {
62+
return this._userId.getInt("BE");
6463
}
6564

66-
get userName(): CString {
67-
return this._userName;
65+
get userName(): string {
66+
return this._userName.toString();
6867
}
6968

70-
get userData(): Uint8_tArray {
69+
get userData(): UserData {
7170
return this._userData;
7271
}
7372

74-
set userId(value: Uint32_t) {
75-
this._userId = value;
73+
set userId(value: number) {
74+
this._userId.setInt(value, "BE");
7675
}
7776

7877
set userName(value: CString) {
7978
this._userName = value;
8079
}
8180

82-
set userData(value: Uint8_tArray) {
83-
this._userData.set(value.get());
81+
set userData(value: UserData) {
82+
this._userData = value;
8483
}
8584
}

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ packages:
33
- src/*
44
- libs/@rustymotors/*
55
onlyBuiltDependencies:
6+
- '@sentry/profiling-node'
67
- nx

0 commit comments

Comments
 (0)