Commit d6111209 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/callstack' into 'main'

Feat/callstack

See merge request mycard/Neos!146
parents e9d1b91f 2ba135b6
Pipeline #20792 passed with stages
in 20 minutes and 27 seconds
neos-protobuf @ 91892bf3
Subproject commit 3973685c657030b845ef385e8a0610971c8c60b9
Subproject commit 91892bf33e2359f6617c82b0f5f3617ed36f3540
{
"version": 4948,
"servers": [
{
"ip": "koishi-r.momobako.com",
"port": "7211"
}
],
"assetsPath": "/neos-assets",
"cardImgUrl": "https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"ui": {
"ground": {
"width": 9.9,
"height": 8
},
"card": {
"transform": {
"x": 0.8,
"y": 1,
"z": 0.05
},
"rotation": {
"x": 1.55,
"y": 0,
"z": 0
},
"reverseRotation": {
"x": 1.55,
"y": 3.1,
"z": 0
},
"defenceRotation": {
"x": 1.55,
"y": 1.55,
"z": 0
},
"handRotation": {
"x": 1,
"y": 0,
"z": 0
},
"handHoverScaling": {
"x": 1.2,
"y": 1.2,
"z": 1
"version":4948,
"servers":[
{
"ip":"koishi-r.momobako.com",
"port":"7211"
}
],
"assetsPath":"/neos-assets",
"cardImgUrl":"https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"ui":{
"ground":{
"width":9.9,
"height":8
},
"floating": 0.02
},
"layout": {
"header": {
"height": 80
"card":{
"transform":{
"x":0.8,
"y":1,
"z":0.05
},
"rotation":{
"x":1.55,
"y":0,
"z":0
},
"reverseRotation":{
"x":1.55,
"y":3.1,
"z":0
},
"defenceRotation":{
"x":1.55,
"y":1.55,
"z":0
},
"handRotation":{
"x":1,
"y":0,
"z":0
},
"handHoverScaling":{
"x":1.2,
"y":1.2,
"z":1
},
"floating":0.02
},
"content": {
"height": 800
"layout":{
"header":{
"height":80
},
"content":{
"height":800
},
"sider":{
"width":300
},
"footer":{
"height":80
}
},
"sider": {
"width": 300
"status":{
"avatarSize":40,
"meAvatarColor":"#0e63e1",
"opAvatarColor":"#e10e68"
},
"footer": {
"height": 80
"hint":{
"waitingDuration":1.5
}
},
"status": {
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
},
"hint": {
"waitingDuration": 1.5
}
}
},
"unimplementedWhiteList":[
1,
6,
7,
30,
31,
32,
34,
54,
55,
56,
60,
61,
62,
63,
64,
65,
70,
71,
72,
73,
74,
75,
76,
80,
81,
83,
93,
95,
96,
97,
101,
102,
110,
111,
112,
113,
114,
120,
121,
122,
123,
130,
131,
132,
133,
160,
161,
163,
164,
165,
170,
180
]
}
{
"version": 4948,
"servers": [
{
"ip": "koishi-r.momobako.com",
"port": "7211"
}
],
"assetsPath": "https://cdn02.moecube.com:444/neos/neos-assets",
"cardImgUrl": "https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"ui": {
"ground": {
"width": 9.9,
"height": 8
},
"card": {
"transform": {
"x": 0.8,
"y": 1,
"z": 0.05
},
"rotation": {
"x": 1.55,
"y": 0,
"z": 0
},
"reverseRotation": {
"x": 1.55,
"y": 3.1,
"z": 0
},
"defenceRotation": {
"x": 1.55,
"y": 1.55,
"z": 0
},
"handRotation": {
"x": 1,
"y": 0,
"z": 0
},
"handHoverScaling": {
"x": 1.2,
"y": 1.2,
"z": 1
"version":4948,
"servers":[
{
"ip":"koishi-r.momobako.com",
"port":"7211"
}
],
"assetsPath":"/neos-assets",
"cardImgUrl":"https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"ui":{
"ground":{
"width":9.9,
"height":8
},
"floating": 0.02
},
"layout": {
"header": {
"height": 80
"card":{
"transform":{
"x":0.8,
"y":1,
"z":0.05
},
"rotation":{
"x":1.55,
"y":0,
"z":0
},
"reverseRotation":{
"x":1.55,
"y":3.1,
"z":0
},
"defenceRotation":{
"x":1.55,
"y":1.55,
"z":0
},
"handRotation":{
"x":1,
"y":0,
"z":0
},
"handHoverScaling":{
"x":1.2,
"y":1.2,
"z":1
},
"floating":0.02
},
"content": {
"height": 800
"layout":{
"header":{
"height":80
},
"content":{
"height":800
},
"sider":{
"width":300
},
"footer":{
"height":80
}
},
"sider": {
"width": 300
"status":{
"avatarSize":40,
"meAvatarColor":"#0e63e1",
"opAvatarColor":"#e10e68"
},
"footer": {
"height": 80
"hint":{
"waitingDuration":1.5
}
},
"status": {
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
},
"hint": {
"waitingDuration": 1.5
}
}
},
"unimplementedWhiteList":[
1,
6,
7,
30,
31,
32,
34,
54,
55,
56,
60,
61,
62,
63,
64,
65,
70,
71,
72,
73,
74,
75,
76,
80,
81,
83,
93,
95,
96,
97,
101,
102,
110,
111,
112,
113,
114,
120,
121,
122,
123,
130,
131,
132,
133,
160,
161,
163,
164,
165,
170,
180
]
}
......@@ -5446,7 +5446,7 @@ export namespace ygopro {
#one_of_decls: number[][] = [
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21,
21, 22,
],
];
constructor(
......@@ -5475,6 +5475,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5498,6 +5499,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5521,6 +5523,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5544,6 +5547,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5567,6 +5571,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5590,6 +5595,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5613,6 +5619,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5636,6 +5643,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5659,6 +5667,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5682,6 +5691,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5705,6 +5715,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5728,6 +5739,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5751,6 +5763,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5774,6 +5787,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5797,6 +5811,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5820,6 +5835,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5843,6 +5859,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5866,6 +5883,7 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5889,6 +5907,7 @@ export namespace ygopro {
update_hp?: StocGameMessage.MsgUpdateHp;
win?: never;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5912,6 +5931,7 @@ export namespace ygopro {
update_hp?: never;
win?: StocGameMessage.MsgWin;
wait?: never;
unimplemented?: never;
}
| {
start?: never;
......@@ -5935,6 +5955,31 @@ export namespace ygopro {
update_hp?: never;
win?: never;
wait?: StocGameMessage.MsgWait;
unimplemented?: never;
}
| {
start?: never;
draw?: never;
new_turn?: never;
new_phase?: never;
hint?: never;
select_idle_cmd?: never;
select_place?: never;
move?: never;
select_card?: never;
select_chain?: never;
select_effect_yn?: never;
select_position?: never;
select_option?: never;
shuffle_hand?: never;
select_battle_cmd?: never;
pos_change?: never;
select_unselect_card?: never;
select_yes_no?: never;
update_hp?: never;
win?: never;
wait?: never;
unimplemented?: StocGameMessage.MsgUnimplemented;
}
))
) {
......@@ -6017,6 +6062,9 @@ export namespace ygopro {
if ("wait" in data && data.wait != undefined) {
this.wait = data.wait;
}
if ("unimplemented" in data && data.unimplemented != undefined) {
this.unimplemented = data.unimplemented;
}
}
}
get start() {
......@@ -6292,6 +6340,19 @@ export namespace ygopro {
get has_wait() {
return pb_1.Message.getField(this, 21) != null;
}
get unimplemented() {
return pb_1.Message.getWrapperField(
this,
StocGameMessage.MsgUnimplemented,
22
) as StocGameMessage.MsgUnimplemented;
}
set unimplemented(value: StocGameMessage.MsgUnimplemented) {
pb_1.Message.setOneofWrapperField(this, 22, this.#one_of_decls[0], value);
}
get has_unimplemented() {
return pb_1.Message.getField(this, 22) != null;
}
get gameMsg() {
const cases: {
[index: number]:
......@@ -6316,7 +6377,8 @@ export namespace ygopro {
| "select_yes_no"
| "update_hp"
| "win"
| "wait";
| "wait"
| "unimplemented";
} = {
0: "none",
1: "start",
......@@ -6340,13 +6402,14 @@ export namespace ygopro {
19: "update_hp",
20: "win",
21: "wait",
22: "unimplemented",
};
return cases[
pb_1.Message.computeOneofCase(
this,
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21,
20, 21, 22,
]
)
];
......@@ -6403,6 +6466,9 @@ export namespace ygopro {
>;
win?: ReturnType<typeof StocGameMessage.MsgWin.prototype.toObject>;
wait?: ReturnType<typeof StocGameMessage.MsgWait.prototype.toObject>;
unimplemented?: ReturnType<
typeof StocGameMessage.MsgUnimplemented.prototype.toObject
>;
}): StocGameMessage {
const message = new StocGameMessage({});
if (data.start != null) {
......@@ -6496,6 +6562,11 @@ export namespace ygopro {
if (data.wait != null) {
message.wait = StocGameMessage.MsgWait.fromObject(data.wait);
}
if (data.unimplemented != null) {
message.unimplemented = StocGameMessage.MsgUnimplemented.fromObject(
data.unimplemented
);
}
return message;
}
toObject() {
......@@ -6551,6 +6622,9 @@ export namespace ygopro {
>;
win?: ReturnType<typeof StocGameMessage.MsgWin.prototype.toObject>;
wait?: ReturnType<typeof StocGameMessage.MsgWait.prototype.toObject>;
unimplemented?: ReturnType<
typeof StocGameMessage.MsgUnimplemented.prototype.toObject
>;
} = {};
if (this.start != null) {
data.start = this.start.toObject();
......@@ -6615,6 +6689,9 @@ export namespace ygopro {
if (this.wait != null) {
data.wait = this.wait.toObject();
}
if (this.unimplemented != null) {
data.unimplemented = this.unimplemented.toObject();
}
return data;
}
serialize(): Uint8Array;
......@@ -6693,6 +6770,10 @@ export namespace ygopro {
writer.writeMessage(20, this.win, () => this.win.serialize(writer));
if (this.has_wait)
writer.writeMessage(21, this.wait, () => this.wait.serialize(writer));
if (this.has_unimplemented)
writer.writeMessage(22, this.unimplemented, () =>
this.unimplemented.serialize(writer)
);
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocGameMessage {
......@@ -6861,6 +6942,14 @@ export namespace ygopro {
() => (message.wait = StocGameMessage.MsgWait.deserialize(reader))
);
break;
case 22:
reader.readMessage(
message.unimplemented,
() =>
(message.unimplemented =
StocGameMessage.MsgUnimplemented.deserialize(reader))
);
break;
default:
reader.skipField();
}
......@@ -11471,5 +11560,85 @@ export namespace ygopro {
return MsgWait.deserialize(bytes);
}
}
export class MsgUnimplemented extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(
data?:
| any[]
| {
command?: 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 ("command" in data && data.command != undefined) {
this.command = data.command;
}
}
}
get command() {
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set command(value: number) {
pb_1.Message.setField(this, 1, value);
}
static fromObject(data: { command?: number }): MsgUnimplemented {
const message = new MsgUnimplemented({});
if (data.command != null) {
message.command = data.command;
}
return message;
}
toObject() {
const data: {
command?: number;
} = {};
if (this.command != null) {
data.command = this.command;
}
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.command != 0) writer.writeInt32(1, this.command);
if (!w) return writer.getResultBuffer();
}
static deserialize(
bytes: Uint8Array | pb_1.BinaryReader
): MsgUnimplemented {
const reader =
bytes instanceof pb_1.BinaryReader
? bytes
: new pb_1.BinaryReader(bytes),
message = new MsgUnimplemented();
while (reader.nextField()) {
if (reader.isEndGroup()) break;
switch (reader.getFieldNumber()) {
case 1:
message.command = reader.readInt32();
break;
default:
reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): MsgUnimplemented {
return MsgUnimplemented.deserialize(bytes);
}
}
}
}
......@@ -149,7 +149,9 @@ export default class GameMsgAdapter implements StocAdapter {
break;
}
default: {
console.log("Unhandled GameMessage function=", func);
gameMsg.unimplemented = new ygopro.StocGameMessage.MsgUnimplemented({
command: func,
});
break;
}
......
......@@ -144,6 +144,8 @@ export interface DuelState {
waiting?: boolean;
unimplemented?: number; // 未处理的`Message`
// UI相关
modalState: ModalState;
}
......@@ -264,6 +266,11 @@ const duelSlice = createSlice({
setWaiting: (state, action: PayloadAction<boolean>) => {
state.waiting = action.payload;
},
// 未处理状态`Reducer`
setUnimplemented: (state, action: PayloadAction<number>) => {
state.unimplemented = action.payload;
},
},
extraReducers(builder) {
handsCase(builder);
......@@ -344,6 +351,7 @@ export const {
clearAllPlaceInteractivities,
setResult,
setWaiting,
setUnimplemented,
} = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null;
......@@ -354,4 +362,7 @@ export const selectDuelResult = (state: RootState) => {
export const selectWaiting = (state: RootState) => {
return state.duel.waiting;
};
export const selectUnimplemented = (state: RootState) => {
return state.duel.unimplemented;
};
export default duelSlice.reducer;
......@@ -21,6 +21,7 @@ import onMsgSelectYesNo from "./selectYesNo";
import onMsgUpdateHp from "./updateHp";
import onMsgWin from "./win";
import onMsgWait from "./wait";
import onUnimplemented from "./unimplemented";
import { setWaiting } from "../../reducers/duel/mod";
const ActiveList = [
......@@ -150,6 +151,11 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
break;
}
case "unimplemented": {
onUnimplemented(msg.unimplemented, dispatch);
break;
}
default: {
break;
}
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { setUnimplemented } from "../../reducers/duel/mod";
import { AppDispatch } from "../../store";
import NeosConfig from "../../../neos.config.json";
export default (
unimplemented: ygopro.StocGameMessage.MsgUnimplemented,
dispatch: AppDispatch
) => {
if (!NeosConfig.unimplementedWhiteList.includes(unimplemented.command)) {
dispatch(setUnimplemented(unimplemented.command));
}
};
import React from "react";
export const Button2D = (props: {
text: string;
left: number;
enable: boolean;
onClick: () => void;
}) => (
<adtFullscreenUi name="ui">
<rectangle
name="rect"
height="20px"
width="60px"
isEnabled={props.enable}
left={props.left}
>
<rectangle>
<babylon-button
name="close-icon"
onPointerDownObservable={props.onClick}
>
<textBlock
text={props.text}
fontFamily="FontAwesome"
fontStyle="bold"
fontSize={15}
color={props.enable ? "yellow" : "white"}
/>
</babylon-button>
</rectangle>
</rectangle>
</adtFullscreenUi>
);
import React from "react";
import { useNavigate } from "react-router-dom";
import { sendSurrender } from "../../api/ocgcore/ocgHelper";
import { useAppSelector } from "../../hook";
import { selectUnimplemented } from "../../reducers/duel/mod";
import { Alert } from "antd";
const NeosAlert = () => {
const unimplemented = useAppSelector(selectUnimplemented);
const navigate = useNavigate();
return (
<>
{unimplemented ? (
<Alert
message={`Unimplemented message with code=${unimplemented}`}
description="It seems that there's something unimplemented by Neos. Sincerely apologize for that. Contact use to fix this issue: <linuxgnulover@gmail.com>"
showIcon
type="error"
closable
banner
afterClose={() => {
// 发送投降信号
sendSurrender();
navigate("/");
}}
/>
) : (
<></>
)}
</>
);
};
export default NeosAlert;
......@@ -25,11 +25,13 @@ import DuelTimeLine from "./timeLine";
import { Row } from "antd";
import SendBox from "./sendBox";
import PlayerStatus from "./status";
import Alert from "./alert";
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const NeosDuel = () => {
return (
<>
<Alert />
<NeosLayout
sider={<NeosSider />}
header={<PlayerStatus />}
......
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