keytops-game-framework 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,10 @@ import { AnalyticsAble, AnalyticsData } from "../AnalyticsAble";
2
2
  export declare class LaunchAnalyticsAble {
3
3
  private readonly _baseAble;
4
4
  constructor(baseAble: AnalyticsAble);
5
+ /**
6
+ * 标记应用准备就绪,开始统计启动时间
7
+ */
8
+ ready(): void;
5
9
  /**
6
10
  * 上报启动事件
7
11
  * @param name 事件名称
@@ -1,5 +1,8 @@
1
1
  import { ConfigResolveMeta } from "../../analytics/AnalyticsAbleConst";
2
2
  export interface OnlineConfig extends Record<string, any> {
3
+ buildRequestData?(request?: ServerParamStruct | undefined): ServerParamStruct | undefined;
4
+ extractPayloads?(response: ServerResponseStruct): Record<string, any> | undefined;
5
+ merge?(target: this, payloads?: Record<string, any>): this;
3
6
  }
4
7
  export type ServerResponseStruct = {
5
8
  timestamp?: number;
@@ -10,57 +13,16 @@ type BaseValueType = string | number | boolean;
10
13
  export type ServerParamStruct = {
11
14
  [key: string]: BaseValueType | BaseValueType[] | ServerParamStruct;
12
15
  };
13
- export type RemoteConfigScope = {
14
- gameFlag?: string;
15
- [key: string]: BaseValueType | undefined;
16
- };
17
16
  export type RemoteConfigRequestOptions = {
18
17
  refresh?: boolean;
19
18
  debug?: boolean;
20
19
  };
21
- export interface RemoteConfigDefinition<TConfig extends OnlineConfig = OnlineConfig, TQuery extends ServerParamStruct | undefined = ServerParamStruct> {
22
- /**
23
- * 配置端口名称,内置system\config\level
24
- */
25
- method: string;
26
- /**
27
- * 创建该配置类型的默认实例。
28
- * 未请求远端时,snapshot 也必须能返回一个可用对象,所以这里不能省略。
29
- */
30
- createDefault(): TConfig;
31
- /**
32
- * 把业务侧传入的 request 参数转换成服务器协议需要的 data 字段。
33
- * 公共字段由 IServer 实现补齐,这里只负责当前配置类型自己的请求载荷。
34
- */
35
- buildRequestData(request?: TQuery, scope?: RemoteConfigScope): ServerParamStruct | undefined;
36
- /**
37
- * 从统一的服务器响应中抽出当前配置真正关心的 payload 部分。
38
- * 如果后续不同配置类型的响应结构不一致,这里就是第一层适配点。
39
- */
40
- extractPayloads(response: ServerResponseStruct): Record<string, any> | undefined;
41
- /**
42
- * 定义当前配置的装配策略。
43
- * 可按字段 merge,也可整体替换,RemoteConfigStore 不关心具体策略,只调用这里。
44
- */
45
- merge(target: TConfig, payloads?: Record<string, any>): TConfig;
46
- }
47
- /**
48
- * definition 的公共抽象基类。
49
- * interface 负责定义框架契约,abstract class 负责沉淀共用实现。
50
- */
51
- export declare abstract class AbstractRemoteConfigDefinition<TConfig extends OnlineConfig = OnlineConfig, TQuery extends ServerParamStruct | undefined = ServerParamStruct> implements RemoteConfigDefinition<TConfig, TQuery> {
52
- abstract method: string;
53
- abstract createDefault(): TConfig;
54
- abstract merge(target: TConfig, payloads?: Record<string, any>): TConfig;
55
- protected mergeConfigField(target: OnlineConfig, key: string, payload: unknown): void;
56
- protected mergeObjectConfig<T extends OnlineConfig>(target: T, payloads?: Record<string, any>): T;
57
- buildRequestData(request?: TQuery, _scope?: RemoteConfigScope): ServerParamStruct | undefined;
58
- extractPayloads(response: ServerResponseStruct): Record<string, any> | undefined;
59
- }
60
20
  export interface ServerRequestContext<TConfig extends OnlineConfig = OnlineConfig, TQuery extends ServerParamStruct | undefined = ServerParamStruct> {
61
- definition: RemoteConfigDefinition<TConfig, TQuery>;
62
- scope?: RemoteConfigScope;
21
+ method: string;
22
+ gameFlag: string;
23
+ config: TConfig;
63
24
  request?: TQuery;
25
+ requestData?: ServerParamStruct;
64
26
  options?: RemoteConfigRequestOptions;
65
27
  }
66
28
  export interface IServer {
@@ -1,15 +1,21 @@
1
- import { AbstractRemoteConfigDefinition, OnlineConfig, type ServerParamStruct } from "../net/server/IServer";
2
- export declare class BaseOnlineConfig implements OnlineConfig {
1
+ import type { OnlineConfig, ServerParamStruct, ServerResponseStruct } from "../net/server/IServer";
2
+ export type RemoteConfigRequest = ServerParamStruct | undefined;
3
+ export declare class BaseOnlineConfig<TRequest extends RemoteConfigRequest = ServerParamStruct> implements OnlineConfig {
3
4
  static KEY: string;
5
+ protected mergeConfigField(target: OnlineConfig, key: string, payload: unknown): void;
6
+ protected mergeObjectConfig<T extends OnlineConfig>(target: T, payloads?: Record<string, any>): T;
7
+ buildRequestData(request?: TRequest): ServerParamStruct | undefined;
8
+ extractPayloads(response: ServerResponseStruct): Record<string, any> | undefined;
9
+ merge(target: this, payloads?: Record<string, any>): this;
4
10
  }
5
- /**
6
- * Base/config 端口的内建定义。
7
- * 后续新增 activity / dungeon 等远程配置时,直接新增新的 definition 即可,
8
- * 不需要再回到 Server.ts 里扩展 method 分支。
9
- */
10
- export declare class BaseRemoteConfigDefinitionClass extends AbstractRemoteConfigDefinition<BaseOnlineConfig, ServerParamStruct> {
11
+ export type RemoteConfigClass<TConfig extends BaseOnlineConfig<any> = BaseOnlineConfig<any>> = {
12
+ new (): TConfig;
13
+ };
14
+ export type RemoteConfigRequestOf<TConfigClass extends RemoteConfigClass> = InstanceType<TConfigClass> extends BaseOnlineConfig<infer TRequest> ? TRequest : ServerParamStruct;
15
+ export type RemoteConfigMeta<TConfigClass extends RemoteConfigClass = RemoteConfigClass> = {
11
16
  method: string;
12
- createDefault(): BaseOnlineConfig;
13
- merge(target: BaseOnlineConfig, payloads?: Record<string, any>): BaseOnlineConfig;
14
- }
15
- export declare const BaseRemoteConfigDefinition: BaseRemoteConfigDefinitionClass;
17
+ gameFlag: string;
18
+ key: string;
19
+ injectorKey: string;
20
+ configClass: TConfigClass;
21
+ };
@@ -1,9 +1,10 @@
1
1
  import { ConfigResolveMeta } from "../analytics/AnalyticsAbleConst";
2
- import type { OnlineConfig, RemoteConfigDefinition, RemoteConfigScope, ServerResponseStruct } from "../net/server/IServer";
2
+ import type { ServerResponseStruct } from "../net/server/IServer";
3
+ import type { RemoteConfigClass } from "./BaseOnlineConfig";
3
4
  export interface IRemoteConfigStore {
4
- snapshot<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): TConfig;
5
- apply<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope: RemoteConfigScope | undefined, response: ServerResponseStruct): TConfig;
6
- getResolveMeta<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): ConfigResolveMeta | undefined;
7
- isLoaded<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): boolean;
5
+ snapshot<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): InstanceType<TConfigClass>;
6
+ apply<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass, response: ServerResponseStruct): InstanceType<TConfigClass>;
7
+ getResolveMeta<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): ConfigResolveMeta | undefined;
8
+ isLoaded<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): boolean;
8
9
  clear(): void;
9
10
  }
@@ -1,16 +1,14 @@
1
- import { OnlineConfig } from "../net/server/IServer";
2
- import { BaseRemoteConfigDefinitionClass } from "./BaseOnlineConfig";
3
- export declare class LevelOnlineConfig implements OnlineConfig {
1
+ import { BaseOnlineConfig } from "./BaseOnlineConfig";
2
+ type LevelConfigRequest = {
3
+ id: string;
4
+ };
5
+ export declare class LevelOnlineConfig extends BaseOnlineConfig<LevelConfigRequest> {
4
6
  static KEY: string;
5
7
  info: {
6
8
  id: string;
7
9
  repeat: 0 | 1;
8
10
  [key: string]: any;
9
11
  };
12
+ merge(_target: this, payloads?: Record<string, any>): this;
10
13
  }
11
- export declare class LevelRemoteConfigDefinitionClass extends BaseRemoteConfigDefinitionClass {
12
- method: string;
13
- createDefault(): LevelOnlineConfig;
14
- merge(_target: LevelOnlineConfig, payloads?: Record<string, any>): LevelOnlineConfig;
15
- }
16
- export declare const LevelRemoteConfigDefinition: LevelRemoteConfigDefinitionClass;
14
+ export {};
@@ -1,7 +1,7 @@
1
- import type { OnlineConfig, RemoteConfigDefinition, ServerParamStruct } from "../net/server/IServer";
1
+ export { remoteConfig, type IRemoteConfigRegistry, } from "./RemoteConfigRegistry";
2
+ export { type RemoteConfigClass, type RemoteConfigMeta, type RemoteConfigRequestOf, } from "./BaseOnlineConfig";
2
3
  export declare const INTERNAL_METHODS: {
3
- readonly CONFIG: string;
4
- readonly SYSTEM: string;
5
- readonly LEVEL: string;
4
+ readonly CONFIG: "config";
5
+ readonly SYSTEM: "system";
6
+ readonly LEVEL: "level";
6
7
  };
7
- export declare function getRemoteConfigDefinition(method: string): RemoteConfigDefinition<OnlineConfig, ServerParamStruct>;
@@ -0,0 +1,10 @@
1
+ import { type RemoteConfigClass, type RemoteConfigMeta } from "./BaseOnlineConfig";
2
+ export interface IRemoteConfigRegistry {
3
+ register<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass, method: string, gameFlag?: string, injectorKey?: string): void;
4
+ getMeta<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): RemoteConfigMeta<TConfigClass>;
5
+ getActiveMeta<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): RemoteConfigMeta;
6
+ create<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): InstanceType<TConfigClass>;
7
+ createKey(method: string, gameFlag?: string): string;
8
+ }
9
+ export declare function getRemoteConfigRegistry(): IRemoteConfigRegistry;
10
+ export declare function remoteConfig(method: string, gameFlag?: string, injectorKey?: string): ClassDecorator;
@@ -1,46 +1,39 @@
1
- import type { OnlineConfig, RemoteConfigDefinition, RemoteConfigRequestOptions, RemoteConfigScope, ServerParamStruct } from "../net/server/IServer";
1
+ import type { IRemoteConfigStore } from "./IRemoteConfigStore";
2
+ import type { RemoteConfigRequestOptions } from "../net/server/IServer";
2
3
  import { ConfigResolveMeta } from "../analytics/AnalyticsAbleConst";
4
+ import type { RemoteConfigClass, RemoteConfigRequestOf } from "./BaseOnlineConfig";
3
5
  export declare class RemoteConfigService {
4
6
  private _store;
7
+ private _registry;
5
8
  /**
6
9
  * 统一暴露给测试和少量编排场景的 server 门面。
7
10
  * 真正的协议实现仍然隐藏在 server 内部注入链路后面。
8
11
  */
9
12
  get server(): import("../net/server/Server").Server;
13
+ private get registry();
10
14
  /**
11
15
  * store 只负责快照/持久化/resolveMeta,不负责发请求。
12
16
  * 这样请求协议切换时,不需要改缓存与装配逻辑。
13
17
  */
14
- private get store();
18
+ get store(): IRemoteConfigStore;
15
19
  /**
16
20
  * 请求并应用远程配置,返回已装配的快照。
17
- * @param definition 配置定义
21
+ * @param configClass 配置类
18
22
  * @param request 请求参数
19
- * @param scope 作用域
20
23
  * @param options 请求选项
21
24
  * @returns 装配后的配置快照
22
25
  */
23
- refresh<TConfig extends OnlineConfig, TQuery extends ServerParamStruct | undefined>(definition: RemoteConfigDefinition<TConfig, TQuery>, request?: TQuery, scope?: RemoteConfigScope, options?: RemoteConfigRequestOptions): Promise<TConfig>;
24
- /**
25
- * 与旧调用习惯兼容的主入口。
26
- * 语义上等价于 refresh:必要时请求远端,失败时回退本地快照。
27
- */
28
- resolve<TConfig extends OnlineConfig, TQuery extends ServerParamStruct | undefined>(definition: RemoteConfigDefinition<TConfig, TQuery>, request?: TQuery, scope?: RemoteConfigScope, options?: RemoteConfigRequestOptions): Promise<TConfig>;
26
+ fetch<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass, request?: RemoteConfigRequestOf<TConfigClass>, options?: RemoteConfigRequestOptions): Promise<InstanceType<TConfigClass>>;
29
27
  /**
30
28
  * 获取配置。
31
- * @param definition 配置定义
32
- * @param scope 作用域
29
+ * @param configClass 配置类
33
30
  * @returns 配置
34
31
  */
35
- config<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): TConfig;
36
- /**
37
- * 与旧调用习惯兼容的只读快照接口。
38
- */
39
- snapshot<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): TConfig;
32
+ config<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): InstanceType<TConfigClass>;
40
33
  /**
41
34
  * 读取最近一次成功命中的 resolve 元信息。
42
35
  */
43
- resolveMeta<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): ConfigResolveMeta | undefined;
36
+ resolveMeta<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): ConfigResolveMeta | undefined;
44
37
  /**
45
38
  * system URL 统一从这里解析,避免调用方直接依赖 helper 或拼接规则。
46
39
  */
@@ -1,20 +1,22 @@
1
1
  import type { IRemoteConfigStore } from "./IRemoteConfigStore";
2
- import type { OnlineConfig, RemoteConfigDefinition, RemoteConfigScope, ServerResponseStruct } from "../net/server/IServer";
2
+ import type { ServerResponseStruct } from "../net/server/IServer";
3
3
  import { ConfigResolveMeta } from "../analytics/AnalyticsAbleConst";
4
+ import type { RemoteConfigClass } from "./BaseOnlineConfig";
5
+ import type { IRemoteConfigRegistry } from "./RemoteConfigRegistry";
4
6
  export declare class RemoteConfigStore implements IRemoteConfigStore {
7
+ private _registry;
5
8
  static KEY: string;
6
9
  private _snapshots;
7
10
  private _loadedKeys;
8
11
  private _contexts;
9
- snapshot<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): TConfig;
10
- apply<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope: RemoteConfigScope | undefined, response: ServerResponseStruct): TConfig;
11
- getResolveMeta<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): ConfigResolveMeta | undefined;
12
- isLoaded<TConfig extends OnlineConfig>(definition: RemoteConfigDefinition<TConfig, any>, scope?: RemoteConfigScope): boolean;
12
+ constructor(_registry: IRemoteConfigRegistry);
13
+ snapshot<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): InstanceType<TConfigClass>;
14
+ apply<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass, response: ServerResponseStruct): InstanceType<TConfigClass>;
15
+ getResolveMeta<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): ConfigResolveMeta | undefined;
16
+ isLoaded<TConfigClass extends RemoteConfigClass>(configClass: TConfigClass): boolean;
13
17
  clear(): void;
14
18
  private ensureContexts;
15
- private getScopeGameFlag;
16
- private createScopedKey;
17
- private getScopeKey;
19
+ private getConfigKey;
18
20
  private getStorageKey;
19
21
  private setResolveMeta;
20
22
  }
@@ -1,13 +1,12 @@
1
1
  import type { AliAnalyticsConfig } from "../analytics/ALiAnalyticsSender";
2
2
  import type { KeytopsAnalyticsConfig } from "../analytics/KeytopsAnalyticsSender";
3
3
  import { ADConfig } from "../publisher/IADAble";
4
- import { OnlineConfig } from "../net/server/IServer";
5
- import { BaseRemoteConfigDefinitionClass } from "./BaseOnlineConfig";
4
+ import { BaseOnlineConfig } from "./BaseOnlineConfig";
6
5
  export type RelayAnalyticsConfig = Partial<AliAnalyticsConfig> & KeytopsAnalyticsConfig;
7
6
  /**
8
7
  * system 端口默认配置,承载 SDK 基础运行时能力。
9
8
  */
10
- export declare class SystemOnlineConfig implements OnlineConfig {
9
+ export declare class SystemOnlineConfig extends BaseOnlineConfig {
11
10
  static KEY: string;
12
11
  url: {
13
12
  domain: string;
@@ -32,10 +31,4 @@ export declare class SystemOnlineConfig implements OnlineConfig {
32
31
  toString(): string;
33
32
  resolveSystemUrl(path?: string): string;
34
33
  }
35
- export declare class SystemRemoteConfigDefinitionClass extends BaseRemoteConfigDefinitionClass {
36
- method: string;
37
- createDefault(): SystemOnlineConfig;
38
- merge(target: SystemOnlineConfig, payloads?: Record<string, any>): SystemOnlineConfig;
39
- }
40
- export declare const SystemRemoteConfigDefinition: SystemRemoteConfigDefinitionClass;
41
34
  export declare function resolveSystemUrl(path?: string, config?: SystemOnlineConfig): string;
package/dist/index.js CHANGED
@@ -2923,11 +2923,7 @@ Server.KEY = "Server";
2923
2923
  */
2924
2924
  const server = new Server();
2925
2925
 
2926
- /**
2927
- * definition 的公共抽象基类。
2928
- * interface 负责定义框架契约,abstract class 负责沉淀共用实现。
2929
- */
2930
- class AbstractRemoteConfigDefinition {
2926
+ class BaseOnlineConfig {
2931
2927
  mergeConfigField(target, key, payload) {
2932
2928
  const current = target[key];
2933
2929
  if (current &&
@@ -2947,48 +2943,78 @@ class AbstractRemoteConfigDefinition {
2947
2943
  });
2948
2944
  return target;
2949
2945
  }
2950
- buildRequestData(request, _scope) {
2946
+ buildRequestData(request) {
2951
2947
  return request;
2952
2948
  }
2953
2949
  extractPayloads(response) {
2954
2950
  return response.payloads || {};
2955
2951
  }
2956
- }
2957
- class NoRequestServer {
2958
- requestConfig(_context) {
2959
- return Promise.resolve({ payloads: {} });
2952
+ merge(target, payloads) {
2953
+ return this.mergeObjectConfig(target, payloads);
2960
2954
  }
2961
2955
  }
2962
- NoRequestServer.KEY = "Server";
2956
+ BaseOnlineConfig.KEY = "OnlineConfig_config_default_class";
2963
2957
 
2964
- class BaseOnlineConfig {
2965
- }
2966
- BaseOnlineConfig.KEY = "OnlineConfig_config_default";
2967
- /**
2968
- * Base/config 端口的内建定义。
2969
- * 后续新增 activity / dungeon 等远程配置时,直接新增新的 definition 即可,
2970
- * 不需要再回到 Server.ts 里扩展 method 分支。
2971
- */
2972
- class BaseRemoteConfigDefinitionClass extends AbstractRemoteConfigDefinition {
2958
+ class RemoteConfigRegistry {
2973
2959
  constructor() {
2974
- super(...arguments);
2975
- this.method = "config";
2960
+ this._classMeta = new Map();
2961
+ this._keyClass = new Map();
2976
2962
  }
2977
- createDefault() {
2978
- return Injector.getInjectAlone(BaseOnlineConfig.KEY, BaseOnlineConfig);
2963
+ register(configClass, method, gameFlag = "default", injectorKey) {
2964
+ if (!(configClass.prototype instanceof BaseOnlineConfig) && configClass !== BaseOnlineConfig) {
2965
+ throw new Error(`远程配置${configClass.name || method}必须继承BaseOnlineConfig`);
2966
+ }
2967
+ const normalizedGameFlag = gameFlag || "default";
2968
+ const key = this.createKey(method, normalizedGameFlag);
2969
+ const resolvedInjectorKey = injectorKey || `OnlineConfig_${method}_${normalizedGameFlag}_class`;
2970
+ const meta = {
2971
+ method,
2972
+ gameFlag: normalizedGameFlag,
2973
+ key,
2974
+ injectorKey: resolvedInjectorKey,
2975
+ configClass,
2976
+ };
2977
+ this._classMeta.set(configClass, meta);
2978
+ this._keyClass.set(key, configClass);
2979
+ Injector.inject(resolvedInjectorKey, configClass);
2979
2980
  }
2980
- merge(target, payloads) {
2981
- return this.mergeObjectConfig(target, payloads);
2981
+ getMeta(configClass) {
2982
+ const meta = this._classMeta.get(configClass);
2983
+ if (!meta) {
2984
+ throw new Error(`远程配置${configClass.name}未注册`);
2985
+ }
2986
+ return meta;
2987
+ }
2988
+ getActiveMeta(configClass) {
2989
+ const meta = this.getMeta(configClass);
2990
+ const activeClass = this._keyClass.get(meta.key) || configClass;
2991
+ return this.getMeta(activeClass);
2992
+ }
2993
+ create(configClass) {
2994
+ const meta = this.getActiveMeta(configClass);
2995
+ return Injector.getInjectAlone(meta.injectorKey, meta.configClass);
2996
+ }
2997
+ createKey(method, gameFlag = "default") {
2998
+ return `${method}:${gameFlag || "default"}`;
2982
2999
  }
2983
3000
  }
2984
- const BaseRemoteConfigDefinition = new BaseRemoteConfigDefinitionClass();
2985
- Injector.inject(BaseOnlineConfig.KEY, BaseOnlineConfig);
3001
+ const remoteConfigRegistry = new RemoteConfigRegistry();
3002
+ function getRemoteConfigRegistry() {
3003
+ return remoteConfigRegistry;
3004
+ }
3005
+ function remoteConfig(method, gameFlag = "default", injectorKey) {
3006
+ return function (target) {
3007
+ remoteConfigRegistry.register(target, method, gameFlag, injectorKey);
3008
+ };
3009
+ }
3010
+ remoteConfigRegistry.register(BaseOnlineConfig, "config", "default", BaseOnlineConfig.KEY);
2986
3011
 
2987
3012
  /**
2988
3013
  * system 端口默认配置,承载 SDK 基础运行时能力。
2989
3014
  */
2990
- class SystemOnlineConfig {
3015
+ let SystemOnlineConfig = class SystemOnlineConfig extends BaseOnlineConfig {
2991
3016
  constructor() {
3017
+ super(...arguments);
2992
3018
  this.url = {
2993
3019
  domain: "https://api.kktgame.com",
2994
3020
  configAPI: "/v2/config/{appid}/resolve",
@@ -3072,22 +3098,11 @@ class SystemOnlineConfig {
3072
3098
  const normalizedPath = resolvedPath.startsWith("/") ? resolvedPath : `/${resolvedPath}`;
3073
3099
  return `${normalizedDomain}${normalizedPath}`;
3074
3100
  }
3075
- }
3076
- SystemOnlineConfig.KEY = "OnlineConfig_system_default";
3077
- Injector.inject(SystemOnlineConfig.KEY, SystemOnlineConfig);
3078
- class SystemRemoteConfigDefinitionClass extends BaseRemoteConfigDefinitionClass {
3079
- constructor() {
3080
- super(...arguments);
3081
- this.method = "system";
3082
- }
3083
- createDefault() {
3084
- return Injector.getInjectAlone(SystemOnlineConfig.KEY, SystemOnlineConfig);
3085
- }
3086
- merge(target, payloads) {
3087
- return this.mergeObjectConfig(target, payloads);
3088
- }
3089
- }
3090
- const SystemRemoteConfigDefinition = new SystemRemoteConfigDefinitionClass();
3101
+ };
3102
+ SystemOnlineConfig.KEY = "OnlineConfig_system_default_class";
3103
+ SystemOnlineConfig = __decorate([
3104
+ remoteConfig("system", "default", "OnlineConfig_system_default_class")
3105
+ ], SystemOnlineConfig);
3091
3106
  function resolveSystemUrl(path = "", config = new SystemOnlineConfig()) {
3092
3107
  const urlConfig = config.url;
3093
3108
  const resolvedPath = path.replace(/\{appid\}/g, publisher.appId);
@@ -3105,6 +3120,278 @@ function resolveSystemUrl(path = "", config = new SystemOnlineConfig()) {
3105
3120
  return `${normalizedDomain}${normalizedPath}`;
3106
3121
  }
3107
3122
 
3123
+ const RESOLVE_META_STORAGE_KEY = "ONLINE_CONFIG_CONTEXTS";
3124
+ class RemoteConfigStore {
3125
+ constructor(_registry) {
3126
+ this._registry = _registry;
3127
+ // 运行时快照:给业务读配置时尽量返回稳定对象实例,减少外部感知到的替换。
3128
+ this._snapshots = {};
3129
+ this._loadedKeys = {};
3130
+ this._contexts = null;
3131
+ }
3132
+ snapshot(configClass) {
3133
+ const configKey = this.getConfigKey(configClass);
3134
+ if (!this._snapshots[configKey]) {
3135
+ const config = this._registry.create(configClass);
3136
+ const persisted = storage.getGValue(this.getStorageKey(configClass), undefined);
3137
+ // 首次读取时先构造默认对象,再把本地持久化内容 merge 回来,保证未请求时也能正常工作。
3138
+ this._snapshots[configKey] = persisted ? config.merge(config, persisted) : config;
3139
+ }
3140
+ return this._snapshots[configKey];
3141
+ }
3142
+ apply(configClass, response) {
3143
+ const configKey = this.getConfigKey(configClass);
3144
+ const behavior = this._registry.create(configClass);
3145
+ const payloads = behavior.extractPayloads(response) || {};
3146
+ // merge 策略完全交给配置类,这里不关心是对象合并还是整体替换。
3147
+ const snapshot = behavior.merge(this.snapshot(configClass), payloads);
3148
+ this._snapshots[configKey] = snapshot;
3149
+ this._loadedKeys[configKey] = true;
3150
+ storage.setGValue(this.getStorageKey(configClass), snapshot);
3151
+ this.setResolveMeta(configKey, response.resolveMeta);
3152
+ return snapshot;
3153
+ }
3154
+ getResolveMeta(configClass) {
3155
+ this.ensureContexts();
3156
+ return this._contexts[this.getConfigKey(configClass)];
3157
+ }
3158
+ isLoaded(configClass) {
3159
+ return !!this._loadedKeys[this.getConfigKey(configClass)];
3160
+ }
3161
+ clear() {
3162
+ this._snapshots = {};
3163
+ this._loadedKeys = {};
3164
+ this._contexts = {};
3165
+ storage.setGValue(RESOLVE_META_STORAGE_KEY, {});
3166
+ }
3167
+ ensureContexts() {
3168
+ if (this._contexts == null) {
3169
+ this._contexts = storage.getGValue(RESOLVE_META_STORAGE_KEY, {}) || {};
3170
+ }
3171
+ }
3172
+ getConfigKey(configClass) {
3173
+ const meta = this._registry.getActiveMeta(configClass);
3174
+ return `OnlineConfig_${meta.method}_${meta.gameFlag}`;
3175
+ }
3176
+ getStorageKey(configClass) {
3177
+ return this.getConfigKey(configClass);
3178
+ }
3179
+ setResolveMeta(configKey, resolveMeta) {
3180
+ this.ensureContexts();
3181
+ if (resolveMeta) {
3182
+ this._contexts[configKey] = resolveMeta;
3183
+ }
3184
+ else {
3185
+ delete this._contexts[configKey];
3186
+ }
3187
+ // resolveMeta 单独存一份,避免把命中信息混进真实配置 payload。
3188
+ storage.setGValue(RESOLVE_META_STORAGE_KEY, this._contexts);
3189
+ }
3190
+ }
3191
+ RemoteConfigStore.KEY = "RemoteConfigStore";
3192
+
3193
+ class RemoteConfigService {
3194
+ /**
3195
+ * 统一暴露给测试和少量编排场景的 server 门面。
3196
+ * 真正的协议实现仍然隐藏在 server 内部注入链路后面。
3197
+ */
3198
+ get server() {
3199
+ return server;
3200
+ }
3201
+ get registry() {
3202
+ if (!this._registry) {
3203
+ this._registry = getRemoteConfigRegistry();
3204
+ }
3205
+ return this._registry;
3206
+ }
3207
+ /**
3208
+ * store 只负责快照/持久化/resolveMeta,不负责发请求。
3209
+ * 这样请求协议切换时,不需要改缓存与装配逻辑。
3210
+ */
3211
+ get store() {
3212
+ if (!this._store) {
3213
+ this._store = new RemoteConfigStore(this.registry);
3214
+ }
3215
+ return this._store;
3216
+ }
3217
+ /**
3218
+ * 请求并应用远程配置,返回已装配的快照。
3219
+ * @param configClass 配置类
3220
+ * @param request 请求参数
3221
+ * @param options 请求选项
3222
+ * @returns 装配后的配置快照
3223
+ */
3224
+ fetch(configClass, request, options) {
3225
+ return __awaiter(this, void 0, void 0, function* () {
3226
+ const meta = this.registry.getActiveMeta(configClass);
3227
+ const config = this.registry.create(configClass);
3228
+ const requestData = config.buildRequestData(request);
3229
+ // 非强刷时,优先复用当前已加载快照,避免重复触发同一配置请求。
3230
+ if (!(options === null || options === void 0 ? void 0 : options.refresh) && this.store.isLoaded(configClass)) {
3231
+ return this.config(configClass);
3232
+ }
3233
+ const response = yield this.server.requestConfig({
3234
+ method: meta.method,
3235
+ gameFlag: meta.gameFlag,
3236
+ config,
3237
+ request,
3238
+ requestData,
3239
+ options,
3240
+ });
3241
+ // 远端失败时退回本地快照,保持“配置可读”优先于“请求必须成功”。
3242
+ if (!response) {
3243
+ return this.config(configClass);
3244
+ }
3245
+ const snapshot = this.store.apply(configClass, response);
3246
+ this.applyResolveSideEffects(meta.method, response.resolveMeta, request);
3247
+ return snapshot;
3248
+ });
3249
+ }
3250
+ /**
3251
+ * 获取配置。
3252
+ * @param configClass 配置类
3253
+ * @returns 配置
3254
+ */
3255
+ config(configClass) {
3256
+ return this.store.snapshot(configClass);
3257
+ }
3258
+ /**
3259
+ * 读取最近一次成功命中的 resolve 元信息。
3260
+ */
3261
+ resolveMeta(configClass) {
3262
+ return this.store.getResolveMeta(configClass);
3263
+ }
3264
+ /**
3265
+ * system URL 统一从这里解析,避免调用方直接依赖 helper 或拼接规则。
3266
+ */
3267
+ getSystemUrl(path = "") {
3268
+ return this.config(SystemOnlineConfig).resolveSystemUrl(path);
3269
+ }
3270
+ applyResolveSideEffects(method, resolveMeta, request) {
3271
+ // system 配置本身承担基础设施能力,不需要重复记录 resolve_key / assignment 事件。
3272
+ if (!resolveMeta || method === "system") {
3273
+ return;
3274
+ }
3275
+ analytics.base.setProperty(`${method}_resolve_key`, resolveMeta.resolveKey);
3276
+ const reportAssignments = analytics.reportAssignments;
3277
+ if (typeof reportAssignments === "function") {
3278
+ reportAssignments.call(analytics, resolveMeta, this.getLevelId(request));
3279
+ }
3280
+ }
3281
+ getLevelId(request) {
3282
+ var _a, _b;
3283
+ if (!request) {
3284
+ return undefined;
3285
+ }
3286
+ const levelId = (_b = (_a = request.levelid) !== null && _a !== void 0 ? _a : request.level_id) !== null && _b !== void 0 ? _b : request.id;
3287
+ return levelId === undefined || levelId === null ? undefined : String(levelId);
3288
+ }
3289
+ }
3290
+ const remoteConfigService = new RemoteConfigService();
3291
+
3292
+ let LevelOnlineConfig = class LevelOnlineConfig extends BaseOnlineConfig {
3293
+ merge(_target, payloads) {
3294
+ return (payloads || {});
3295
+ }
3296
+ };
3297
+ LevelOnlineConfig.KEY = "OnlineConfig_level_level_class";
3298
+ LevelOnlineConfig = __decorate([
3299
+ remoteConfig("level", "level", "OnlineConfig_level_level_class")
3300
+ ], LevelOnlineConfig);
3301
+
3302
+ var GameLeaveType;
3303
+ (function (GameLeaveType) {
3304
+ GameLeaveType["success"] = "lv_success";
3305
+ GameLeaveType["fail"] = "lv_fail";
3306
+ GameLeaveType["leave"] = "lv_leave";
3307
+ GameLeaveType["skip"] = "lv_skip";
3308
+ GameLeaveType["revive"] = "lv_revive";
3309
+ GameLeaveType["break"] = "lv_break";
3310
+ GameLeaveType["retry"] = "lv_retry";
3311
+ })(GameLeaveType || (GameLeaveType = {}));
3312
+ /**
3313
+ * 关卡行为自动上报器
3314
+ * 只依赖 GameDimension 的只读会话上下文,不维护独立状态。
3315
+ */
3316
+ class LevelBehaviorReporter {
3317
+ constructor(_game, baseAble) {
3318
+ this._game = _game;
3319
+ this.baseAble = baseAble;
3320
+ }
3321
+ start() {
3322
+ const context = this._getContext();
3323
+ if (!context) {
3324
+ return;
3325
+ }
3326
+ this.reset();
3327
+ this._setTimers();
3328
+ App.onHide(this._leaveApp, this);
3329
+ this.baseAble.report("lv_enter", context);
3330
+ }
3331
+ end(type, data) {
3332
+ const context = this._getContext();
3333
+ if (!context) {
3334
+ this.reset();
3335
+ return;
3336
+ }
3337
+ const levelsession = this._game.getCurrentLevelSession();
3338
+ // 有效操作的平均思考时间
3339
+ const time = levelsession.stepsUsed > 0 ? Math.floor(levelsession.thinkTimeTotal / levelsession.stepsUsed) : 0;
3340
+ this.baseAble.report(type, Object.assign(Object.assign(Object.assign({}, context), data), { time }));
3341
+ this.reset();
3342
+ }
3343
+ reportLeave(data) {
3344
+ const context = this._getContext();
3345
+ if (!context) {
3346
+ return;
3347
+ }
3348
+ this.baseAble.report(GameLeaveType.leave, Object.assign(Object.assign(Object.assign({}, context), { name: "切出游戏" }), data));
3349
+ }
3350
+ reportTimeout(data) {
3351
+ const context = this._getContext();
3352
+ if (!context) {
3353
+ return;
3354
+ }
3355
+ this.baseAble.report("lv_timeout", Object.assign(Object.assign(Object.assign({}, context), { name: "超时" }), data));
3356
+ }
3357
+ reportItem(name, data) {
3358
+ const context = this._getContext();
3359
+ if (!context) {
3360
+ return;
3361
+ }
3362
+ this.baseAble.report("lv_item", Object.assign(Object.assign(Object.assign({}, context), { name: name.toLocaleLowerCase() }), data));
3363
+ }
3364
+ reset() {
3365
+ this.baseAble.cancelTime(GameLeaveType.success);
3366
+ this.baseAble.cancelTime(GameLeaveType.leave);
3367
+ this.baseAble.cancelTime(GameLeaveType.fail);
3368
+ this.baseAble.cancelTime(GameLeaveType.skip);
3369
+ this.baseAble.cancelTime(GameLeaveType.revive);
3370
+ this.baseAble.cancelTime(GameLeaveType.break);
3371
+ this.baseAble.cancelTime(GameLeaveType.retry);
3372
+ this.baseAble.cancelTime("lv_timeout");
3373
+ this.baseAble.cancelTime("ad");
3374
+ App.offHide(this._leaveApp, this);
3375
+ }
3376
+ _leaveApp() {
3377
+ this.reportLeave();
3378
+ }
3379
+ _setTimers() {
3380
+ this.baseAble.time(GameLeaveType.success, false);
3381
+ this.baseAble.time(GameLeaveType.leave, false);
3382
+ this.baseAble.time(GameLeaveType.fail, false);
3383
+ this.baseAble.time(GameLeaveType.skip, false);
3384
+ this.baseAble.time(GameLeaveType.revive, false);
3385
+ this.baseAble.time(GameLeaveType.break, false);
3386
+ this.baseAble.time(GameLeaveType.retry, false);
3387
+ this.baseAble.time("lv_timeout", false);
3388
+ this.baseAble.time("ad", false);
3389
+ }
3390
+ _getContext() {
3391
+ return this._game.getCurrentBehaviorContext();
3392
+ }
3393
+ }
3394
+
3108
3395
  const LEVEL_STATS_NAME = "LEVEL_STATS";
3109
3396
  const LEVEL_STATS_METRIC_ORDER_V1 = [
3110
3397
  'LEVEL_STATS.launch_avg_enters_ma',
@@ -4012,296 +4299,6 @@ class GameDimension extends BaseDimension {
4012
4299
  }
4013
4300
  }
4014
4301
 
4015
- const RESOLVE_META_STORAGE_KEY = "ONLINE_CONFIG_CONTEXTS";
4016
- class RemoteConfigStore {
4017
- constructor() {
4018
- // 运行时快照:给业务读配置时尽量返回稳定对象实例,减少外部感知到的替换。
4019
- this._snapshots = {};
4020
- this._loadedKeys = {};
4021
- this._contexts = null;
4022
- }
4023
- snapshot(definition, scope) {
4024
- const scopeKey = this.getScopeKey(definition, scope);
4025
- if (!this._snapshots[scopeKey]) {
4026
- const config = definition.createDefault();
4027
- const persisted = storage.getGValue(this.getStorageKey(definition, scope), undefined);
4028
- // 首次读取时先构造默认对象,再把本地持久化内容 merge 回来,保证未请求时也能正常工作。
4029
- this._snapshots[scopeKey] = persisted ? definition.merge(config, persisted) : config;
4030
- }
4031
- return this._snapshots[scopeKey];
4032
- }
4033
- apply(definition, scope, response) {
4034
- const scopeKey = this.getScopeKey(definition, scope);
4035
- const payloads = definition.extractPayloads(response) || {};
4036
- // merge 策略完全交给 definition,这里不关心是对象合并还是整体替换。
4037
- const snapshot = definition.merge(this.snapshot(definition, scope), payloads);
4038
- this._snapshots[scopeKey] = snapshot;
4039
- this._loadedKeys[scopeKey] = true;
4040
- storage.setGValue(this.getStorageKey(definition, scope), snapshot);
4041
- this.setResolveMeta(scopeKey, response.resolveMeta);
4042
- return snapshot;
4043
- }
4044
- getResolveMeta(definition, scope) {
4045
- this.ensureContexts();
4046
- return this._contexts[this.getScopeKey(definition, scope)];
4047
- }
4048
- isLoaded(definition, scope) {
4049
- return !!this._loadedKeys[this.getScopeKey(definition, scope)];
4050
- }
4051
- clear() {
4052
- this._snapshots = {};
4053
- this._loadedKeys = {};
4054
- this._contexts = {};
4055
- storage.setGValue(RESOLVE_META_STORAGE_KEY, {});
4056
- }
4057
- ensureContexts() {
4058
- if (this._contexts == null) {
4059
- this._contexts = storage.getGValue(RESOLVE_META_STORAGE_KEY, {}) || {};
4060
- }
4061
- }
4062
- getScopeGameFlag(scope) {
4063
- return (scope === null || scope === void 0 ? void 0 : scope.gameFlag) || DEFAULT_GAME_FLAG;
4064
- }
4065
- createScopedKey(method, scope) {
4066
- return `OnlineConfig_${method}_${this.getScopeGameFlag(scope)}`;
4067
- }
4068
- getScopeKey(definition, scope) {
4069
- return this.createScopedKey(definition.method, scope);
4070
- }
4071
- getStorageKey(definition, scope) {
4072
- return this.createScopedKey(definition.method, scope);
4073
- }
4074
- setResolveMeta(scopeKey, resolveMeta) {
4075
- this.ensureContexts();
4076
- if (resolveMeta) {
4077
- this._contexts[scopeKey] = resolveMeta;
4078
- }
4079
- else {
4080
- delete this._contexts[scopeKey];
4081
- }
4082
- // resolveMeta 单独存一份,避免把命中信息混进真实配置 payload。
4083
- storage.setGValue(RESOLVE_META_STORAGE_KEY, this._contexts);
4084
- }
4085
- }
4086
- RemoteConfigStore.KEY = "RemoteConfigStore";
4087
-
4088
- class RemoteConfigService {
4089
- /**
4090
- * 统一暴露给测试和少量编排场景的 server 门面。
4091
- * 真正的协议实现仍然隐藏在 server 内部注入链路后面。
4092
- */
4093
- get server() {
4094
- return server;
4095
- }
4096
- /**
4097
- * store 只负责快照/持久化/resolveMeta,不负责发请求。
4098
- * 这样请求协议切换时,不需要改缓存与装配逻辑。
4099
- */
4100
- get store() {
4101
- if (!this._store) {
4102
- this._store = Injector.getInject(RemoteConfigStore.KEY);
4103
- }
4104
- return this._store;
4105
- }
4106
- /**
4107
- * 请求并应用远程配置,返回已装配的快照。
4108
- * @param definition 配置定义
4109
- * @param request 请求参数
4110
- * @param scope 作用域
4111
- * @param options 请求选项
4112
- * @returns 装配后的配置快照
4113
- */
4114
- refresh(definition, request, scope, options) {
4115
- return __awaiter(this, void 0, void 0, function* () {
4116
- // 非强刷时,优先复用当前已加载快照,避免重复触发同一配置请求。
4117
- if (!(options === null || options === void 0 ? void 0 : options.refresh) && this.store.isLoaded(definition, scope)) {
4118
- return this.config(definition, scope);
4119
- }
4120
- const response = yield this.server.requestConfig({
4121
- definition,
4122
- request,
4123
- scope,
4124
- options,
4125
- });
4126
- // 远端失败时退回本地快照,保持“配置可读”优先于“请求必须成功”。
4127
- if (!response) {
4128
- return this.config(definition, scope);
4129
- }
4130
- const snapshot = this.store.apply(definition, scope, response);
4131
- this.applyResolveSideEffects(definition, response.resolveMeta, request);
4132
- return snapshot;
4133
- });
4134
- }
4135
- /**
4136
- * 与旧调用习惯兼容的主入口。
4137
- * 语义上等价于 refresh:必要时请求远端,失败时回退本地快照。
4138
- */
4139
- resolve(definition, request, scope, options) {
4140
- return __awaiter(this, void 0, void 0, function* () {
4141
- return this.refresh(definition, request, scope, options);
4142
- });
4143
- }
4144
- /**
4145
- * 获取配置。
4146
- * @param definition 配置定义
4147
- * @param scope 作用域
4148
- * @returns 配置
4149
- */
4150
- config(definition, scope) {
4151
- return this.store.snapshot(definition, scope);
4152
- }
4153
- /**
4154
- * 与旧调用习惯兼容的只读快照接口。
4155
- */
4156
- snapshot(definition, scope) {
4157
- return this.config(definition, scope);
4158
- }
4159
- /**
4160
- * 读取最近一次成功命中的 resolve 元信息。
4161
- */
4162
- resolveMeta(definition, scope) {
4163
- return this.store.getResolveMeta(definition, scope);
4164
- }
4165
- /**
4166
- * system URL 统一从这里解析,避免调用方直接依赖 helper 或拼接规则。
4167
- */
4168
- getSystemUrl(path = "") {
4169
- return resolveSystemUrl(path, this.snapshot(SystemRemoteConfigDefinition));
4170
- }
4171
- applyResolveSideEffects(definition, resolveMeta, request) {
4172
- // system 配置本身承担基础设施能力,不需要重复记录 resolve_key / assignment 事件。
4173
- if (!resolveMeta || definition.method === SystemRemoteConfigDefinition.method) {
4174
- return;
4175
- }
4176
- analytics.base.setProperty(`${definition.method}_resolve_key`, resolveMeta.resolveKey);
4177
- const reportAssignments = analytics.reportAssignments;
4178
- if (typeof reportAssignments === "function") {
4179
- reportAssignments.call(analytics, resolveMeta, this.getLevelId(request));
4180
- }
4181
- }
4182
- getLevelId(request) {
4183
- var _a, _b;
4184
- if (!request) {
4185
- return undefined;
4186
- }
4187
- const levelId = (_b = (_a = request.levelid) !== null && _a !== void 0 ? _a : request.level_id) !== null && _b !== void 0 ? _b : request.id;
4188
- return levelId === undefined || levelId === null ? undefined : String(levelId);
4189
- }
4190
- }
4191
- Injector.inject(RemoteConfigStore.KEY, RemoteConfigStore);
4192
- const remoteConfigService = new RemoteConfigService();
4193
-
4194
- class LevelOnlineConfig {
4195
- }
4196
- LevelOnlineConfig.KEY = "OnlineConfig_level_default";
4197
- Injector.inject(LevelOnlineConfig.KEY, LevelOnlineConfig);
4198
- class LevelRemoteConfigDefinitionClass extends BaseRemoteConfigDefinitionClass {
4199
- constructor() {
4200
- super(...arguments);
4201
- this.method = "level";
4202
- }
4203
- createDefault() {
4204
- return Injector.getInjectAlone(LevelOnlineConfig.KEY, LevelOnlineConfig);
4205
- }
4206
- merge(_target, payloads) {
4207
- return (payloads || {});
4208
- }
4209
- }
4210
- const LevelRemoteConfigDefinition = new LevelRemoteConfigDefinitionClass();
4211
-
4212
- var GameLeaveType;
4213
- (function (GameLeaveType) {
4214
- GameLeaveType["success"] = "lv_success";
4215
- GameLeaveType["fail"] = "lv_fail";
4216
- GameLeaveType["leave"] = "lv_leave";
4217
- GameLeaveType["skip"] = "lv_skip";
4218
- GameLeaveType["revive"] = "lv_revive";
4219
- GameLeaveType["break"] = "lv_break";
4220
- GameLeaveType["retry"] = "lv_retry";
4221
- })(GameLeaveType || (GameLeaveType = {}));
4222
- /**
4223
- * 关卡行为自动上报器
4224
- * 只依赖 GameDimension 的只读会话上下文,不维护独立状态。
4225
- */
4226
- class LevelBehaviorReporter {
4227
- constructor(_game, baseAble) {
4228
- this._game = _game;
4229
- this.baseAble = baseAble;
4230
- }
4231
- start() {
4232
- const context = this._getContext();
4233
- if (!context) {
4234
- return;
4235
- }
4236
- this.reset();
4237
- this._setTimers();
4238
- App.onHide(this._leaveApp, this);
4239
- this.baseAble.report("lv_enter", context);
4240
- }
4241
- end(type, data) {
4242
- const context = this._getContext();
4243
- if (!context) {
4244
- this.reset();
4245
- return;
4246
- }
4247
- const levelsession = this._game.getCurrentLevelSession();
4248
- // 有效操作的平均思考时间
4249
- const time = levelsession.stepsUsed > 0 ? Math.floor(levelsession.thinkTimeTotal / levelsession.stepsUsed) : 0;
4250
- this.baseAble.report(type, Object.assign(Object.assign(Object.assign({}, context), data), { time }));
4251
- this.reset();
4252
- }
4253
- reportLeave(data) {
4254
- const context = this._getContext();
4255
- if (!context) {
4256
- return;
4257
- }
4258
- this.baseAble.report(GameLeaveType.leave, Object.assign(Object.assign(Object.assign({}, context), { name: "切出游戏" }), data));
4259
- }
4260
- reportTimeout(data) {
4261
- const context = this._getContext();
4262
- if (!context) {
4263
- return;
4264
- }
4265
- this.baseAble.report("lv_timeout", Object.assign(Object.assign(Object.assign({}, context), { name: "超时" }), data));
4266
- }
4267
- reportItem(name, data) {
4268
- const context = this._getContext();
4269
- if (!context) {
4270
- return;
4271
- }
4272
- this.baseAble.report("lv_item", Object.assign(Object.assign(Object.assign({}, context), { name: name.toLocaleLowerCase() }), data));
4273
- }
4274
- reset() {
4275
- this.baseAble.cancelTime(GameLeaveType.success);
4276
- this.baseAble.cancelTime(GameLeaveType.leave);
4277
- this.baseAble.cancelTime(GameLeaveType.fail);
4278
- this.baseAble.cancelTime(GameLeaveType.skip);
4279
- this.baseAble.cancelTime(GameLeaveType.revive);
4280
- this.baseAble.cancelTime(GameLeaveType.break);
4281
- this.baseAble.cancelTime(GameLeaveType.retry);
4282
- this.baseAble.cancelTime("lv_timeout");
4283
- this.baseAble.cancelTime("ad");
4284
- App.offHide(this._leaveApp, this);
4285
- }
4286
- _leaveApp() {
4287
- this.reportLeave();
4288
- }
4289
- _setTimers() {
4290
- this.baseAble.time(GameLeaveType.success, false);
4291
- this.baseAble.time(GameLeaveType.leave, false);
4292
- this.baseAble.time(GameLeaveType.fail, false);
4293
- this.baseAble.time(GameLeaveType.skip, false);
4294
- this.baseAble.time(GameLeaveType.revive, false);
4295
- this.baseAble.time(GameLeaveType.break, false);
4296
- this.baseAble.time(GameLeaveType.retry, false);
4297
- this.baseAble.time("lv_timeout", false);
4298
- this.baseAble.time("ad", false);
4299
- }
4300
- _getContext() {
4301
- return this._game.getCurrentBehaviorContext();
4302
- }
4303
- }
4304
-
4305
4302
  class LevelAnalyticsAble {
4306
4303
  constructor(baseAble) {
4307
4304
  this._games = {};
@@ -4353,7 +4350,7 @@ class LevelAnalyticsAble {
4353
4350
  onStart(id, index, gameFlag = DEFAULT_GAME_FLAG, data) {
4354
4351
  return __awaiter(this, void 0, void 0, function* () {
4355
4352
  this._currentGame = this._game(gameFlag);
4356
- const levelInfo = (yield remoteConfigService.resolve(LevelRemoteConfigDefinition, { id }, { gameFlag }, { refresh: true })).info;
4353
+ const levelInfo = (yield remoteConfigService.fetch(LevelOnlineConfig, { id }, { refresh: true })).info;
4357
4354
  if (levelInfo) {
4358
4355
  data = Object.assign(Object.assign({}, levelInfo), data);
4359
4356
  }
@@ -4467,6 +4464,12 @@ class LaunchAnalyticsAble {
4467
4464
  constructor(baseAble) {
4468
4465
  this._baseAble = baseAble;
4469
4466
  }
4467
+ /**
4468
+ * 标记应用准备就绪,开始统计启动时间
4469
+ */
4470
+ ready() {
4471
+ this._baseAble.time("app_launch");
4472
+ }
4470
4473
  /**
4471
4474
  * 上报启动事件
4472
4475
  * @param name 事件名称
@@ -4475,7 +4478,6 @@ class LaunchAnalyticsAble {
4475
4478
  report(name, data) {
4476
4479
  const payload = Object.assign(Object.assign({}, (data || {})), { name });
4477
4480
  this._baseAble.report("app_launch", payload);
4478
- this._baseAble.time("app_launch");
4479
4481
  }
4480
4482
  }
4481
4483
 
@@ -6567,7 +6569,7 @@ class AnalyticsManager {
6567
6569
  return !!String(config && config.project || "").trim() && !!String(config && config.logstore || "").trim();
6568
6570
  }
6569
6571
  createBehaviorSenders() {
6570
- const analyticsConfig = remoteConfigService.config(SystemRemoteConfigDefinition).getAnalyticsConfig();
6572
+ const analyticsConfig = remoteConfigService.config(SystemOnlineConfig).getAnalyticsConfig();
6571
6573
  if (this.hasRelayUrl(analyticsConfig)) {
6572
6574
  return [new KeytopsAnalyticsSender(analyticsConfig)];
6573
6575
  }
@@ -6675,7 +6677,7 @@ class AnalyticsManager {
6675
6677
  }
6676
6678
  get assignmentSender() {
6677
6679
  if (!this._assignmentSender) {
6678
- const analyticsConfig = remoteConfigService.config(SystemRemoteConfigDefinition).getAssignmentConfig();
6680
+ const analyticsConfig = remoteConfigService.config(SystemOnlineConfig).getAssignmentConfig();
6679
6681
  this._assignmentSender = this.hasRelayUrl(analyticsConfig)
6680
6682
  ? new KeytopsAnalyticsSender(analyticsConfig, analyticsConfig.exclude || ["view"])
6681
6683
  : new EmptyAnalyticsSender();
@@ -9066,15 +9068,14 @@ const ab = new ABTesting();
9066
9068
 
9067
9069
  class KKTServer {
9068
9070
  requestConfig(context) {
9069
- var _a, _b, _c;
9070
- const gameFlag = ((_a = context.scope) === null || _a === void 0 ? void 0 : _a.gameFlag) || DEFAULT_GAME_FLAG;
9071
+ var _a, _b;
9072
+ const gameFlag = context.gameFlag || DEFAULT_GAME_FLAG;
9071
9073
  // KKT 协议始终把“通用维度 + 当前玩法关卡维度”一起带上,保持现有服务端分流能力。
9072
- const gameMetrics = ((_b = analytics.level) === null || _b === void 0 ? void 0 : _b.getGameMetrics)
9074
+ const gameMetrics = ((_a = analytics.level) === null || _a === void 0 ? void 0 : _a.getGameMetrics)
9073
9075
  ? analytics.level.getGameMetrics(gameFlag)
9074
9076
  : {};
9075
- // 每种配置 definition 只负责自己的业务参数,KKT 公共协议字段由这里统一补齐。
9076
- const requestData = context.definition.buildRequestData(context.request, context.scope);
9077
- const params = this.getRequestParams(context.definition.method, gameFlag, gameMetrics, requestData, (_c = context.options) === null || _c === void 0 ? void 0 : _c.debug);
9077
+ // 每种配置类只负责自己的业务参数,KKT 公共协议字段由这里统一补齐。
9078
+ const params = this.getRequestParams(context.method, gameFlag, gameMetrics, context.requestData, (_b = context.options) === null || _b === void 0 ? void 0 : _b.debug);
9078
9079
  return this.sentRequest(this.getResolveUrl(), params).then((response) => this.normalizeResponse(response));
9079
9080
  }
9080
9081
  getRequestParams(method, gameFlag, gameMetrics, data, isDebug) {
@@ -9100,7 +9101,7 @@ class KKTServer {
9100
9101
  }
9101
9102
  getResolveUrl() {
9102
9103
  // resolve URL 仍然来自 system 配置快照,这样协议实现不直接持有配置缓存状态。
9103
- const systemConfig = remoteConfigService.config(SystemRemoteConfigDefinition);
9104
+ const systemConfig = remoteConfigService.config(SystemOnlineConfig);
9104
9105
  return systemConfig.resolveSystemUrl(systemConfig.url.configAPI || `/v2/config/${publisher.appId}/resolve`);
9105
9106
  }
9106
9107
  normalizeResponse(response) {
@@ -9138,6 +9139,13 @@ class KKTServer {
9138
9139
  }
9139
9140
  Injector.inject("Server", KKTServer);
9140
9141
 
9142
+ class NoRequestServer {
9143
+ requestConfig(_context) {
9144
+ return Promise.resolve({ payloads: {} });
9145
+ }
9146
+ }
9147
+ NoRequestServer.KEY = "Server";
9148
+
9141
9149
  let handlerMap = new Map();
9142
9150
  /**
9143
9151
  * socket response 处理装饰器
@@ -10535,7 +10543,7 @@ class KSLogin extends ILoginAble {
10535
10543
  return super.init(type);
10536
10544
  }
10537
10545
  login(caller, onSuccess, onFail) {
10538
- const secret = (remoteConfigService.snapshot(BaseRemoteConfigDefinition)['secret'] || []).join("");
10546
+ const secret = (remoteConfigService.config(BaseOnlineConfig)['secret'] || []).join("");
10539
10547
  this._ks.login({
10540
10548
  force: true,
10541
10549
  success: (res) => {
@@ -11707,7 +11715,7 @@ class TTLogin extends ILoginAble {
11707
11715
  force: true,
11708
11716
  success: (res) => {
11709
11717
  console.log(`tt.login 调用成功${res.code} ${res.anonymousCode}`);
11710
- const systemConfig = remoteConfigService.snapshot(SystemRemoteConfigDefinition);
11718
+ const systemConfig = remoteConfigService.config(SystemOnlineConfig);
11711
11719
  net.http.post(remoteConfigService.getSystemUrl(systemConfig.url.loginAPI), {
11712
11720
  data: {
11713
11721
  appid: publisher.appId,
@@ -11965,7 +11973,7 @@ class WXLogin extends ILoginAble {
11965
11973
  success: (res) => {
11966
11974
  if (res.code) {
11967
11975
  // this._code = res.code;
11968
- const systemConfig = remoteConfigService.snapshot(SystemRemoteConfigDefinition);
11976
+ const systemConfig = remoteConfigService.config(SystemOnlineConfig);
11969
11977
  net.http.post(remoteConfigService.getSystemUrl(systemConfig.url.loginAPI), {
11970
11978
  data: {
11971
11979
  appid: publisher.appId,
@@ -12073,7 +12081,7 @@ class PublisherManagerImpl extends IPublisherManager {
12073
12081
  }
12074
12082
  _enableWeb() {
12075
12083
  const TYPE = IPublisher.TYPE_H5;
12076
- this.enableAdAble(TYPE, IADAble, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12084
+ this.enableAdAble(TYPE, IADAble, remoteConfigService.config(SystemOnlineConfig).ad);
12077
12085
  return true;
12078
12086
  }
12079
12087
  _initTT() {
@@ -12093,7 +12101,7 @@ class PublisherManagerImpl extends IPublisherManager {
12093
12101
  return false;
12094
12102
  }
12095
12103
  const TYPE = IPublisher.TYPE_TT;
12096
- this.enableAdAble(TYPE, TTAd, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12104
+ this.enableAdAble(TYPE, TTAd, remoteConfigService.config(SystemOnlineConfig).ad);
12097
12105
  return true;
12098
12106
  }
12099
12107
  _initWX() {
@@ -12112,7 +12120,7 @@ class PublisherManagerImpl extends IPublisherManager {
12112
12120
  return false;
12113
12121
  }
12114
12122
  const TYPE = "WX";
12115
- this.enableAdAble(TYPE, WXAd, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12123
+ this.enableAdAble(TYPE, WXAd, remoteConfigService.config(SystemOnlineConfig).ad);
12116
12124
  return true;
12117
12125
  }
12118
12126
  _initKS() {
@@ -12132,7 +12140,7 @@ class PublisherManagerImpl extends IPublisherManager {
12132
12140
  return false;
12133
12141
  }
12134
12142
  const TYPE = "KS";
12135
- this.enableAdAble(TYPE, KSAd, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12143
+ this.enableAdAble(TYPE, KSAd, remoteConfigService.config(SystemOnlineConfig).ad);
12136
12144
  return true;
12137
12145
  }
12138
12146
  _initMY() {
@@ -12151,7 +12159,7 @@ class PublisherManagerImpl extends IPublisherManager {
12151
12159
  return false;
12152
12160
  }
12153
12161
  const TYPE = "MY";
12154
- this.enableAdAble(TYPE, MYAd, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12162
+ this.enableAdAble(TYPE, MYAd, remoteConfigService.config(SystemOnlineConfig).ad);
12155
12163
  return true;
12156
12164
  }
12157
12165
  _initNative() {
@@ -12172,7 +12180,7 @@ class PublisherManagerImpl extends IPublisherManager {
12172
12180
  return false;
12173
12181
  }
12174
12182
  const TYPE = "native";
12175
- this.enableAdAble(TYPE, NativeAd, remoteConfigService.snapshot(SystemRemoteConfigDefinition).ad);
12183
+ this.enableAdAble(TYPE, NativeAd, remoteConfigService.config(SystemOnlineConfig).ad);
12176
12184
  return true;
12177
12185
  }
12178
12186
  }
@@ -12712,42 +12720,11 @@ class TTAnalyticsSender extends EmptyAnalyticsSender {
12712
12720
  }
12713
12721
  }
12714
12722
 
12715
- const definitionCache = new Map();
12716
- class DynamicRemoteConfigDefinition extends AbstractRemoteConfigDefinition {
12717
- constructor(method) {
12718
- super();
12719
- this.method = method;
12720
- }
12721
- createDefault() {
12722
- return {};
12723
- }
12724
- merge(target, payloads) {
12725
- return this.mergeObjectConfig(target, payloads);
12726
- }
12727
- }
12728
12723
  const INTERNAL_METHODS = {
12729
- CONFIG: BaseRemoteConfigDefinition.method,
12730
- SYSTEM: SystemRemoteConfigDefinition.method,
12731
- LEVEL: LevelRemoteConfigDefinition.method,
12724
+ CONFIG: "config",
12725
+ SYSTEM: "system",
12726
+ LEVEL: "level",
12732
12727
  };
12733
- function getRemoteConfigDefinition(method) {
12734
- if (method === BaseRemoteConfigDefinition.method) {
12735
- return BaseRemoteConfigDefinition;
12736
- }
12737
- if (method === SystemRemoteConfigDefinition.method) {
12738
- return SystemRemoteConfigDefinition;
12739
- }
12740
- if (method === LevelRemoteConfigDefinition.method) {
12741
- return LevelRemoteConfigDefinition;
12742
- }
12743
- const cached = definitionCache.get(method);
12744
- if (cached) {
12745
- return cached;
12746
- }
12747
- const dynamicDefinition = new DynamicRemoteConfigDefinition(method);
12748
- definitionCache.set(method, dynamicDefinition);
12749
- return dynamicDefinition;
12750
- }
12751
12728
 
12752
12729
  /**
12753
12730
  * 掩码
@@ -15164,4 +15141,4 @@ TipsView = __decorate([
15164
15141
  menu("基础视图/TipsView")
15165
15142
  ], TipsView);
15166
15143
 
15167
- export { ADAnalyticsAble, ADBehaviorReporter, ADEvent, ADType, AD_METRIC_ORDER_V1, ALiAnalyticsSender, AbstractRemoteConfigDefinition, AdDimension, AnalyticsAble, App, Application, Async, AudioBusiness, BaseDimension, BaseOnlineConfig, BaseProtocolHelper, BaseRemoteConfigDefinition, BaseRemoteConfigDefinitionClass, BusinessCenter, ByteView, CCPViewLoader, CCSceneLoader, CocosNativeHelper, CocosStorageUtils, CocosViewManager, Component, ConfigHelper, DEFAULT_GAME_FLAG, Dictionary, DimensionType, ECS, EffectAudioSourceProxy, EmptyAnalyticsSender, EmptyLink, EnterOptionParser, Event$2 as Event, EventDispatcher, Fsm, FsmBase, GameDimension, GameLeaveType, GeometryUtils, Handler, HttpNode, HttpRequest, IADAble, IDevice, IGameUpdateAble, ILoginAble, INTERNAL_METHODS, INativeHelper, IPayAble, IPublisher, IPublisherManager, IRecordAble, IShareAble, IViewLoader, Injector, Json, KKTServer, KSAd, KSDevice, KSLogin, KSPublisher, KSRecorder, KSShare, KeytopsAnalyticsSender, LEVEL_STATS_METRIC_ORDER_V1, LaunchAnalyticsAble, LevelAnalyticsAble, LevelBehaviorReporter, LevelOnlineConfig, LevelRemoteConfigDefinition, LevelRemoteConfigDefinitionClass, LevelStatsDimension, Link, List, LogType, Logger, MYAd, MYDevice, MYLogin, MYPublisher, Mask, MathUtils, MemeryStorage, NativeAd, NativeAnalyticsSender, NativeDevice, NativeHelper, NativeLogin, NativePay, NativePublisher, NativeRecorder, NativeShare, NativeUtils, NetManager, NoRequestServer, PLAYER_ABILITY_METRIC_ORDER_V1, PlayerAbilityDimension, Pool, PromiseUtils, PropSupport, PublisherManager, PublisherManagerImpl, RemoteConfigService, RemoteConfigStore, ResourceManager, RewardVideoMaskBusiness, RuntimeApplicationImpl, Scene, Server, SessionAnalyticsAble, SessionDimension, SocialAnalyticsAble, SocialDimension, Socket, SocketLogType, SocketNode, Storage, StorageImpl, StringUtils, System, SystemOnlineConfig, SystemRemoteConfigDefinition, SystemRemoteConfigDefinitionClass, TKAd, TKAnalyticsSender, TKDevice, TKLogin, TKPublisher, TTAd, TTAnalyticsSender, TTDevice, TTGameUpdater, TTLogin, TTPay, TTPublisher, TTRecorder, TTShare, Task, TaskQueue, TaskSequence, Timer, TimerImpl, TipsType, TipsView, View, ViewControl, ViewLevel, ViewManager, WXAd, WXAnalyticsSender, WXDevice, WXGameUpdater, WXLogin, WXPay, WXPublisher, WXShare, ab, analytics, audio, bidding, businessCenter, cmd, component, eventCenter, fsmManager, getRemoteConfigDefinition, manager, md5, net, publisher, remoteConfigService, res, resolveSystemUrl, server, storage, system, timer, version, viewAnalytics, viewClass, viewManager };
15144
+ export { ADAnalyticsAble, ADBehaviorReporter, ADEvent, ADType, AD_METRIC_ORDER_V1, ALiAnalyticsSender, AdDimension, AnalyticsAble, App, Application, Async, AudioBusiness, BaseDimension, BaseOnlineConfig, BaseProtocolHelper, BusinessCenter, ByteView, CCPViewLoader, CCSceneLoader, CocosNativeHelper, CocosStorageUtils, CocosViewManager, Component, ConfigHelper, DEFAULT_GAME_FLAG, Dictionary, DimensionType, ECS, EffectAudioSourceProxy, EmptyAnalyticsSender, EmptyLink, EnterOptionParser, Event$2 as Event, EventDispatcher, Fsm, FsmBase, GameDimension, GameLeaveType, GeometryUtils, Handler, HttpNode, HttpRequest, IADAble, IDevice, IGameUpdateAble, ILoginAble, INTERNAL_METHODS, INativeHelper, IPayAble, IPublisher, IPublisherManager, IRecordAble, IShareAble, IViewLoader, Injector, Json, KKTServer, KSAd, KSDevice, KSLogin, KSPublisher, KSRecorder, KSShare, KeytopsAnalyticsSender, LEVEL_STATS_METRIC_ORDER_V1, LaunchAnalyticsAble, LevelAnalyticsAble, LevelBehaviorReporter, LevelOnlineConfig, LevelStatsDimension, Link, List, LogType, Logger, MYAd, MYDevice, MYLogin, MYPublisher, Mask, MathUtils, MemeryStorage, NativeAd, NativeAnalyticsSender, NativeDevice, NativeHelper, NativeLogin, NativePay, NativePublisher, NativeRecorder, NativeShare, NativeUtils, NetManager, NoRequestServer, PLAYER_ABILITY_METRIC_ORDER_V1, PlayerAbilityDimension, Pool, PromiseUtils, PropSupport, PublisherManager, PublisherManagerImpl, RemoteConfigService, RemoteConfigStore, ResourceManager, RewardVideoMaskBusiness, RuntimeApplicationImpl, Scene, Server, SessionAnalyticsAble, SessionDimension, SocialAnalyticsAble, SocialDimension, Socket, SocketLogType, SocketNode, Storage, StorageImpl, StringUtils, System, SystemOnlineConfig, TKAd, TKAnalyticsSender, TKDevice, TKLogin, TKPublisher, TTAd, TTAnalyticsSender, TTDevice, TTGameUpdater, TTLogin, TTPay, TTPublisher, TTRecorder, TTShare, Task, TaskQueue, TaskSequence, Timer, TimerImpl, TipsType, TipsView, View, ViewControl, ViewLevel, ViewManager, WXAd, WXAnalyticsSender, WXDevice, WXGameUpdater, WXLogin, WXPay, WXPublisher, WXShare, ab, analytics, audio, bidding, businessCenter, cmd, component, eventCenter, fsmManager, manager, md5, net, publisher, remoteConfig, remoteConfigService, res, resolveSystemUrl, server, storage, system, timer, version, viewAnalytics, viewClass, viewManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keytops-game-framework",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "cocos creator game framework library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",