Commit f5654819 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/game' into 'main'

Feat/game

See merge request mycard/Neos!13
parents 83b0126b 9684ee92
[submodule "neos-protobuf"]
path = neos-protobuf
url = git@github.com:DarkNeos/neos-protobuf.git
url = git@git.mycard.moe:mycard/neos-protobuf.git
neos-protobuf @ e7cfaff5
Subproject commit 53a9cf4cf7cdfc55f1bfa7d86d74e61c56a5533f
Subproject commit e7cfaff59f5c1ed640e21c2257d0bd39b6a27648
......@@ -458,7 +458,7 @@ export namespace ygopro {
}
}
export class YgoStocMsg extends pb_1.Message {
#one_of_decls: number[][] = [[1, 2, 3, 4, 5, 6, 7, 8, 9]];
#one_of_decls: number[][] = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]];
constructor(
data?:
| any[]
......@@ -473,6 +473,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -484,6 +486,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -495,6 +499,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -506,6 +512,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -517,6 +525,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -528,6 +538,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -539,6 +551,8 @@ export namespace ygopro {
stoc_select_hand?: StocSelectHand;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -550,6 +564,8 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: StocHandResult;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
......@@ -561,6 +577,34 @@ export namespace ygopro {
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: StocSelectTp;
stoc_deck_count?: never;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
stoc_chat?: never;
stoc_hs_player_enter?: never;
stoc_type_change?: never;
stoc_hs_player_change?: never;
stoc_hs_watch_change?: never;
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: StocDeckCount;
stoc_duel_start?: never;
}
| {
stoc_join_game?: never;
stoc_chat?: never;
stoc_hs_player_enter?: never;
stoc_type_change?: never;
stoc_hs_player_change?: never;
stoc_hs_watch_change?: never;
stoc_select_hand?: never;
stoc_hand_result?: never;
stoc_select_tp?: never;
stoc_deck_count?: never;
stoc_duel_start?: StocDuelStart;
}
))
) {
......@@ -610,6 +654,12 @@ export namespace ygopro {
if ("stoc_select_tp" in data && data.stoc_select_tp != undefined) {
this.stoc_select_tp = data.stoc_select_tp;
}
if ("stoc_deck_count" in data && data.stoc_deck_count != undefined) {
this.stoc_deck_count = data.stoc_deck_count;
}
if ("stoc_duel_start" in data && data.stoc_duel_start != undefined) {
this.stoc_duel_start = data.stoc_duel_start;
}
}
}
get stoc_join_game() {
......@@ -725,6 +775,32 @@ export namespace ygopro {
get has_stoc_select_tp() {
return pb_1.Message.getField(this, 9) != null;
}
get stoc_deck_count() {
return pb_1.Message.getWrapperField(
this,
StocDeckCount,
10
) as StocDeckCount;
}
set stoc_deck_count(value: StocDeckCount) {
pb_1.Message.setOneofWrapperField(this, 10, this.#one_of_decls[0], value);
}
get has_stoc_deck_count() {
return pb_1.Message.getField(this, 10) != null;
}
get stoc_duel_start() {
return pb_1.Message.getWrapperField(
this,
StocDuelStart,
11
) as StocDuelStart;
}
set stoc_duel_start(value: StocDuelStart) {
pb_1.Message.setOneofWrapperField(this, 11, this.#one_of_decls[0], value);
}
get has_stoc_duel_start() {
return pb_1.Message.getField(this, 11) != null;
}
get msg() {
const cases: {
[index: number]:
......@@ -737,7 +813,9 @@ export namespace ygopro {
| "stoc_hs_watch_change"
| "stoc_select_hand"
| "stoc_hand_result"
| "stoc_select_tp";
| "stoc_select_tp"
| "stoc_deck_count"
| "stoc_duel_start";
} = {
0: "none",
1: "stoc_join_game",
......@@ -749,9 +827,11 @@ export namespace ygopro {
7: "stoc_select_hand",
8: "stoc_hand_result",
9: "stoc_select_tp",
10: "stoc_deck_count",
11: "stoc_duel_start",
};
return cases[
pb_1.Message.computeOneofCase(this, [1, 2, 3, 4, 5, 6, 7, 8, 9])
pb_1.Message.computeOneofCase(this, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
];
}
static fromObject(data: {
......@@ -770,6 +850,8 @@ export namespace ygopro {
stoc_select_hand?: ReturnType<typeof StocSelectHand.prototype.toObject>;
stoc_hand_result?: ReturnType<typeof StocHandResult.prototype.toObject>;
stoc_select_tp?: ReturnType<typeof StocSelectTp.prototype.toObject>;
stoc_deck_count?: ReturnType<typeof StocDeckCount.prototype.toObject>;
stoc_duel_start?: ReturnType<typeof StocDuelStart.prototype.toObject>;
}): YgoStocMsg {
const message = new YgoStocMsg({});
if (data.stoc_join_game != null) {
......@@ -811,6 +893,16 @@ export namespace ygopro {
if (data.stoc_select_tp != null) {
message.stoc_select_tp = StocSelectTp.fromObject(data.stoc_select_tp);
}
if (data.stoc_deck_count != null) {
message.stoc_deck_count = StocDeckCount.fromObject(
data.stoc_deck_count
);
}
if (data.stoc_duel_start != null) {
message.stoc_duel_start = StocDuelStart.fromObject(
data.stoc_duel_start
);
}
return message;
}
toObject() {
......@@ -830,6 +922,8 @@ export namespace ygopro {
stoc_select_hand?: ReturnType<typeof StocSelectHand.prototype.toObject>;
stoc_hand_result?: ReturnType<typeof StocHandResult.prototype.toObject>;
stoc_select_tp?: ReturnType<typeof StocSelectTp.prototype.toObject>;
stoc_deck_count?: ReturnType<typeof StocDeckCount.prototype.toObject>;
stoc_duel_start?: ReturnType<typeof StocDuelStart.prototype.toObject>;
} = {};
if (this.stoc_join_game != null) {
data.stoc_join_game = this.stoc_join_game.toObject();
......@@ -858,6 +952,12 @@ export namespace ygopro {
if (this.stoc_select_tp != null) {
data.stoc_select_tp = this.stoc_select_tp.toObject();
}
if (this.stoc_deck_count != null) {
data.stoc_deck_count = this.stoc_deck_count.toObject();
}
if (this.stoc_duel_start != null) {
data.stoc_duel_start = this.stoc_duel_start.toObject();
}
return data;
}
serialize(): Uint8Array;
......@@ -900,6 +1000,14 @@ export namespace ygopro {
writer.writeMessage(9, this.stoc_select_tp, () =>
this.stoc_select_tp.serialize(writer)
);
if (this.has_stoc_deck_count)
writer.writeMessage(10, this.stoc_deck_count, () =>
this.stoc_deck_count.serialize(writer)
);
if (this.has_stoc_duel_start)
writer.writeMessage(11, this.stoc_duel_start, () =>
this.stoc_duel_start.serialize(writer)
);
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): YgoStocMsg {
......@@ -974,6 +1082,20 @@ export namespace ygopro {
() => (message.stoc_select_tp = StocSelectTp.deserialize(reader))
);
break;
case 10:
reader.readMessage(
message.stoc_deck_count,
() =>
(message.stoc_deck_count = StocDeckCount.deserialize(reader))
);
break;
case 11:
reader.readMessage(
message.stoc_duel_start,
() =>
(message.stoc_duel_start = StocDuelStart.deserialize(reader))
);
break;
default:
reader.skipField();
}
......@@ -2671,4 +2793,245 @@ export namespace ygopro {
return StocSelectTp.deserialize(bytes);
}
}
export class StocDeckCount extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(
data?:
| any[]
| {
meMain?: number;
meExtra?: number;
meSide?: number;
opMain?: number;
opExtra?: number;
opSide?: number;
}
) {
super();
pb_1.Message.initialize(
this,
Array.isArray(data) ? data : [],
0,
-1,
[],
this.#one_of_decls
);
if (!Array.isArray(data) && typeof data == "object") {
if ("meMain" in data && data.meMain != undefined) {
this.meMain = data.meMain;
}
if ("meExtra" in data && data.meExtra != undefined) {
this.meExtra = data.meExtra;
}
if ("meSide" in data && data.meSide != undefined) {
this.meSide = data.meSide;
}
if ("opMain" in data && data.opMain != undefined) {
this.opMain = data.opMain;
}
if ("opExtra" in data && data.opExtra != undefined) {
this.opExtra = data.opExtra;
}
if ("opSide" in data && data.opSide != undefined) {
this.opSide = data.opSide;
}
}
}
get meMain() {
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set meMain(value: number) {
pb_1.Message.setField(this, 1, value);
}
get meExtra() {
return pb_1.Message.getFieldWithDefault(this, 2, 0) as number;
}
set meExtra(value: number) {
pb_1.Message.setField(this, 2, value);
}
get meSide() {
return pb_1.Message.getFieldWithDefault(this, 3, 0) as number;
}
set meSide(value: number) {
pb_1.Message.setField(this, 3, value);
}
get opMain() {
return pb_1.Message.getFieldWithDefault(this, 4, 0) as number;
}
set opMain(value: number) {
pb_1.Message.setField(this, 4, value);
}
get opExtra() {
return pb_1.Message.getFieldWithDefault(this, 5, 0) as number;
}
set opExtra(value: number) {
pb_1.Message.setField(this, 5, value);
}
get opSide() {
return pb_1.Message.getFieldWithDefault(this, 6, 0) as number;
}
set opSide(value: number) {
pb_1.Message.setField(this, 6, value);
}
static fromObject(data: {
meMain?: number;
meExtra?: number;
meSide?: number;
opMain?: number;
opExtra?: number;
opSide?: number;
}): StocDeckCount {
const message = new StocDeckCount({});
if (data.meMain != null) {
message.meMain = data.meMain;
}
if (data.meExtra != null) {
message.meExtra = data.meExtra;
}
if (data.meSide != null) {
message.meSide = data.meSide;
}
if (data.opMain != null) {
message.opMain = data.opMain;
}
if (data.opExtra != null) {
message.opExtra = data.opExtra;
}
if (data.opSide != null) {
message.opSide = data.opSide;
}
return message;
}
toObject() {
const data: {
meMain?: number;
meExtra?: number;
meSide?: number;
opMain?: number;
opExtra?: number;
opSide?: number;
} = {};
if (this.meMain != null) {
data.meMain = this.meMain;
}
if (this.meExtra != null) {
data.meExtra = this.meExtra;
}
if (this.meSide != null) {
data.meSide = this.meSide;
}
if (this.opMain != null) {
data.opMain = this.opMain;
}
if (this.opExtra != null) {
data.opExtra = this.opExtra;
}
if (this.opSide != null) {
data.opSide = this.opSide;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.meMain != 0) writer.writeInt32(1, this.meMain);
if (this.meExtra != 0) writer.writeInt32(2, this.meExtra);
if (this.meSide != 0) writer.writeInt32(3, this.meSide);
if (this.opMain != 0) writer.writeInt32(4, this.opMain);
if (this.opExtra != 0) writer.writeInt32(5, this.opExtra);
if (this.opSide != 0) writer.writeInt32(6, this.opSide);
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocDeckCount {
const reader =
bytes instanceof pb_1.BinaryReader
? bytes
: new pb_1.BinaryReader(bytes),
message = new StocDeckCount();
while (reader.nextField()) {
if (reader.isEndGroup()) break;
switch (reader.getFieldNumber()) {
case 1:
message.meMain = reader.readInt32();
break;
case 2:
message.meExtra = reader.readInt32();
break;
case 3:
message.meSide = reader.readInt32();
break;
case 4:
message.opMain = reader.readInt32();
break;
case 5:
message.opExtra = reader.readInt32();
break;
case 6:
message.opSide = reader.readInt32();
break;
default:
reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): StocDeckCount {
return StocDeckCount.deserialize(bytes);
}
}
export class StocDuelStart extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {}) {
super();
pb_1.Message.initialize(
this,
Array.isArray(data) ? data : [],
0,
-1,
[],
this.#one_of_decls
);
if (!Array.isArray(data) && typeof data == "object") {
}
}
static fromObject(data: {}): StocDuelStart {
const message = new StocDuelStart({});
return message;
}
toObject() {
const data: {} = {};
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocDuelStart {
const reader =
bytes instanceof pb_1.BinaryReader
? bytes
: new pb_1.BinaryReader(bytes),
message = new StocDuelStart();
while (reader.nextField()) {
if (reader.isEndGroup()) break;
switch (reader.getFieldNumber()) {
default:
reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): StocDuelStart {
return StocDuelStart.deserialize(bytes);
}
}
}
......@@ -10,6 +10,8 @@ import {
STOC_SELECT_HAND,
STOC_SELECT_TP,
STOC_HAND_RESULT,
STOC_DECK_COUNT,
STOC_DUEL_START,
} from "./protoDecl";
import StocChat from "./stoc/stocChat";
import StocJoinGame from "./stoc/stocJoinGame";
......@@ -19,6 +21,7 @@ import StocHsWatchChange from "./stoc/stocHsWatchChange";
import StocTypeChange from "./stoc/stocTypeChange";
import StocSelectHand from "./stoc/stocSelectHand";
import StocSelectTp from "./stoc/stocSelectTp";
import StocDeckCount from "./stoc/stocDeckCount";
/*
* 将[`ygoProPacket`]对象转换成[`ygopro.YgoStocMsg`]对象
......@@ -74,6 +77,16 @@ export function adaptStoc(packet: ygoProPacket): ygopro.YgoStocMsg {
break;
}
case STOC_DECK_COUNT: {
pb = new StocDeckCount(packet).upcast();
break;
}
case STOC_DUEL_START: {
// TODO
break;
}
default: {
break;
}
......
......@@ -19,3 +19,5 @@ export const STOC_TYPE_CHANGE = 19;
export const STOC_SELECT_HAND = 3;
export const STOC_SELECT_TP = 4;
export const STOC_HAND_RESULT = 5;
export const STOC_DECK_COUNT = 9;
export const STOC_DUEL_START = 21;
import { ygopro } from "../../idl/ocgcore";
import { ygoProPacket, StocAdapter } from "../packet";
const LITTLE_ENDIAN = true;
const INT16_BYTE_OFFSET = 2;
/*
* STOC DeckCount
*
* @param see ocgcore.proto
*
* @usage - 展示双方卡组信息
* */
export default class deckCountAdapter implements StocAdapter {
packet: ygoProPacket;
constructor(packet: ygoProPacket) {
this.packet = packet;
}
upcast(): ygopro.YgoStocMsg {
const pb = new ygopro.StocDeckCount({});
const dataView = new DataView(this.packet.exData.buffer);
pb.meMain = dataView.getInt16(0 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
pb.meExtra = dataView.getInt16(1 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
pb.meSide = dataView.getInt16(2 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
pb.opMain = dataView.getInt16(3 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
pb.opExtra = dataView.getInt16(4 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
pb.opSide = dataView.getInt16(5 * INT16_BYTE_OFFSET, LITTLE_ENDIAN);
return new ygopro.YgoStocMsg({
stoc_deck_count: pb,
});
}
}
......@@ -14,7 +14,7 @@ export default class joinGameAdapter implements StocAdapter {
}
upcast(): ygopro.YgoStocMsg {
// todo
// TODO
return new ygopro.YgoStocMsg({
stoc_join_game: new ygopro.StocJoinGame({}),
});
......
......@@ -9,6 +9,13 @@ export interface Player {
name?: string;
state?: string;
isHost?: boolean;
deckInfo?: deckInfo;
}
export interface deckInfo {
mainCnt: number;
extraCnt: number;
sideCnt: number;
}
export interface playerState {
......@@ -47,6 +54,12 @@ const playerSlice = createSlice({
player1Leave: (state) => {
state.player1 = {};
},
player0DeckInfo: (state, action: PayloadAction<deckInfo>) => {
state.player0.deckInfo = action.payload;
},
player1DeckInfo: (state, action: PayloadAction<deckInfo>) => {
state.player1.deckInfo = action.payload;
},
hostChange: (state, action: PayloadAction<number>) => {
const i = action.payload;
......@@ -77,6 +90,8 @@ export const {
player1Update,
player0Leave,
player1Leave,
player0DeckInfo,
player1DeckInfo,
hostChange,
observerIncrement,
observerChange,
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { store } from "../../store";
import { player0DeckInfo, player1DeckInfo } from "../../reducers/playerSlice";
// FIXME: player0 不一定是当前玩家
export default function handleDeckCount(pb: ygopro.YgoStocMsg) {
const dispath = store.dispatch;
const deckCount = pb.stoc_deck_count;
dispath(
player0DeckInfo({
mainCnt: deckCount.meMain,
extraCnt: deckCount.meExtra,
sideCnt: deckCount.meSide,
})
);
dispath(
player1DeckInfo({
mainCnt: deckCount.opMain,
extraCnt: deckCount.opExtra,
sideCnt: deckCount.opSide,
})
);
}
......@@ -12,6 +12,7 @@ import { ygoProPacket } from "../api/ocgcore/ocgAdapter/packet";
import { adaptStoc } from "../api/ocgcore/ocgAdapter/adapter";
import handleSelectHand from "./mora/selectHand";
import handleSelectTp from "./mora/selectTp";
import handleDeckCount from "./mora/deckCount";
/*
* 先将从长连接中读取到的二进制数据通过Adapter转成protobuf结构体,
......@@ -69,7 +70,20 @@ export default function handleSocketMessage(e: MessageEvent) {
break;
}
case "stoc_deck_count": {
handleDeckCount(pb);
break;
}
case "stoc_duel_start": {
// TODO
console.log("TODO: handle STOC DuleStart.");
break;
}
default: {
console.log(packet);
break;
}
}
......
......@@ -13,13 +13,16 @@ import {
selectTpSelectAble,
unSelectTpAble,
} from "../reducers/moraSlice";
import { selectPlayer0, selectPlayer1 } from "../reducers/playerSlice";
import { store } from "../store";
// TODO: 应该展示对手卡组信息和聊天信息
// TODO: 应该展示聊天信息
export default function Mora() {
const dispatch = store.dispatch;
const selectHandAble = useAppSelector(selectHandSelectAble);
const selectTpAble = useAppSelector(selectTpSelectAble);
const player0 = useAppSelector(selectPlayer0);
const player1 = useAppSelector(selectPlayer1);
const handleSelectScissors = () => {
sendHandResult("scissors");
......@@ -63,6 +66,16 @@ export default function Mora() {
second
</button>
</div>
<div className="item">
<p>
Me: main={player0.deckInfo?.mainCnt}, extra=
{player0.deckInfo?.extraCnt}, side={player0.deckInfo?.sideCnt}
</p>
<p>
Me: main={player1.deckInfo?.mainCnt}, extra=
{player1.deckInfo?.extraCnt}, side={player1.deckInfo?.sideCnt}
</p>
</div>
</div>
);
}
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