初始化 Line_Project_Bot:LP_Bot 重構版(介面重設計+平台環境改讀試算表)

根本原因:
LP_Bot 介面老舊且環境設定寫死在程式內,新增平台或環境都要改碼重建。

影響:
全新深色控制台介面;首頁改為「平台+環境+Token」,平台清單與連線設定
即時讀取 Google 試算表(quickopen 同款資料來源),選擇與 Token 會記憶於
localStorage;支援「開遊戲」直開跳過維護網址;SD 機台自製 Spin 面板
(押注/延遲/倍率停/轉數停+Log 終端)。

修法:
- 底層引擎(Engine/Common/define/FormTable*)自 LP_Bot 原封搬移
- UI 層全部重寫(Login/Lobby/SlotList/SDGame),antd 深色主題
- 新增 GoogleSheetService:service account 簽 JWT 讀 Sheets API,
  非安全來源 fallback jsrsasign
- 移除 React.StrictMode(雙重掛載會讓 NetManagerSD 單例連線互蓋)
- SD socket 依 gameUrl 協定強制 wss
- 機台 1310/1311/1801/1803/1804/1805 Spin 帶 mode:0 特例
  (依 SD3 客戶端 MainState 原始碼)
- credentials.json 不進版控,附 credentials.example.json 範本

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 11:04:49 +08:00
co-authored by Claude Fable 5
commit ebe8c3caca
445 changed files with 42552 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
export * from "../Slot1";
export * from "../Slot1201";
export * from "../Slot1302";
export * from "../Slot1305";
export * from "../Slot1306";
export * from "../Slot1310";
export * from "../Slot1311";
export * from "../Slot1801";
export * from "../Slot1803";
export * from "../Slot1804";
export * from "../Slot1805";
export * from "../Slot32";
export * from "../Slot34";
export * from "../Slot48";
export * from "../Slot50";
export * from "../Slot62";
export * from "../Slot64";
export * from "../Slot65";
export * from "../Slot66";
export * from "../Slot70";
export * from "./SlotBase";
+203
View File
@@ -0,0 +1,203 @@
import CSMessage from "@/Common/Message/CSMessage";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import CSSettingsSDV3 from "@/FormTableSD/CSSettingsSDV3";
import { gameObj } from "@/context/GameItemsContext";
import GameManager from "@/modules/GameManager";
import { NumberEx } from "@/utils/Number/NumberEx";
import { CommonSlotAERequest, CommonSlotFgSpinRequest, CommonSlotSpinRequest } from "../Request/CommonSlotRequest";
import { Slot_ChoiceRequest } from "../Request/SlotRequest";
export class SlotBase {
//#region public
public get ID(): number { return this.id; }
public get FreeID(): number { return 1; }
public get FreeCount(): number { return +this.GameRunData["free"][1]; }
public get HasChoiceFreeGame(): boolean { return false; }
public get SlotReqRespIsCount(): boolean { return false; }
public get HasRetriggerFreeSpin(): boolean { return false; }
/** Spin協定的mode欄位(null=不帶, Cluster系列機台需帶0) */
public get SpinMode(): number { return null; }
public GameRunData: JSON = null;
//#endregion
//#region protected
protected id: number;
//#endregion
//#region private
private addLog: (v: string) => void;
//#endregion
//#region Lifecycle
/**
*
*/
constructor(id: number, addLog: (v: string) => void) {
this.id = id;
this.addLog = addLog;
this.onLoad();
}
public async onLoad(): Promise<void> {
//
}
//#endregion
//#region Custom
public *Spin(bet: number, OnClickStop: () => void): IterableIterator<any> {
const { player, setPlayer } = gameObj;
let gameRunData: JSON = null;
let req: CommonSlotSpinRequest = new CommonSlotSpinRequest(this.id, bet, this.SpinMode);
yield req.SendAsync();
let resp: INetResponse<JSON> = req.Result;
if (resp.IsValid) {
gameRunData = this.GameRunData = resp.Data;
} else {
CSMessage.NetError(resp.Method, resp.Status);
this.addLog(`Slot${this.ID} Spin失敗 [${resp.Method}] status:${resp.Status}`);
OnClickStop();
return;
}
let money: number = gameRunData["money"] ? +gameRunData["money"] : 0;
let winMoney: number = 0;
let winMoneyLog: string = "";
let freeLog: string = "";
let resources: any[] = gameRunData["get"];
let free: any = gameRunData["free"];
let choiceFreeGame: boolean = gameRunData["rs"] === 0;
if (resources) {
winMoney = this._getWinMoney(resources);
}
if (choiceFreeGame && this.HasChoiceFreeGame) {
free = true;
}
if (free) {
let freeCount: number = yield* this._getFreeCount();
let fsWinMoney: number = 0;
let fsMoney: number = 0;
[freeCount, fsWinMoney, fsMoney] = yield* this.FreeSpin(freeCount);
if (fsMoney > 0) {
money = fsMoney;
}
if (fsWinMoney > 0) {
winMoney = fsWinMoney;
}
freeLog = `, hasFree: ${freeCount}`;
}
if (winMoney > 0) {
winMoneyLog = `, winMoney: ${winMoney}`;
}
setPlayer({ ...player, m: money });
let ratio: number = winMoney > 0 ? NumberEx.divide(winMoney, GameManager.SlotData.NowBet) : 0;
if (GameManager.SlotData.IsRatioStop && ratio >= GameManager.SlotData.RatioStop) {
OnClickStop();
}
if (GameManager.SlotData.IsCountStop && GameManager.SlotData.CountStop === 0) {
OnClickStop();
}
if (ratio > 100) {
this.addLog(`Slot${this.ID} Spin Bet: ${GameManager.SlotData.NowBet}, Money: ${money}${winMoneyLog}${freeLog}, Ratio: ${ratio}`);
}
this.addLog(`Slot${this.ID} Spin Bet: ${GameManager.SlotData.NowBet}, Money: ${money}${winMoneyLog}${freeLog}`);
if (ratio > 0) {
this.slotAE();
}
}
public * FreeSpin(freeCount: number) {
let fsWinMoney: number = 0;
let fsMoney: number = 0;
for (let i: number = 0; i < freeCount; i++) {
let gameRunData: JSON = null;
let req: CommonSlotFgSpinRequest = new CommonSlotFgSpinRequest(this.ID);
yield req.SendAsync();
let resp: INetResponse<JSON> = req.Result;
if (resp.IsValid) {
gameRunData = resp.Data;
if (this.HasRetriggerFreeSpin) {
let reTriggerCount: number = this._getRetriggerFreeSpinCount(gameRunData);
freeCount += reTriggerCount;
}
if (i === freeCount - 1) {
let resources: any[] = gameRunData["get"];
if (resources) {
fsWinMoney = this._getWinMoney(resources);
}
fsMoney = gameRunData["money"] ? +gameRunData["money"] : 0;
}
} else {
CSMessage.NetError(resp.Method, resp.Status);
}
this.addLog(`Slot${this.ID} FreeSpin MaxCount: ${freeCount}, Count: ${i + 1}`);
}
return [freeCount, fsWinMoney, fsMoney];
}
protected _getWinMoney(resources: any[]): number {
for (let i: number = 0; i < resources.length; i++) {
const resource: any[] = resources[i];
if (resource[0] === 1) {
return resource[1];
}
}
return 0;
}
protected _getRetriggerFreeSpinCount(gameRunData: JSON): number {
if (gameRunData["free"]) {
return gameRunData["free"][1];
}
return 0;
}
protected *_getFreeCount() {
if (this.HasChoiceFreeGame) {
return yield* this._getChoiceFreeCount();
} else {
return this.FreeCount;
}
}
protected * _getChoiceFreeCount() {
let id: number = this._getFreeID();
let request: Slot_ChoiceRequest = new Slot_ChoiceRequest(id);
yield request.SendAsync(true);
let result: INetResponse<number> = request.Result;
if (result.IsValid) {
if (this.SlotReqRespIsCount) {
return result.Data;
} else {
let slotNameSetting: string = CSSettingsSDV3.Slotset[this.ID].NameSetting;
let free_info_id: number = result.Data;
let slotSetting: any = CSSettingsSDV3[slotNameSetting];
let freeInfo: any = slotSetting.FreeInfo;
let count: number = freeInfo[free_info_id].Spins;
return count;
}
}
return 0;
}
protected _getFreeID(): number {
return this.FreeID;
}
private slotAE(): void {
let req: CommonSlotAERequest = new CommonSlotAERequest();
req.Send();
}
//#endregion
}
export default SlotBase;
@@ -0,0 +1,93 @@
//=======================================================================================
import { NetRequestSD } from "../../../Engine/CatanEngine/NetManagerV2/NetRequestSD";
/**共用MAIN SPIN協定 */
export interface SpinRequest {
pay: number;
/** Cluster系列機台必帶(0=一般Spin) */
mode?: number;
}
export class CommonSlotSpinRequest extends NetRequestSD<SpinRequest, JSON> {
private _id: number = 0;
get Method(): string {
return "slot" + this._id + ".spin";
}
constructor(slotId: number, totalBet: number, mode: number = null) {
super();
this._id = slotId;
this.Data = {
pay: totalBet,
};
if (mode !== null && mode !== undefined) {
this.Data.mode = mode;
}
}
}
//=======================================================================================
export class CommonSlotFgSpinRequest extends NetRequestSD<any, JSON> {
private _id: number = 0;
get Method(): string {
return "slot" + this._id + ".fgspin";
}
constructor(slotId: number) {
super();
this._id = slotId;
}
}
//=======================================================================================
export class CommonSlotCollectUnlockRequest extends NetRequestSD<any, JSON> {
private _id: number = 0;
get Method(): string {
return "collect" + this._id + ".unlock";
}
constructor(slotId: number, grid: number) {
super();
this._id = slotId;
this.Data = {
Grid: grid,
};
}
}
//=======================================================================================
export class CommonSlotCollectSpinRequest extends NetRequestSD<any, JSON> {
private _id: number = 0;
get Method(): string {
return "collect" + this._id + ".spin";
}
constructor(slotId: number) {
super();
this._id = slotId;
}
}
//=======================================================================================
/**賓果 ChangeSet協定 */
export class CommonBingoChangeSet extends NetRequestSD<any, JSON> {
private _id: number = 0;
get Method(): string {
return "slot" + this._id + ".chset";
}
constructor(slotId: number) {
super();
this._id = slotId;
}
}
//=======================================================================================
/** 動畫結束通知 */
export class CommonSlotAERequest extends NetRequestSD<null, null> {
get Method(): string {
return "slot.ae";
}
constructor() {
super();
}
}
//=======================================================================================
+78
View File
@@ -0,0 +1,78 @@
import { NetRequestSD } from "@/Engine/CatanEngine/NetManagerV2/NetRequestSD";
//=======================================================================================
interface ChoiceRequest {
}
/**五龍選擇協定 */
export class Slot_ChoiceRequest extends NetRequestSD<ChoiceRequest, number> {
get Method(): string {
return "slot.req";
}
constructor(id: number) {
super();
this.Data = id;
}
}
//=======================================================================================
interface GmRequest {
pay: number;
slot: string;
type: number;
}
export class Slot_GMRequest extends NetRequestSD<GmRequest, JSON> {
get Method(): string {
return "slot.gm";
}
get MethodBack(): string {
return "slot" + this._id + ".spin";
}
private _id: number = 1;
constructor(id: number, totalBet: number, symbols: string, type: number) {
super();
this._id = id;
this.Data = {
pay: totalBet,
slot: symbols,
type: type,
};
}
}
//=======================================================================================
export class Bingo_GMRequest extends NetRequestSD<GmRequest, JSON> {
get Method(): string {
return "bingo.gm";
}
get MethodBack(): string {
return "slot" + this._id + ".spin";
}
private _id: number = 0;
constructor(id: number, totalBet: number, bingos: string, type: number) {
super();
this._id = id;
this.Data = {
pay: totalBet,
slot: bingos,
type: type,
};
}
}
//=======================================================================================
/**前後端金額對不上協定 */
export class Slot_ErrorRequest extends NetRequestSD<any, JSON> {
get Method(): string {
return "slot.error";
}
constructor() {
super();
}
}
//=======================================================================================
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot1 extends SlotBase {
//#region public
public get ID(): number { return 1; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot1;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot1201 extends SlotBase {
//#region public
public get FreeCount(): number { return +this.GameRunData["free"]; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot1201;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot1302 extends SlotBase {
//#region public
public get ID(): number { return 1302; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot1302;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot1305 extends SlotBase {
//#region public
public get ID(): number { return 1305; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot1305;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot1306 extends SlotBase {
//#region public
public get ID(): number { return 1306; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot1306;
+15
View File
@@ -0,0 +1,15 @@
import SlotBase from "./Base/SlotBase";
export class Slot1310 extends SlotBase {
//#region public
public get ID(): number { return 1310; }
public get HasRetriggerFreeSpin(): boolean { return true; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1310;
+15
View File
@@ -0,0 +1,15 @@
import SlotBase from "./Base/SlotBase";
export class Slot1311 extends SlotBase {
//#region public
public get ID(): number { return 1311; }
public get HasRetriggerFreeSpin(): boolean { return true; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1311;
+14
View File
@@ -0,0 +1,14 @@
import SlotBase from "./Base/SlotBase";
export class Slot1801 extends SlotBase {
//#region public
public get ID(): number { return 1801; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1801;
+14
View File
@@ -0,0 +1,14 @@
import SlotBase from "./Base/SlotBase";
export class Slot1803 extends SlotBase {
//#region public
public get ID(): number { return 1803; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1803;
+14
View File
@@ -0,0 +1,14 @@
import SlotBase from "./Base/SlotBase";
export class Slot1804 extends SlotBase {
//#region public
public get ID(): number { return 1804; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1804;
+14
View File
@@ -0,0 +1,14 @@
import SlotBase from "./Base/SlotBase";
export class Slot1805 extends SlotBase {
//#region public
public get ID(): number { return 1805; }
/** Spin協定需帶mode:0 */
public get SpinMode(): number { return 0; }
//#endregion
}
export default Slot1805;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot32 extends SlotBase {
//#region public
public get ID(): number { return 32; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot32;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot34 extends SlotBase {
//#region public
public get ID(): number { return 34; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot34;
+16
View File
@@ -0,0 +1,16 @@
import SlotBase from "./Base/SlotBase";
export class Slot48 extends SlotBase {
//#region public
public get ID(): number { return 48; }
public get FreeID(): number { return 3; }
public get HasChoiceFreeGame(): boolean { return true; }
public get SlotReqRespIsCount(): boolean { return true; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot48;
+15
View File
@@ -0,0 +1,15 @@
import SlotBase from "./Base/SlotBase";
export class Slot50 extends SlotBase {
//#region public
public get ID(): number { return 50; }
public get FreeID(): number { return 1; }
public get HasChoiceFreeGame(): boolean { return true; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot50;
+31
View File
@@ -0,0 +1,31 @@
import SlotBase from "./Base/SlotBase";
export class Slot62 extends SlotBase {
//#region public
public get ID(): number { return 62; }
public get FreeID(): number { return 3; }
public get HasChoiceFreeGame(): boolean { return true; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
//#region Custom
protected _getFreeID(): number {
let gameRunData: JSON = this.GameRunData;
let scatterAmount: number = gameRunData["scatter"][0][0].length;
if (scatterAmount > 4) {
return 5;
} else if (scatterAmount > 3) {
return 4;
} else {
return this.FreeID;
}
}
//#endregion
}
export default Slot62;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot64 extends SlotBase {
//#region public
public get ID(): number { return 64; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot64;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot65 extends SlotBase {
//#region public
public get ID(): number { return 65; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot65;
+13
View File
@@ -0,0 +1,13 @@
import SlotBase from "./Base/SlotBase";
export class Slot66 extends SlotBase {
//#region public
public get ID(): number { return 66; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
}
export default Slot66;
+31
View File
@@ -0,0 +1,31 @@
import SlotBase from "./Base/SlotBase";
export class Slot70 extends SlotBase {
//#region public
public get ID(): number { return 70; }
public get FreeID(): number { return 3; }
public get HasChoiceFreeGame(): boolean { return true; }
public get HasRetriggerFreeSpin(): boolean { return true; }
//#endregion
//#region Custom
protected _getFreeID(): number {
let gameRunData: JSON = this.GameRunData;
let scatterAmount: number = gameRunData["scatter"][0][0].length;
if (scatterAmount > 4) {
return 5;
} else if (scatterAmount > 3) {
return 4;
} else {
return this.FreeID;
}
}
//#endregion
}
export default Slot70;
+9
View File
@@ -0,0 +1,9 @@
interface GameData {
slotData: SlotData[];
slotList: number[];
nowSlotId: number;
}
export type SlotData = [componyID: number, slotId: number, vip: number, status: number, tag: number]
export { type GameData };
+15
View File
@@ -0,0 +1,15 @@
interface PlayerData {
token: string;
aId: number;
f: number;
r: number;
rf: number;
name: string;
a: number;
m: number;
lp: number;
tr: number;
lct: number;
}
export { type PlayerData };
+28
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
+311
View File
@@ -0,0 +1,311 @@
import { NetRequestSD } from "@/Engine/CatanEngine/NetManagerV2/NetRequestSD";
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
// =======================================================================================
/** 通用回傳SERVER創的遊戲帳號 */
export interface CommonAccountResponse {
id: string;
pw: string;
}
// =======================================================================================
interface CreateResquest {
p: number;
d: string;
}
/** 直接玩(訪客給SERVER創帳號) */
export class AccountCreateRequest extends NetRequest<CreateResquest, CommonAccountResponse> {
get Method(): string {
return "account.create";
}
/*constructor() {
super();
this.Data = {
p: Config.GetRunDevice(),
d: LocalStorageData.Instance.ComboDeviceID,
};
}*/
}
// =======================================================================================
interface LoginRequest {
// p: number;
// d: string;
// fcm_token: string;
id: number;
pw: string;
pl: number;
// ver: string;
}
interface LoginResponse {
pr: string;
cu: string;
}
/** 通用登入 */
export class AccountLoginRequest extends NetRequest<LoginRequest, LoginResponse> {
get Method(): string {
return "account.login";
}
constructor(account: string, password: string, partner: string) {
super();
this.Data = {
id: +account,
pw: password,
pl: 3
};
if (partner) {
this.Data["pn"] = partner;
}
}
}
interface SDLoginRequest {
token: string;
}
export class SDAccountLoginRequest extends NetRequestSD<SDLoginRequest, LoginResponse> {
get Method(): string {
return "account.login";
}
constructor(token: string) {
super();
this.Data = {
token: token,
};
}
}
// =======================================================================================
interface CustomResquest {
a: string;
pw: string;
}
/** 自定帳號榜定 */
export class CustomBindRequest extends NetRequest<CustomResquest, null> {
get Method(): string {
return "register.account_bind";
}
constructor(account: string, password: string) {
super();
this.Data = {
a: account,
pw: password,
};
}
}
/** 自定帳號登入(回傳SERVER帳號) */
export class CustomLoginRequest extends NetRequest<string, CommonAccountResponse> {
get Method(): string {
return "register.account_login";
}
constructor(account: string) {
super();
this.Data = account;
}
}
// =======================================================================================
interface FBResquest {
t: string;
}
/** FB綁定 */
export class FBBindRequest extends NetRequest<FBResquest, null> {
get Method(): string {
return "register.fb_bind";
}
constructor(token: string) {
super();
this.Data = {
t: token,
};
}
}
/** FB登入(回傳SERVER帳號) */
export class FBLoginRequest extends NetRequest<FBResquest, CommonAccountResponse> {
get Method(): string {
return "register.fb_login";
}
constructor(token: string) {
super();
this.Data = {
t: token,
};
}
}
// =======================================================================================
interface GoogleResquest {
c: string;
}
/** GOOGLE綁定 */
export class GoogleBindRequest extends NetRequest<GoogleResquest, null> {
get Method(): string {
return "register.google_bind";
}
constructor(token: string) {
super();
this.Data = {
c: token,
};
}
}
/** GOOGLE登入(回傳SERVER帳號) */
export class GoogleLoginRequest extends NetRequest<GoogleResquest, CommonAccountResponse> {
get Method(): string {
return "register.google_login";
}
constructor(token: string) {
super();
this.Data = {
c: token,
};
}
}
// =======================================================================================
interface AppleResquest {
c: string;
}
/** APPEL綁定 */
export class AppleBindRequest extends NetRequest<AppleResquest, null> {
get Method(): string {
return "register.apple_bind";
}
constructor(token: string) {
super();
this.Data = {
c: token,
};
}
}
/** APPLE登入(回傳SERVER帳號) */
export class AppleLoginRequest extends NetRequest<AppleResquest, CommonAccountResponse> {
get Method(): string {
return "register.apple_login";
}
constructor(token: string) {
super();
this.Data = {
c: token,
};
}
}
// =======================================================================================
/** 電話確認 */
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 PhoneGet 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;
}
}
// =======================================================================================
+140
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
+98
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
+166
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
+108
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;
}
}
// =======================================================================================
}
+43
View File
@@ -0,0 +1,43 @@
import { NetRequest } from "@/Engine/CatanEngine/NetManagerV2/NetRequest";
// #region Request
export type RpcGamInfoResponse = JSON
export class GameInfoRequest extends NetRequest<null, RpcGamInfoResponse> {
get Method(): string {
return "game.info";
}
constructor() {
super();
}
}
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;
}
}
// #endregion
+26
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,
}
+65
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;
}
}
}
// =======================================================================================
}
+29
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
+72
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];
}
}
// =======================================================================================
}
+11
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;
}
}
+132
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;
}
}
// =======================================================================================
+50
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";
}
}
// =======================================================================================
}
+19
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];
}
}
+83
View File
@@ -0,0 +1,83 @@
import { NetRequestSD } from "@/Engine/CatanEngine/NetManagerV2/NetRequestSD";
import { LanguageManager } from "@/FormTableExt/Manage/Language/LanguageManager";
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
//=======================================================================================
/**取得歷史紀錄網頁網址協定 */
export class HistoryRequest extends NetRequest<any, JSON> {
get Method(): string {
return "history.url";
}
constructor(slotId: number) {
super();
this.Data = {
slot: slotId,
lang: LanguageManager.UseLanguageUrlStr,
};
}
}
//=======================================================================================
export class SlotInRequest extends NetRequestSD<any, JSON> {
get Method(): string {
return "slot.in";
}
constructor(slotid: number, hall: number = 0, uid: number = 0) {
super();
this.Data = {
id: slotid
};
}
}
//=======================================================================================
export class SlotOutRequest extends NetRequest<null, null> {
get Method(): string {
return "slot.out";
}
}
//=======================================================================================
export class FishOutRequest extends NetRequest<null, null> {
get Method(): string {
return "fish.out";
}
}
//=======================================================================================
export class TableOutRequest extends NetRequest<null, null> {
get Method(): string {
return "table.out";
}
}
//=======================================================================================
export class Table3002OutRequest extends NetRequest<any, JSON> {
get Method(): string {
return "two_sicbo.leave";
}
constructor() {
super();
}
}
//=======================================================================================
export class Table3003OutRequest extends NetRequest<any, JSON> {
get Method(): string {
return "nine_sicbo.leave";
}
constructor() {
super();
}
}
//=======================================================================================
export class Table3012OutRequest extends NetRequest<any, JSON> {
get Method(): string {
return "triple_baccarat.leave";
}
constructor() {
super();
}
}
//=======================================================================================
export class PinBallOutRequest extends NetRequest<null, null> {
get Method(): string {
return "pinball.out";
}
}
//=======================================================================================
+66
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();
}
}
// =======================================================================================
}