Commit 53511cbc authored by Chunchi Che's avatar Chunchi Che

migrate

parent fe02e6f3
Pipeline #17246 passed with stage
in 1 minute and 32 seconds
import { ygopro } from "../api/idl/ocgcore"; import { ygopro } from "../api/idl/ocgcore";
import { setJoined, selectJoined } from "../reducers/joinSlice";
import { postChat, selectChat } from "../reducers/chatSlice";
import { useAppDispatch, useAppSelector } from "../hook";
import {
player0Enter,
player1Enter,
player0Update,
player1Update,
player0Leave,
player1Leave,
hostChange,
observerIncrement,
observerChange,
updateIsHost,
} from "../reducers/playerSlice";
export enum socketCmd { export enum socketCmd {
CONNECT, CONNECT,
...@@ -14,6 +29,9 @@ export interface socketAction { ...@@ -14,6 +29,9 @@ export interface socketAction {
let ws: WebSocket | null = null; let ws: WebSocket | null = null;
const READY_STATE = "ready";
const NO_READY_STATE = "not ready";
export default function (action: socketAction) { export default function (action: socketAction) {
switch (action.cmd) { switch (action.cmd) {
case socketCmd.CONNECT: { case socketCmd.CONNECT: {
...@@ -23,6 +41,8 @@ export default function (action: socketAction) { ...@@ -23,6 +41,8 @@ export default function (action: socketAction) {
ws.onopen = () => { ws.onopen = () => {
console.log("WebSocket open."); console.log("WebSocket open.");
ws!.binaryType = "arraybuffer";
}; };
ws.onclose = () => { ws.onclose = () => {
console.log("WebSocket closed."); console.log("WebSocket closed.");
...@@ -30,8 +50,143 @@ export default function (action: socketAction) { ...@@ -30,8 +50,143 @@ export default function (action: socketAction) {
}; };
ws.onmessage = (e) => { ws.onmessage = (e) => {
const pb = ygopro.YgoStocMsg.deserializeBinary(e.data); const pb = ygopro.YgoStocMsg.deserializeBinary(e.data);
const dispatch = useAppDispatch();
switch (pb.msg) {
case "stoc_join_game": {
const msg = pb.stoc_join_game;
// todo
dispatch(setJoined());
break;
}
case "stoc_chat": {
const chat = pb.stoc_chat;
dispatch(postChat(chat.msg));
break;
}
case "stoc_hs_player_change": {
const change = pb.stoc_hs_player_change;
if (change.pos > 1) {
console.log("Currently only supported 2v2 mode.");
} else {
switch (change.state) {
case ygopro.StocHsPlayerChange.State.UNKNOWN: {
console.log("Unknown HsPlayerChange State");
break;
}
case ygopro.StocHsPlayerChange.State.MOVE: {
console.log(
"Player " + change.pos + " moved to " + change.moved_pos
);
let src = change.pos;
let dst = change.moved_pos;
// todo
// if (src === 0 && dst === 1) {
// setPlayer1(player0);
// setPlayer0({});
// } else if (src === 1 && dst === 0) {
// setPlayer0(player1);
// setPlayer1({});
// }
break;
}
case ygopro.StocHsPlayerChange.State.READY: {
change.pos == 0
? dispatch(player0Update(READY_STATE))
: dispatch(player1Update(READY_STATE));
break;
}
case ygopro.StocHsPlayerChange.State.NO_READY: {
change.pos == 0
? dispatch(player0Update(NO_READY_STATE))
: dispatch(player1Update(NO_READY_STATE));
break;
}
case ygopro.StocHsPlayerChange.State.LEAVE: {
change.pos == 0
? dispatch(player0Leave)
: dispatch(player1Leave);
break;
}
case ygopro.StocHsPlayerChange.State.TO_OBSERVER: {
change.pos == 0
? dispatch(player0Leave)
: dispatch(player1Leave);
dispatch(observerIncrement());
break;
}
default: {
break;
}
}
}
break;
}
case "stoc_hs_watch_change": {
const count = pb.stoc_hs_watch_change.count;
dispatch(observerChange(count));
break;
}
case "stoc_hs_player_enter": {
const name = pb.stoc_hs_player_enter.name;
const pos = pb.stoc_hs_player_enter.pos;
if (pos > 1) {
console.log("Currently only supported 2v2 mode.");
} else {
pos == 0
? dispatch(player0Enter(name))
: dispatch(player1Enter(name));
}
break;
}
case "stoc_type_change": {
const selfType = pb.stoc_type_change.self_type;
const assertHost = pb.stoc_type_change.is_host;
dispatch(updateIsHost(assertHost));
if (assertHost) {
switch (selfType) {
case ygopro.StocTypeChange.SelfType.PLAYER1: {
dispatch(hostChange(0));
dispatch(player0Update(NO_READY_STATE));
break;
}
case ygopro.StocTypeChange.SelfType.PLAYER2: {
dispatch(hostChange(0));
dispatch(player1Update(NO_READY_STATE));
break;
}
default: {
break;
}
}
}
// todo break;
}
default: {
break;
}
}
}; };
} }
break; break;
......
...@@ -11,12 +11,14 @@ export interface playerState { ...@@ -11,12 +11,14 @@ export interface playerState {
player0: Player; player0: Player;
player1: Player; player1: Player;
observerCount: number; observerCount: number;
isHost: boolean;
} }
const initialState: playerState = { const initialState: playerState = {
player0: {}, player0: {},
player1: {}, player1: {},
observerCount: 0, observerCount: 0,
isHost: false,
}; };
const playerSlice = createSlice({ const playerSlice = createSlice({
...@@ -35,6 +37,12 @@ const playerSlice = createSlice({ ...@@ -35,6 +37,12 @@ const playerSlice = createSlice({
player1Update: (state, action: PayloadAction<string>) => { player1Update: (state, action: PayloadAction<string>) => {
state.player1.state = action.payload; state.player1.state = action.payload;
}, },
player0Leave: (state) => {
state.player0 = {};
},
player1Leave: (state) => {
state.player1 = {};
},
hostChange: (state, action: PayloadAction<number>) => { hostChange: (state, action: PayloadAction<number>) => {
const i = action.payload; const i = action.payload;
...@@ -46,8 +54,14 @@ const playerSlice = createSlice({ ...@@ -46,8 +54,14 @@ const playerSlice = createSlice({
state.player0.isHost = false; state.player0.isHost = false;
} }
}, },
observerIncrement: (state) => {
state.observerCount += 1;
},
observerChange: (state, action: PayloadAction<number>) => { observerChange: (state, action: PayloadAction<number>) => {
state.observerCount += action.payload; state.observerCount = action.payload;
},
updateIsHost: (state, action: PayloadAction<boolean>) => {
state.isHost = action.payload;
}, },
}, },
}); });
...@@ -57,9 +71,16 @@ export const { ...@@ -57,9 +71,16 @@ export const {
player1Enter, player1Enter,
player0Update, player0Update,
player1Update, player1Update,
player0Leave,
player1Leave,
hostChange, hostChange,
observerIncrement,
observerChange, observerChange,
updateIsHost,
} = playerSlice.actions; } = playerSlice.actions;
export const selectPlayer0 = (state: RootState) => state.player.player0; export const selectPlayer0 = (state: RootState) => state.player.player0;
export const selectPlayer1 = (state: RootState) => state.player.player1; export const selectPlayer1 = (state: RootState) => state.player.player1;
export const selectIsHost = (state: RootState) => state.player.isHost;
export const selectObserverCount = (state: RootState) =>
state.player.observerCount;
export default playerSlice.reducer; export default playerSlice.reducer;
...@@ -3,23 +3,17 @@ import { useParams } from "react-router-dom"; ...@@ -3,23 +3,17 @@ import { useParams } from "react-router-dom";
import { ygopro } from "../api/idl/ocgcore"; import { ygopro } from "../api/idl/ocgcore";
import { fetchDeck, IDeck } from "../api/Card"; import { fetchDeck, IDeck } from "../api/Card";
import "../css/WaitRoom.css"; import "../css/WaitRoom.css";
import { useAppDispatch, useAppSelector } from "../hook"; import { useAppSelector } from "../hook";
import { setJoined, selectJoined } from "../reducers/joinSlice"; import { selectJoined } from "../reducers/joinSlice";
import { postChat, selectChat } from "../reducers/chatSlice"; import { selectChat } from "../reducers/chatSlice";
import { import {
player0Enter, selectIsHost,
player1Enter, selectPlayer0,
player0Update, selectPlayer1,
player1Update, selectObserverCount,
hostChange,
observerChange,
} from "../reducers/playerSlice"; } from "../reducers/playerSlice";
type Player = { import socketMiddleWare, { socketCmd } from "../middleware/socket";
name?: string;
state?: string; // todo: use enum or boolean
isHost?: boolean;
};
const READY_STATE = "ready"; const READY_STATE = "ready";
const NO_READY_STATE = "not ready"; const NO_READY_STATE = "not ready";
...@@ -32,234 +26,43 @@ export default function WaitRoom() { ...@@ -32,234 +26,43 @@ export default function WaitRoom() {
}>(); }>();
const [choseDeck, setChoseDeck] = useState<boolean>(false); const [choseDeck, setChoseDeck] = useState<boolean>(false);
const [observerCount, setObserverCount] = useState<number>(0);
const [player0, setPlayer0] = useState<Player>({});
const [player1, setPlayer1] = useState<Player>({});
const [isHost, setIsHost] = useState<boolean>(false);
const [_, forceUpdate] = useReducer((x) => x + 1, 0); // todo: use correct update design
const ws = useRef<WebSocket | null>(null);
const dispatch = useAppDispatch();
const { player, passWd, ip } = params; const { player, passWd, ip } = params;
useEffect(() => { useEffect(() => {
if (!ws.current) { if (
ws.current = new WebSocket("ws://" + ip); player != null &&
player.length != 0 &&
passWd != null &&
passWd.length != 0
) {
socketMiddleWare({ cmd: socketCmd.CONNECT, ip });
sendPlayerInfo(player);
sendJoinGame(4947, passWd);
} }
}, []);
ws.current.onopen = () => {
console.log("Websocket open");
if (
player != null &&
player.length != 0 &&
passWd != null &&
passWd.length != 0 &&
ws.current
) {
const wsCurrent = ws.current;
wsCurrent.binaryType = "arraybuffer";
sendPlayerInfo(wsCurrent, player);
sendJoinGame(wsCurrent, 4947, passWd);
}
};
ws.current.onclose = () => {
console.log("Websocket closed");
};
ws.current.onmessage = (e) => {
const pb = ygopro.YgoStocMsg.deserializeBinary(e.data);
switch (pb.msg) {
case "stoc_join_game": {
const msg = pb.stoc_join_game;
// todo
dispatch(setJoined());
break;
}
case "stoc_chat": {
const chat = pb.stoc_chat;
dispatch(postChat(chat.msg));
break;
}
case "stoc_hs_player_change": {
const change = pb.stoc_hs_player_change;
if (change.pos > 1) {
console.log("Currently only supported 2v2 mode.");
} else {
switch (change.state) {
case ygopro.StocHsPlayerChange.State.UNKNOWN: {
console.log("Unknown HsPlayerChange State");
break;
}
case ygopro.StocHsPlayerChange.State.MOVE: {
console.log(
"Player " + change.pos + " moved to " + change.moved_pos
);
let src = change.pos;
let dst = change.moved_pos;
if (src === 0 && dst === 1) {
setPlayer1(player0);
setPlayer0({});
} else if (src === 1 && dst === 0) {
setPlayer0(player1);
setPlayer1({});
}
break;
}
case ygopro.StocHsPlayerChange.State.READY: {
const updateState = (player: Player) => {
player.state = READY_STATE;
return player;
};
change.pos == 0
? setPlayer0(updateState)
: setPlayer1(updateState);
break;
}
case ygopro.StocHsPlayerChange.State.NO_READY: {
const updateState = (player: Player) => {
const state = NO_READY_STATE;
player.state = state;
return player;
};
change.pos == 0
? setPlayer0(updateState)
: setPlayer1(updateState);
break;
}
case ygopro.StocHsPlayerChange.State.LEAVE: {
change.pos == 0 ? setPlayer0({}) : setPlayer1({});
break;
}
case ygopro.StocHsPlayerChange.State.TO_OBSERVER: {
change.pos == 0 ? setPlayer0({}) : setPlayer1({});
setObserverCount(observerCount + 1);
break;
}
default: {
break;
}
}
forceUpdate();
}
break;
}
case "stoc_hs_watch_change": {
const count = pb.stoc_hs_watch_change.count;
setObserverCount(count);
break;
}
case "stoc_hs_player_enter": {
const name = pb.stoc_hs_player_enter.name;
const pos = pb.stoc_hs_player_enter.pos;
if (pos > 1) {
console.log("Currently only supported 2v2 mode.");
} else {
const updatePlayer = (player: Player) => {
player.name = name;
return player;
};
pos == 0 ? setPlayer0(updatePlayer) : setPlayer1(updatePlayer);
forceUpdate();
}
break;
}
case "stoc_type_change": {
const selfType = pb.stoc_type_change.self_type;
const assertHost = pb.stoc_type_change.is_host;
setIsHost(assertHost);
if (assertHost) {
const updatePlayer = (player: Player) => {
player.isHost = assertHost;
player.state = NO_READY_STATE;
return player;
};
switch (selfType) {
case ygopro.StocTypeChange.SelfType.PLAYER1: {
setPlayer0(updatePlayer);
break;
}
case ygopro.StocTypeChange.SelfType.PLAYER2: {
setPlayer1(updatePlayer);
break;
}
default: {
break;
}
}
forceUpdate();
}
break;
}
default: {
break;
}
}
};
const wsCurrent = ws.current;
return () => {
if (wsCurrent.readyState == 1) {
wsCurrent.close();
}
};
}, [ws]);
const joined = useAppSelector(selectJoined); const joined = useAppSelector(selectJoined);
const chat = useAppSelector(selectChat); const chat = useAppSelector(selectChat);
const isHost = useAppSelector(selectIsHost);
const player0 = useAppSelector(selectPlayer0);
const player1 = useAppSelector(selectPlayer1);
const observerCount = useAppSelector(selectObserverCount);
const handleChoseDeck = async () => { const handleChoseDeck = async () => {
if (ws.current) { const deck = await fetchDeck("hero.ydk");
const deck = await fetchDeck("hero.ydk");
sendUpdateDeck(ws.current, deck); sendUpdateDeck(deck);
setChoseDeck(true); setChoseDeck(true);
}
}; };
const handleChoseReady = () => { const handleChoseReady = () => {
if (ws.current) { sendHsReady();
sendHsReady(ws.current);
}
}; };
const handleChoseStart = () => { const handleChoseStart = () => {
if (ws.current) { sendHsStart();
sendHsStart(ws.current);
}
}; };
return ( return (
...@@ -310,17 +113,17 @@ export default function WaitRoom() { ...@@ -310,17 +113,17 @@ export default function WaitRoom() {
); );
} }
function sendPlayerInfo(ws: WebSocket, player: string) { function sendPlayerInfo(player: string) {
const playerInfo = new ygopro.YgoCtosMsg({ const playerInfo = new ygopro.YgoCtosMsg({
ctos_player_info: new ygopro.CtosPlayerInfo({ ctos_player_info: new ygopro.CtosPlayerInfo({
name: player, name: player,
}), }),
}); });
ws.send(playerInfo.serialize()); socketMiddleWare({ cmd: socketCmd.SEND, payload: playerInfo });
} }
function sendJoinGame(ws: WebSocket, version: number, passWd: string) { function sendJoinGame(version: number, passWd: string) {
const joinGame = new ygopro.YgoCtosMsg({ const joinGame = new ygopro.YgoCtosMsg({
ctos_join_game: new ygopro.CtosJoinGame({ ctos_join_game: new ygopro.CtosJoinGame({
version, // todo: use config version, // todo: use config
...@@ -329,10 +132,10 @@ function sendJoinGame(ws: WebSocket, version: number, passWd: string) { ...@@ -329,10 +132,10 @@ function sendJoinGame(ws: WebSocket, version: number, passWd: string) {
}), }),
}); });
ws.send(joinGame.serialize()); socketMiddleWare({ cmd: socketCmd.SEND, payload: joinGame });
} }
function sendUpdateDeck(ws: WebSocket, deck: IDeck) { function sendUpdateDeck(deck: IDeck) {
const updateDeck = new ygopro.YgoCtosMsg({ const updateDeck = new ygopro.YgoCtosMsg({
ctos_update_deck: new ygopro.CtosUpdateDeck({ ctos_update_deck: new ygopro.CtosUpdateDeck({
main: deck.main, main: deck.main,
...@@ -341,21 +144,21 @@ function sendUpdateDeck(ws: WebSocket, deck: IDeck) { ...@@ -341,21 +144,21 @@ function sendUpdateDeck(ws: WebSocket, deck: IDeck) {
}), }),
}); });
ws.send(updateDeck.serialize()); socketMiddleWare({ cmd: socketCmd.SEND, payload: updateDeck });
} }
function sendHsReady(ws: WebSocket) { function sendHsReady() {
const hasReady = new ygopro.YgoCtosMsg({ const hasReady = new ygopro.YgoCtosMsg({
ctos_hs_ready: new ygopro.CtosHsReady({}), ctos_hs_ready: new ygopro.CtosHsReady({}),
}); });
ws.send(hasReady.serialize()); socketMiddleWare({ cmd: socketCmd.SEND, payload: hasReady });
} }
function sendHsStart(ws: WebSocket) { function sendHsStart() {
const hasStart = new ygopro.YgoCtosMsg({ const hasStart = new ygopro.YgoCtosMsg({
ctos_hs_start: new ygopro.CtosHsStart({}), ctos_hs_start: new ygopro.CtosHsStart({}),
}); });
ws.send(hasStart.serialize()); socketMiddleWare({ cmd: socketCmd.SEND, payload: hasStart });
} }
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