Connection.ts
2.86 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
import { Socket } from "socket.io";
import {
RawMessage,
ServerInboundMessage,
ServerInboundMessageKey,
ServerOutboundMessage,
ServerOutboundMessageKey,
ServerResponse,
} from "../../common";
import { Room } from "../room/Room";
import { RoomManager } from "../room/RoomManager";
import { User } from "../user/User";
import { MessageValidator } from "./MessageValidator";
import { SocketWrapper } from "./SocketWrapper";
export class Connection {
public readonly socket: SocketWrapper;
public readonly roomManager: RoomManager;
static readonly validator: MessageValidator = new MessageValidator();
public user?: User;
constructor(socket: SocketWrapper, roomManager: RoomManager) {
this.socket = socket;
this.roomManager = roomManager;
socket.setHandler((raw) => this.handleRaw(raw));
socket.setDisconnectHandler(() => this.handleDisconnect());
socket.setPingHandler(() => this.handlePing());
}
public send<T extends ServerOutboundMessageKey>(
type: T,
message: ServerOutboundMessage<T>
) {
this.socket.send({
type: type as string,
message: message,
});
}
public sendPing() {
this.socket.sendPing();
}
public handleRaw(raw: RawMessage): ServerResponse<any> {
if (!raw || !raw.message || !raw.type) {
return { ok: false };
}
const type = raw.type as ServerInboundMessageKey;
const message = raw.message;
if (!Connection.validator.validate(type, message)) {
return { ok: false };
}
// 유저 정보가 없으므로 로그인은 따로 핸들링
if (type === "login") {
return this.handleLogin(message);
}
// Game > Room > User 순으로 전달
if (this.user?.room?.game) {
const response = this.user.room.game.handler.handle(
type,
this.user,
message
);
if (response) return response;
}
if (this.user?.room) {
const response = this.user.room.handler.handle(type, this.user, message);
if (response) return response;
}
if (this.user) {
const response = this.user.handler.handle(type, this.user, message);
if (response) return response;
}
return { ok: false };
}
private handleLogin(
message: ServerInboundMessage<"login">
): ServerResponse<"login"> {
if (message.nickname.length > 12) {
return { ok: false, reason: "닉네임은 최대 12글자입니다." };
}
if (message.nickname.trim().length === 0) {
return { ok: false, reason: "닉네임을 공백으로 설정할 수 없습니다." };
}
this.user = new User(message.nickname, this);
// console.log(`User ${message.username} has logged in!`);
return { ok: true, result: this.user.username };
}
public handleDisconnect(): void {
this.user?.disconnected();
}
public handlePing(): void {
if (this.user) {
this.user?.room?.pong(this.user);
}
}
}