[add] 進機台

This commit is contained in:
2023-12-05 17:27:18 +08:00
parent 987aa1cb5e
commit d80118bb68
40 changed files with 1538 additions and 1109 deletions

35
src/UI/Lobby/Player.tsx Normal file
View File

@@ -0,0 +1,35 @@
import { CurrencyManager } from "@/FormTableExt/Manage/Currency/CurrencyManager";
import { useGameItems } from "@/context/GameItemsContext";
import { useEffect } from "react";
const Player = () => {
const { player } = useGameItems();
const { aId, name, m } = player;
function onLoad() {
}
useEffect(() => {
onLoad();
}, []);
return (
<div style={siderStyle}>
<p>aId: {aId}</p>
<p>: {name}</p>
<p>: {CurrencyManager.GetNumberWithComma(m)}</p>
</div>
);
};
export default Player;
const siderStyle: React.CSSProperties = {
fontSize: "1rem",
color: "#000000",
display: "flex",
textAlign: "left",
flexDirection: "column",
justifyContent: "center",
width: "20%"
};

145
src/UI/Lobby/SDGame.tsx Normal file
View File

@@ -0,0 +1,145 @@
import CSMessage from "@/Common/Message/CSMessage";
import { CoroutineV2 } from "@/Engine/CatanEngine/CoroutineV2/CoroutineV2";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { NetConnector } from "@/Engine/CatanEngine/NetManagerV2/NetConnector";
import { NetManagerSD } from "@/Engine/CatanEngine/NetManagerV2/NetManagerSD";
import { useGameItems } from "@/context/GameItemsContext";
import SlotBase from "@/define/Game/Base/SlotBase";
import { SDAccountLoginRequest } from "@/define/Request/AccountRequest";
import { SlotInRequest } from "@/define/Request/SlotRequest";
import { Button, Flex } from "antd";
import { useEffect, useState } from "react";
const SDGame = (props: ISDGame) => {
const { gameUrl, onClickSlotOut } = props;
const { player, setPlayer } = useGameItems();
const { gameData } = useGameItems();
const { nowSlotId } = gameData;
const [slotId, setSlotId] = useState<number>(undefined);
const [slotData, setSlotData] = useState<Object>(undefined);
let conn: NetConnector = undefined;
function* onLoad(): IterableIterator<any> {
const url: URL = new URL(gameUrl);
const queryParameters: URLSearchParams = new URLSearchParams(url.search);
const token: string = queryParameters.get("token");
const slotid: number = +queryParameters.get("slotid");
const host: string = queryParameters.get("host");
const port: number = 9005;
setSlotId(slotid);
conn = new NetConnector("https://" + host, port);
conn.OnDataReceived.AddCallback(onNetDataReceived);
conn.OnDisconnected.AddCallback(onNetDisconnected);
NetManagerSD.Initialize(conn);
console.log("[SDsocket] connecting...");
yield NetManagerSD.ConnectAsync();
yield* login(token);
yield* slotIn(slotid);
}
function* login(token: string): IterableIterator<any> {
const req = new SDAccountLoginRequest(token);
yield req.SendAsync(true);
const resp = req.Result;
if (!resp.IsValid) {
CSMessage.NetError(resp.Method, resp.Status, "SD Account Login Fail");
return;
}
}
function* slotIn(slotid: number): IterableIterator<any> {
let req: SlotInRequest = new SlotInRequest(slotid);
yield req.SendAsync(true);
let resp: INetResponse<JSON> = req.Result;
if (resp.IsValid) {
setSlotData(resp.Data);
}
}
async function OnclickSpin() {
let slot: any;
const slotGroup: typeof import("../../define/Game/Base/Slot") = await import(/* @vite-ignore */`../../define/Game/Base/Slot`);
try {
slot = slotGroup[`Slot${slotId}`];
} catch (error) {
//
}
if (!slot) {
slot = slotGroup.SlotBase;
}
const slotClass: SlotBase = new slot(slotId);
// this.IsSpin.value = true;
CoroutineV2.Single(spin(slotClass)).Start();
}
function* spin(slotClass: SlotBase): IterableIterator<any> {
yield* slotClass.Spin(20);
// await Tools.Sleep(this.SpinDelay.value * 1000);
// if (this.IsSpin.value && this._bj_Casino_Bot.LobbyScript.IsSlotIn.value) {
// this.Spin();
// } else {
// this.IsRun = false;
// }
}
/**RPC回傳.若協定錯誤斷線.原因也會在這裡收到 */
function onNetDataReceived(resp: INetResponse<any>) {
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]);
}
/**只要連線中斷不管主被動都會走到這裡 */
function onNetDisconnected() {
console.warn("[socket] Disconnected");
conn.OnDataReceived.RemoveAllCallbacks();
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]);
}
useEffect(() => {
CoroutineV2.Single(onLoad()).Start();
}, []);
return (<>
<div style={siderStyle}>
<Flex gap="small" wrap="wrap">
<div style={controlStyle}>
Bet: 20
<p>
<Button type="primary" onClick={OnclickSpin} style={{ width: "20%" }}>Spin</Button>
<Button type="primary" danger onClick={onClickSlotOut} style={{ width: "20%" }}></Button>
</p>
</div>
<div>
Log
</div>
</Flex>
</div>
</>);
};
export default SDGame;
interface ISDGame {
gameUrl: string;
onClickSlotOut: () => void;
}
const siderStyle: React.CSSProperties = {
fontSize: "1rem",
color: "#000000",
display: "flex",
textAlign: "left",
flexDirection: "column",
justifyContent: "center",
width: "100%"
};
const controlStyle: React.CSSProperties = {
fontSize: "1rem",
display: "flex",
textAlign: "left",
flexDirection: "column",
justifyContent: "center",
lineHeight: "30px",
width: "30%"
};

93
src/UI/Lobby/SlotList.tsx Normal file
View File

@@ -0,0 +1,93 @@
import CSMessage from "@/Common/Message/CSMessage";
import { CoroutineV2 } from "@/Engine/CatanEngine/CoroutineV2/CoroutineV2";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import CSSettingsV3 from "@/FormTable/CSSettingsV3";
import BusinessTypeSetting from "@/_BusinessTypeSetting/BusinessTypeSetting";
import Image from "@/components/Image/Image";
import { useGameItems } from "@/context/GameItemsContext";
import { GameLaunchRequest, GameLeaveRequest, RpcGameLaunchResponse } from "@/define/Request/GameRequest";
import { SlotData } from "@/define/gameData";
import { Button, Flex } from "antd";
import { useEffect, useState } from "react";
import SDGame from "./SDGame";
const SlotList = () => {
const { gameData, setGameData } = useGameItems();
const { slotData, slotList, nowSlotId } = gameData;
const [isGameIn, setIsGameIn] = useState<boolean>(false);
const [gameUrl, setGameUrl] = useState<string>("");
function onLoad() {
}
function* onClickSlotIn(slotId: number): IterableIterator<any> {
const data: SlotData = slotData[slotId];
const [componyID] = data;
const req: GameLaunchRequest = new GameLaunchRequest(componyID, slotId);
yield req.SendAsync();
const resp: INetResponse<RpcGameLaunchResponse> = req.Result;
if (!resp.IsValid) {
if (resp.Status === 18) {
CSMessage.CreateYesMsg(CSSettingsV3.prototype.CommonString(16));
}
return;
}
setIsGameIn(true);
const url: string = resp.Data;
setGameData({
...gameData,
nowSlotId: slotId
});
if (componyID === 2) {
setGameUrl(url);
}
else {
window.open(url, "_blank");
}
}
function onClickSlotOut() {
const gameLeaveReq: GameLeaveRequest = new GameLeaveRequest(nowSlotId);
gameLeaveReq.Send();
setGameUrl("");
setIsGameIn(false);
}
useEffect(() => {
onLoad();
}, []);
return (<>
{isGameIn
? <>{gameUrl
? <SDGame gameUrl={gameUrl} onClickSlotOut={onClickSlotOut} />
: <Flex gap="small" wrap="wrap">
<Button type="primary" onClick={onClickSlotOut}></Button>
</Flex>}</>
: <div style={contentStyle}>
<Flex gap="small" wrap="wrap">
{slotList.map((slotId: number, index: number) =>
<Image key={index} width={80} height={80} src={`${BusinessTypeSetting.UseDownloadUrl}game/${slotId}/s`}
onClick={() => { CoroutineV2.Single(onClickSlotIn(slotId)).Start(); }} style={{ cursor: "pointer" }} />
)}
</Flex>
</div>
}
</>);
};
export default SlotList;
const contentStyle: React.CSSProperties = {
fontSize: "1rem",
minHeight: 120,
lineHeight: "120px",
color: "#000000",
display: "flex",
textAlign: "center",
flexDirection: "column",
justifyContent: "center",
width: "100%"
};