211 lines
5.5 KiB
TypeScript
Raw Normal View History

2022-12-04 22:10:30 +08:00
import { ApiMsgEnum, InputTypeEnum } from "./Enum";
2022-12-05 21:46:02 +08:00
import { strdecode, strencode } from "./Utils";
const encodeActorMove = (proto: ApiMsgEnum, data: any, view: DataView, index: number) => {
view.setUint8(index++, data.type)
view.setUint8(index++, data.id)
view.setFloat32(index, data.direction.x)
index += 4
view.setFloat32(index, data.direction.y)
index += 4
view.setFloat32(index, data.dt)
index += 4
}
const encodeWeaponShoot = (proto: ApiMsgEnum, data: any, view: DataView, index: number) => {
view.setUint8(index++, data.type)
view.setUint8(index++, data.owner)
view.setFloat32(index, data.position.x)
index += 4
view.setFloat32(index, data.position.y)
index += 4
view.setFloat32(index, data.direction.x)
index += 4
view.setFloat32(index, data.direction.y)
index += 4
}
export const encdoeTimePast = (proto: ApiMsgEnum, data: any, view: DataView, index: number) => {
view.setUint8(index++, data.type)
view.setFloat32(index, data.dt)
index += 4
}
2022-12-04 22:10:30 +08:00
export const binaryEncode = (proto: ApiMsgEnum, data: any): DataView => {
if (proto === ApiMsgEnum.MsgClientSync) {
2022-12-05 21:46:02 +08:00
if (data.type === InputTypeEnum.ActorMove) {
let index = 0
const ab = new ArrayBuffer(3 + 12)
const view = new DataView(ab)
view.setUint8(index++, proto)
encodeActorMove(proto, data, view, index)
return view
} else if (data.type === InputTypeEnum.WeaponShoot) {
let index = 0
const ab = new ArrayBuffer(3 + 16)
const view = new DataView(ab)
view.setUint8(index++, proto)
encodeWeaponShoot(proto, data, view, index)
return view
} else {
let index = 0
const ab = new ArrayBuffer(2 + 4)
const view = new DataView(ab)
view.setUint8(index++, proto)
encdoeTimePast(proto, data, view, index)
return view
}
} else if (proto === ApiMsgEnum.MsgServerSync) {
let total = 0
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.type === InputTypeEnum.ActorMove) {
total += 14
} else if (item.type === InputTypeEnum.WeaponShoot) {
total += 18
} else {
total += 5
2022-12-04 22:10:30 +08:00
}
2022-12-05 21:46:02 +08:00
}
const ab = new ArrayBuffer(1 + 1 + total)
const view = new DataView(ab)
let index = 0
view.setUint8(index++, proto)
view.setUint8(index++, data.length)
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.type === InputTypeEnum.ActorMove) {
encodeActorMove(proto, item, view, index)
index += 14
} else if (item.type === InputTypeEnum.WeaponShoot) {
encodeWeaponShoot(proto, item, view, index)
index += 18
} else {
encdoeTimePast(proto, item, view, index)
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)
view.setUint8(index++, proto)
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++)
const directionX = view.getFloat32(index)
index += 4
const directionY = view.getFloat32(index)
index += 4
const dt = view.getFloat32(index)
index += 4
const msg = {
name: ApiMsgEnum.MsgClientSync,
data: {
type: InputTypeEnum.ActorMove,
id,
direction: {
x: directionX,
y: directionY,
},
dt
}
}
return msg
}
const decodeWeaponShoot = (view: DataView, index: number) => {
const owner = view.getUint8(index++)
const positionX = view.getFloat32(index)
index += 4
const positionY = view.getFloat32(index)
index += 4
const directionX = view.getFloat32(index)
index += 4
const directionY = view.getFloat32(index)
index += 4
const msg = {
name: ApiMsgEnum.MsgClientSync,
data: {
type: InputTypeEnum.WeaponShoot,
owner,
position: {
x: positionX,
y: positionY,
},
direction: {
x: directionX,
y: directionY,
},
}
}
return msg
}
const decodeTimePast = (view: DataView, index: number) => {
const dt = view.getFloat32(index)
index += 4
const msg = {
name: ApiMsgEnum.MsgClientSync,
data: {
type: InputTypeEnum.TimePast,
dt,
}
}
return msg
}
export const binaryDecode = (buffer: ArrayBuffer) => {
let index = 0
const view = new DataView(buffer)
const proto = view.getUint8(index++)
if (proto === ApiMsgEnum.MsgClientSync) {
const inputType = view.getUint8(index++)
if (inputType === InputTypeEnum.ActorMove) {
return decodeActorMove(view, index)
} else if (inputType === InputTypeEnum.WeaponShoot) {
return decodeWeaponShoot(view, index)
} else {
return decodeTimePast(view, index)
}
} else if (proto === ApiMsgEnum.MsgServerSync) {
const len = view.getUint8(index++)
const res = []
for (let i = 0; i < len; i++) {
const inputType = view.getUint8(index++)
if (inputType === InputTypeEnum.ActorMove) {
res.push(decodeActorMove(view, index).data)
index += 13
} else if (inputType === InputTypeEnum.WeaponShoot) {
res.push(decodeWeaponShoot(view, index).data)
index += 17
} else {
res.push(decodeTimePast(view, index).data)
index += 4
}
}
return {
name: ApiMsgEnum.MsgServerSync,
data: res
}
} else {
return {
name: proto,
data: JSON.parse(strdecode(new Uint8Array(buffer.slice(1))))
}
}
2022-12-04 22:10:30 +08:00
}