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
|
|
|
}
|