[add] 整理警告

This commit is contained in:
建喵 2022-04-29 15:12:51 +08:00
parent d797a2a41a
commit 3d331ee10d
10 changed files with 60 additions and 42 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
PORT = 3000
TZ = Asia/Taipei

14
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "backend-.", "name": "backend-.",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"dotenv": "^16.0.0",
"tsrpc": "^3.1.3" "tsrpc": "^3.1.3"
}, },
"devDependencies": { "devDependencies": {
@ -533,6 +534,14 @@
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/dotenv": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz",
"integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==",
"engines": {
"node": ">=12"
}
},
"node_modules/editorconfig": { "node_modules/editorconfig": {
"version": "0.15.3", "version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
@ -2504,6 +2513,11 @@
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
"dev": true "dev": true
}, },
"dotenv": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz",
"integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q=="
},
"editorconfig": { "editorconfig": {
"version": "0.15.3", "version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",

View File

@ -22,6 +22,7 @@
"typescript": "^4.5.2" "typescript": "^4.5.2"
}, },
"dependencies": { "dependencies": {
"dotenv": "^16.0.0",
"tsrpc": "^3.1.3" "tsrpc": "^3.1.3"
} }
} }

View File

@ -2,11 +2,11 @@ import { ApiCallWs } from "tsrpc";
import { roomInstance } from ".."; import { roomInstance } from "..";
import { ReqJoin, ResJoin } from "../shared/protocols/PtlJoin"; import { ReqJoin, ResJoin } from "../shared/protocols/PtlJoin";
export async function ApiJoin(call: ApiCallWs<ReqJoin, ResJoin>) { export async function ApiJoin(call: ApiCallWs<ReqJoin, ResJoin>): Promise<void> {
let playerId = roomInstance.join(call.req, call.conn); let playerId: number = roomInstance.join(call.req, call.conn);
call.succ({ call.succ({
playerId: playerId, playerId: playerId,
gameState: roomInstance.gameSystem.state gameState: roomInstance.gameSystem.state
}) });
} }

View File

@ -1,18 +1,19 @@
import 'k8w-extend-native'; import "k8w-extend-native";
import * as path from "path"; import * as path from "path";
import { WsConnection, WsServer } from "tsrpc"; import { WsConnection, WsServer } from "tsrpc";
import { Room } from './models/Room'; import { Room } from "./models/Room";
import { serviceProto, ServiceType } from './shared/protocols/serviceProto'; import { serviceProto, ServiceType } from "./shared/protocols/serviceProto";
require("dotenv").config();
// 创建 TSRPC WebSocket Server // 创建 TSRPC WebSocket Server
export const server = new WsServer(serviceProto, { export const server: WsServer<ServiceType> = new WsServer(serviceProto, {
port: 3000, port: +process.env.PORT! || 3000,
json: true json: true
}); });
// 断开连接后退出房间 // 断开连接后退出房间
server.flows.postDisconnectFlow.push(v => { server.flows.postDisconnectFlow.push(v => {
let conn = v.conn as WsConnection<ServiceType>; let conn: WsConnection<ServiceType> = v.conn as WsConnection<ServiceType>;
if (conn.playerId) { if (conn.playerId) {
roomInstance.leave(conn.playerId, conn); roomInstance.leave(conn.playerId, conn);
} }
@ -20,19 +21,19 @@ server.flows.postDisconnectFlow.push(v => {
return v; return v;
}); });
export const roomInstance = new Room(server); export const roomInstance: Room = new Room(server);
// 初始化 // 初始化
async function init() { async function init(): Promise<void> {
// 挂载 API 接口 // 挂载 API 接口
await server.autoImplementApi(path.resolve(__dirname, 'api')); await server.autoImplementApi(path.resolve(__dirname, "api"));
// TODO // TODO
// Prepare something... (e.g. connect the db) // Prepare something... (e.g. connect the db)
}; }
// 启动入口点 // 启动入口点
async function main() { async function main(): Promise<void> {
await init(); await init();
await server.start(); await server.start();
} }

View File

@ -23,78 +23,78 @@ export class Room {
constructor(server: WsServer<ServiceType>) { constructor(server: WsServer<ServiceType>) {
this.server = server; this.server = server;
setInterval(() => { this.sync() }, 1000 / this.syncRate); setInterval(() => { this.sync(); }, 1000 / this.syncRate);
} }
/** 加入房间 */ /** 加入房间 */
join(req: ReqJoin, conn: WsConnection<ServiceType>) { join(req: ReqJoin, conn: WsConnection<ServiceType>): number {
let input: PlayerJoin = { let input: PlayerJoin = {
type: 'PlayerJoin', type: "PlayerJoin",
playerId: this.nextPlayerId++, playerId: this.nextPlayerId++,
// 初始位置随机 // 初始位置随机
pos: { pos: {
x: Math.random() * 10 - 5, x: Math.random() * 10 - 5,
y: Math.random() * 10 - 5 y: Math.random() * 10 - 5
} }
} };
this.applyInput(input); this.applyInput(input);
this.conns.push(conn); this.conns.push(conn);
conn.playerId = input.playerId; conn.playerId = input.playerId;
conn.listenMsg('client/ClientInput', call => { conn.listenMsg("client/ClientInput", call => {
this.playerLastSn[input.playerId] = call.msg.sn; this.playerLastSn[input.playerId] = call.msg.sn;
call.msg.inputs.forEach(v => { call.msg.inputs.forEach(v => {
this.applyInput({ this.applyInput({
...v, ...v,
playerId: input.playerId playerId: input.playerId
}); });
}) });
}); });
return input.playerId; return input.playerId;
} }
applyInput(input: GameSystemInput) { applyInput(input: GameSystemInput): void {
this.pendingInputs.push(input); this.pendingInputs.push(input);
} }
sync() { sync(): void {
let inputs = this.pendingInputs; let inputs = this.pendingInputs;
this.pendingInputs = []; this.pendingInputs = [];
// Apply inputs // Apply inputs
inputs.forEach(v => { inputs.forEach(v => {
this.gameSystem.applyInput(v) this.gameSystem.applyInput(v);
}); });
// Apply TimePast // Apply TimePast
let now = process.uptime() * 1000; let now = process.uptime() * 1000;
this.applyInput({ this.applyInput({
type: 'TimePast', type: "TimePast",
dt: now - (this.lastSyncTime ?? now) dt: now - (this.lastSyncTime ?? now)
}); });
this.lastSyncTime = now; this.lastSyncTime = now;
// 发送同步帧 // 发送同步帧
this.conns.forEach(v => { this.conns.forEach(v => {
v.sendMsg('server/Frame', { v.sendMsg("server/Frame", {
inputs: inputs, inputs: inputs,
lastSn: this.playerLastSn[v.playerId!] lastSn: this.playerLastSn[v.playerId!]
}) });
}); });
} }
/** 离开房间 */ /** 离开房间 */
leave(playerId: number, conn: WsConnection<ServiceType>) { leave(playerId: number, conn: WsConnection<ServiceType>): void {
this.conns.removeOne(v => v.playerId === playerId); this.conns.removeOne(v => v.playerId === playerId);
this.applyInput({ this.applyInput({
type: 'PlayerLeave', type: "PlayerLeave",
playerId: playerId playerId: playerId
}); });
} }
} }
declare module 'tsrpc' { declare module "tsrpc" {
export interface WsConnection { export interface WsConnection {
playerId?: number; playerId?: number;
} }

View File

@ -11,4 +11,4 @@ export const gameConfig = {
arrowAttackRadius: 2, arrowAttackRadius: 2,
// 被箭矢几种后的晕眩时间(毫秒) // 被箭矢几种后的晕眩时间(毫秒)
arrowDizzyTime: 1000 arrowDizzyTime: 1000
} };

View File

@ -7,9 +7,9 @@ export interface ReqJoin {
export interface ResJoin { export interface ResJoin {
/** 加入房间后,自己的 ID */ /** 加入房间后,自己的 ID */
playerId: number, playerId: number;
/** 状态同步:一次性同步当前状态 */ /** 状态同步:一次性同步当前状态 */
gameState: GameSystemState gameState: GameSystemState;
} }
// export const conf = {} // export const conf = {}

View File

@ -1,7 +1,7 @@
import { ServiceProto } from 'tsrpc-proto'; import { ServiceProto } from "tsrpc-proto";
import { MsgClientInput } from './client/MsgClientInput'; import { MsgClientInput } from "./client/MsgClientInput";
import { ReqJoin, ResJoin } from './PtlJoin'; import { ReqJoin, ResJoin } from "./PtlJoin";
import { MsgFrame } from './server/MsgFrame'; import { MsgFrame } from "./server/MsgFrame";
export interface ServiceType { export interface ServiceType {
api: { api: {
@ -9,11 +9,11 @@ export interface ServiceType {
req: ReqJoin, req: ReqJoin,
res: ResJoin res: ResJoin
} }
}, };
msg: { msg: {
"client/ClientInput": MsgClientInput, "client/ClientInput": MsgClientInput,
"server/Frame": MsgFrame "server/Frame": MsgFrame
} };
} }
export const serviceProto: ServiceProto<ServiceType> = { export const serviceProto: ServiceProto<ServiceType> = {

View File

@ -17,14 +17,14 @@ describe("ApiSend", function (): void {
}); });
it("Success", async function (): Promise<void> { it("Success", async function (): Promise<void> {
let ret: any = await client.callApi("Send", { let ret: any = await client.callApi("Join", {
content: "Test" content: "Test"
}); });
assert.ok(ret.isSucc) assert.ok(ret.isSucc);
}); });
it("Check content is empty", async function (): Promise<void> { it("Check content is empty", async function (): Promise<void> {
let ret: any = await client.callApi("Send", { let ret: any = await client.callApi("Join", {
content: "" content: ""
}); });
assert.deepStrictEqual(ret, { assert.deepStrictEqual(ret, {
@ -33,7 +33,7 @@ describe("ApiSend", function (): void {
}); });
}); });
after(async function () { after(async function (): Promise<void> {
await client.disconnect(); await client.disconnect();
}); });
}); });