Commit 7cdee8e9 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/reload' into 'main'

支持断线重连

See merge request !291
parents ad0a228f 31db6b11
Pipeline #23328 passed with stages
in 12 minutes and 28 seconds
......@@ -28,14 +28,6 @@ export default (data: Uint8Array) => {
overlay_count,
}),
);
} else {
zone_actions.push(
new MsgReloadField.ZoneAction({
zone: ygopro.CardZone.MZONE,
sequence,
position: ygopro.CardPosition.FACEDOWN,
}),
);
}
}
......@@ -52,14 +44,6 @@ export default (data: Uint8Array) => {
position: numberToCardPosition(position),
}),
);
} else {
zone_actions.push(
new MsgReloadField.ZoneAction({
zone: ygopro.CardZone.SZONE,
sequence,
position: ygopro.CardPosition.FACEDOWN,
}),
);
}
}
......
import { v4 as v4uuid } from "uuid";
import { ygopro } from "@/api";
import { cardStore, matStore } from "@/stores";
import { genCard } from "../utils";
type MsgReloadField = ygopro.StocGameMessage.MsgReloadField;
export default (_field: MsgReloadField) => {
// TODO: 断线重连比较复杂,先留着后面时实现
export default (field: MsgReloadField) => {
// 重置
cardStore.reset();
const actions = field.actions;
actions.forEach((action) => {
const controller = action.player;
// 更新生命值
matStore.initInfo.of(controller).life = action.lp;
// 更新卡片集合
const cards = action.zone_actions
.map((zoneAction) =>
Array.from({ length: zoneAction.overlay_count + 1 }).map(
(_, overlaySequence) =>
genCard({
uuid: v4uuid(),
code: 0,
location: new ygopro.CardLocation({
controller,
zone: zoneAction.zone,
sequence: zoneAction.sequence,
is_overlay: overlaySequence > 0,
overlay_sequence: Math.min(overlaySequence - 1, 0),
position: zoneAction.position,
}),
counters: {},
idleInteractivities: [],
meta: { id: 0, data: {}, text: {} },
isToken: false,
selected: false,
}),
),
)
.flat();
cardStore.inner.push(...cards);
});
};
import { flatten } from "lodash-es";
import { v4 as v4uuid } from "uuid";
import { proxy } from "valtio";
import { subscribeKey } from "valtio/utils";
import PlayerType = ygopro.StocGameMessage.MsgStart.PlayerType;
import { fetchCard, ygopro } from "@/api";
import { ygopro } from "@/api";
import { useConfig } from "@/config";
import { sleep } from "@/infra";
import {
cardStore,
CardType,
matStore,
RoomStage,
roomStore,
......@@ -16,6 +13,8 @@ import {
sideStore,
} from "@/stores";
import { replayStart } from "@/ui/Match/ReplayModal";
import { genCard } from "../utils";
const TOKEN_SIZE = 13; // 每人场上最多就只可能有13个token
export default async (start: ygopro.StocGameMessage.MsgStart) => {
......@@ -72,7 +71,6 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => {
sequence,
position: ygopro.CardPosition.FACEDOWN,
}),
originController: i < 3 ? 0 : 1,
counters: {},
idleInteractivities: [],
meta: {
......@@ -101,13 +99,3 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => {
// 否则在和AI对战时,由于后端给传给前端的`MSG`频率太高,会导致一些问题。
await sleep(useConfig().startDelay);
};
// 自动从code推断出occupant
const genCard = (o: CardType) => {
const t = proxy(o);
subscribeKey(t, "code", async (code) => {
const meta = fetchCard(code ?? 0);
t.meta = meta;
});
return t;
};
......@@ -3,6 +3,7 @@ import { cardStore } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
import MsgUpdateData = ygopro.StocGameMessage.MsgUpdateData;
import { TYPE_TOKEN } from "@/common";
export default async (updateData: MsgUpdateData) => {
const { player: controller, zone, actions } = updateData;
if (controller !== undefined && zone !== undefined && actions !== undefined) {
......@@ -17,7 +18,10 @@ export default async (updateData: MsgUpdateData) => {
// 目前只更新以下字段
if (action?.code >= 0) {
const newMeta = fetchCard(action.code);
target.code = action.code;
if (target.code !== action.code) {
// 这个if判断一定要有,不然会触发`genCard`里面的事件
target.code = action.code;
}
target.meta = newMeta;
}
......@@ -32,6 +36,9 @@ export default async (updateData: MsgUpdateData) => {
}
if (action?.type_ >= 0) {
meta.data.type = action.type_;
if (action.type_ & TYPE_TOKEN) {
target.isToken = true;
}
}
if (action?.level >= 0) {
meta.data.level = action.level;
......
import { proxy } from "valtio";
import { subscribeKey } from "valtio/utils";
import { fetchCard } from "@/api";
import { CardType } from "@/stores";
// 自动从code推断出meta
//
// TODO: 其实不是很推荐这样做,因为随着项目复杂度增加,这样可能会带来meta更新的时序问题
export const genCard = (card: CardType) => {
const t = proxy(card);
subscribeKey(t, "code", async (code) => {
const meta = fetchCard(code);
t.meta = meta;
});
return t;
};
export * from "./fetchCheckCardMeta";
export * from "./genCard";
......@@ -13,7 +13,6 @@ export interface CardType {
code: number; // 卡号
meta: CardMeta; // 卡片元数据
location: ygopro.CardLocation;
originController: number; // 在卡组构建之中持有这张卡的玩家,方便reloadField的使用
idleInteractivities: Interactivity<number>[]; // IDLE状态下的互动信息
placeInteractivity?: Interactivity<{
controller: number;
......
......@@ -28,7 +28,7 @@ const Cards: React.FC = () => {
return (
<>
{Array.from({ length }).map((_, i) => (
<Card key={i} idx={i} />
<Card key={inner[i].uuid} idx={i} />
))}
</>
);
......
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