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)] #![allow(non_snake_case)]
mod adapters;
mod buffer; mod buffer;
mod utils; mod utils;
use std::convert::TryInto; pub use adapters::*;
use wasm_bindgen::prelude::wasm_bindgen; pub use buffer::BufferReader;
pub use utils::set_panic_hook; pub use utils::set_panic_hook;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
...@@ -13,31 +13,3 @@ pub use utils::set_panic_hook; ...@@ -13,31 +13,3 @@ pub use utils::set_panic_hook;
#[cfg(feature = "wee_alloc")] #[cfg(feature = "wee_alloc")]
#[global_allocator] #[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 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 { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
const LITTLE_ENDIAN = true;
/* /*
* MSG Draw * MSG Draw
...@@ -11,7 +10,7 @@ const LITTLE_ENDIAN = true; ...@@ -11,7 +10,7 @@ const LITTLE_ENDIAN = true;
* @usage - 玩家抽卡内容 * @usage - 玩家抽卡内容
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
const count = reader.readUint8(); const count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
const LITTLE_ENDIAN = true;
/* /*
* Msg Hint * Msg Hint
...@@ -14,7 +13,7 @@ const LITTLE_ENDIAN = true; ...@@ -14,7 +13,7 @@ const LITTLE_ENDIAN = true;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN); const reader = new BufferReader(data);
const hintCommand = reader.readUint8(); const hintCommand = reader.readUint8();
const hintPlayer = reader.readUint8(); const hintPlayer = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
const LITTLE_ENDIAN = true;
/* /*
* Msg New Phase * Msg New Phase
...@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true; ...@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN); const reader = new BufferReader(data);
const phase = reader.readUint16(); const phase = reader.readUint16();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
const LITTLE_ENDIAN = true;
/* /*
* MSG New Turn * MSG New Turn
...@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true; ...@@ -12,7 +11,7 @@ const LITTLE_ENDIAN = true;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
/* /*
* Msg Recover * Msg Recover
...@@ -8,7 +9,7 @@ import { BufferReader } from "../../bufferIO"; ...@@ -8,7 +9,7 @@ import { BufferReader } from "../../bufferIO";
* @param value - 回复的Hp数值 * @param value - 回复的Hp数值
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, true); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
const value = reader.readInt32(); const value = reader.readInt32();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption; import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption;
/* /*
...@@ -11,7 +12,7 @@ import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption; ...@@ -11,7 +12,7 @@ import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, true); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
const count = reader.readUint8(); const count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace; import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace;
/* /*
...@@ -11,7 +12,7 @@ import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace; ...@@ -11,7 +12,7 @@ import MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, true); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
let count = reader.readUint8(); let count = reader.readUint8();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition; import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition;
/* /*
...@@ -11,7 +12,7 @@ import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition; ...@@ -11,7 +12,7 @@ import MsgSelectPosition = ygopro.StocGameMessage.MsgSelectPosition;
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, true); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
const code = reader.readUint32(); const code = reader.readUint32();
......
import { ygopro } from "../../../idl/ocgcore"; import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
import MsgWin = ygopro.StocGameMessage.MsgWin; import MsgWin = ygopro.StocGameMessage.MsgWin;
/* /*
...@@ -9,7 +10,7 @@ import MsgWin = ygopro.StocGameMessage.MsgWin; ...@@ -9,7 +10,7 @@ import MsgWin = ygopro.StocGameMessage.MsgWin;
* @param winType - 结果类型 * @param winType - 结果类型
* */ * */
export default (data: Uint8Array) => { export default (data: Uint8Array) => {
const reader = new BufferReader(data, true); const reader = new BufferReader(data);
const player = reader.readUint8(); const player = reader.readUint8();
const winType = reader.readUint8(); const winType = reader.readUint8();
......
import { ygopro } from "../../idl/ocgcore"; import { ygopro } from "../../idl/ocgcore";
import { YgoProPacket, StocAdapter } from "../packet"; import { YgoProPacket, StocAdapter } from "../packet";
import { BufferReader } from "../bufferIO"; // @ts-ignore
import { BufferReader } from "rust-src";
/* /*
* STOC TimeLimit * STOC TimeLimit
...@@ -16,7 +17,7 @@ export default class TimeLimit implements StocAdapter { ...@@ -16,7 +17,7 @@ export default class TimeLimit implements StocAdapter {
} }
upcast(): ygopro.YgoStocMsg { upcast(): ygopro.YgoStocMsg {
const reader = new BufferReader(this.packet.exData, true); const reader = new BufferReader(this.packet.exData);
const player = reader.readInt8(); const player = reader.readInt8();
const leftTime = reader.readUint16(); const leftTime = reader.readUint16();
......
...@@ -20,7 +20,6 @@ import Phase from "./phase"; ...@@ -20,7 +20,6 @@ import Phase from "./phase";
import CheckCardModalV2 from "./checkCardModalV2"; import CheckCardModalV2 from "./checkCardModalV2";
import ExtraDeck from "./extraDeck"; import ExtraDeck from "./extraDeck";
import NeosLayout from "./layout"; import NeosLayout from "./layout";
import { initStrings } from "../../api/strings";
import NeosConfig from "../../../neos.config.json"; import NeosConfig from "../../../neos.config.json";
import DuelTimeLine from "./timeLine"; import DuelTimeLine from "./timeLine";
import { Row } from "antd"; import { Row } from "antd";
...@@ -34,21 +33,6 @@ import { ...@@ -34,21 +33,6 @@ import {
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126 // Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const NeosDuel = () => { 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 meInfo = useAppSelector(selectMeInitInfo);
const opInfo = useAppSelector(selectOpInitInfo); const opInfo = useAppSelector(selectOpInitInfo);
......
...@@ -46,6 +46,7 @@ import NeosConfig from "../../neos.config.json"; ...@@ -46,6 +46,7 @@ import NeosConfig from "../../neos.config.json";
import YGOProDeck from "ygopro-deck-encode"; import YGOProDeck from "ygopro-deck-encode";
//@ts-ignore //@ts-ignore
import rustInit from "rust-src"; import rustInit from "rust-src";
import { initStrings } from "../api/strings";
const READY_STATE = "ready"; const READY_STATE = "ready";
...@@ -78,9 +79,11 @@ const WaitRoom = () => { ...@@ -78,9 +79,11 @@ const WaitRoom = () => {
initInfo: { dbUrl: NeosConfig.cardsDbUrl }, initInfo: { dbUrl: NeosConfig.cardsDbUrl },
}); });
// 初始化文案
await initStrings();
// 初始化wasm // 初始化wasm
const wasm = await rustInit(); await rustInit();
console.log(wasm);
}; };
init(); 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