feat: wire lobby task and VIP prefab flows and sync UI assets

This commit is contained in:
2026-09-06 18:46:37 +08:00
parent 842c68ef55
commit 9c4510697c
184 changed files with 8348 additions and 19133 deletions
@@ -1,10 +1,18 @@
import { logNativeCall } from '../../core/native-call-log.ts';
type BrowserHost={kind:'settings';browser(url:string):void}|{kind:'bridge';call(name:'browser',data:string):void}|{kind:'h5';open(url:string):void};
/** 12_Logic AppStart: uAgent_3 uses app_Launchtype, every other host reads Launchtype from the URL. */
export function resolveLobbyLaunchMode(search:string,bridgeHost:boolean,appLaunchtype:unknown):0|1 {
const value=bridgeHost?appLaunchtype:new URLSearchParams(search).get('Launchtype');
const mode=Number(value); // Source URL absence is null and explicitly means from_self (0).
if(mode!==0&&mode!==1)throw Error('Invalid Launchtype');
return mode;
}
/** 05_Func.fixUrl + browser. The settings host alone appends timestamp. */
export function openLobbyUrl(url:string,host:BrowserHost,now:()=>number):void {
if(!url)return;
const index=url.indexOf('?');
const fixed=index<0?url:url.slice(0,index+1)+url.slice(index+1).replace(/\?/g,'&');
if(host.kind==='settings')host.browser(`${fixed}&timestamp=${now()}`);
if(host.kind==='settings'){const target=`${fixed}&timestamp=${now()}`;logNativeCall('settings','browser',[target],true);host.browser(target);}
else if(host.kind==='bridge')host.call('browser',fixed);
else host.open(fixed);
else {logNativeCall('settings','browser',[fixed],false);host.open(fixed);}
}
@@ -1,6 +1,7 @@
import type { LoginAccountIdentity, DeviceLoginMode } from '../../protocol/contracts/login-contract.ts';
import type { LoginPolicy } from '../../presentation/login-policy.ts';
import { generate } from '../local/visitor-account.ts';
import { logNativeCall } from '../../core/native-call-log.ts';
import { readPhoneCode } from './phone-code.ts';
export interface LoginNativeSettings {
@@ -71,6 +72,7 @@ export class LoginAccounts {
}
constructor(private readonly options:Options){
// Browser source explicitly uses the legacy getVersionState default of zero.
logNativeCall('settings','getcompareCode',[],!!options.settings);
const state=options.settings?Number(options.settings.getcompareCode()):0;
if(state!==0&&state!==1)throw Error('Invalid getcompareCode result');this.versionState=state;
}
@@ -118,7 +120,8 @@ export class LoginAccounts {
}
authorize(provider:'wechat'|'qq'):void {
if(!this.requireAgreement())return;
if(!this.options.settings){this.options.tip('当前宿主未提供原生登录授权接口');return;}
logNativeCall('settings','accreditlogin',[provider==='wechat'?2:1],!!this.options.settings);
if(!this.options.settings)return;
if(provider==='wechat')this.options.storage.setItem(`tsgame_playerid_${this.options.gameid}${this.options.agentid}`,'');
this.options.settings.accreditlogin(provider==='wechat'?2:1);
}
@@ -1,4 +1,5 @@
import type { NativeSettingName, NativeSettingsPort } from './native-contracts.ts';
import { logNativeCall } from '../../core/native-call-log.ts';
export interface NativeSettingsChannel {
getothername(name: NativeSettingName): string | number;
@@ -11,14 +12,14 @@ export class NativeSettingsAdapter implements NativeSettingsPort {
constructor(private readonly settings: NativeSettingsChannel) {}
getOtherName(name: NativeSettingName): string | number {
return this.settings.getothername(name);
logNativeCall('settings','getothername',[name],true);return this.settings.getothername(name);
}
getChannelName(): string | number {
return this.settings.getchannelName();
logNativeCall('settings','getchannelName',[],true);return this.settings.getchannelName();
}
getMarketName(): string | number {
return this.settings.getmarketname();
logNativeCall('settings','getmarketname',[],true);return this.settings.getmarketname();
}
}
@@ -0,0 +1,14 @@
import type {VipCode} from '../../core/types/vip-room.ts';
/** Same key and {data:[]} format as Utl.Config.vipRoom / Logic.saveVipRoom. */
export class VipRoomHistory {
private readonly key:string;
constructor(private readonly storage:Pick<Storage,'getItem'|'setItem'>,gameid:string|number,agentid:string|number){this.key=`tsgame_vipRoom_${gameid}${agentid}`;}
read():readonly VipCode[]{
const text=this.storage.getItem(this.key);
if(text===null){this.storage.setItem(this.key,JSON.stringify({data:[]}));return [];}
const value=JSON.parse(text);
if(!value||!Array.isArray(value.data)||value.data.some((v:unknown)=>!(typeof v==='string'&&v.length>0||typeof v==='number'&&Number.isFinite(v))))throw Error(`Invalid ${this.key}`);
return value.data;
}
add(code:VipCode):void {this.storage.setItem(this.key,JSON.stringify({data:[code,...this.read().filter(v=>v!==code)]}));}
}
@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "1a646893-8674-4b0e-b9c5-115be014edb1",
"files": [],
"subMetas": {},
"userData": {}
}
@@ -1,3 +1,4 @@
import { logNativeCall } from '../../core/native-call-log.ts';
import {
NATIVE_CALL_NAMES,
REGISTERED_NATIVE_HANDLER_NAMES,
@@ -115,6 +116,7 @@ export class WebViewJavascriptBridgeAdapter implements NativeBridgePort {
if (!includesName(NATIVE_CALL_NAMES, name)) {
throw new Error(`Unknown native call: ${String(name)}`);
}
logNativeCall('WVJB',name,[data,callback],!!this.channel);
if (!this.channel) throw new Error('Native bridge is not ready');
this.channel.callHandler(name, data, callback);
}