File size: 1,890 Bytes
eee16fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import World from '@/core/domain/World';
import Server from '../../../core/interface/server/Server';
import GameConnection from '@/game/interface/networking/GameConnection';
import { Socket } from 'net';
import { Logger } from 'winston';
import { GameConfig } from '@/game/infra/config/GameConfig';
import { PacketMapValue } from '@/core/interface/networking/packets/Packets';

export default class GameServer extends Server {
    private readonly world: World;

    constructor(container: {
        logger: Logger;
        config: GameConfig;
        packets: Map<number, PacketMapValue<any>>;
        world: World;
    }) {
        super(container);
        this.world = container.world;
    }

    async onData(connection: GameConnection, data: Buffer) {
        this.container.containerInstance.createScope();
        this.logger.debug(`[IN][DATA SOCKET EVENT] Data received from ID: ${connection.getId()}`);
        const header = data[0];
        const packetBuilder = this.packets.get(header);

        if (!packetBuilder) {
            this.logger.info(`[IN][PACKET] Unknown header packet: ${data[0]}`);
            return;
        }

        const { createPacket, createHandler } = packetBuilder;
        const packet = createPacket({});
        const handler = createHandler(this.container);
        this.logger.debug(`[IN][PACKET] processing packet: ${handler.constructor.name}`);
        connection.cork();
        await handler
            .execute(connection, packet.unpack(data))
            .catch((err) => this.logger.error(err))
            .finally(() => {
                connection.uncork();
            });
    }

    createConnection(socket: Socket) {
        return new GameConnection({
            socket,
            logger: this.logger,
        });
    }

    async close(): Promise<void> {
        await this.world.close();
        return super.close();
    }
}