[add] Lobby

This commit is contained in:
建喵 2023-11-24 11:15:26 +08:00
parent bd457c7f10
commit 987aa1cb5e
27 changed files with 1985 additions and 27 deletions

View File

@ -1,4 +1,9 @@
import { Action } from "@/Engine/CatanEngine/CSharp/System/Action";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { NetConnector } from "@/Engine/CatanEngine/NetManagerV2/NetConnector";
import { NetManager } from "@/Engine/CatanEngine/NetManagerV2/NetManager";
import BaseSingleton from "@/Engine/Utils/Singleton/BaseSingleton";
import BusinessTypeSetting from "@/_BusinessTypeSetting/BusinessTypeSetting";
export class MainControl extends BaseSingleton<MainControl>() {
/** 每次啟動APP */
@ -16,6 +21,41 @@ export class MainControl extends BaseSingleton<MainControl>() {
public IsInGame: boolean = false;
/** 現在時間 */
public get NowTime(): number { return Date.now(); }
public static readonly DataReceivedEvent: Action<any[]> = new Action<any[]>();
/** 連線控制 */
private _conn: NetConnector = null;
//#region 網路相關
/**連線(目前沒有重連機制) */
public * ConnectAsync() {
if (NetManager.IsConnected) {
return;
}
this._conn = new NetConnector(BusinessTypeSetting.UseHost, BusinessTypeSetting.UsePort);
this._conn.OnDataReceived.AddCallback(this._onNetDataReceived, this);
this._conn.OnDisconnected.AddCallback(this._onNetDisconnected, this);
NetManager.Initialize(this._conn);
console.log("[socket] connecting...");
// 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect()
yield NetManager.ConnectAsync();
}
/**只要連線中斷不管主被動都會走到這裡 */
private _onNetDisconnected() {
console.warn("[socket] Disconnected");
this._conn.OnDataReceived.RemoveAllCallbacks();
MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]);
}
/**RPC回傳.若協定錯誤斷線.原因也會在這裡收到 */
private _onNetDataReceived(resp: INetResponse<any>) {
MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]);
}
//#endregion
}
export module MainControl {

View File

@ -1,4 +1,3 @@
import Event from "@/modules/event";
import { Action } from "../CSharp/System/Action";
import { Encoding } from "../CSharp/System/Text/Encoding";
import { BaseEnumerator } from "../CoroutineV2/Core/BaseEnumerator";
@ -21,8 +20,6 @@ export interface Func {
}
export class NetConnector {
/** Event */
public readonly event: Event<Func> = new Event<Func>();
readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>();
readonly OnDisconnected: Action<void> = new Action<void>();
readonly OnLoadUIMask: Action<boolean> = new Action<boolean>();
@ -147,10 +144,7 @@ export class NetConnector {
}
private OnWebSocketOpen(e: Event) {
// if (CC_DEBUG) {
console.debug(`[RPC] ${this._host} Connected.`);
// }
this.event.emit(Socket.Connect);
}
private OnWebSocketMessage(e: MessageEvent) {
@ -221,11 +215,10 @@ export class NetConnector {
private OnWebSocketClose(e: CloseEvent) {
this.WebSocketEnded();
this.event.emit(Socket.Disconnect);
}
private OnWebSocketError(e: CloseEvent) {
this.event.emit(Socket.Error);
}
}

View File

@ -1,4 +1,52 @@
import MainControl from "@/Common/MainControl/MainControl";
import CSMessage from "@/Common/Message/CSMessage";
import { CoroutineV2 } from "@/Engine/CatanEngine/CoroutineV2/CoroutineV2";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { useGameItems } from "@/context/GameItemsContext";
import { CommonAccountResponse, LineLoginRequest } from "@/define/Request/RegisterRequest";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
const Lobby = () => {
const { player, setPlayer } = useGameItems();
const navigate = useNavigate();
const { token } = player;
function onLoad() {
if (!token) {
navigate(`/`);
return;
}
CoroutineV2.Single(onStart()).Start();
}
function* onStart() {
yield* MainControl.Instance.ConnectAsync();
}
function* registerLineLogin() {
let req: LineLoginRequest = new LineLoginRequest(token);
yield req.SendAsync(true);
let resp: INetResponse<CommonAccountResponse> = req.Result;
if (!resp.IsValid) {
//取得帳號失敗直接斷開SOCKET
if (resp.Status != 12) {
const msg: string = "Line Info Error. Error Code:" + req.Result.Status;
CSMessage.CreateYesMsg(msg);
return;
}
console.warn("LINE帳號無綁定");
return;
}
// yield* this.ServerAccountLogin(resp.Data.id, resp.Data.pw);
return;
}
useEffect(() => {
onLoad();
}, []);
return (
<>Lobby</>
);

View File

@ -1,7 +1,9 @@
import { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import { useGameItems } from "@/context/GameItemsContext";
import { Button, Cascader } from "antd";
import TextArea from "antd/es/input/TextArea";
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
interface Option {
value: string;
@ -10,10 +12,12 @@ interface Option {
}
const Login = () => {
const { onLoad } = useGameItems();
const { onLoad, player, setPlayer } = useGameItems();
const navigate = useNavigate();
const serverType: typeof BusinessEnum.ServerType = BusinessEnum.ServerType;
const [type, setType] = useState<number>(BusinessEnum.ServerType.Internal_Dev);
const [isLogin, setIsLogin] = useState<boolean>(false);
const [token, SetToken] = useState("");
const options: Option[] = [];
for (let i = 0, names: string[] = Object.keys(serverType); i < names.length; i++) {
const key: string = names[i];
@ -28,13 +32,23 @@ const Login = () => {
async function login() {
setIsLogin(true);
await onLoad(type);
setPlayer({
...player,
token: token
});
navigate(`/lobby/`);
}
return (
<>{!isLogin &&
<div style={boxStyle}>
<Cascader defaultValue={[BusinessEnum.ServerType[BusinessEnum.ServerType.Internal_Dev]]} options={options} onChange={(v: string[]) => setType(+v[0])} />
<Button type="primary" onClick={login}></Button>
<div style={boxStyle2}>
<Cascader defaultValue={[BusinessEnum.ServerType[BusinessEnum.ServerType.Internal_Dev]]} options={options} onChange={(v: string[]) => setType(+v[0])} />
<br />
<TextArea rows={4} value={token} onChange={e => SetToken(e.target.value)} />
<br />
<Button type="primary" onClick={login}></Button>
</div>
</div>
}</>
);
@ -43,11 +57,15 @@ const Login = () => {
export default Login;
const boxStyle: React.CSSProperties = {
width: "100%",
display: "flex",
justifyContent: "center",
};
const boxStyle2: React.CSSProperties = {
width: "50%",
height: "100vh",
borderRadius: 6,
border: "1px solid #40a9ff",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column"
};

View File

@ -1,6 +1,7 @@
import { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import MainControl from "@/Common/MainControl/MainControl";
import BusinessTypeSetting, { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import { PlayerData } from "@/define/playerData";
import { IGameItems } from "@/types";
import { LineTools } from "@/utils/LineTools";
import { ReactNode, createContext, useContext, useState } from "react";
type GameItemsProviderProps = {
@ -15,26 +16,70 @@ export let gameObj: IGameItems = null;
export function GameItemsProvider({ children }: GameItemsProviderProps) {
const [gameId, setGameId] = useState<number>(null);
const [player, setPlayer] = useState<PlayerData>({
token: "",
});
const game: IGameItems = gameObj = {
onLoad,
gameId,
setGameId
setGameId,
player,
setPlayer
};
async function onLoad(serverType: BusinessEnum.ServerType) {
new MainControl();
await Promise.all([
// // 設定執行環境
// setBusinessType(),
// 設定執行環境
setBusinessType(serverType),
// // 設定LineTools環境
// await setLineTools(),
]);
}
/** 設定LineTools環境 */
async function setLineTools() {
await LineTools.onLoad();
/** 設定執行環境 */
function setBusinessType(useServerType: BusinessEnum.ServerType): void {
// 連線參數自定義
const queryParameters = new URLSearchParams(location.search);
const servertype: string = queryParameters.get("servertype") ?? useServerType.toString();
const host: string = queryParameters.get("host");
const port: string = queryParameters.get("port");
const patch: string = queryParameters.get("patch");
const downloadurl: string = queryParameters.get("downloadurl");
const liffid: string = queryParameters.get("liffid");
if (servertype) {
// 自定預設環境
BusinessTypeSetting.UseServerType = +servertype;
BusinessTypeSetting.UseHost = BusinessTypeSetting.GetHostUrl(BusinessTypeSetting.UseServerType);
BusinessTypeSetting.UsePort = BusinessTypeSetting.GetPortNum(BusinessTypeSetting.UseServerType);
BusinessTypeSetting.UsePatch = BusinessTypeSetting.GetPatchUrl(BusinessTypeSetting.UseServerType);
BusinessTypeSetting.UseDownloadUrl = BusinessTypeSetting.GetDownloadUrl(BusinessTypeSetting.UseServerType);
BusinessTypeSetting.UseLiffID = BusinessTypeSetting.GetLiffID(BusinessTypeSetting.UseServerType);
BusinessTypeSetting.UseLineID = BusinessTypeSetting.GetLineID(BusinessTypeSetting.UseServerType);
}
if (host) {
// 自定連線1(有自定則無視UseServerType)
BusinessTypeSetting.UseHost = host;
}
if (port) {
// 自定連線2(有自定則無視UseServerType)
BusinessTypeSetting.UsePort = +port;
}
if (patch) {
// 自定連資源伺服器(有自定則無視UseServerType)
BusinessTypeSetting.UsePatch = patch;
}
if (downloadurl) {
// 自定連靜態伺服器(有自定則無視UseServerType)
BusinessTypeSetting.UseDownloadUrl = downloadurl;
}
if (liffid) {
// 自定連Line Liff(有自定則無視UseServerType)
BusinessTypeSetting.UseLiffID = liffid;
}
return;
}
return (

5
src/define/PlayerData.ts Normal file
View File

@ -0,0 +1,5 @@
interface PlayerData {
token: string;
}
export { type PlayerData };

View File

@ -0,0 +1,28 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcExampleCodeRequest = null
export type RpcExampleCodeResponse = ExampleCodeData[]
export class ExampleCodeRequest extends NetRequest<RpcExampleCodeRequest, RpcExampleCodeResponse> {
get Method(): string {
return "example.code";
}
constructor() {
super();
}
}
// #endregion
// #region Type
export type ExampleCodeData = [
id: number,
title: number,
content: number,
time: number,
];
// #endregion

View File

@ -0,0 +1,140 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
import { AdSyncType, TAdParam } from "./AdRequest";
// #region Request
export type RpcActivityListRequest = null
export type RpcActivityListResponse = TActivityList[]
export class ActivityListRequest extends NetRequest<RpcActivityListRequest, RpcActivityListResponse> {
get Method(): string {
return "activity.list";
}
constructor() {
super();
}
}
export type RpcActivityDetailRequest = null
export type RpcActivityDetailResponse = TActivityDetail[]
export class ActivityDetailRequest extends NetRequest<RpcActivityDetailRequest, RpcActivityDetailResponse> {
get Method(): string {
return "activity.detail";
}
constructor() {
super();
}
}
//-------- ActivityCommon
interface ActivityCommonDetailId {
id: number;
}
export class ActivityCommonDetail extends NetRequest<ActivityCommonDetailId, JSON> {
get Method(): string {
return "activity_com.detail";
}
constructor(id: number) {
super();
this.Data = {
id: id
};
}
}
interface ActivityCommand {
id: number;
c: number;
}
export class ActivityCommonCommand extends NetRequest<ActivityCommand, JSON> {
get Method(): string {
return "activity_com.cmd";
}
constructor(id: number, c: number) {
super();
this.Data = {
id: id,
c: c
};
}
}
export type RpcActivityComSyncResponse = TActivityComSyncData[]
// #endregion
// #region Type
export type TActivityList = [
id: number,
eventName: string,
eventType: EActivityType,
sort: number,
showStartTime: number,
showEndTime: number,
activityStartTime: number,
activityEndTime: number,
image: string,
eventEnd: number,
];
export type TActivityDetail = [
slot: number[],
vipLimit: number,
navType: AdSyncType,
navRef: TAdParam,
content1: number,
content2: number,
modData: TModData,
prizeData: TPrizeData,
jpAmount: number,
];
type TModData = [
rankType: number,
minBet: number,
minRounds: number,
totalRanks: number,
];
type TPrizeData = [
aid: number,
nickname: number,
multiplier: number,
money: number,
];
export type TActivityComSyncData = [
id: number,
activitySyncData: TActivitySyncData[],
];
export type TActivitySyncData = [
type: EActivitySyncType,
extra1: any,
extra2: any,
extra3: any
];
// #endregion
// #region Enum
export enum EActivityType {
Normal = 1,
JP = 2,
Rank = 3,
}
export enum EActivitySyncType {
IsOpen = 1,
Sync,
Task,
}
// #endregion

View File

@ -0,0 +1,98 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcAdSyncRequest = null
export type RpcAdSyncResponse = [TLobbyAdData[], TPopupAdData[]]
export class AdSyncRequest extends NetRequest<RpcAdSyncRequest, RpcAdSyncResponse> {
get Method(): string {
return "ad.sync";
}
constructor() {
super();
}
}
// #endregion
// #region Type
export type TLobbyAdData = [
id: number,
type: AdSyncType,
priority: number,
image: string,
param: TAdParam,
time: number,
];
export type TPopupAdData = [
id: number,
type: AdSyncType,
priority: number,
image: string,
param: TAdParam,
cond: IPopupAdCond,
time: number,
intervalTime: number,
];
export type TAdParam = any[];
// #endregion
// #region Interface
export interface IPopupAdCond {
/** 每日首次登入 */
1: number,
/** 進入大廳 */
2: number,
/** 進度大廳且金幣低於1000 */
3: number,
/** 在大廳關閉商城頁 */
4: number,
/** 離開特定機台跳出 */
5: number,
}
// #endregion
// #region Enum
export enum AdType {
/** 大廳 */
lobby_ad = 1,
/** 蓋台 */
inter_ad = 2
}
export enum AdSyncType {
/** 純廣告 */
Ad = 1,
/** 得來購 */
Dlygo,
/** 前往商城 */
Shop,
/** 指定機台 */
Slot,
/** 公告 */
Announce,
/** 活動 */
Activity,
/** 任務 */
Task,
/** 首頁教學 */
FrontPageTutorial,
/** 贈禮 */
Txn,
/** 排行 */
Rank,
}
// #endregion

View File

@ -0,0 +1,18 @@
import { ResourceItemType } from "@/Common/ResourceItem/ResourceItemType";
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
import { ItemInfo } from "../backpack/itemInfo";
export type ResponseBackpackInfo = [
ResourceType: ResourceItemType,
itemInfo: ItemInfo,
];
/** 背包內容 */
export class BackpackInfo extends NetRequest<null, ResponseBackpackInfo[]> {
get Method(): string {
return "backpack.info";
}
constructor() {
super();
}
}

View File

@ -0,0 +1,166 @@
import { NetRequest } from "@/Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcChatSendRequest = [
channel: [channelType: ChannelType | number, uuid?: string],
message: messageData,
]
export type RpcChatSendResponse = null
/**聊天室發言角色(還未有客服小姐姐分類) */
export enum Role {
Normal,
}
/** 聊天室 傳送聊天訊息 協定 */
export class ChatSendRequest extends NetRequest<RpcChatSendRequest, RpcChatSendResponse> {
get Method(): string {
return "chat.send";
}
/**
* @param {ChannelType} channelType
* @param {string} msg
*/
constructor(channelType: ChannelType, msg: string, type: MsgType, uuid?: number) {
super();
const channelData: [channelType: ChannelType, uuid?: string] = [channelType];
uuid && channelData.push(uuid);
this.Data = [channelData, [type, msg]];
}
}
export type RpcChatMessageResponse = [
channelType: ChannelType,
from: [
aId: number,
name: string,
avatar: 0 | 1,
vip: number,
role: Role,
],
messageData: messageData,
timestamp: number
]
export type RpcChatLogRequest = [
channelType: ChannelType,
lastTime: number,
]
export type RpcChatLogResponse = [
channelType: ChannelType,
message: string,
]
/** 聊天室 頻道紀錄 協定 */
export class ChatLogRequest extends NetRequest<RpcChatLogRequest, RpcChatLogResponse> {
get Method(): string {
return "chat.log";
}
/**
* @param {ChannelType} channelType
* @param {number} lastTime
*/
constructor(channelType: ChannelType, lastTime: number) {
super();
this.Data = [channelType, lastTime];
}
}
export type RpcChatReadRequest = number
export type RpcChatReadResponse = null
/** 聊天室 私訊已讀 協定 */
export class ChatReadRequest extends NetRequest<RpcChatReadRequest, RpcChatReadResponse> {
get Method(): string {
return "chat.read";
}
/**
* @param {number} aId aId
*/
constructor(aId: number) {
super();
this.Data = aId;
}
}
// #endregion
// #region Type
export type ChatLogData = [
channelType: ChannelType,
messageData: publicChatLogData[] | privateChatLogData[],
]
export type publicChatLogData = [
from: chatFromData,
messageData: messageData,
timestamp: number,
]
export type chatFromData = [
aId: number,
name: string,
avatar: 0 | 1,
vip: number,
role: Role,
]
export type privateChatLogData = [
senderAid: number,
receiveAid: number,
messageData: messageData,
timestamp: number,
isRead: boolean,
]
export type messageData = [type: MsgType, message: string]
export type msgAwardData = [name: string, slotID: number, slotName: string, Ratio: number]
// #endregion
// #region Interface
// #endregion
// #region Enum
/** 頻道類型 */
export enum ChannelType {
Unknown,
/** 公頻 */
Public,
/** 私訊 */
Private,
/** 公會 */
Guild,
}
/** 訊息類型 */
export enum MsgType {
/** 純文字 */
Text = 1,
/** 圖片 */
Image,
/** 貼圖 */
Sticker,
/** 大獎推播 */
BigWinNotify,
/** 團體戰 */
TeamBattle = 101,
}
// #endregion

View File

@ -0,0 +1,219 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
import { ResourceInfo } from "../resource";
/**
* @link dlygo() https://docs.google.com/spreadsheets/d/1bm1FwHyY2X7JGkCqSeCUoZAgaMcT7fUB7K4SiDtkyig
*/
// #region Request
export type RpcDlygoListRequest = { t: DlygoMainType }
export type RpcDlygoListResponse = TDlygoList[]
/** 商品清單 */
export class DlygoListRequest extends NetRequest<RpcDlygoListRequest, RpcDlygoListResponse> {
get Method(): string {
return "dlygo.list";
}
constructor(type: DlygoMainType) {
super();
this.Data = {
t: type
};
}
}
export type RpcDlygoSNRequest = { i: number; }
export type RpcDlygoSNResponse = TDlygoSN
/** 商品明細 */
export class DlygoSNRequest extends NetRequest<RpcDlygoSNRequest, RpcDlygoSNResponse> {
get Method(): string {
return "dlygo.sn";
}
constructor(id: number) {
super();
this.Data = {
i: id
};
}
}
export type RpcDlygoRedeemRequest = { i: number; p: number; }
export type RpcDlygoRedeemResponse = TDlygoRedeem
/** 商品兌換 */
export class DlygoRedeemRequest extends NetRequest<RpcDlygoRedeemRequest, RpcDlygoRedeemResponse> {
get Method(): string {
return "dlygo.redeem";
}
constructor(id: number, p: number) {
super();
this.Data = {
i: id,
p: p
};
}
}
export type RpcDlygoExchangeRequest = RpcDlygoSNRequest
export type RpcDlygoExchangeResponse = TDlygoExchange
/** 金幣兌換 */
export class DlygoExchangeRequest extends NetRequest<RpcDlygoExchangeRequest, RpcDlygoExchangeResponse> {
get Method(): string {
return "dlygo.exchange";
}
constructor(id: number) {
super();
this.Data = {
i: id
};
}
}
export type RpcDlygoLogRequest = {
/**
* @param u true: 使,
* @param u false: ,
*/
u: boolean;
}
export type RpcDlygoLogResponse = TDlygoLog[]
/** 商品記錄 */
export class DlygoLogRequest extends NetRequest<RpcDlygoLogRequest, RpcDlygoLogResponse> {
get Method(): string {
return "dlygo.log";
}
constructor(u: boolean) {
super();
this.Data = {
u: u
};
}
}
export type RpcDlygoUsedRequest = [productId: number, productSerialNumber: string]
export type RpcDlygoUsedResponse = TDlygoUsed
/** 商品使用 */
export class DlygoUsedRequest extends NetRequest<RpcDlygoUsedRequest[], RpcDlygoUsedResponse> {
get Method(): string {
return "dlygo.used";
}
constructor(arg: RpcDlygoUsedRequest[]) {
super();
this.Data = arg;
}
}
// #endregion
// #region Type
export type TDlygoItem = [
dataType: DlygoDataType,
productId: number,
productName: string,
productDisplayName: string,
productSerialNumber: string,
expiryDate: number,
prizeRedemptionTime: number,
]
export type TDlygoList = [
id: number,
name: string,
price: number,
discountPrice: number,
tag: DlygoTag,
remainQuantity: number,
dayLimitAmount: number,
];
export type TDlygoSN = {
/** 本日已兌換數量 */
q: number,
/** 說明1 */
c1: string,
/** 說明2 */
c2: string,
}
export type TDlygoRedeem = [TDlygoItem, ResourceInfo[]]
export type TDlygoExchange = [TDlygoItem, ResourceInfo[]]
export type TDlygoLog = [
dataType: DlygoDataType,
productId: number,
productName: string,
productDisplayName: string,
productSerialNumber: string,
expiryDate: number,
time: number,
]
export type TDlygoUsed = {
/** 使用時間 */
t: number,
}
// #endregion
// #region Server Error Enum
export enum DlygoRedeemStatus {
NotEnough = 11,
NoMoney = 12,
ExceededDailyLimit = 13,
DBError = 14,
PriceUpdated = 15,
}
export enum DlygoExchangeStatus {
NoMoney = 11,
DBError = 12,
}
export enum DlygoUsedStatus {
DBError = 11,
}
// #endregion
// #region Enum
export enum DlygoMainType {
/** 點子點數 */
Point = 1,
/** 精緻餐飲 */
Food = 2,
/** 超商禮券 */
Seven = 3,
/** 生活百貨 */
Shop = 4,
/** 其他品項 */
Other = 5,
/** Coin */
Coin = 99
}
export enum DlygoDataType {
/** 商品 */
Product = 1,
/** 金幣 */
Coin = 2,
}
export enum DlygoTag {
None,
New,
Popular,
SpecialOffer,
}
// #endregion

View File

@ -0,0 +1,108 @@
import { NetRequest } from "@/Engine/CatanEngine/NetManagerV2/NetRequest";
import { VipRequest } from "./VIPRequest";
export namespace FriendRequest {
export type SingleFriendData = [
aId: number,
nickname: string,
hasAvatar: 0 | 1,
vip: VipRequest.Level,
isOnline: 0 | 1,
]
export type ListFriendData = SingleFriendData[];
// =======================================================================================
/** 好友 朋友列表 協定 */
export class List extends NetRequest<null, ListFriendData> {
get Method(): string {
return "friend.allow_list";
}
constructor() {
super();
}
}
// =======================================================================================
export enum AddError {
Self = 11,
Exists,
PlayerNotExists,
IsDeny,
}
/** 好友 加好友 協定 */
export class Add extends NetRequest<number, JSON> {
get Method(): string {
return "friend.add_allow";
}
/**
* @param {number} aid aid
*/
constructor(aid: number) {
super();
this.Data = aid;
}
}
// =======================================================================================
/** 好友 刪除好友 協定 */
export class Del extends NetRequest<number, JSON> {
get Method(): string {
return "friend.del_allow";
}
/**
* @param {number} aid aid
*/
constructor(aid: number) {
super();
this.Data = aid;
}
}
// =======================================================================================
/** 好友 拒絕列表 協定 */
export class DenyList extends NetRequest<null, ListFriendData> {
get Method(): string {
return "friend.deny_list";
}
constructor() {
super();
}
}
// =======================================================================================
export enum DenyAddError {
Self = 11,
Exists = 12,
PlayerNotExists = 13,
IsAllow = 14,
}
/** 好友 加入拒絕列表 協定 */
export class DenyAdd extends NetRequest<number, JSON> {
get Method(): string {
return "friend.add_deny";
}
/**
* @param {number} aid aid
*/
constructor(aid: number) {
super();
this.Data = aid;
}
}
// =======================================================================================
/** 好友 刪除拒絕列表 協定 */
export class DenyDel extends NetRequest<number, JSON> {
get Method(): string {
return "friend.del_deny";
}
/**
* @param {number} aid aid
*/
constructor(aid: number) {
super();
this.Data = aid;
}
}
// =======================================================================================
}

View File

@ -0,0 +1,53 @@
import { ResourceItemType } from "@/Common/ResourceItem/ResourceItemType";
import { NetRequest } from "@/Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcGameLaunchRequest = number[]
export type RpcGameLaunchResponse = string
/** 廠商ID 遊戲ID */
export class GameLaunchRequest extends NetRequest<RpcGameLaunchRequest, RpcGameLaunchResponse> {
get Method(): string {
return "game.launch";
}
constructor(companyId: number, slotId: number) {
super();
this.Data = [
companyId,
slotId
];
}
}
export type RpcGameLeaveRequest = number
export type RpcGameLeaveResponse = null
export class GameLeaveRequest extends NetRequest<RpcGameLeaveRequest, RpcGameLeaveResponse> {
get Method(): string {
return "game.leave";
}
constructor(id: number) {
super();
this.Data = id;
}
}
export type RpcGameShareRewardRequest = null
export type RpcGameShareRewardResponse = TGameShareReward
export class GameShareReward extends NetRequest<RpcGameShareRewardRequest, RpcGameShareRewardResponse> {
get Method(): string {
return "game.share_reward";
}
constructor() {
super();
}
}
// #endregion
// #region Type
export type TGameShareReward = [ResourceType: ResourceItemType, Count: number]
// #endregion

View File

@ -0,0 +1,26 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export type GiftExchangeResponse = [nickName: string[], item: number[][]]
/** 禮包兌換 */
export class GiftExchange extends NetRequest<string, GiftExchangeResponse> {
get Method(): string {
return "gift.exchange";
}
constructor(serialNum: string) {
super();
this.Data = serialNum;
}
}
export enum GiftExchangeErrorType {
PlayerNotFound = 11,
PlayerDataIssue,
DatabaseNotFound,
SerialNumberUnavailable = 14,
InvalidSerialNumber,
SerialNumberRedeemed = 16,
ExchangeFailed,
SerialNumberNotFound,
ExceededExchangeLimit = 19,
Other,
}

View File

@ -0,0 +1,65 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export namespace MyCardRequest {
export interface ListData {
last: {
[id: string]: [type: string, productId: string];
};
items: {
[id: string]: [ID: number, price: number];
};
ingame: {
type: string;
items: [ID: number, ItemCode: string, price: number][];
};
point: string[];
freeMyCard: any[];
mobile: any[];
webAtm: any[];
creditCard: any[];
telecom: any[];
}
/**儲值品項清單 */
export class MyCardList extends NetRequest<any, ListData> {
get Method(): string {
return "my_card.info";
}
constructor() {
super();
}
}
// =======================================================================================
export interface TxnSend {
id: number;
paymentType?: string;
itemCode?: string;
/* 道具ID */
use?: number;
}
export type TxnGet = string;
/** MyCard 創建 */
export class Txn extends NetRequest<TxnSend, TxnGet> {
get Method(): string {
return "my_card.txn";
}
constructor(id: number, paymentType: string, itemCode: string, use: number) {
super();
this.Data = JSON.parse("{}");
this.Data["id"] = id;
if (paymentType !== null) {
this.Data["paymentType"] = paymentType;
}
if (itemCode !== null) {
this.Data["itemCode"] = itemCode;
}
if (use !== 0) {
this.Data["use"] = use;
}
}
}
// =======================================================================================
}

View File

@ -0,0 +1,29 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcPaSyncRequest = null
export type RpcPaSyncResponse = TPaSync[]
export class PaSyncRequest extends NetRequest<RpcPaSyncRequest, RpcPaSyncResponse> {
get Method(): string {
return "pa.sync";
}
constructor() {
super();
}
}
// #endregion
// #region Type
export type TPaSync = [
id: number,
title: string,
content: string,
startTime: number,
remainTime: number,
];
// #endregion

View File

@ -0,0 +1,72 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
import { Role } from "./ChatRequest";
export namespace ProfileRequest {
// =======================================================================================
export type InfoRequest = number;
export interface InfoResponse {
aId: number
name: string
msg: string
money: number
lp: number
vip: number
phone: string
avatar: 0 | 1
}
export enum InfoError {
NoPlayer = 11,
}
/** 個人資訊 */
export class Info extends NetRequest<InfoRequest, InfoResponse> {
get Method(): string {
return "profile.info";
}
constructor(aid: number) {
super();
this.Data = aid;
}
}
// =======================================================================================
/**修改暱稱 */
export class ChangeName extends NetRequest<string, null> {
get Method(): string {
return "profile.name";
}
constructor(name: string) {
super();
this.Data = name;
}
}
// =======================================================================================
/**修改自介 */
export class ChangeMsg extends NetRequest<string, null> {
get Method(): string {
return "profile.msg";
}
constructor(message: string) {
super();
this.Data = message;
}
}
// =======================================================================================
export enum MInfoType {
/** 聊天 */
Chat = 1
}
export interface MInfoResponse {
aID: MInfoData
}
export type MInfoData = [role: Role, name: string, avatar: 0 | 1, vip: number]
/**多人資訊 */
export class MInfo extends NetRequest<any, MInfoResponse> {
get Method(): string {
return "profile.m_info";
}
constructor(MInfoType: number, aIDs: number[]) {
super();
this.Data = [MInfoType, aIDs];
}
}
// =======================================================================================
}

View File

@ -0,0 +1,11 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export class RankInfo extends NetRequest<number, JSON> {
get Method(): string {
return "rank.info";
}
constructor(Type: number) {
super();
this.Data = Type;
}
}

View File

@ -0,0 +1,132 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
// =======================================================================================
/** 通用回傳SERVER創的遊戲帳號 */
export interface CommonAccountResponse {
id: string;
pw: string;
}
// =======================================================================================
/** 電話確認 */
export class PhoneCheck extends NetRequest<PhoneCodeRequest, string> {
get Method(): string {
return "register.phone_check";
}
constructor(p: string) {
super();
this.Data = {
p: p
};
}
}
/** 電話驗證 */
export interface PhoneCodeRequest {
p: string;
}
export class PhoneCode extends NetRequest<PhoneCodeRequest, string> {
get Method(): string {
return "register.phone_code";
}
constructor(p: string) {
super();
this.Data = {
p: p
};
}
}
export interface PhoneBindRequest {
c: string;
}
export class PhoneBind extends NetRequest<PhoneBindRequest, string> {
get Method(): string {
return "register.phone_bind";
}
constructor(c: string) {
super();
this.Data = {
c: c
};
}
}
// =======================================================================================
/** 旗標更新 */
export class FlagOpenAdd extends NetRequest<number, string> {
get Method(): string {
return "flag.open_add";
}
constructor(type: number) {
super();
this.Data = type;
}
}
// ========================================================================================
export interface ForgotInfo {
a: string;
p: string;
}
/** 忘記密碼 */
export class ForgotPassword extends NetRequest<ForgotInfo, null> {
get Method(): string {
return "register.account_forget";
}
constructor(account: string, phone: string) {
super();
this.Data = {
a: account,
p: phone,
};
}
}
export interface ChangePasswordInfo {
a: string;
opw: string;
pw: string;
}
/** 修改密碼 */
export class ChangePassword extends NetRequest<ChangePasswordInfo, null> {
get Method(): string {
return "register.account_change";
}
constructor(account: string, prePassword: string, password: string) {
super();
this.Data = {
a: account,
opw: prePassword,
pw: password
};
}
}
// =======================================================================================
export interface LineBindResponse {
n: string;
}
export class LineBind extends NetRequest<string, LineBindResponse> {
get Method(): string {
return "register.line_bind";
}
constructor(token: string) {
super();
this.Data = token;
}
}
/** LINE登入(回傳SERVER帳號) */
export class LineLoginRequest extends NetRequest<string, CommonAccountResponse> {
get Method(): string {
return "register.line_login";
}
constructor(token: string) {
super();
this.Data = token;
}
}
// =======================================================================================

View File

@ -0,0 +1,50 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export namespace ReportRequest {
// =======================================================================================
export enum ReportPlayerType {
Report = 1,
}
export enum ReportPlayerError {
Self = 11,
PlayerNotExists,
MessageLength,
Dba,
System,
}
/** 檢舉 */
export class ReportPlayer extends NetRequest<any, null> {
get Method(): string {
return "report.player";
}
constructor(id: number, t: number, m: string) {
super();
this.Data = [id, t, m];
}
}
// =======================================================================================
/** 回報記錄 */
export class ReportList extends NetRequest<null, JSON> {
get Method(): string {
return "report.list";
}
constructor() {
super();
}
}
// =======================================================================================
export class UpLoadToken extends NetRequest<number, JSON> {
constructor(type: number) {
super();
this.Data = type;
}
get Method(): string {
return "upload.token";
}
}
// =======================================================================================
}

View File

@ -0,0 +1,19 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
/** WEB更新資源 */
export class RefreshMoneyRequest extends NetRequest<null, number> {
get Method(): string {
return "res.money";
}
}
export class ResCustomUpdateRequest extends NetRequest<any, null> {
get Method(): string {
return "resource.update";
}
constructor(index: number[]) {
super();
this.Data = [index];
}
}

View File

@ -0,0 +1,90 @@
import { ResourceInfo } from "@/define/resource";
import { NetRequest } from "@/Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcTaskInfoRequest = null
export type RpcTaskInfoResponse = TaskInfo[]
export class TaskInfoRequest extends NetRequest<RpcTaskInfoRequest, RpcTaskInfoResponse> {
constructor() {
super();
}
get Method(): string {
return "task.info";
}
}
export type RpcTaskLogRequest = null
export type RpcTaskLogResponse = TaskInfo[]
export class TaskLogRequest extends NetRequest<RpcTaskLogRequest, RpcTaskLogResponse> {
constructor() {
super();
}
get Method(): string {
return "task.log";
}
}
export type RpcTaskProcessRequest = {
act: number;
id: TaskAction;
};
export type RpcTaskProcessResponse = TaskInfo | null | ResourceInfo[]
export class TaskProcessRequest extends NetRequest<RpcTaskProcessRequest, RpcTaskProcessResponse> {
constructor(act: TaskAction, id: number) {
super();
this.Data = {
act,
id
};
}
get Method(): string {
return "task.process";
}
}
// #endregion
// #region Type
export type TaskInfo = [
taskType: TaskType,
taskID: number,
taskProgress: number[],
dailyTaskStatus: DailyTaskStatus[],
receiveTaskTime: number,
taskStatus: TaskStatus | undefined
];
// #endregion
// #region Enum
export enum TaskType {
Normal = 1,
Advance
}
export enum DailyTaskStatus {
NotYetStarted,
Success,
Failure,
InProgress
}
export enum TaskStatus {
Completed = 1,
Failure,
GiveUp,
InProgress
}
export enum TaskAction {
TakeTask,
GiveUp,
Complete
}
// #endregion

View File

@ -0,0 +1,413 @@
import { ResourceItemType } from "@/Common/ResourceItem/ResourceItemType";
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export namespace TxnRequest {
/**贈禮資訊 */
export type TxnInfo = [
serialNum: number,
time: number,
giver: [aId: number, nickName: string],
receiver: [aId: number, nickName: string],
status: string,
fee: number,
goodsInfo: GoodsInfo[],
];
/**物品資訊 */
export type GoodsInfo = [
itemType: ResourceItemType,
id: number,
count: number
];
/**凍結資訊 */
export type FrozenInfo = [
time: number,
type: StoredValueType,
amount: number,
];
/**儲值類型(凍結類別) */
export enum StoredValueType {
StoredValue = 1, // wait for notifications on web functions
StoredValueBonus,
RewardsSharing,
PackageSerialNumber,
BindingRewards,
InitialGoldCoins,
FortuneGold,
Family,
Backpack,
LineFriend
}
/**贈禮狀態 */
export enum Status {
Applying = 0,
GiverGift = 1,
Authentication = 2,
Receive = 3,
Cancel = 11,
Reject = 12,
Timeout = 13,
Done = 21,
CancelComplete = 22,
RefuseComplete = 23,
TimeoutComplete = 24,
Unknown = 25,
}
/**常用名單玩家資訊 */
export type PlayerInfo = [
aId: number,
nickName: string,
vip: number,
/**上線狀態(0: 離線, 1: 在線) */
onlineStatus: 0 | 1,
];
/**個人贈禮可使用額度 */
export interface UsageQuotaSelf {
/**可送數量 */
msm: number;
/**可送額度 */
sm: number;
/**可送次數 */
sc: number;
/**凍結總額 */
fm: number;
}
// =======================================================================================
/**贈禮中心 */
export class Center extends NetRequest<null, TxnInfo[]> {
get Method(): string {
return "txn.center";
}
constructor() {
super();
}
}
// =======================================================================================
/**個人贈禮資訊 */
export class GetInfoSelf extends NetRequest<null, UsageQuotaSelf> {
get Method(): string {
return "txn.info";
}
constructor() {
super();
}
}
// =======================================================================================
enum GetFrozenInfoError {
PhoneNotBound = 11,
GiftGivingPunishment,
GettingGiftInfoError,
StatusError,
OTPRequestTimeTooShort,
OTPSendingFailed,
}
/**凍結資訊 */
export class GetFrozenInfo extends NetRequest<null, FrozenInfo[]> {
get Method(): string {
return "txn.frozen";
}
constructor() {
super();
}
}
// =======================================================================================
enum CreateNewError {
giftGivingPunishment = 11,
UnboundMobilePhone,
Unloaded,
TargetNotExist,
OnTargetGiftPenalty,
TargetVIPLevel,
TargetAIDError,
AimIsPlayerItsSelf,
ExceededNumbersOfGifts,
GiftItems_resource,
GiftItems_json_resource,
MoneyMistakes,
InsufficientAmount,
ExceedingAvailableGiftAmount,
BuildFailed,
FailedGettingTargetCache,
}
interface CreateNewRequest {
a?: number;
n?: string;
i: GoodsInfo[];
f?: CreateNewFlagType;
}
export enum CreateNewFlagType {
/**新增常用名單 */
AddFrequentlyUsedList,
}
/**建立贈禮 */
export class CreateNew extends NetRequest<CreateNewRequest, TxnInfo> {
get Method(): string {
return "txn.new";
}
constructor(name: string, i: GoodsInfo[], flag?: CreateNewFlagType) {
super();
this.Data = {
n: name,
i: i,
f: flag
};
}
}
// =======================================================================================
interface TradeRequest {
/**流水號 */
id: number;
/**操作類型 */
t: TradeOperationType;
/**密碼 */
c?: string;
}
/**贈禮操作類型 */
export enum TradeOperationType {
/**同意(收禮方) */
Agree_Receiver = 1,
/**認證(贈禮方) */
Authentication_Giver,
/**取得(收禮方) */
Obtain_Receiver,
/**取回(贈禮方) */
Retrieve_Giver,
/**取消(贈禮方) */
Cancellation_Giver,
/**拒絕(收禮方) */
Reject_Receiver,
}
export interface TradeResponse {
id: number;
s: Status;
p: GoodsInfo[];
}
export enum TradeError {
TargetGiftInPenalty = 11,
GiftInPenalty,
GiftNotExist,
OperationError,
WrongPassword,
}
/**贈禮操作 */
export class Trade extends NetRequest<TradeRequest, TradeResponse> {
get Method(): string {
return "txn.trade";
}
constructor(txn: number, type: TradeOperationType, c?: string) {
super();
this.Data = {
id: txn,
t: type,
c: c,
};
}
}
// =======================================================================================
/**贈禮常用名單 */
export class GetUserList extends NetRequest<null, PlayerInfo[]> {
get Method(): string {
return "txn.user_list";
}
constructor() {
super();
}
}
// =======================================================================================
export type UserAddResponse = {
u: PlayerInfo;
/*
* AID
* */
r?: number;
};
export enum UserAddError {
TargetIsUserItsSelf = 11,
TargetHasAlreadyBeenExist,
VIPLevel,
TargetNotExist,
}
/**增加常用名單 */
export class UserAdd extends NetRequest<{ n: string }, UserAddResponse> {
get Method(): string {
return "txn.user_add";
}
constructor(nickName: string) {
super();
this.Data = {
n: nickName
};
}
}
// =======================================================================================
export enum UserDelError {
TargetIsUserItsSelf = 11,
TargetHasNotExist,
}
/**移除常用名單 */
export class UserDel extends NetRequest<{ a: number }, null> {
get Method(): string {
return "txn.user_del";
}
constructor(aid: number) {
super();
this.Data = {
a: aid
};
}
}
// =======================================================================================
interface AuthCodeResquest {
id: number
}
export interface AuthCodeResponse {
t: number;
c: string;
}
export enum CodeError {
PhoneNotBound = 11,
GiftGivingPunishment,
GettingGiftInfoError,
StatusError,
OTPRequestTimeTooShort,
OTPSendingFailed,
}
/**請SERVER發送贈禮的簡訊OPT認證碼(未設定贈禮密碼) */
export class AuthCode extends NetRequest<AuthCodeResquest, AuthCodeResponse> {
get Method(): string {
return "txn.code";
}
constructor(txn: number) {
super();
this.Data = {
id: txn,
};
}
}
// =======================================================================================
export enum SetPassWordError {
PasswordHasBeenSet = 11,
PhoneNotBound,
OTPError,
}
/**設定贈禮密碼(簡訊OTP驗證建立新密碼) */
export class SetPassWord extends NetRequest<{ pw: string; c: string; }, null> {
get Method(): string {
return "txn.pw";
}
constructor(pw: string, c: string) {
super();
this.Data = {
pw: pw,
c: c
};
}
}
// =======================================================================================
enum ChangePassWordError {
PasswordNotSet = 11,
PhoneNotBound,
WrongPasswordFormat,
PasswordAuthenticationFailed,
}
/**變更贈禮密碼 */
export class ChangePassWord extends NetRequest<{ opw: string; pw: string; }, null> {
get Method(): string {
return "txn.pw_change";
}
constructor(opw: string, pw: string) {
super();
this.Data = {
opw: opw,
pw: pw
};
}
}
// =======================================================================================
export enum GiftForgotError {
PasswordHasNotBeenSetYet = 11,
PhoneNotBound,
OTPError,
}
/**忘記密碼(簡訊OTP驗證建立新密碼) */
export class GiftForgot extends NetRequest<{ pw: string; c: string; }, null> {
get Method(): string {
return "txn.pw_fg";
}
constructor(pw: string, c: string) {
super();
this.Data = {
pw: pw,
c: c
};
}
}
// =======================================================================================
interface GetPassWordResponse {
t: number;
c: string;
}
export enum GetPassWordError {
PasswordHasBeenSet = 11,
PhoneNotBound,
OTPRequestTimeTooShort,
OTPSendingFailed,
}
/**取得贈禮密碼OTP */
export class GetPassWord extends NetRequest<null, GetPassWordResponse> {
get Method(): string {
return "txn.pw_code";
}
constructor() {
super();
}
}
// =======================================================================================
interface GetForgotPassWordResponse {
t: number;
c: string;
}
export enum GetForgotPassWordError {
PasswordHasNotBeenSetYet = 11,
PhoneNotBound,
OTPRequestTimeTooShort,
OTPSendingFailed,
}
/**取得贈禮忘記密碼OTP */
export class GetForgotPassWord extends NetRequest<null, GetForgotPassWordResponse> {
get Method(): string {
return "txn.pw_fg_code";
}
constructor() {
super();
}
}
// =======================================================================================
/**贈禮紀錄 */
export class Record extends NetRequest<null, TxnInfo[]> {
get Method(): string {
return "txn.record";
}
constructor() {
super();
}
}
// =======================================================================================
enum GetListError {
NotExist = 11,
}
/**取得贈禮品項 */
export class GetTxnList extends NetRequest<{ t: number[] }, TxnInfo[]> {
get Method(): string {
return "txn.get";
}
constructor(txn: number[]) {
super();
this.Data = {
t: txn,
};
}
}
// =======================================================================================
}

View File

@ -0,0 +1,66 @@
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
export namespace VipRequest {
export enum Level {
Iron = 1,
Copper,
Silver,
Gold,
Platinum,
Diamond,
}
// =======================================================================================
export interface InfoResponse {
/** vip 等級 */
level: Level,
/** [次數, 時間], */
rich: number[],
/** 當前下注(前一個月+當月) */
bet: number,
/** 當前儲值(前一個月+當月) */
sv: number,
/** 剩餘時間 */
et: number,
}
export class VIPInfo extends NetRequest<null, InfoResponse> {
get Method(): string {
return "vip.info";
}
constructor() {
super();
}
}
// =======================================================================================
export class VIPLevel extends NetRequest<null, number> {
get Method(): string {
return "vip.level";
}
constructor() {
super();
}
}
// =======================================================================================
export class VIPRich extends NetRequest<null, JSON> {
get Method(): string {
return "vip.rich";
}
constructor() {
super();
}
}
// =======================================================================================
export class VIPMonth extends NetRequest<null, JSON> {
get Method(): string {
return "vip.month";
}
constructor() {
super();
}
}
// =======================================================================================
}

View File

@ -7,16 +7,17 @@ import type { Router } from "@remix-run/router";
import dayjs from "dayjs";
import "dayjs/locale/zh-tw";
import ReactDOM from "react-dom/client";
import { RouterProvider, createHashRouter } from "react-router-dom";
import { RouterProvider, createBrowserRouter, createHashRouter } from "react-router-dom";
import { BaseEnumerator } from "./Engine/CatanEngine/CoroutineV2/Core/BaseEnumerator";
import Game from "./UI/Game";
import Lobby from "./UI/Lobby";
import Login from "./UI/Login";
import "./index.css";
import "./utils/catan";
BaseEnumerator.Init();
dayjs.locale("zh-tw");
const hashRouter: Router = createHashRouter([
const router = [
{
path: "/",
element: <Login />,
@ -29,10 +30,12 @@ const hashRouter: Router = createHashRouter([
path: "/game/:id",
element: <Game />,
},
]);
];
const browserRouter: Router = createBrowserRouter(router);
const hashRouter: Router = createHashRouter(router);
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<GameItemsProvider>
<RouterProvider router={hashRouter} />
<RouterProvider router={browserRouter} />
</GameItemsProvider>
);

View File

@ -1,7 +1,10 @@
import { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import { PlayerData } from "@/define/playerData";
export interface IGameItems {
onLoad: (serverType: BusinessEnum.ServerType) => Promise<void>;
gameId: number;
setGameId: (gameId: number) => void;
setGameId: (v: number) => void;
player: PlayerData;
setPlayer: (v: PlayerData) => void;
}