[add] rs 還要調整

This commit is contained in:
建喵 2024-08-30 18:17:09 +08:00
parent f8528713e6
commit 05cbd9daa9
20 changed files with 252 additions and 59 deletions

View File

@ -0,0 +1,29 @@
{
"slotData": [
{"slot":[10,9,4,5,7,11,5,6,8,6,6,5,9,6,9],"pay":[[1,-120]],"money":10017339},
{"slot":[11,1,5,3,11,4,13,6,8,8,5,5,9,4,5],"way":[[[10,11,2],60]],"pay":[[1,-120]],"get":[[1,60]],"money":10017519},
{"slot":[4,2,9,10,1,5,10,7,6,8,5,13,5,7,9],"way":[[[5,10,1,12],120]],"pay":[[1,-120]],"get":[[1,120]],"money":10017339},
{"slot":[7,7,7,10,11,6,7,7,11,10,6,9,6,5,5],"way":[[[0,1,6,2,7],120]],"pay":[[1,-120]],"get":[[1,120]],"money":10017459},
{"slot":[11,12,5,7,10,7,7,7,8,5,7,2,8,2,5],"way":[[[5,10,6,11,7,3,13],480]],"pay":[[1,-120]],"get":[[1,480]],"money":10017579},
{"slot":[4,8,5,10,10,5,5,5,5,5,5,6,11,5,5],"way":[[[5,10,6,2,7,8,13,9,14],4800]],"pay":[[1,-120]],"get":[[1,4800]],"money":10024359},
{"slot":[12,4,4,2,2,13,4,2,12,8,4,10,6,10,5],"way":[[[10,1,6,2,7,3,4],2400]],"pay":[[1,-120]],"get":[[1,2400]],"money":10019799},
{"slot":[6,1,7,10,8,12,10,1,9,5,1,8,6,6,11],"scatter":[[[10,1,7],240]],"pay":[[1,-120]],"rs":0},
{"slot":[6,1,7,10,8,12,10,1,9,5,1,8,6,1,11],"scatter":[[[10,1,7,13],600]],"pay":[[1,-120]],"rs":0},
{"slot":[1,2,5,11,1,11,11,1,2,12,6,4,6,9,13],"way":[[[10,1,12,8],60]],"scatter":[[[0,1,7,8,4],2400]],"pay":[[1,-120]],"rs":0}
],
"slotFreeData": [
{"slot":[12,8,13,9,8,7,3,7,10,3,8,9,13,4,13,9,9,12,11,9,1,4,1,12,10],"t":[[[5,6,21,7,13,9],3000,3]]},
{"slot":[11,9,12,10,12,11,1,12,12,10,5,9,13,6,12,12,10,13,7,11,6,10,1,13,12]},
{"slot":[10,1,5,13,13,1,13,3,5,5,11,13,13,13,8,8,7,12,8,13,11,13,11,2,8]},
{"slot":[12,1,13,12,9,1,11,4,1,4,8,9,13,13,9,3,10,11,12,12,8,6,11,6,11],"t":[[[15,21,7,23,9],120,7]]},
{"slot":[5,10,8,1,11,12,6,9,13,13,6,12,9,12,9,12,8,5,6,13,7,4,10,8,10],"t":[[[0,10,20,6,21,17,18],360,7]],"get":[[1,3720]],"money":10027449},
{"slot":[5,5,13,3,12,10,10,12,11,10,12,13,13,8,11,10,8,6,9,8,11,9,9,4,11,6,3,3,9,13],"t":[[[0,25,1,26,17,27,3,23],2400,4]]},
{"slot":[12,5,13,9,3,9,9,12,9,11,7,8,13,8,10,12,10,6,12,11,9,13,9,13,10,10,3,3,12,10],"way":[[[5,20,6,22,3,8],120]],"t":[[[10,1,26,17,27],120,7]]},
{"slot":[8,13,9,9,11,11,6,10,8,12,12,7,13,8,13,5,11,3,11,10,10,4,8,11,4,12,11,8,12,8],"t":[[[15,6,11,21,17],180,5]],"get":[[1,3420]],"money":10030749},
{"slot":[10,4,13,7,13,9,13,13,11,11,8,10,12,13,10,6,3,4,4,5,9,7,3,11,12,10,9,8,12,13,11,6,9,11,12,7,5,13,3,13],"way":[[[5,20,26,32],30]],"t":[[[15,35,1,16,21,31,36,17,22,3,18,38,19],9000,6]],"get":[[1,11490]],"money":10042119}
]
}

8
shared/jsons/slot70.json Normal file
View File

@ -0,0 +1,8 @@
{
"slotData": [
{"slot":[1,2,5,11,1,11,11,1,2,12,6,4,6,9,13],"way":[[[10,1,12,8],60]],"scatter":[[[0,1,7,8,4],2400]],"pay":[[1,-120]],"rs":0}
],
"slotFreeData": [
{"slot":[5,10,8,1,11,12,6,9,13,13,6,12,9,12,9,12,8,5,6,13,7,4,10,8,10],"t":[[[0,10,20,6,21,17,18],360,7]],"get":[[1,100]],"money":10027449}
]
}

View File

@ -1,6 +0,0 @@
// src/electron/NetConnector1.ts
export class NetConnector1 {
constructor() {
console.log("NetConnector instance created");
}
}

View File

@ -1,5 +1,7 @@
import path from 'path';
export const slotJsons: Map<number, any> = new Map();
export function getExternalJsonPath(filename: string): string {
if (process.env.NODE_ENV === 'dev') {
// 开发模式下使用相对路径

View File

@ -2,21 +2,48 @@ import { INetRequest } from "../../script/Engine/CatanEngine/NetManagerV2/Core/I
import { INetResponse } from "../../script/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { ClientData } from "../../shared/protocols/define/interface";
import { RpcSlot1SpinRequest, RpcSlot1SpinResponse } from "../../shared/protocols/Slot1Request";
import SlotSpinBase from "./SlotSpinBase";
export default abstract class SlotFgSpinBase {
export default abstract class SlotFgSpinBase extends SlotSpinBase {
public *fgspin(clientData: ClientData, req: INetRequest<RpcSlot1SpinRequest>): IterableIterator<any> {
const data: RpcSlot1SpinRequest = req.Data
const { count, freeData } = clientData.free;
yield* this.init(clientData);
// if (clientData.reqFree) {
// const { count, freeData } = clientData.free;
// const slotData: any = freeData[count];
// const response: INetResponse<RpcSlot1SpinResponse> = {
// Status: 0,
// Method: req.Method,
// Data: slotData,
// IsValid: true
// };
// clientData.free.count++;
// return response;
// }
const { nowFree, freeData } = clientData.free;
const { count, totalGet } = clientData.reqFree;
const slotData: any = freeData[count];
if (clientData.reqFree && nowFree === count - 1) {
if (totalGet) {
slotData.get = [[1, totalGet]];
}
if (slotData.get) {
clientData.money += slotData.get[0][1];
}
slotData["money"] = clientData.money;
}
const response: INetResponse<RpcSlot1SpinResponse> = {
Status: 0,
Method: req.Method,
Data: slotData,
IsValid: true
};
clientData.free.count++;
clientData.free.nowFree++;
return response;
}
}

View File

@ -7,16 +7,19 @@ export default abstract class SlotInBase {
protected ver: string = "";
protected abstract db: number;
protected abstract br: number[];
protected abstract jp: { [key: string]: number; };
protected jp: { [key: string]: number; };
public *in(clientData: ClientData, req: INetRequest<RpcSlotInRequest>): IterableIterator<any> {
const data: RpcSlotInRequest = req.Data;
const { ver, db, br, jp } = this;
const respData = { ver, db, br };
if (jp) respData["jp"] = jp;
const response: INetResponse<RpcSlotInResponse> = {
Status: 0,
Method: req.Method,
Data: { ver, db, br, jp },
Data: respData,
IsValid: true
};
return response;

View File

@ -0,0 +1,8 @@
export default abstract class SlotSetting {
public IsHaveFreeSpin: boolean = false;
public IsHaveReSpin: boolean = false;
public IsHaveRetriggerFreeSpin: boolean = false;
public IsHaveReq: boolean = false;
public FreeMax: number = 50;
}

View File

@ -4,62 +4,66 @@ import { INetResponse } from "../../script/Engine/CatanEngine/NetManagerV2/Core/
import { ClientData } from "../../shared/protocols/define/interface";
import { RpcSlot1SpinRequest, RpcSlot1SpinResponse } from "../../shared/protocols/Slot1Request";
import { RandomEx } from "../../Utils/Number/RandomEx";
import { getExternalJsonPath } from "../../Utils/tools";
import { getExternalJsonPath, slotJsons } from "../../Utils/tools";
import SlotSetting from './SlotSetting';
export default abstract class SlotSpinBase {
protected abstract ID: number;
protected IsHaveFreeSpin: boolean = false;
protected IsHaveReSpin: boolean = false;
protected IsHaveRetriggerFreeSpin: boolean = false;
protected FreeMax: number = 50;
protected setting: SlotSetting;
protected ID: number;
protected get IsHaveFreeSpin(): boolean { return this.setting.IsHaveFreeSpin };
protected get IsHaveReSpin(): boolean { return this.setting.IsHaveReSpin };
protected get IsHaveRetriggerFreeSpin(): boolean { return this.setting.IsHaveRetriggerFreeSpin };
protected get IsHaveReq(): boolean { return this.setting.IsHaveReq };
protected get FreeMax(): number { return this.setting.FreeMax };
protected JsonData: any;
protected get Temps(): string[] { return this.JsonData.slotData };
protected get FreeTemps(): string[] { return this.JsonData.slotFreeData };
protected get Temps(): JSON[] { return this.JsonData.slotData };
protected get FreeTemps(): JSON[] { return this.JsonData.slotFreeData };
public *spin(clientData: ClientData, req: INetRequest<RpcSlot1SpinRequest>): IterableIterator<any> {
const self = this;
const data: RpcSlot1SpinRequest = req.Data
if (!clientData.jsons[this.ID]) {
let slotData: any;
let AsyncFunction = async function () {
slotData = await self.GetTemps();
};
AsyncFunction();
while (!slotData) {
yield;
}
clientData.jsons[this.ID] = slotData;
}
this.JsonData = clientData.jsons[this.ID];
yield* this.init(clientData);
clientData.free = null;
clientData.reqFree = null;
const slotData: any = this.Temps[RandomEx.GetInt(0, this.Temps.length)];
delete slotData.get;
delete slotData.money;
let totalGet: number = 0;
if (slotData.line) {
totalGet += this.getLineGet(slotData.line);
totalGet += this.getLineMoney(slotData.line);
}
if (slotData.way) {
totalGet += this.getWayMoney(slotData.way);
}
if (slotData.scatter) {
totalGet += this.getScatterGet(slotData.scatter);
totalGet += this.getScatterMoney(slotData.scatter);
if (this.IsHaveReq && this.isHasReqFree(slotData.scatter)) {
clientData.reqFree = { count: 0, totalGet };
}
}
if (this.IsHaveFreeSpin && slotData.free) {
const count = slotData.free[1];
const { freeData, totalFreeGet } = this.getFree(count);
totalGet += totalFreeGet;
clientData.free = { count: 0, freeData };
clientData.free = { nowFree: 0, freeData };
}
if (totalGet) {
slotData.get = [[1, totalGet]];
}
clientData.money -= data.pay;
if (slotData.get) {
clientData.money += slotData.get[0][1];
if (clientData.reqFree) {
slotData["rs"] = 0;
} else {
if (slotData.get) {
clientData.money += slotData.get[0][1];
}
slotData["money"] = clientData.money;
}
slotData["pay"] = [[1, -data.pay]];
slotData["money"] = clientData.money;
const response: INetResponse<RpcSlot1SpinResponse> = {
Status: 0,
@ -70,17 +74,19 @@ export default abstract class SlotSpinBase {
return response;
}
protected getFree(count: number) {
public getFree(count: number) {
let freeData = [];
let totalFreeGet = 0;
for (let i: number = 0; i < count; i++) {
const slotData: any = this.FreeTemps[RandomEx.GetInt(0, this.FreeTemps.length)];
delete slotData.get;
delete slotData.money;
freeData.push(slotData);
if (slotData.line) {
totalFreeGet += this.getLineGet(slotData.line);
totalFreeGet += this.getLineMoney(slotData.line);
}
if (slotData.scatter) {
totalFreeGet += this.getScatterGet(slotData.scatter);
totalFreeGet += this.getScatterMoney(slotData.scatter);
if (this.IsHaveRetriggerFreeSpin && slotData.free && freeData.length < this.FreeMax) {
const count = slotData.free[1] + freeData.length > this.FreeMax
? slotData.free[1] + freeData.length - this.FreeMax
@ -94,7 +100,7 @@ export default abstract class SlotSpinBase {
return { freeData, totalFreeGet }
}
getLineGet(lines: number[][]): number {
private getLineMoney(lines: any[][]): number {
let totalGet: number = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
@ -103,11 +109,38 @@ export default abstract class SlotSpinBase {
return totalGet;
}
getScatterGet(scatter: number[][]): number {
let totalGet: number = scatter[0][1];
private getWayMoney(ways: any[][]): number {
let totalGet: number = 0;
for (let i = 0; i < ways.length; i++) {
const way = ways[i];
totalGet += way[1]
}
return totalGet;
}
private getScatterMoney(scatters: any[][]): number {
let totalGet: number = 0;
let hasReqFree: boolean = false;
for (let i = 0; i < scatters.length; i++) {
const scatter = scatters[i];
totalGet += scatter[1]
if (this.IsHaveReq && scatter[0].length >= 3) {
hasReqFree = true;
}
}
return totalGet;
}
private isHasReqFree(scatters: any[][]): boolean {
for (let i = 0; i < scatters.length; i++) {
const scatter = scatters[i];
if (this.IsHaveReq && scatter[0].length >= 3) {
return true;
}
}
return false;
}
protected async GetTemps(): Promise<any> {
const filePath = getExternalJsonPath(`slot${this.ID}.json`);
// console.log('filePath', filePath);
@ -115,6 +148,32 @@ export default abstract class SlotSpinBase {
const jsonData = JSON.parse(data);
return jsonData;
}
public *init(clientData: ClientData): IterableIterator<any> {
const self = this;
this.ID = clientData.slotId;
let AsyncFunction = async function () {
let module = await import(`../slot${self.ID}/setting`);
self.setting = new module.default();
};
AsyncFunction();
while (!this.setting) {
yield;
}
if (!slotJsons.has(this.ID)) {
let slotData: any;
let AsyncFunction = async function () {
slotData = await self.GetTemps();
};
AsyncFunction();
while (!slotData) {
yield;
}
slotJsons.set(this.ID, slotData);
}
this.JsonData = slotJsons.get(this.ID);
}
}

View File

@ -7,6 +7,7 @@ import SlotIn1 from "../slot1/in";
export default function* (clientData: ClientData, req: INetRequest<RpcSlotInRequest>): IterableIterator<any> {
const data: RpcSlotInRequest = req.Data;
const { id } = data;
clientData.slotId = id;
let moduleClass: SlotIn1;
let AsyncFunction = async function () {

35
src/api/slot/req.ts Normal file
View File

@ -0,0 +1,35 @@
import { INetRequest } from "../../script/Engine/CatanEngine/NetManagerV2/Core/INetRequest";
import { INetResponse } from "../../script/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { ClientData } from "../../shared/protocols/define/interface";
import { RpcSlotReqRequest, RpcSlotReqResponse } from "../../shared/protocols/SlotRequest";
import SlotFgSpinBase from "./SlotFgSpinBase";
export default function* (clientData: ClientData, req: INetRequest<RpcSlotReqRequest>): IterableIterator<any> {
const count = req.Data
const { slotId } = clientData;
let totalGet = clientData.reqFree.totalGet;
let fgspin: SlotFgSpinBase;
let AsyncFunction = async function () {
let module = await import(`../slot${slotId}/fgspin`);
fgspin = new module.default();
};
AsyncFunction();
while (!fgspin) {
yield;
}
yield* fgspin.init(clientData);
const { freeData, totalFreeGet } = fgspin.getFree(count);
totalGet += totalFreeGet;
clientData.free = { nowFree: 0, freeData };
clientData.reqFree = { count: count, totalGet };
const response: INetResponse<RpcSlotReqResponse> = {
Status: 0,
Method: req.Method,
Data: req.Data,
IsValid: true
};
return response;
}

6
src/api/slot1/setting.ts Normal file
View File

@ -0,0 +1,6 @@
import SlotSetting from "../slot/SlotSetting";
export default class SlotSetting1 extends SlotSetting {
public IsHaveFreeSpin: boolean = true;
public IsHaveRetriggerFreeSpin: boolean = true;
}

View File

@ -1,7 +1,3 @@
import SlotSpinBase from "../slot/SlotSpinBase";
export default class SlotSpin1 extends SlotSpinBase {
protected ID: number = 1;
protected IsHaveFreeSpin: boolean = true;
protected IsHaveRetriggerFreeSpin: boolean = true;
}
export default class SlotSpin1 extends SlotSpinBase { }

4
src/api/slot70/fgspin.ts Normal file
View File

@ -0,0 +1,4 @@
import SlotFgSpinBase from "../slot/SlotFgSpinBase";
export default class SlotFgSpin70 extends SlotFgSpinBase { }

6
src/api/slot70/in.ts Normal file
View File

@ -0,0 +1,6 @@
import SlotInBase from "../slot/SlotInBase";
export default class SlotIn70 extends SlotInBase {
protected db: number = 5;
protected br: number[] = [4, 12, 20, 40, 80, 120, 160, 200, 240, 400, 600, 800, 1000, 1200, 1600, 2000, 4000, 10000, 20000, 30000];
}

View File

@ -0,0 +1,7 @@
import SlotSetting from "../slot/SlotSetting";
export default class SlotSetting70 extends SlotSetting {
public IsHaveFreeSpin: boolean = true;
public IsHaveRetriggerFreeSpin: boolean = true;
public IsHaveReq: boolean = true;
}

3
src/api/slot70/spin.ts Normal file
View File

@ -0,0 +1,3 @@
import SlotSpinBase from "../slot/SlotSpinBase";
export default class SlotSpin70 extends SlotSpinBase { }

View File

@ -12,6 +12,7 @@ import * as path from 'path';
import { WebSocketServer } from 'ws';
import { BaseEnumerator } from "../CatanEngine/CoroutineV2/Core/BaseEnumerator";
import { NetConnector } from "../script/Engine/CatanEngine/NetManagerV2/NetConnector";
import { slotJsons } from "../Utils/tools";
onload();
@ -39,8 +40,6 @@ function createWindow() {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
// contextIsolation: false, // 使渲染進程能夠使用 Node.js
// nodeIntegration: true, // 使渲染進程可以使用 Node.js 模組
},
});
@ -91,7 +90,7 @@ ipcMain.on('stop-websocket', (event: Electron.IpcMainEvent) => {
// 打开开发者工具
ipcMain.on('json-reload', () => {
NetConnector.clients.forEach(client => {
client.jsons = {};
slotJsons.clear();
});
console.log(`重載成功`);
});

View File

@ -19,7 +19,7 @@ export class NetConnector {
const ip = request.socket.remoteAddress.replace("::ffff:", "") || 'Unknown IP';
console.log(`Client connected from IP: ${ip}`);
NetConnector.clients.set(socket, { socket, id: id, name: "", money: 0, jsons: {} });
NetConnector.clients.set(socket, { socket, id: id, name: "", money: 0 });
id++;
socket.on('message', (message: Buffer) => NetConnector.OnWebSocketMessage(socket, message));
@ -57,7 +57,7 @@ export class NetConnector {
// 动态导入处理函数
try {
// 动态导入文件
const module = await import(`../../../../api/${req.Method.replace(".", "/")}`);
let module = await import(`../../../../api/${req.Method.replace(".", "/")}`);
const isClass = typeof module.default === 'function' && module.default.prototype && Object.getOwnPropertyNames(module.default.prototype).includes('constructor');
// 调用导入模块中的处理函数
@ -76,6 +76,7 @@ export class NetConnector {
console.error(`Error handling request ${req.Method}: ${error.message}`);
NetConnector.sendError(socket, req);
}
module = null;
};
CoroutineV2.Single(AsyncFunction()).Start();
} else {
@ -85,6 +86,7 @@ export class NetConnector {
if (response) {
NetConnector.Send(socket, response);
}
module = null;
};
CoroutineV2.Single(AsyncFunction()).Start();
}

View File

@ -1,6 +1,9 @@
// #region Request
export type RpcSlotInRequest = { id: number }
export type RpcSlotInResponse = { "ver": string, "db": number, "br": number[], "jp": { [key: string]: number } }
export type RpcSlotInResponse = { ver: string, db: number, br: number[], jp?: { [key: string]: number } }
export type RpcSlotReqRequest = number
export type RpcSlotReqResponse = number
// #endregion

View File

@ -6,6 +6,7 @@ export interface ClientData {
id: number;
name: string;
money: number;
jsons: { [key: number]: any; };
free?: { count: number, freeData: any[] };
slotId?: number;
free?: { nowFree: number, freeData: any[] };
reqFree?: { count: number, totalGet: number };
}