Commit c61bcaba authored by Chunchi Che's avatar Chunchi Che

support observer

parent ece99eb0
Pipeline #22940 failed with stages
in 12 minutes and 51 seconds
......@@ -49,6 +49,11 @@ export default class TypeChangeAdapter implements StocAdapter {
case 5: {
selfType = ygopro.StocTypeChange.SelfType.PLAYER6;
break;
}
case 7: {
selfType = ygopro.StocTypeChange.SelfType.OBSERVER;
break;
}
}
......
......@@ -27,12 +27,11 @@ export default function handleHsPlayerChange(pb: ygopro.YgoStocMsg) {
break;
}
case ygopro.StocHsPlayerChange.State.READY:
case ygopro.StocHsPlayerChange.State.NO_READY: {
roomStore.players[change.pos].state = change.state;
break;
}
case ygopro.StocHsPlayerChange.State.NO_READY:
case ygopro.StocHsPlayerChange.State.LEAVE: {
roomStore.players.splice(change.pos, 1);
// 因为某种原因,当state为`LEAVE`的时候不能把它从`players`中去掉,
// 只能修改状态然后UI上做特化处理
roomStore.players[change.pos].state = change.state;
break;
}
case ygopro.StocHsPlayerChange.State.TO_OBSERVER: {
......
......@@ -11,9 +11,11 @@ export default function handleTypeChange(pb: ygopro.YgoStocMsg) {
if (assertHost) {
switch (selfType) {
case SelfType.UNKNOWN:
case SelfType.UNKNOWN: {
console.warn("<HandleTypeChange>selfType is UNKNOWN");
break;
}
case SelfType.OBSERVER: {
console.warn("<HandleTypeChange>selfType is UNKNOWN or OBSERVER");
break;
}
default: {
......
......@@ -48,7 +48,6 @@ export const MatchModal: React.FC = ({}) => {
setPasswd(event.target.value);
};
// 因为萌卡服务器的房间密码会有`#`等特殊字符,因此这里用`encodeURIComponent`做下转义
const handleSubmit = async () => {
setConfirmLoading(true);
await init({ player, ip: server, passWd: passwd });
......
......@@ -81,6 +81,15 @@
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5);
}
.uncheck {
position: absolute;
bottom: 0;
right: 0;
z-index: 99;
color: red;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5);
}
.btn-join {
margin-left: auto;
}
......
import { CheckCircleFilled } from "@ant-design/icons";
import { sendHsNotReady, sendHsReady, sendUpdateDeck, ygopro } from "@/api";
import {
sendHsNotReady,
sendHsReady,
sendHsToDuelList,
sendHsToObserver,
sendUpdateDeck,
ygopro,
} from "@/api";
import socketMiddleWare, { socketCmd } from "@/middleware/socket";
import PlayerState = ygopro.StocHsPlayerChange.State;
import SelfType = ygopro.StocTypeChange.SelfType;
import { Avatar, Button, ConfigProvider, Popover, Skeleton, Space } from "antd";
import classNames from "classnames";
import {
......@@ -11,6 +20,7 @@ import {
useRef,
useState,
} from "react";
import { useNavigate } from "react-router-dom";
import { useSnapshot } from "valtio";
import { useConfig } from "@/config";
......@@ -236,9 +246,9 @@ const PlayerZone: React.FC<{
<div style={{ position: "relative" }}>
<Avatar
src={
avatar
avatar && player
? avatar
: player
: player && player.state != PlayerState.LEAVE
? `${NeosConfig.assetsPath}/default-avatar.png`
: ""
}
......@@ -250,7 +260,11 @@ const PlayerZone: React.FC<{
</div>
</OrderPopup>
<div className={styles.name}>
{player ? player.name : <Skeleton.Input size="small" />}
{player && player.state != PlayerState.LEAVE ? (
player.name
) : (
<Skeleton.Input size="small" />
)}
</div>
{btn}
</div>
......@@ -260,15 +274,17 @@ const PlayerZone: React.FC<{
const Controller: React.FC<{ onDeckChange: (deckName: string) => void }> = ({
onDeckChange,
}) => {
const snap = useSnapshot(deckStore);
const snapDeck = useSnapshot(deckStore);
const snapRoom = useSnapshot(roomStore);
const navigate = useNavigate();
return (
<Space>
<Select
title="卡组"
showSearch
style={{ width: 300 }}
defaultValue={snap.decks[0].deckName}
options={snap.decks.map((deck) => ({
defaultValue={snapDeck.decks[0].deckName}
options={snapDeck.decks.map((deck) => ({
value: deck.deckName,
title: deck.deckName,
}))}
......@@ -277,22 +293,43 @@ const Controller: React.FC<{ onDeckChange: (deckName: string) => void }> = ({
(value) => onDeckChange(value)
}
/>
<Button size="large" icon={<IconFont type="icon-record" size={18} />}>
加入观战
<Button
size="large"
icon={<IconFont type="icon-record" size={18} />}
onClick={() => {
if (snapRoom.selfType != SelfType.OBSERVER) {
sendHsToObserver();
} else {
sendHsToDuelList();
}
}}
>
{snapRoom.selfType == SelfType.OBSERVER ? "加入决斗者" : "加入观战"}
<Avatar.Group className={styles["avatars-watch"]}>
{Array.from({ length: snapRoom.observerCount }).map((_, idx) => (
<Avatar
src="https://xsgames.co/randomusers/avatar.php?g=pixel&key=1"
key={idx}
src={`${NeosConfig.assetsPath}/default-avatar.png`}
size="small"
/>
<Avatar style={{ backgroundColor: "#f56a00" }} size="small">
K
</Avatar>
<Avatar style={{ backgroundColor: "#87d068" }} size="small" />
))}
</Avatar.Group>
</Button>
<Button size="large" icon={<IconFont type="icon-play" size={12} />}>
开始游戏
</Button>
<Button
size="large"
danger
onClick={() => {
// 断开websocket🔗,
socketMiddleWare({ cmd: socketCmd.DISCONNECT });
// 返回上一个路由
navigate("..");
}}
>
退出房间
</Button>
</Space>
);
};
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