237 lines
6.2 KiB
TypeScript
Raw Normal View History

2022-12-04 22:10:30 +08:00
import { ApiMsgEnum, InputTypeEnum } from "./Enum";
2022-12-05 22:02:24 +08:00
import { strdecode, strencode, toFixed } from "./Utils";
2022-12-05 21:46:02 +08:00
2022-12-08 21:14:02 +08:00
const encodeActorMove = (input: any, view: DataView, index: number) => {
view.setUint8(index++, input.type)
view.setUint8(index++, input.id)
view.setFloat32(index, input.direction.x)
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
view.setFloat32(index, input.direction.y)
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
view.setFloat32(index, input.dt)
2022-12-05 21:46:02 +08:00
index += 4
}
2022-12-08 21:14:02 +08:00
const encodeWeaponShoot = (input: any, view: DataView, index: number) => {
view.setUint8(index++, input.type)
view.setUint8(index++, input.owner)
view.setFloat32(index, input.position.x)
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
view.setFloat32(index, input.position.y)
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
view.setFloat32(index, input.direction.x)
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
view.setFloat32(index, input.direction.y)
2022-12-05 21:46:02 +08:00
index += 4
}
2022-12-08 21:14:02 +08:00
export const encodeTimePast = (input: any, view: DataView, index: number) => {
view.setUint8(index++, input.type)
view.setFloat32(index, input.dt)
2022-12-05 21:46:02 +08:00
index += 4
}
2022-12-04 22:10:30 +08:00
2022-12-08 21:14:02 +08:00
export const binaryEncode = (name: ApiMsgEnum, data: any): DataView => {
if (name === ApiMsgEnum.MsgClientSync) {
//name 1字节 + frameId 4字节 + 数据长度 n 字节
const { frameId, input } = data
if (input.type === InputTypeEnum.ActorMove) {
2022-12-05 21:46:02 +08:00
let index = 0
2022-12-08 21:14:02 +08:00
const ab = new ArrayBuffer(1 + 4 + 14)
2022-12-05 21:46:02 +08:00
const view = new DataView(ab)
2022-12-08 21:14:02 +08:00
view.setUint8(index++, name)
view.setUint32(index, frameId)
index += 4
encodeActorMove(input, view, index)
2022-12-05 21:46:02 +08:00
return view
2022-12-08 21:14:02 +08:00
} else if (input.type === InputTypeEnum.WeaponShoot) {
2022-12-05 21:46:02 +08:00
let index = 0
2022-12-08 21:14:02 +08:00
const ab = new ArrayBuffer(1 + 4 + 18)
2022-12-05 21:46:02 +08:00
const view = new DataView(ab)
2022-12-08 21:14:02 +08:00
view.setUint8(index++, name)
view.setUint32(index, frameId)
index += 4
encodeWeaponShoot(input, view, index)
2022-12-05 21:46:02 +08:00
return view
} else {
let index = 0
2022-12-08 21:14:02 +08:00
const ab = new ArrayBuffer(1 + 4 + 5)
2022-12-05 21:46:02 +08:00
const view = new DataView(ab)
2022-12-08 21:14:02 +08:00
view.setUint8(index++, name)
view.setUint32(index, frameId)
index += 4
encodeTimePast(input, view, index)
2022-12-05 21:46:02 +08:00
return view
}
2022-12-08 21:14:02 +08:00
} else if (name === ApiMsgEnum.MsgServerSync) {
const { lastFrameId, inputs } = data
2022-12-05 21:46:02 +08:00
let total = 0
2022-12-08 21:14:02 +08:00
for (const input of inputs) {
if (input.type === InputTypeEnum.ActorMove) {
2022-12-05 21:46:02 +08:00
total += 14
2022-12-08 21:14:02 +08:00
} else if (input.type === InputTypeEnum.WeaponShoot) {
2022-12-05 21:46:02 +08:00
total += 18
} else {
total += 5
2022-12-04 22:10:30 +08:00
}
2022-12-05 21:46:02 +08:00
}
2022-12-08 21:14:02 +08:00
//name 1字节 + lastFrameId 4字节 + 数组长度 1字节 + 数据长度 n 字节
const ab = new ArrayBuffer(1 + 4 + 1 + total)
2022-12-05 21:46:02 +08:00
const view = new DataView(ab)
let index = 0
2022-12-08 21:14:02 +08:00
view.setUint8(index++, name)
view.setUint32(index, lastFrameId)
index += 4
view.setUint8(index++, inputs.length)
for (const input of inputs) {
if (input.type === InputTypeEnum.ActorMove) {
encodeActorMove(input, view, index)
2022-12-05 21:46:02 +08:00
index += 14
2022-12-08 21:14:02 +08:00
} else if (input.type === InputTypeEnum.WeaponShoot) {
encodeWeaponShoot(input, view, index)
2022-12-05 21:46:02 +08:00
index += 18
} else {
2022-12-08 21:14:02 +08:00
encodeTimePast(input, view, index)
2022-12-05 21:46:02 +08:00
index += 5
2022-12-04 22:10:30 +08:00
}
}
2022-12-05 21:46:02 +08:00
return view
2022-12-04 22:10:30 +08:00
} else {
let index = 0
const str = JSON.stringify(data)
const ta = strencode(str)
const ab = new ArrayBuffer(ta.length + 1)
const view = new DataView(ab)
2022-12-08 21:14:02 +08:00
view.setUint8(index++, name)
2022-12-04 22:10:30 +08:00
for (let i = 0; i < ta.length; i++) {
view.setUint8(index++, ta[i])
}
return view
}
2022-12-05 21:46:02 +08:00
}
const decodeActorMove = (view: DataView, index: number) => {
const id = view.getUint8(index++)
2022-12-05 22:02:24 +08:00
const directionX = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-05 22:02:24 +08:00
const directionY = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-05 22:02:24 +08:00
const dt = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
const input = {
type: InputTypeEnum.ActorMove,
id,
direction: {
x: directionX,
y: directionY,
},
dt
2022-12-05 21:46:02 +08:00
}
2022-12-08 21:14:02 +08:00
return input
2022-12-05 21:46:02 +08:00
}
const decodeWeaponShoot = (view: DataView, index: number) => {
const owner = view.getUint8(index++)
2022-12-05 22:02:24 +08:00
const positionX = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-05 22:02:24 +08:00
const positionY = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-05 22:02:24 +08:00
const directionX = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-05 22:02:24 +08:00
const directionY = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
const input = {
type: InputTypeEnum.WeaponShoot,
owner,
position: {
x: positionX,
y: positionY,
},
direction: {
x: directionX,
y: directionY,
},
2022-12-05 21:46:02 +08:00
}
2022-12-08 21:14:02 +08:00
return input
2022-12-05 21:46:02 +08:00
}
const decodeTimePast = (view: DataView, index: number) => {
2022-12-05 22:02:24 +08:00
const dt = toFixed(view.getFloat32(index))
2022-12-05 21:46:02 +08:00
index += 4
2022-12-08 21:14:02 +08:00
const input = {
type: InputTypeEnum.TimePast,
dt,
2022-12-05 21:46:02 +08:00
}
2022-12-08 21:14:02 +08:00
return input
2022-12-05 21:46:02 +08:00
}
export const binaryDecode = (buffer: ArrayBuffer) => {
let index = 0
const view = new DataView(buffer)
2022-12-08 21:14:02 +08:00
const name = view.getUint8(index++)
2022-12-05 21:46:02 +08:00
2022-12-08 21:14:02 +08:00
if (name === ApiMsgEnum.MsgClientSync) {
const frameId = view.getUint32(index)
index += 4
2022-12-05 21:46:02 +08:00
const inputType = view.getUint8(index++)
if (inputType === InputTypeEnum.ActorMove) {
2022-12-08 21:14:02 +08:00
const input = decodeActorMove(view, index)
return {
name,
data: {
frameId,
input
}
}
2022-12-05 21:46:02 +08:00
} else if (inputType === InputTypeEnum.WeaponShoot) {
2022-12-08 21:14:02 +08:00
const input = decodeWeaponShoot(view, index)
return {
name,
data: {
frameId,
input
}
}
2022-12-05 21:46:02 +08:00
} else {
2022-12-08 21:14:02 +08:00
const input = decodeTimePast(view, index)
return {
name,
data: {
frameId,
input
}
}
2022-12-05 21:46:02 +08:00
}
2022-12-08 21:14:02 +08:00
} else if (name === ApiMsgEnum.MsgServerSync) {
const lastFrameId = view.getUint32(index)
index += 4
2022-12-05 21:46:02 +08:00
const len = view.getUint8(index++)
2022-12-08 21:14:02 +08:00
const inputs = []
2022-12-05 21:46:02 +08:00
for (let i = 0; i < len; i++) {
const inputType = view.getUint8(index++)
if (inputType === InputTypeEnum.ActorMove) {
2022-12-08 21:14:02 +08:00
inputs.push(decodeActorMove(view, index))
2022-12-05 21:46:02 +08:00
index += 13
} else if (inputType === InputTypeEnum.WeaponShoot) {
2022-12-08 21:14:02 +08:00
inputs.push(decodeWeaponShoot(view, index))
2022-12-05 21:46:02 +08:00
index += 17
} else {
2022-12-08 21:14:02 +08:00
inputs.push(decodeTimePast(view, index))
2022-12-05 21:46:02 +08:00
index += 4
}
}
return {
name: ApiMsgEnum.MsgServerSync,
2022-12-08 21:14:02 +08:00
data: {
lastFrameId,
inputs
}
2022-12-05 21:46:02 +08:00
}
} else {
return {
2022-12-08 21:14:02 +08:00
name: name,
2022-12-05 21:46:02 +08:00
data: JSON.parse(strdecode(new Uint8Array(buffer.slice(1))))
}
}
2022-12-04 22:10:30 +08:00
}