Commit 00261951 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/rust/buffer' into 'main'

Feat/rust/buffer

See merge request mycard/Neos!135
parents dc12d558 3b0de3ec
Pipeline #20716 passed with stages
in 14 minutes and 13 seconds
use std::convert::TryInto;
use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
pub struct MsgUpdateHp {
pub player: Option<u8>,
pub type_: Option<u8>,
pub value: Option<i32>,
}
#[repr(u8)]
enum ActionType {
_Unknown = 0,
Damage = 1,
_Recover = 2,
}
#[wasm_bindgen]
pub fn ocgDamageAdapter(data: js_sys::Uint8Array) -> MsgUpdateHp {
let data = data.to_vec();
let player = data[0];
let value = data[1..5].try_into().map(i32::from_le_bytes).ok();
MsgUpdateHp {
player: Some(player),
type_: Some(ActionType::Damage as u8),
value,
}
}
//! 一些`ocg raw buffer`到`neos-protobuf message`的转换逻辑
//!
//! TODO: neos与ygopro交互设计介绍
mod damage;
pub use damage::*;
// TODO
//! Raw Buffer 解析工具
//!
//! 在Javascript/Typescript中数字类型只有`numbuer`,
//! 要做二进制数组的解析需要用[`DataView`],比较复杂,且性能不佳。
//! 因此这里用WASM实现两个基础的二进制数据解析模块[`BufferReader`]和[`BufferWriter`]。
use wasm_bindgen::prelude::wasm_bindgen;
const OFFSET_UINT8: usize = 1;
const OFFSET_INT8: usize = 1;
const OFFSET_UINT16: usize = 2;
const OFFSET_UINT32: usize = 4;
const OFFSET_INT32: usize = 4;
#[wasm_bindgen]
pub struct BufferReader {
array: Vec<u8>,
offset: usize,
}
#[wasm_bindgen]
impl BufferReader {
#[wasm_bindgen(constructor)]
pub fn new(array: js_sys::Uint8Array) -> Self {
Self {
array: array.to_vec(),
offset: 0,
}
}
pub fn readUint8(&mut self) -> u8 {
let ret = self.array[self.offset];
self.offset += OFFSET_UINT8;
ret
}
pub fn readInt8(&mut self) -> i8 {
let ret = self.array[self.offset] as i8;
self.offset += OFFSET_INT8;
ret
}
pub fn readUint16(&mut self) -> u16 {
let ret = self.array[self.offset..self.offset + OFFSET_UINT16]
.try_into()
.map(u16::from_le_bytes)
.unwrap();
self.offset += OFFSET_UINT16;
ret
}
pub fn readUint32(&mut self) -> u32 {
let ret = self.array[self.offset..self.offset + OFFSET_UINT32]
.try_into()
.map(u32::from_le_bytes)
.unwrap();
self.offset += OFFSET_UINT32;
ret
}
pub fn readInt32(&mut self) -> i32 {
let ret = self.array[self.offset..self.offset + OFFSET_INT32]
.try_into()
.map(i32::from_le_bytes)
.unwrap();
self.offset += OFFSET_INT32;
ret
}
}
#![allow(non_snake_case)]
mod adapters;
mod buffer;
mod utils;
use std::convert::TryInto;
use wasm_bindgen::prelude::wasm_bindgen;
pub use adapters::*;
pub use buffer::BufferReader;
pub use utils::set_panic_hook;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
......@@ -13,31 +13,3 @@ pub use utils::set_panic_hook;
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
pub struct MsgUpdateHp {
pub player: Option<u8>,
pub type_: Option<u8>,
pub value: Option<i32>,
}
#[repr(u8)]
enum ActionType {
_Unknown = 0,
Damage = 1,
_Recover = 2,
}
#[wasm_bindgen]
pub fn ocgDamageAdapter(data: js_sys::Uint8Array) -> MsgUpdateHp {
let data = data.to_vec();
let player = data[0];
let value = data[1..5].try_into().map(i32::from_le_bytes).ok();
MsgUpdateHp {
player: Some(player),
type_: Some(ActionType::Damage as u8),
value,
}
}
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
const LITTLE_ENDIAN = true;
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* MSG Draw
......@@ -11,7 +10,7 @@ const LITTLE_ENDIAN = true;
* @usage - 玩家抽卡内容
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN);
const reader = new BufferReader(data);
const player = reader.readUint8();
const count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
const LITTLE_ENDIAN = true;
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* Msg Hint
......@@ -14,7 +13,7 @@ const LITTLE_ENDIAN = true;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN);
const reader = new BufferReader(data);
const hintCommand = reader.readUint8();
const hintPlayer = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
const LITTLE_ENDIAN = true;
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* Msg New Phase
......@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN);
const reader = new BufferReader(data);
const phase = reader.readUint16();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
const LITTLE_ENDIAN = true;
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* MSG New Turn
......@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN);
const reader = new BufferReader(data);
const player = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* Msg Recover
......@@ -8,7 +9,7 @@ import { BufferReader } from "../../bufferIO";
* @param value - 回复的Hp数值
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, true);
const reader = new BufferReader(data);
const player = reader.readUint8();
const value = reader.readInt32();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption;
/*
......@@ -11,7 +12,7 @@ import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, true);
const reader = new BufferReader(data);
const player = reader.readUint8();
const count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace;
/*
......@@ -11,7 +12,7 @@ import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, true);
const reader = new BufferReader(data);
const player = reader.readUint8();
let count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition;
/*
......@@ -11,7 +12,7 @@ import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition;
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, true);
const reader = new BufferReader(data);
const player = reader.readUint8();
const code = reader.readUint32();
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
import MsgWin = ygopro.StocGameMessage.MsgWin;
/*
......@@ -9,7 +10,7 @@ import MsgWin = ygopro.StocGameMessage.MsgWin;
* @param winType - 结果类型
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, true);
const reader = new BufferReader(data);
const player = reader.readUint8();
const winType = reader.readUint8();
......
import { ygopro } from "../../idl/ocgcore";
import { YgoProPacket, StocAdapter } from "../packet";
import { BufferReader } from "../bufferIO";
// @ts-ignore
import { BufferReader } from "rust-src";
/*
* STOC TimeLimit
......@@ -16,7 +17,7 @@ export default class TimeLimit implements StocAdapter {
}
upcast(): ygopro.YgoStocMsg {
const reader = new BufferReader(this.packet.exData, true);
const reader = new BufferReader(this.packet.exData);
const player = reader.readInt8();
const leftTime = reader.readUint16();
......
......@@ -20,7 +20,6 @@ import Phase from "./phase";
import CheckCardModalV2 from "./checkCardModalV2";
import ExtraDeck from "./extraDeck";
import NeosLayout from "./layout";
import { initStrings } from "../../api/strings";
import NeosConfig from "../../../neos.config.json";
import DuelTimeLine from "./timeLine";
import { Row } from "antd";
......@@ -34,21 +33,6 @@ import {
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const NeosDuel = () => {
// 应该用更优雅的方式处理`useEffect`执行两次的问题
const initialRender = useRef(true);
useEffect(() => {
const init = async () => {
await initStrings();
};
if (initialRender.current) {
initialRender.current = false;
return;
}
init();
}, []);
const meInfo = useAppSelector(selectMeInitInfo);
const opInfo = useAppSelector(selectOpInitInfo);
......
......@@ -46,6 +46,7 @@ import NeosConfig from "../../neos.config.json";
import YGOProDeck from "ygopro-deck-encode";
//@ts-ignore
import rustInit from "rust-src";
import { initStrings } from "../api/strings";
const READY_STATE = "ready";
......@@ -78,9 +79,11 @@ const WaitRoom = () => {
initInfo: { dbUrl: NeosConfig.cardsDbUrl },
});
// 初始化文案
await initStrings();
// 初始化wasm
const wasm = await rustInit();
console.log(wasm);
await rustInit();
};
init();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment