diff --git a/src/commands/kick.ts b/src/commands/kick.ts index bc41889..924d3bd 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,5 +1,3 @@ -import { BlackLimitLevel, PlayerKickOutScNotify, PlayerKickOutScNotify_KickType } from "../data/proto/StarRail"; -import SRServer from "../server/kcp/SRServer"; import Logger from "../util/Logger"; import Interface, { Command } from "./Interface"; const c = new Logger("/kick", "blue"); @@ -10,17 +8,7 @@ export default async function handle(command: Command) { return; } - Interface.target.send("PlayerKickOutScNotify", { - kickType: PlayerKickOutScNotify_KickType.KICK_BLACK, - blackInfo: { - limitLevel: BlackLimitLevel.BLACK_LIMIT_LEVEL_ALL, - beginTime: Math.round(Date.now() / 1000), - endTime: Math.round(Date.now() / 1000), - banType: 2 - } - } as PlayerKickOutScNotify); - - // SRServer.getInstance().sessions.delete(`${Interface.target.ctx.address}:${Interface.target.ctx.port}`); + Interface.target.kick(); c.log(`Kicked ${Interface.target.account.name}`); } \ No newline at end of file diff --git a/src/server/kcp/SRServer.ts b/src/server/kcp/SRServer.ts index 3ce7e9e..21d2cbe 100644 --- a/src/server/kcp/SRServer.ts +++ b/src/server/kcp/SRServer.ts @@ -40,8 +40,7 @@ export default class SRServer { switch (handshake.handshakeType) { case HandshakeType.CONNECT: c.log(`${client} connected`); - const rsp = new Handshake(HandshakeType.SEND_BACK_CONV).encode(); - this.udpSocket.send(rsp, 0, rsp.byteLength, rinfo.port, rinfo.address); + this.handshake(HandshakeType.SEND_BACK_CONV, rinfo); const kcpobj = new KCP(0x69, 0x420, { address: rinfo.address, port: rinfo.port, @@ -50,7 +49,7 @@ export default class SRServer { kcpobj.nodelay(1, 5, 2, 0); kcpobj.output((d, s, u) => this.output(d, s, u)); kcpobj.wndsize(256, 256); - this.sessions.set(client, new Session(kcpobj, rinfo)); + this.sessions.set(client, new Session(kcpobj, rinfo, client)); break; case HandshakeType.DISCONNECT: c.log(`${client} disconnected`); @@ -72,6 +71,11 @@ export default class SRServer { this.udpSocket.send(buf, 0, size, ctx.port, ctx.address); } + public handshake(hType: HandshakeType, rinfo: RemoteInfo) { + const rsp = new Handshake(hType).encode(); + this.udpSocket.send(rsp, 0, rsp.byteLength, rinfo.port, rinfo.address); + } + private async onError(err: Error) { c.error(err); } diff --git a/src/server/kcp/Session.ts b/src/server/kcp/Session.ts index 8306076..5e1378c 100644 --- a/src/server/kcp/Session.ts +++ b/src/server/kcp/Session.ts @@ -8,8 +8,10 @@ import Logger, { VerboseLevel } from '../../util/Logger'; import defaultHandler from '../packets/PacketHandler'; import Account from '../../db/Account'; import Player from '../../db/Player'; -import { PlayerSyncScNotify } from '../../data/proto/StarRail'; +import { BlackLimitLevel, PlayerKickOutScNotify, PlayerKickOutScNotify_KickType, PlayerSyncScNotify } from '../../data/proto/StarRail'; import Avatar from '../../db/Avatar'; +import SRServer from './SRServer'; +import { HandshakeType } from './Handshake'; function r(...args: string[]) { return fs.readFileSync(resolve(__dirname, ...args)); @@ -20,18 +22,21 @@ export default class Session { public c: Logger; public account!: Account; public player!: Player; - public constructor(private readonly kcpobj: KCP.KCP, public readonly ctx: RemoteInfo) { - this.kcpobj = kcpobj; + public kicked = false; + + public constructor(private kcpobj: KCP.KCP, public readonly ctx: RemoteInfo, public id: string) { this.ctx = ctx; this.c = new Logger(`${this.ctx.address}:${this.ctx.port}`, 'yellow'); this.update(); } public inputRaw(data: Buffer) { + if (this.kicked) return; this.kcpobj.input(data); } public async update() { + if (this.kicked) return; if (!this.kcpobj) { console.error("wtf kcpobj is undefined"); console.debug(this) @@ -79,10 +84,26 @@ export default class Session { }, basicInfo: this.player.db.basicInfo } as PlayerSyncScNotify); - + this.player.save(); } + public kick(hard: boolean = true) { + SRServer.getInstance().sessions.delete(this.id); + this.kicked = true; + if (hard) this.send("PlayerKickOutScNotify", { + kickType: PlayerKickOutScNotify_KickType.KICK_BLACK, + blackInfo: { + limitLevel: BlackLimitLevel.BLACK_LIMIT_LEVEL_ALL, + beginTime: Math.round(Date.now() / 1000), + endTime: Math.round(Date.now() / 1000), + banType: 2 + } + } as PlayerKickOutScNotify); + + SRServer.getInstance().handshake(HandshakeType.DISCONNECT, this.ctx); + } + public send(name: PacketName, body: {}) { this.c.verbL(body); const packet = Packet.encode(name, body); @@ -93,6 +114,7 @@ export default class Session { } public sendRaw(data: Buffer) { + if (this.kicked) return; this.kcpobj.send(data); } } \ No newline at end of file