消息导出脚本,收发消息简化
This commit is contained in:
parent
e5fc17d1f6
commit
e245377391
@ -4,3 +4,7 @@ export class PrefabNames {
|
|||||||
return this.login
|
return this.login
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum EventType {
|
||||||
|
Ws = 'ws-message',
|
||||||
|
}
|
||||||
|
@ -2,11 +2,8 @@ import { _decorator, Button, Component, EditBox, Label, Node } from 'cc'
|
|||||||
import { WsClient } from '../network/wsclient'
|
import { WsClient } from '../network/wsclient'
|
||||||
import { WsConfig } from '../network/wsconfig'
|
import { WsConfig } from '../network/wsconfig'
|
||||||
import { PbHelper } from '../network/pbHelper'
|
import { PbHelper } from '../network/pbHelper'
|
||||||
import pb from '../pb/login.js'
|
import { ReqUserLogin, ServiceTypeId, MsgId, RspUserLogin } from '../network/pbExport'
|
||||||
import pb1 from '../pb/client.js'
|
import { EventType } from '../constant'
|
||||||
import pb2 from '../pb/msgId.js'
|
|
||||||
import pb3 from '../pb/service.js'
|
|
||||||
// import * as pb from '../pb/login.d'
|
|
||||||
const { ccclass, property } = _decorator
|
const { ccclass, property } = _decorator
|
||||||
|
|
||||||
@ccclass('loginPanel')
|
@ccclass('loginPanel')
|
||||||
@ -24,11 +21,11 @@ export class loginPanel extends Component {
|
|||||||
start() {
|
start() {
|
||||||
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginButtonClick, this)
|
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginButtonClick, this)
|
||||||
// 监听websocket消息事件
|
// 监听websocket消息事件
|
||||||
window.addEventListener('ws-message', this.onMessage.bind(this))
|
window.addEventListener(EventType.Ws, this.onMessage.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onDestroy(): void {
|
protected onDestroy(): void {
|
||||||
window.removeEventListener('ws-message', this.onMessage.bind(this))
|
window.removeEventListener(EventType.Ws, this.onMessage.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录按钮点击处理函数
|
// 登录按钮点击处理函数
|
||||||
@ -46,7 +43,7 @@ export class loginPanel extends Component {
|
|||||||
const ws = WsClient.Instance()
|
const ws = WsClient.Instance()
|
||||||
console.log(typeof ws)
|
console.log(typeof ws)
|
||||||
if (!ws.IsConnected) {
|
if (!ws.IsConnected) {
|
||||||
await ws.ConnectAsync(WsConfig.Address[0].Address[0])
|
await ws.ConnectAsync(WsConfig.Address[1].Address[0])
|
||||||
if (!ws.IsConnected) {
|
if (!ws.IsConnected) {
|
||||||
this.statusLable.string = '连接网络失败'
|
this.statusLable.string = '连接网络失败'
|
||||||
return
|
return
|
||||||
@ -54,33 +51,28 @@ export class loginPanel extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('登陆帐号:', username, '密码:', pwd)
|
console.log('登陆帐号:', username, '密码:', pwd)
|
||||||
console.log('ReqUserLogin:', pb.ReqUserLogin)
|
|
||||||
|
|
||||||
const req = new pb.ReqUserLogin()
|
const req = new ReqUserLogin()
|
||||||
req.username = username
|
req.username = username
|
||||||
req.password = pwd
|
req.password = pwd
|
||||||
req.version = '20250601123030'
|
req.version = '20250601123030'
|
||||||
// const req = pb.ReqUserLogin.create({ username: username, password: pwd, ip: '', deviceId: '', version: '' })
|
const buffer = ReqUserLogin.encode(req).finish()
|
||||||
const buffer = pb.ReqUserLogin.encode(req).finish()
|
ws.Send(ServiceTypeId.STI_Login, MsgId.ReqUserLoginId, buffer)
|
||||||
const clinetMsg = new pb1.ClientMsg()
|
|
||||||
clinetMsg.msgId = pb2.MsgId.ReqUserLoginId
|
|
||||||
clinetMsg.data = buffer
|
|
||||||
clinetMsg.serviceTid = pb3.ServiceTypeId.STI_Login
|
|
||||||
const buffer1 = pb1.ClientMsg.encode(clinetMsg).finish()
|
|
||||||
ws.Send(buffer1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMessage(event: CustomEvent) {
|
private onMessage(event: CustomEvent) {
|
||||||
try {
|
try {
|
||||||
const message = JSON.parse(event.detail) // 解析消息内容
|
const [msgid, buffer] = PbHelper.DecodeClient(event.detail)
|
||||||
if (message.type === 'loginSuccess') {
|
switch (msgid) {
|
||||||
this.statusLable.string = '登录成功'
|
case MsgId.RspUserLoginId:
|
||||||
this.node.active = false
|
const rsp = PbHelper.Decode(RspUserLogin, buffer)
|
||||||
} else if (message.type === 'loginError') {
|
console.log('收到返回消息:', rsp)
|
||||||
this.statusLable.string = '登录失败:' + message.reason
|
default:
|
||||||
|
// console.log('收到非json消息:', event.detail)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('收到非json消息:', event.detail)
|
// console.log('解析错误失败:', error)
|
||||||
|
console.log(PbHelper.Uint8ToHex(event.detail))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
80
assets/scripts/network/pbExport.ts
Normal file
80
assets/scripts/network/pbExport.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// 由 pb-import-export-generator 自动生成,请勿手动修改
|
||||||
|
|
||||||
|
// 导入语句
|
||||||
|
import chat from '../pb/chat.js'
|
||||||
|
import client from '../pb/client.js'
|
||||||
|
import code from '../pb/code.js'
|
||||||
|
import colorgame from '../pb/colorgame.js'
|
||||||
|
import common from '../pb/common.js'
|
||||||
|
import login from '../pb/login.js'
|
||||||
|
import match from '../pb/match.js'
|
||||||
|
import msgId from '../pb/msgId.js'
|
||||||
|
import service from '../pb/service.js'
|
||||||
|
import user from '../pb/user.js'
|
||||||
|
|
||||||
|
// 解构赋值
|
||||||
|
const { ChatType, ReqChat, ChatUser, GameUser, ServiceTypeId } = chat
|
||||||
|
const { ClientMsg } = client
|
||||||
|
const { ErrCode } = code
|
||||||
|
const { ColorPrizeArea, ColorPrizeAreaRange, ColorRoomConfig, ColorType, ColorBetArea, ColorGameStatus, ColorRoomWaitStart, ColorRoomStart, ColorRoomBetting, ColorRoomEndBet, ColorRoomOpenThreeDice, ColorRoomSettle, NtfColorRoomInfo, NtfColorGameStart, NtfColorBetting, ReqColorBetting, RspColorBetting, ColorBetAreaInfo, NtfColorBetAreaInfo, ColorPrizeType, ColorBetAreaMul, NtfColorEndBetting, NtfColorOpenThreeDice, NtfColorSettle, ColorUser, NtfColorBigUser, NtfColorTrend, ColorBigUser, NtfColorMaintain } = colorgame
|
||||||
|
const { NtfKickOutUser, ReqEnterRoom, RspEnterRoom, ReqLeaveRoom, RspLeaveRoom, NtfPayoutFail } = common
|
||||||
|
const { ReqUserLogin, RspUserLogin, NtfUserOnline, NtfUserInService, ReqUserLogout, RspUserLogout, NtfUserOffline } = login
|
||||||
|
const { ReqMatchRoom, RspMatchRoom, NotifyUserEnterRoom } = match
|
||||||
|
const { MsgId } = msgId
|
||||||
|
|
||||||
|
// 导出语句
|
||||||
|
export {
|
||||||
|
ChatType,
|
||||||
|
ReqChat,
|
||||||
|
ChatUser,
|
||||||
|
GameUser,
|
||||||
|
ServiceTypeId,
|
||||||
|
ClientMsg,
|
||||||
|
ErrCode,
|
||||||
|
ColorPrizeArea,
|
||||||
|
ColorPrizeAreaRange,
|
||||||
|
ColorRoomConfig,
|
||||||
|
ColorType,
|
||||||
|
ColorBetArea,
|
||||||
|
ColorGameStatus,
|
||||||
|
ColorRoomWaitStart,
|
||||||
|
ColorRoomStart,
|
||||||
|
ColorRoomBetting,
|
||||||
|
ColorRoomEndBet,
|
||||||
|
ColorRoomOpenThreeDice,
|
||||||
|
ColorRoomSettle,
|
||||||
|
NtfColorRoomInfo,
|
||||||
|
NtfColorGameStart,
|
||||||
|
NtfColorBetting,
|
||||||
|
ReqColorBetting,
|
||||||
|
RspColorBetting,
|
||||||
|
ColorBetAreaInfo,
|
||||||
|
NtfColorBetAreaInfo,
|
||||||
|
ColorPrizeType,
|
||||||
|
ColorBetAreaMul,
|
||||||
|
NtfColorEndBetting,
|
||||||
|
NtfColorOpenThreeDice,
|
||||||
|
NtfColorSettle,
|
||||||
|
ColorUser,
|
||||||
|
NtfColorBigUser,
|
||||||
|
NtfColorTrend,
|
||||||
|
ColorBigUser,
|
||||||
|
NtfColorMaintain,
|
||||||
|
NtfKickOutUser,
|
||||||
|
ReqEnterRoom,
|
||||||
|
RspEnterRoom,
|
||||||
|
ReqLeaveRoom,
|
||||||
|
RspLeaveRoom,
|
||||||
|
NtfPayoutFail,
|
||||||
|
ReqUserLogin,
|
||||||
|
RspUserLogin,
|
||||||
|
NtfUserOnline,
|
||||||
|
NtfUserInService,
|
||||||
|
ReqUserLogout,
|
||||||
|
RspUserLogout,
|
||||||
|
NtfUserOffline,
|
||||||
|
ReqMatchRoom,
|
||||||
|
RspMatchRoom,
|
||||||
|
NotifyUserEnterRoom,
|
||||||
|
MsgId
|
||||||
|
};
|
@ -1,8 +1,4 @@
|
|||||||
/**
|
import { ClientMsg } from '../network/pbExport'
|
||||||
*
|
|
||||||
* pb helper
|
|
||||||
*/
|
|
||||||
// import { Message } from 'protobufjs'
|
|
||||||
|
|
||||||
interface ProtoEncodable<T> {
|
interface ProtoEncodable<T> {
|
||||||
create(data: T): unknown
|
create(data: T): unknown
|
||||||
@ -16,9 +12,18 @@ export class PbHelper {
|
|||||||
const message = protoClass.create(data)
|
const message = protoClass.create(data)
|
||||||
return protoClass.encode(message).finish()
|
return protoClass.encode(message).finish()
|
||||||
}
|
}
|
||||||
|
static DecodeClient(buffer: Uint8Array): [number, Uint8Array] {
|
||||||
|
const cMsg = ClientMsg.decode(buffer)
|
||||||
|
return [cMsg.msgId, cMsg.data]
|
||||||
|
}
|
||||||
static Decode<T>(protoClass: ProtoEncodable<T>, buffer: Uint8Array): T {
|
static Decode<T>(protoClass: ProtoEncodable<T>, buffer: Uint8Array): T {
|
||||||
return protoClass.decode(buffer)
|
return protoClass.decode(buffer)
|
||||||
}
|
}
|
||||||
|
static Uint8ToHex(buffer: Uint8Array): string {
|
||||||
|
return Array.from(buffer)
|
||||||
|
.map((byte) => byte.toString(16).padStart(2, '0'))
|
||||||
|
.join(' ')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 假设有一个生成的 Protobuf 类
|
// // 假设有一个生成的 Protobuf 类
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import { ClientMsg } from '../network/pbExport'
|
||||||
|
import { EventType } from '../constant'
|
||||||
|
import { PbHelper } from '../network/pbHelper'
|
||||||
|
|
||||||
export class WsClient {
|
export class WsClient {
|
||||||
private socket: WebSocket | null = null
|
private socket: WebSocket | null = null
|
||||||
private url: string = 'ws://echo.websocket.org' // 测试服务器
|
private url: string = 'ws://echo.websocket.org' // 测试服务器
|
||||||
@ -81,19 +85,18 @@ export class WsClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送消息到服务器
|
// 发送消息到服务器
|
||||||
Send(message: Uint8Array) {
|
Send(sid: number, msgId: number, msg: Uint8Array) {
|
||||||
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
||||||
// 如果连接不存在或未打开
|
// 如果连接不存在或未打开
|
||||||
console.error('websocket未连接,无法发送消息')
|
console.error('websocket未连接,无法发送消息')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// var msg: string = ''
|
const clinetMsg = new ClientMsg()
|
||||||
// if (typeof message == 'string') {
|
clinetMsg.msgId = msgId
|
||||||
// msg = message
|
clinetMsg.data = msg
|
||||||
// } else {
|
clinetMsg.serviceTid = sid
|
||||||
// msg = JSON.stringify(message)
|
const buffer = ClientMsg.encode(clinetMsg).finish()
|
||||||
// }
|
this.socket.send(buffer)
|
||||||
this.socket.send(message)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +107,16 @@ export class WsClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 收到消息回调
|
// 收到消息回调
|
||||||
private onMessage(event: MessageEvent) {
|
private async onMessage(event: MessageEvent) {
|
||||||
console.log('收到消息:', event.data)
|
try {
|
||||||
window.dispatchEvent(new CustomEvent('ws-message', { detail: event.data }))
|
const buffer = await event.data.arrayBuffer()
|
||||||
|
const uint8Array = new Uint8Array(buffer)
|
||||||
|
// console.log('收到消息:', uint8Array)
|
||||||
|
console.log('收到消息:', PbHelper.Uint8ToHex(uint8Array))
|
||||||
|
window.dispatchEvent(new CustomEvent(EventType.Ws, { detail: uint8Array }))
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析网络消息失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 连接关闭回调
|
// 连接关闭回调
|
||||||
|
@ -6,7 +6,7 @@ class AddressInfo {
|
|||||||
// 网关配置
|
// 网关配置
|
||||||
export class WsConfig {
|
export class WsConfig {
|
||||||
public static Address: Array<AddressInfo> = [
|
public static Address: Array<AddressInfo> = [
|
||||||
{ Name: 'super', Address: ['ws://127.0.0.1:5100', 'ws://127.0.0.1:5101'] },
|
{ Name: 'dev', Address: ['ws://127.0.0.1:5100', 'ws://127.0.0.1:5101'] },
|
||||||
{ Name: 'test', Address: ['ws://114.132.124.145:5100', 'ws://114.132.124.145:5101'] },
|
{ Name: 'test', Address: ['ws://114.132.124.145:5100', 'ws://114.132.124.145:5101'] },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
138
tools/pb_exports.js
Normal file
138
tools/pb_exports.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PB 模块导入导出代码生成器
|
||||||
|
* @param {string} pbDir - PB 文件所在的目录路径
|
||||||
|
* @param {string} outputFile - 生成的代码输出文件路径
|
||||||
|
* @param {string} [relativePath='../pb'] - 导入语句中的相对路径
|
||||||
|
*/
|
||||||
|
function generatePbImportsAndExports(pbDir, outputFile, relativePath = '../pb') {
|
||||||
|
try {
|
||||||
|
// 读取 PB 目录下的所有文件
|
||||||
|
const files = fs.readdirSync(pbDir)
|
||||||
|
|
||||||
|
// 过滤出 .js 文件并去除扩展名
|
||||||
|
const jsFiles = files.filter((file) => file.endsWith('.js'))
|
||||||
|
|
||||||
|
if (jsFiles.length === 0) {
|
||||||
|
console.warn(`警告: 在目录 ${pbDir} 中没有找到任何 .js 文件`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成导入语句
|
||||||
|
const importStatements = jsFiles
|
||||||
|
.map((file) => {
|
||||||
|
const moduleName = file.replace('.js', '')
|
||||||
|
return `import ${moduleName} from '${relativePath}/${moduleName}.js'`
|
||||||
|
})
|
||||||
|
.join('\n')
|
||||||
|
|
||||||
|
// 为每个文件生成导出内容
|
||||||
|
const moduleExports = {}
|
||||||
|
const allExports = new Set()
|
||||||
|
const exportSources = {} // 记录每个导出项的来源
|
||||||
|
|
||||||
|
jsFiles.forEach((file) => {
|
||||||
|
const filePath = path.join(pbDir, file)
|
||||||
|
const code = fs.readFileSync(filePath, 'utf-8')
|
||||||
|
const moduleName = file.replace('.js', '')
|
||||||
|
|
||||||
|
// 提取 $root.X 形式的导出
|
||||||
|
const rootExports = extractRootExports(code)
|
||||||
|
|
||||||
|
// 提取 enum 定义
|
||||||
|
const enumExports = extractEnumExports(code)
|
||||||
|
|
||||||
|
// 合并所有导出
|
||||||
|
const exports = [...rootExports, ...enumExports]
|
||||||
|
|
||||||
|
if (exports.length > 0) {
|
||||||
|
moduleExports[moduleName] = exports
|
||||||
|
|
||||||
|
// 记录导出项的来源
|
||||||
|
exports.forEach((exp) => {
|
||||||
|
if (!exportSources[exp]) {
|
||||||
|
exportSources[exp] = moduleName
|
||||||
|
allExports.add(exp)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (allExports.size === 0) {
|
||||||
|
console.warn(`警告: 没有找到任何可导出的类或枚举`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成解构赋值语句(只包含首次出现的导出项)
|
||||||
|
const destructureStatements = Object.entries(moduleExports)
|
||||||
|
.map(([moduleName, exports]) => {
|
||||||
|
// 过滤出该模块独有的导出项
|
||||||
|
const uniqueExports = exports.filter((exp) => exportSources[exp] === moduleName)
|
||||||
|
if (uniqueExports.length > 0) {
|
||||||
|
return `const { ${uniqueExports.join(', ')} } = ${moduleName}`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
.filter(Boolean) // 移除空字符串
|
||||||
|
.join('\n')
|
||||||
|
|
||||||
|
// 生成导出语句(所有唯一导出项)
|
||||||
|
const exportList = Array.from(allExports)
|
||||||
|
|
||||||
|
// 完整的输出代码
|
||||||
|
const outputCode =
|
||||||
|
`// 由 pb-import-export-generator 自动生成,请勿手动修改\n\n` +
|
||||||
|
`// 导入语句\n${importStatements}\n\n` +
|
||||||
|
`// 解构赋值\n${destructureStatements}\n\n` +
|
||||||
|
`// 导出语句\nexport {\n ${exportList.join(',\n ')}\n};\n`
|
||||||
|
|
||||||
|
// 确保输出目录存在
|
||||||
|
const outputDir = path.dirname(outputFile)
|
||||||
|
if (!fs.existsSync(outputDir)) {
|
||||||
|
fs.mkdirSync(outputDir, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入输出文件
|
||||||
|
fs.writeFileSync(outputFile, outputCode)
|
||||||
|
|
||||||
|
console.log(`成功生成 PB 导入导出代码到 ${outputFile}`)
|
||||||
|
console.log(`共生成 ${jsFiles.length} 个导入语句和 ${exportList.length} 个导出变量`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('生成 PB 导入导出代码时出错:', error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取 $root.X 形式的导出
|
||||||
|
*/
|
||||||
|
function extractRootExports(code) {
|
||||||
|
const exports = []
|
||||||
|
const rootExportRegex = /\$root\.([A-Za-z][A-Za-z0-9_]*)\s*=/g
|
||||||
|
|
||||||
|
let match
|
||||||
|
while ((match = rootExportRegex.exec(code)) !== null) {
|
||||||
|
exports.push(match[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return exports
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取 enum 定义
|
||||||
|
*/
|
||||||
|
function extractEnumExports(code) {
|
||||||
|
const exports = []
|
||||||
|
const enumRegex = /@enum\s*{.*?}\s*\n\s*\*\s*@exports\s+([A-Za-z][A-Za-z0-9_]*)/g
|
||||||
|
|
||||||
|
let match
|
||||||
|
while ((match = enumRegex.exec(code)) !== null) {
|
||||||
|
exports.push(match[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return exports
|
||||||
|
}
|
||||||
|
|
||||||
|
// 示例用法
|
||||||
|
generatePbImportsAndExports('../assets/scripts/pb', '../assets/scripts/network/pbExport.ts')
|
Loading…
x
Reference in New Issue
Block a user