Compare commits

..

7 Commits

Author SHA1 Message Date
TJH
f1c0800544 1
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 44s
2026-06-29 17:21:24 +08:00
TJH
0029d82b19 缅甸泰语在某些系统下错位问题的修改
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 47s
2026-06-29 15:19:40 +08:00
TJH
a45298708d 开始滚动前获取余额时,如果网络错误,添加错误后的处理
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m31s
2026-06-25 16:44:56 +08:00
TJH
e77e909d91 1
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 45s
2026-06-11 11:22:53 +08:00
TJH
24a6b80fb2 点击余额不足提示确认按钮时刷新玩家余额的显示
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 46s
2026-06-10 14:38:00 +08:00
TJH
1edb5cd3e5 余额刷新添加点击限制
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 46s
2026-06-10 09:55:51 +08:00
TJH
0ebfe00e4b 余额不足时在客户端拦截,不经过spin接口
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 46s
2026-06-08 15:51:13 +08:00
9 changed files with 1001 additions and 807 deletions

View File

@ -19,7 +19,9 @@ jobs:
echo "💡 The ${{ github.repository }} repository has been cloned to the runner." echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- name: npm i - name: npm i
run: | run: |
echo 'npm i'
npm i npm i
echo "✅ npm i done"
- name: build - name: build
run: | run: |
echo 'build' echo 'build'

File diff suppressed because it is too large Load Diff

View File

@ -1160,7 +1160,7 @@
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 0, "x": 0,
"y": -70, "y": -83.523,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@ -1201,7 +1201,7 @@
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 167.19189453125, "width": 167.19189453125,
"height": 54.18 "height": 80
}, },
"_anchorPoint": { "_anchorPoint": {
"__type__": "cc.Vec2", "__type__": "cc.Vec2",
@ -1243,7 +1243,7 @@
"_fontSize": 43, "_fontSize": 43,
"_fontFamily": "Arial", "_fontFamily": "Arial",
"_lineHeight": 43, "_lineHeight": 43,
"_overflow": 0, "_overflow": 2,
"_enableWrapText": true, "_enableWrapText": true,
"_font": null, "_font": null,
"_isSystemFontUsed": true, "_isSystemFontUsed": true,

View File

@ -5,12 +5,13 @@ import { SLOT_BAR_EVENT } from './game/Define';
import { AutoSpinPanel } from './game/AutoSpinPanel'; import { AutoSpinPanel } from './game/AutoSpinPanel';
import { NodePoolManager } from '../../Loading/scripts/manager/NodePoolManager'; import { NodePoolManager } from '../../Loading/scripts/manager/NodePoolManager';
import { webView } from './game/WebView'; import { webView } from './game/WebView';
import { cash2gold, getHistoryUrl, getOddsUrl, getSupportUrl, gold2cash } from '../../Loading/scripts/comm'; import { callGameBalanceApi, cash2gold, getGameId, getHistoryUrl, getOddsUrl, getSupportUrl, gold2cash } from '../../Loading/scripts/comm';
import { GameDataManager } from '../../Loading/scripts/manager/GameDataManager'; import { GameDataManager } from '../../Loading/scripts/manager/GameDataManager';
import { I18nManager } from '../../Loading/scripts/manager/I18nManager'; import { I18nManager } from '../../Loading/scripts/manager/I18nManager';
import { LocalizedSprite } from '../../Loading/scripts/i18n/LocalizedSprite'; import { LocalizedSprite } from '../../Loading/scripts/i18n/LocalizedSprite';
import { AudioManager } from '../../Loading/scripts/manager/AudioManager'; import { AudioManager } from '../../Loading/scripts/manager/AudioManager';
import { SpinAni } from './game/SpinAni'; import { SpinAni } from './game/SpinAni';
import { SlotGame } from './SlotGame';
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
@ccclass('SlotBar') @ccclass('SlotBar')
@ -22,6 +23,9 @@ export class SlotBar extends Component {
@property({ type: Prefab }) @property({ type: Prefab })
private autoSpinPanel: Prefab = null; private autoSpinPanel: Prefab = null;
@property(SlotGame)
private slotGame: SlotGame = null;
@property(Node) @property(Node)
private tipSmall_turbo: Node = null; private tipSmall_turbo: Node = null;
@property(Node) @property(Node)
@ -407,6 +411,38 @@ export class SlotBar extends Component {
this.setBet(this.betGrade[this.betIndex]); this.setBet(this.betGrade[this.betIndex]);
} }
private isGetBalance: boolean = false;
async onClickBalance(): Promise<number | null> {
if (this.isGetBalance) return
this.isGetBalance = true;
try {
let balacneData = await this.refreshBalanceFromServer();
this.setBalance(balacneData)
return balacneData;
} catch (err) {
console.log('获取余额失败')
return null;
} finally {
this.scheduleOnce(() => {
this.isGetBalance = false;
}, 0.5)
}
}
async onConfirmErr2(): Promise<number | null> {
try {
let balacneData = await this.refreshBalanceFromServer();
this.setBalance(balacneData)
return balacneData;
} catch (err) {
console.log('获取余额失败')
return null;
} finally {
this.isGetBalance = false;
}
}
private currentTipTween: Tween<Node> = null; private currentTipTween: Tween<Node> = null;
private hideTimer: number = null; private hideTimer: number = null;
showTipSmall(str: string, openTurbo?: boolean) { showTipSmall(str: string, openTurbo?: boolean) {
@ -573,6 +609,8 @@ export class SlotBar extends Component {
this.setBtnEnable(this.menuBtn, false); this.setBtnEnable(this.menuBtn, false);
this.setBtnEnable(this.spinBtn, false); this.setBtnEnable(this.spinBtn, false);
this.slotGame.showFeatureBuy(true)
this.setBtnVisible(this.spinBtn, false); this.setBtnVisible(this.spinBtn, false);
this.setBtnVisible(this.stopAutoBtn, true); this.setBtnVisible(this.stopAutoBtn, true);
@ -593,6 +631,7 @@ export class SlotBar extends Component {
this.setBtnVisible(this.spinBtn, true); this.setBtnVisible(this.spinBtn, true);
this.setBtnVisible(this.stopAutoBtn, false); this.setBtnVisible(this.stopAutoBtn, false);
this.setBtnEnable(this.spinBtn, false); this.setBtnEnable(this.spinBtn, false);
this.slotGame.showFeatureBuy(this.getBet() * this.gameInfo.BuyMul > this.gameInfo.MaxBuyBet)
} }
reconnectState(hasDelete: boolean = false) { reconnectState(hasDelete: boolean = false) {
@ -612,6 +651,7 @@ export class SlotBar extends Component {
this.manualStopNode.active = false this.manualStopNode.active = false
this.isAuto = false; this.isAuto = false;
this.setBtnVisible(this.spinBtn, true); this.setBtnVisible(this.spinBtn, true);
this.spinAniStop()
this.setBtnVisible(this.stopAutoBtn, false); this.setBtnVisible(this.stopAutoBtn, false);
this.setBtnEnable(this.spinBtn, true); this.setBtnEnable(this.spinBtn, true);
@ -769,5 +809,27 @@ export class SlotBar extends Component {
this.setBet(this.betGrade[this.betIndex], true); this.setBet(this.betGrade[this.betIndex], true);
} }
} }
// private _refreshingBalance: boolean = false;
async refreshBalanceFromServer(): Promise<number | null> {
// if (this._refreshingBalance) return this.getBalance();
// this._refreshingBalance = true;
try {
const res = await callGameBalanceApi({});
const balance = Number(res.Balance);
if (!Number.isFinite(balance)) {
console.warn("[SlotBar] invalid balance response:", res);
return this.getBalance();
}
this.setBalance(balance);
return balance;
} catch (err) {
console.error("[SlotBar] refresh balance failed:", err);
return this.getBalance();
} finally {
// this.scheduleOnce(() => {
// this._refreshingBalance = false;
// }, 1)
}
}
} }

View File

@ -4,7 +4,7 @@ import { SlotBar } from './SlotBar';
import { SlotGame } from './SlotGame'; import { SlotGame } from './SlotGame';
import { BigWinUI } from './game/BigWinUI'; import { BigWinUI } from './game/BigWinUI';
import { GameDataManager } from '../../Loading/scripts/manager/GameDataManager'; import { GameDataManager } from '../../Loading/scripts/manager/GameDataManager';
import { callGameApi, getIsFrom } from '../../Loading/scripts/comm'; import { callGameApi, callGameBalanceApi, getGameId, getIsFrom } from '../../Loading/scripts/comm';
import { TipPanel } from './game/TipPanel'; import { TipPanel } from './game/TipPanel';
import { I18nManager } from '../../Loading/scripts/manager/I18nManager'; import { I18nManager } from '../../Loading/scripts/manager/I18nManager';
import { TotalWin } from './game/TotalWin'; import { TotalWin } from './game/TotalWin';
@ -78,6 +78,7 @@ export class SlotScene extends Component {
private lastSpinInfo: any = null; private lastSpinInfo: any = null;
private spinData: any = null; private spinData: any = null;
private isReceiveMsg: boolean = false; private isReceiveMsg: boolean = false;
private isErr2: boolean = false;
private objectId: string[] = []; private objectId: string[] = [];
@ -123,8 +124,6 @@ export class SlotScene extends Component {
this.lastSpinInfo = this.gameInfo; this.lastSpinInfo = this.gameInfo;
this.spinData = this.gameInfo.Data; this.spinData = this.gameInfo.Data;
this.slotGame.showFeatureBuy(this.gameInfo.CloseBuyGame);
// 注册事件监听 // 注册事件监听
this.slotBar.node.on(SLOT_BAR_EVENT.ON_SPIN_CLICK, this.spinBtnClick, this); this.slotBar.node.on(SLOT_BAR_EVENT.ON_SPIN_CLICK, this.spinBtnClick, this);
// this.slotBar.node.on(SLOT_BAR_EVENT.ON_TEST_SPIN_CLICK, this.spinBtnClick2, this); // this.slotBar.node.on(SLOT_BAR_EVENT.ON_TEST_SPIN_CLICK, this.spinBtnClick2, this);
@ -226,19 +225,32 @@ export class SlotScene extends Component {
} }
async spinBtnClick(isFreeSpin: boolean = false, isFeatureBuy: boolean = false) { async spinBtnClick(isFreeSpin: boolean = false, isFeatureBuy: boolean = false) {
this.gameState.isOnReconnect = false;
this.isReceiveMsg = false;
this.isErr = false
this.slotGame.spin(this.gameState.isInFreeSpin);
this.gameState.isOneRoundEnd = false;
this.slotGame.changeBg(this.gameState.isInFreeSpin);
this.slotGame.hideIconMsg();
if (!isFreeSpin) {
this.slotBar.setWin(0);
}
let curBalanceData = await this.slotBar.refreshBalanceFromServer()
if (!curBalanceData) {
curBalanceData = this.slotBar.getBalance()
}
if (curBalanceData < (isFeatureBuy ? this.slotBar.getBet() * this.gameInfo.BuyMul : this.slotBar.getBet()) && !isFreeSpin && !GameDataManager.instance.frb.Ongoing) {
//余额不足不经过服务器,在客户端拦截
this.showErrorTip(2, () => { this.slotBar.onConfirmErr2() });
this.handleErrSpin(true);
this.isErr2 = true;
return
}
try { try {
this.gameState.isOnReconnect = false;
this.isReceiveMsg = false;
this.isErr = false
this.slotGame.spin(this.gameState.isInFreeSpin);
this.gameState.isOneRoundEnd = false;
this.slotGame.changeBg(this.gameState.isInFreeSpin);
this.slotGame.hideIconMsg();
if (!isFreeSpin) {
this.slotBar.setWin(0);
}
// 如果有frb就不会扣除金额 // 如果有frb就不会扣除金额
let frb = GameDataManager.instance.frb; let frb = GameDataManager.instance.frb;
if (frb && frb.Ongoing != null) { if (frb && frb.Ongoing != null) {
@ -370,16 +382,21 @@ export class SlotScene extends Component {
this.slotGame.manualStop(); this.slotGame.manualStop();
} }
private handleErrSpin() { private handleErrSpin(isErr2 = false) {
this.spinInfo = this.lastSpinInfo; this.spinInfo = this.lastSpinInfo;
this.spinData = this.spinInfo.Data; this.spinData = this.spinInfo.Data;
this.slotGame.setRollerIconRule(this.spinData.Mode == 0 ? ROLLER_RULE : FREE_SPIN_ROLLER_RULE); this.slotGame.setRollerIconRule(this.spinData.Mode == 0 ? ROLLER_RULE : FREE_SPIN_ROLLER_RULE);
this.gameState.isAutoSpin = false; this.gameState.isAutoSpin = false;
this.spinData.AllScore = 0; this.spinData.AllScore = 0;
this.spinData.RoundInfo.AllScore = 0; if (this.spinData.RoundInfo) {
this.spinData.RoundInfo.AllScore = 0;
}
this.slotGame.stopScroll(this.spinData, false, null); this.slotGame.stopScroll(this.spinData, false, null);
this.slotGame.manualStop(); // this.slotGame.manualStop();
this.slotBar.setBalance(this.spinInfo.Balance); this.slotBar.setBalance(isErr2 ? this.slotBar.getBalance() : this.spinInfo.Balance);
this.slotBar.closeAutoSpin();
this.slotGame.setFeatureBuyInteractable(true)
} }
private async handleSpinResult() { private async handleSpinResult() {
@ -674,8 +691,13 @@ export class SlotScene extends Component {
} }
private async normalStop(isReconnect: boolean = false) { private async normalStop(isReconnect: boolean = false) {
this.slotBar.setBalance(this.spinData.Balance); if (this.isErr2) {
let winType = this.slotGame.checkWinType(this.spinData.AllScore); this.isErr2 = false;
this.slotBar.setBalance(this.slotBar.getBalance());
} else {
this.slotBar.setBalance(this.spinData.Balance);
} let winType = this.slotGame.checkWinType(this.spinData.AllScore);
await this.handleWinResult(winType, isReconnect, false, () => { await this.handleWinResult(winType, isReconnect, false, () => {
this.checkAutoSpin(winType !== WIN_TYPE.NONE, isReconnect); this.checkAutoSpin(winType !== WIN_TYPE.NONE, isReconnect);
@ -873,7 +895,7 @@ export class SlotScene extends Component {
msg2 = I18nManager.instance.t('AID_ERROR_CODE_2'); msg2 = I18nManager.instance.t('AID_ERROR_CODE_2');
tip = `${msg1}\n${msg2}`; tip = `${msg1}\n${msg2}`;
if (!this.TipPanel.getHasTip()) { if (!this.TipPanel.getHasTip()) {
this.TipPanel.showTip(title, tip, null, null, I18nManager.instance.t('AID_ERROR_OK_BUTTON'), null, false); this.TipPanel.showTip(title, tip, callback, null, I18nManager.instance.t('AID_ERROR_OK_BUTTON'), null, false);
} }
break; break;
case 3: case 3:

View File

@ -1,7 +1,9 @@
import { _decorator, Node, Component, screen, view, ResolutionPolicy, Sprite, sys, Label, Widget, Vec3, UITransform } from 'cc'; import { _decorator, Node, Component, screen, view, ResolutionPolicy, Sprite, sys, Label, Widget, Vec3, UITransform } from 'cc';
import { LocalizedLabel } from './i18n/LocalizedLabel'; import { LocalizedLabel } from './i18n/LocalizedLabel';
import { getLanguage } from './comm'; import { getLanguage } from './comm';
import { installLabelAlignmentCenterFix } from 'common_tools';
installLabelAlignmentCenterFix();
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
export let SWITCH_PROTRAIT_MODE = { export let SWITCH_PROTRAIT_MODE = {
"da": "Skift venligst til portrættilstand", "da": "Skift venligst til portrættilstand",

View File

@ -9,7 +9,7 @@ const qs = new URLSearchParams(location.search)
// let apiaddr = "https://rpgames-api.rpfafafahkdev.com"; // let apiaddr = "https://rpgames-api.rpfafafahkdev.com";
let apiaddr = ""; let apiaddr = "";
let token = "eyJQIjoxMDA5NDksIkUiOjE3NzA2NzA4MTEsIlMiOjk5OCwiRCI6InJwXzEwMDEyIn0.8IGbHU3d63mIZPXD96UTHmDndTb2zf7JYMRpAvH4kGs"; let token = "eyJQIjoxMDA5NDksIkUiOjE3ODI3NjA2MTIsIlMiOjEwMDQsIkQiOiJycF8xMDAxMiJ9.f8r8mMsNIh9XSXq-Ni_h2KRw4EBDu9pTWIfwAQw7O7U";
let language = "en" let language = "en"
let currency = "THB" let currency = "THB"
let isfrom = null let isfrom = null
@ -49,7 +49,7 @@ export function getGameId() {
} }
export function initReqAddr() { export function initReqAddr() {
let partHost = ".rpfafafahkdev.com"; let partHost = ".rpenenenhkdev.com";
if (!PREVIEW) { if (!PREVIEW) {
const qs = new URLSearchParams(location.search) const qs = new URLSearchParams(location.search)
@ -113,6 +113,29 @@ export async function callGameApi(action: string, argsObj: any) {
return obj return obj
} }
export async function callGameBalanceApi(argsObj: any) {
const url = apiaddr + path.join("/gameapi/getPlayerBalance")
const payload = JSON.stringify(argsObj)
const res = await fetch(url, {
signal: AbortSignal.timeout(10000),
headers: {
"Content-Type": "application/json",
"X-Rp-Token": token,
},
method: "POST",
body: payload,
mode: 'cors',
})
if (res.status != 200) {
const errstr = await res.text()
throw new Error(errstr || res.statusText)
}
const obj = await res.json()
return obj
}
export function gold2cash(v: number): string { export function gold2cash(v: number): string {
v /= 10000 v /= 10000
return v.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ','); return v.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');

6
package-lock.json generated
View File

@ -9,9 +9,15 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"common_tools": "git+ssh://git@gitea.rpfafafahkdev.com:taotao/common_tools.git",
"nosleep.js": "^0.12.0" "nosleep.js": "^0.12.0"
} }
}, },
"node_modules/common_tools": {
"version": "1.0.0",
"resolved": "git+ssh://git@gitea.rpfafafahkdev.com:taotao/common_tools.git#c49bf2990a6f348489505ac4998683c814b58dde",
"license": "MIT"
},
"node_modules/nosleep.js": { "node_modules/nosleep.js": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz", "resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz",

View File

@ -14,6 +14,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"common_tools": "git+ssh://git@gitea.rpfafafahkdev.com:taotao/common_tools.git",
"nosleep.js": "^0.12.0" "nosleep.js": "^0.12.0"
} }
} }