@chiyou/minigame-framework 1.4.1 → 1.4.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chiyou/minigame-framework",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "基于 Cocos Creator 3.x 的小游戏开发框架,支持多平台发布",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -1,15 +1,19 @@
1
1
  import { Component } from "cc";
2
2
  import { ScreenInfo } from "../../Definition/SystemDefinition";
3
3
  import { SystemMgr } from "../../Manager/SystemMgr";
4
+ import { LaunchCategory, LaunchSceneInfo } from "../../Definition/AnalyticsDefinition";
4
5
 
5
6
  export abstract class AbsPlatformAdapter extends Component{
6
7
 
7
8
  protected coldStartOptions: any = null;
8
9
  protected warmStartOptions: any = null;
9
10
 
10
- protected coldStartScene: string = "";
11
+ protected _coldStartScene: string = "";
11
12
  protected warmStartScene: string = "";
12
13
 
14
+ /** 启动场景分类表(子类在构造函数中初始化) */
15
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map();
16
+
13
17
  protected isShareActive: boolean = false;
14
18
 
15
19
  protected systemMgr: SystemMgr = null;
@@ -74,15 +78,22 @@ export abstract class AbsPlatformAdapter extends Component{
74
78
 
75
79
  abstract offHide(fn: Function): void;
76
80
 
81
+ /** 获取冷启动场景信息 */
82
+ public getColdStartSceneInfo(): LaunchSceneInfo {
83
+ for (const [category, sceneSet] of this.launchSceneCategoryMap) {
84
+ if (category === LaunchCategory.Other) continue;
85
+ if (sceneSet.has(this._coldStartScene)) {
86
+ return { scene: this._coldStartScene, category };
87
+ }
88
+ }
89
+ return { scene: this._coldStartScene, category: LaunchCategory.Other };
90
+ }
91
+
77
92
  abstract isNavigateToRecentUseAvailable(callback: Function): void;
78
93
 
79
94
  abstract navigateToRecentUse(): void;
80
95
 
81
- abstract isLaunchFromRecentUse(): boolean;
82
-
83
- abstract isLaunchFromDesktopShortcut(): boolean;
84
96
 
85
- abstract isLaunchFromAdvertisement(): boolean;
86
97
 
87
98
  abstract checkSession(callback: (isValid: boolean) => void): void;
88
99
 
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -7,6 +8,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
7
8
  export class PlatformAdapterBilibili extends AbsPlatformAdapter {
8
9
 
9
10
  static TAG: string = "PlatformAdapterBilibili";
11
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
12
+ [LaunchCategory.RecentUse, new Set(["10001", "021036"])],
13
+ [LaunchCategory.Desktop, new Set(["10002"])],
14
+ [LaunchCategory.Search, new Set([])],
15
+ [LaunchCategory.Chat, new Set([])],
16
+ [LaunchCategory.Share, new Set([])],
17
+ [LaunchCategory.Ad, new Set([])],
18
+ [LaunchCategory.Other, new Set([])],
19
+ ]);
10
20
 
11
21
  // Common
12
22
  public init(): void {
@@ -391,18 +401,18 @@ export class PlatformAdapterBilibili extends AbsPlatformAdapter {
391
401
 
392
402
  public onGameColdStart(): void {
393
403
  this.coldStartOptions = null;
394
- this.coldStartScene = "";
404
+ this._coldStartScene = "";
395
405
 
396
406
  if (window["bl"] && window["bl"].getLaunchOptionsSync) {
397
407
  this.coldStartOptions = window["bl"].getLaunchOptionsSync();
398
408
  if (this.coldStartOptions !== null && this.coldStartOptions["scene"]) {
399
- this.coldStartScene = this.coldStartOptions["scene"];
409
+ this._coldStartScene = this.coldStartOptions["scene"];
400
410
  }
401
411
  }
402
412
 
403
413
  LogUtils.Instance.info(PlatformAdapterBilibili.TAG, "冷启动场景更新", {
404
414
  operation: "updateColdStartScene",
405
- scene: this.coldStartScene
415
+ scene: this._coldStartScene
406
416
  });
407
417
  }
408
418
 
@@ -508,38 +518,8 @@ export class PlatformAdapterBilibili extends AbsPlatformAdapter {
508
518
  });
509
519
  }
510
520
 
511
- public isLaunchFromRecentUse(): boolean {
512
- let recentUseSceneSet: Set<string> = new Set<string>([
513
- "10001",
514
- "021036",
515
- ]);
516
521
 
517
- let isLaunchFromRecentUse: boolean = recentUseSceneSet.has(this.coldStartScene) || recentUseSceneSet.has(this.warmStartScene);
518
- LogUtils.Instance.info(PlatformAdapterBilibili.TAG, "判断是否最近使用启动", {
519
- operation: "isLaunchFromRecentUse",
520
- result: isLaunchFromRecentUse
521
- });
522
-
523
- return isLaunchFromRecentUse;
524
- }
525
522
 
526
- public isLaunchFromDesktopShortcut(): boolean {
527
- let desktopShortcutSceneSet: Set<string> = new Set<string>([
528
- "10002",
529
- ]);
530
-
531
- let isLaunchFromDesktopShortcut: boolean = desktopShortcutSceneSet.has(this.coldStartScene) || desktopShortcutSceneSet.has(this.warmStartScene);
532
- LogUtils.Instance.info(PlatformAdapterBilibili.TAG, "判断是否桌面快捷方式启动", {
533
- operation: "isLaunchFromDesktopShortcut",
534
- result: isLaunchFromDesktopShortcut
535
- });
536
-
537
- return isLaunchFromDesktopShortcut;
538
- }
539
-
540
- public isLaunchFromAdvertisement(): boolean {
541
- return false;
542
- }
543
523
 
544
524
  public checkSession(callback: (isValid: boolean) => void): void {
545
525
  if (window["bl"] && window["bl"].checkSession) {
@@ -1,4 +1,5 @@
1
1
  import { game } from 'cc';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
3
4
  import { LogUtils } from '../../Utils/LogUtils';
4
5
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
@@ -9,6 +10,16 @@ export class PlatformAdapterDesktopBrowser extends AbsPlatformAdapter {
9
10
 
10
11
  static TAG: string = "PlatformAdapterDesktopBrowser";
11
12
 
13
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
14
+ [LaunchCategory.RecentUse, new Set()],
15
+ [LaunchCategory.Desktop, new Set()],
16
+ [LaunchCategory.Search, new Set()],
17
+ [LaunchCategory.Chat, new Set()],
18
+ [LaunchCategory.Share, new Set()],
19
+ [LaunchCategory.Ad, new Set()],
20
+ [LaunchCategory.Other, new Set()],
21
+ ]);
22
+
12
23
  // Common
13
24
  public init(): void {
14
25
 
@@ -156,11 +167,11 @@ export class PlatformAdapterDesktopBrowser extends AbsPlatformAdapter {
156
167
 
157
168
  public onGameColdStart(): void {
158
169
  this.coldStartOptions = null;
159
- this.coldStartScene = "";
170
+ this._coldStartScene = "";
160
171
 
161
172
  LogUtils.Instance.info(PlatformAdapterDesktopBrowser.TAG, "冷启动场景更新", {
162
173
  operation: "updateColdStartScene",
163
- scene: this.coldStartScene
174
+ scene: this._coldStartScene
164
175
  });
165
176
  }
166
177
 
@@ -210,17 +221,8 @@ export class PlatformAdapterDesktopBrowser extends AbsPlatformAdapter {
210
221
 
211
222
  }
212
223
 
213
- public isLaunchFromRecentUse(): boolean {
214
- return false;
215
- }
216
224
 
217
- public isLaunchFromDesktopShortcut(): boolean {
218
- return false;
219
- }
220
225
 
221
- public isLaunchFromAdvertisement(): boolean {
222
- return false;
223
- }
224
226
 
225
227
  public checkSession(callback: (isValid: boolean) => void): void {
226
228
  // Browser不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -11,6 +12,15 @@ class DouYinPlatformBusiness {
11
12
  export class PlatformAdapterDouYin extends AbsPlatformAdapter {
12
13
 
13
14
  static TAG: string = "PlatformAdapterDouYin";
15
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
16
+ [LaunchCategory.RecentUse, new Set(["021036", "021012", "101036", "011004", "181003", "061004"])],
17
+ [LaunchCategory.Desktop, new Set(["021020", "101020", "181020", "141020", "991020"])],
18
+ [LaunchCategory.Search, new Set([])],
19
+ [LaunchCategory.Chat, new Set([])],
20
+ [LaunchCategory.Share, new Set([])],
21
+ [LaunchCategory.Ad, new Set(["025001", "235001", "016001", "016002", "016003", "105001"])],
22
+ [LaunchCategory.Other, new Set([])],
23
+ ]);
14
24
 
15
25
  private portalGame: any = null;
16
26
 
@@ -408,18 +418,18 @@ export class PlatformAdapterDouYin extends AbsPlatformAdapter {
408
418
 
409
419
  public onGameColdStart(): void {
410
420
  this.coldStartOptions = null;
411
- this.coldStartScene = "";
421
+ this._coldStartScene = "";
412
422
 
413
423
  if (window["tt"] && window["tt"].getLaunchOptionsSync) {
414
424
  this.coldStartOptions = window["tt"].getLaunchOptionsSync();
415
425
  if (this.coldStartOptions !== null && this.coldStartOptions["scene"]) {
416
- this.coldStartScene = this.coldStartOptions["scene"];
426
+ this._coldStartScene = this.coldStartOptions["scene"];
417
427
  }
418
428
  }
419
429
 
420
430
  LogUtils.Instance.info(PlatformAdapterDouYin.TAG, "冷启动场景更新", {
421
431
  operation: "updateColdStartScene",
422
- scene: this.coldStartScene
432
+ scene: this._coldStartScene
423
433
  });
424
434
  }
425
435
 
@@ -524,54 +534,8 @@ export class PlatformAdapterDouYin extends AbsPlatformAdapter {
524
534
  });
525
535
  }
526
536
 
527
- public isLaunchFromRecentUse(): boolean {
528
- let recentUseSceneSet: Set<string> = new Set<string>([
529
- "021036",
530
- "021012",
531
- "101036",
532
- "011004",
533
- "181003",
534
- "061004",
535
- ]);
536
-
537
- let isLaunchFromRecentUse: boolean = recentUseSceneSet.has(this.coldStartScene) || recentUseSceneSet.has(this.warmStartScene);
538
- LogUtils.Instance.info(PlatformAdapterDouYin.TAG, "判断是否最近使用启动", {
539
- operation: "isLaunchFromRecentUse",
540
- result: isLaunchFromRecentUse
541
- });
542
- return isLaunchFromRecentUse;
543
- }
544
-
545
- public isLaunchFromDesktopShortcut(): boolean {
546
- let desktopShortcutSceneSet: Set<string> = new Set<string>([
547
- "021020",
548
- "101020",
549
- "181020",
550
- "141020",
551
- "991020",
552
- ]);
553
-
554
- let isLaunchFromDesktopShortcut: boolean = desktopShortcutSceneSet.has(this.coldStartScene) || desktopShortcutSceneSet.has(this.warmStartScene);
555
- LogUtils.Instance.info(PlatformAdapterDouYin.TAG, "判断是否桌面快捷方式启动", {
556
- operation: "isLaunchFromDesktopShortcut",
557
- result: isLaunchFromDesktopShortcut
558
- });
559
- return isLaunchFromDesktopShortcut;
560
- }
561
537
 
562
- public isLaunchFromAdvertisement(): boolean {
563
- let advertisementSceneSet: Set<string> = new Set<string>([
564
- "025001", "235001", "016001",
565
- "016002", "016003", "105001",
566
- ]);
567
538
 
568
- let isLaunchFromAdvertisement: boolean = advertisementSceneSet.has(this.coldStartScene);
569
- LogUtils.Instance.info(PlatformAdapterDouYin.TAG, "判断是否广告启动", {
570
- operation: "isLaunchFromAdvertisement",
571
- result: isLaunchFromAdvertisement
572
- });
573
- return isLaunchFromAdvertisement;
574
- }
575
539
 
576
540
  public checkSession(callback: (isValid: boolean) => void): void {
577
541
  if (window["tt"] && window["tt"].checkSession) {
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -6,6 +7,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
6
7
 
7
8
  export class PlatformAdapterHonor extends AbsPlatformAdapter {
8
9
  static TAG: string = "PlatformAdapterHonor";
10
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
11
+ [LaunchCategory.RecentUse, new Set([])],
12
+ [LaunchCategory.Desktop, new Set([])],
13
+ [LaunchCategory.Search, new Set([])],
14
+ [LaunchCategory.Chat, new Set([])],
15
+ [LaunchCategory.Share, new Set([])],
16
+ [LaunchCategory.Ad, new Set([])],
17
+ [LaunchCategory.Other, new Set([])],
18
+ ]);
9
19
 
10
20
  // Common
11
21
  public init(): void {
@@ -289,7 +299,7 @@ export class PlatformAdapterHonor extends AbsPlatformAdapter {
289
299
 
290
300
  public onGameColdStart(): void {
291
301
  this.coldStartOptions = null;
292
- this.coldStartScene = "";
302
+ this._coldStartScene = "";
293
303
  }
294
304
 
295
305
  public onGameShowCallback(warmStartOptions: any): void {
@@ -341,17 +351,8 @@ export class PlatformAdapterHonor extends AbsPlatformAdapter {
341
351
 
342
352
  }
343
353
 
344
- public isLaunchFromRecentUse(): boolean {
345
- return false;
346
- }
347
354
 
348
- public isLaunchFromDesktopShortcut(): boolean {
349
- return false;
350
- }
351
355
 
352
- public isLaunchFromAdvertisement(): boolean {
353
- return false;
354
- }
355
356
 
356
357
  public checkSession(callback: (isValid: boolean) => void): void {
357
358
  // Honor不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
4
5
  import { PlatformID, ScreenInfo } from '../../Definition/SystemDefinition';
@@ -6,6 +7,15 @@ import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
6
7
 
7
8
  export class PlatformAdapterHuaWei extends AbsPlatformAdapter {
8
9
  static TAG: string = "PlatformAdapterHuaWei";
10
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
11
+ [LaunchCategory.RecentUse, new Set([])],
12
+ [LaunchCategory.Desktop, new Set([])],
13
+ [LaunchCategory.Search, new Set([])],
14
+ [LaunchCategory.Chat, new Set([])],
15
+ [LaunchCategory.Share, new Set([])],
16
+ [LaunchCategory.Ad, new Set([])],
17
+ [LaunchCategory.Other, new Set([])],
18
+ ]);
9
19
 
10
20
  // Common
11
21
  public init(): void {
@@ -287,7 +297,7 @@ export class PlatformAdapterHuaWei extends AbsPlatformAdapter {
287
297
 
288
298
  public onGameColdStart(): void {
289
299
  this.coldStartOptions = null;
290
- this.coldStartScene = "";
300
+ this._coldStartScene = "";
291
301
  }
292
302
 
293
303
  public onGameShowCallback(warmStartOptions: any): void {
@@ -339,17 +349,8 @@ export class PlatformAdapterHuaWei extends AbsPlatformAdapter {
339
349
 
340
350
  }
341
351
 
342
- public isLaunchFromRecentUse(): boolean {
343
- return false;
344
- }
345
352
 
346
- public isLaunchFromDesktopShortcut(): boolean {
347
- return false;
348
- }
349
353
 
350
- public isLaunchFromAdvertisement(): boolean {
351
- return false;
352
- }
353
354
 
354
355
  public checkSession(callback: (isValid: boolean) => void): void {
355
356
  // HuaWei不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -8,6 +9,16 @@ export class PlatformAdapterKuaiShou extends AbsPlatformAdapter {
8
9
 
9
10
  static TAG: string = "PlatformAdapterKuaiShou";
10
11
 
12
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
13
+ [LaunchCategory.RecentUse, new Set(["sidebar_new", "sidebar_miniprogram", "profile"])],
14
+ [LaunchCategory.Desktop, new Set()],
15
+ [LaunchCategory.Search, new Set()],
16
+ [LaunchCategory.Chat, new Set()],
17
+ [LaunchCategory.Share, new Set()],
18
+ [LaunchCategory.Ad, new Set(["dsp"])],
19
+ [LaunchCategory.Other, new Set()],
20
+ ]);
21
+
11
22
  // Common
12
23
  public init(): void {
13
24
 
@@ -292,18 +303,18 @@ export class PlatformAdapterKuaiShou extends AbsPlatformAdapter {
292
303
 
293
304
  public onGameColdStart(): void {
294
305
  this.coldStartOptions = null;
295
- this.coldStartScene = "";
306
+ this._coldStartScene = "";
296
307
 
297
308
  if (window["ks"] && window["ks"].getLaunchOptionsSync) {
298
309
  this.coldStartOptions = window["ks"].getLaunchOptionsSync();
299
310
  if (this.coldStartOptions !== null && this.coldStartOptions["from"]) {
300
- this.coldStartScene = this.coldStartOptions["from"];
311
+ this._coldStartScene = this.coldStartOptions["from"];
301
312
  }
302
313
  }
303
314
 
304
315
  LogUtils.Instance.info(PlatformAdapterKuaiShou.TAG, "冷启动场景更新", {
305
316
  operation: "updateColdStartScene",
306
- scene: this.coldStartScene
317
+ scene: this._coldStartScene
307
318
  });
308
319
  }
309
320
 
@@ -361,44 +372,28 @@ export class PlatformAdapterKuaiShou extends AbsPlatformAdapter {
361
372
 
362
373
  }
363
374
 
364
- public isLaunchFromRecentUse(): boolean {
365
- let recentUseSceneSet: Set<string> = new Set<string>([
366
- "sidebar_new",
367
- "sidebar_miniprogram",
368
- "profile",
369
- ]);
370
- let isLaunchFromRecentUse: boolean = recentUseSceneSet.has(this.coldStartScene) || recentUseSceneSet.has(this.warmStartScene);
371
- LogUtils.Instance.info(PlatformAdapterKuaiShou.TAG, "判断是否最近使用启动", {
372
- operation: "isLaunchFromRecentUse",
373
- result: isLaunchFromRecentUse
374
- });
375
- return isLaunchFromRecentUse;
376
- }
377
-
378
- public isLaunchFromDesktopShortcut(): boolean {
379
- let isLaunchFromDesktopShortcut: boolean = false;
375
+ /** 重写:快手桌面判断需调用 API */
376
+ public getColdStartSceneInfo(): { scene: string; category: LaunchCategory } {
377
+ // 先用 API 检查是否从桌面启动
380
378
  if (window["ks"] && window["ks"].isLaunchFromShortcut) {
381
- isLaunchFromDesktopShortcut = window["ks"].isLaunchFromShortcut();
379
+ if (window["ks"].isLaunchFromShortcut()) {
380
+ return { scene: this._coldStartScene, category: LaunchCategory.Desktop };
381
+ }
382
382
  }
383
- LogUtils.Instance.info(PlatformAdapterKuaiShou.TAG, "判断是否桌面快捷方式启动", {
384
- operation: "isLaunchFromDesktopShortcut",
385
- result: isLaunchFromDesktopShortcut
386
- });
387
- return isLaunchFromDesktopShortcut;
388
- }
389
383
 
390
- public isLaunchFromAdvertisement(): boolean {
391
- let advertisementSceneSet: Set<string> = new Set<string>([
392
- "dsp",
393
- ]);
394
- let isLaunchFromAdvertisement: boolean = advertisementSceneSet.has(this.coldStartScene);
395
- LogUtils.Instance.info(PlatformAdapterKuaiShou.TAG, "判断是否广告启动", {
396
- operation: "isLaunchFromAdvertisement",
397
- result: isLaunchFromAdvertisement
398
- });
399
- return isLaunchFromAdvertisement;
384
+ // 否则走通用逻辑(Map 查找)
385
+ for (const [category, sceneSet] of this.launchSceneCategoryMap) {
386
+ if (category === LaunchCategory.Other) continue;
387
+ if (sceneSet.has(this._coldStartScene)) {
388
+ return { scene: this._coldStartScene, category };
389
+ }
390
+ }
391
+ return { scene: this._coldStartScene, category: LaunchCategory.Other };
400
392
  }
401
393
 
394
+
395
+
396
+
402
397
  public checkSession(callback: (isValid: boolean) => void): void {
403
398
  if (window["ks"] && window["ks"].checkSession) {
404
399
  window["ks"].checkSession({
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -6,6 +7,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
6
7
 
7
8
  export class PlatformAdapterOppo extends AbsPlatformAdapter {
8
9
  static TAG: string = "PlatformAdapterOppo";
10
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
11
+ [LaunchCategory.RecentUse, new Set([])],
12
+ [LaunchCategory.Desktop, new Set([])],
13
+ [LaunchCategory.Search, new Set([])],
14
+ [LaunchCategory.Chat, new Set([])],
15
+ [LaunchCategory.Share, new Set([])],
16
+ [LaunchCategory.Ad, new Set([])],
17
+ [LaunchCategory.Other, new Set([])],
18
+ ]);
9
19
 
10
20
  // Common
11
21
  public init(): void {
@@ -278,7 +288,7 @@ export class PlatformAdapterOppo extends AbsPlatformAdapter {
278
288
 
279
289
  public onGameColdStart(): void {
280
290
  this.coldStartOptions = null;
281
- this.coldStartScene = "";
291
+ this._coldStartScene = "";
282
292
 
283
293
  if (window["qg"] && window["qg"].getLaunchOptionsSync) {
284
294
  this.coldStartOptions = window["qg"].getLaunchOptionsSync();
@@ -326,17 +336,8 @@ export class PlatformAdapterOppo extends AbsPlatformAdapter {
326
336
 
327
337
  }
328
338
 
329
- public isLaunchFromRecentUse(): boolean {
330
- return false;
331
- }
332
339
 
333
- public isLaunchFromDesktopShortcut(): boolean {
334
- return false;
335
- }
336
340
 
337
- public isLaunchFromAdvertisement(): boolean {
338
- return false;
339
- }
340
341
 
341
342
  public checkSession(callback: (isValid: boolean) => void): void {
342
343
  // Oppo不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -7,6 +8,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
7
8
  export class PlatformAdapterTapTap extends AbsPlatformAdapter {
8
9
 
9
10
  static TAG: string = "PlatformAdapterTapTap";
11
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
12
+ [LaunchCategory.RecentUse, new Set([])],
13
+ [LaunchCategory.Desktop, new Set([])],
14
+ [LaunchCategory.Search, new Set([])],
15
+ [LaunchCategory.Chat, new Set([])],
16
+ [LaunchCategory.Share, new Set([])],
17
+ [LaunchCategory.Ad, new Set([])],
18
+ [LaunchCategory.Other, new Set([])],
19
+ ]);
10
20
 
11
21
  // Common
12
22
  public init(): void {
@@ -316,18 +326,18 @@ export class PlatformAdapterTapTap extends AbsPlatformAdapter {
316
326
 
317
327
  public onGameColdStart(): void {
318
328
  this.coldStartOptions = null;
319
- this.coldStartScene = "";
329
+ this._coldStartScene = "";
320
330
 
321
331
  if (window["tap"] && window["tap"].getLaunchOptionsSync) {
322
332
  this.coldStartOptions = window["tap"].getLaunchOptionsSync();
323
333
  if (this.coldStartOptions !== null && this.coldStartOptions["scene"]) {
324
- this.coldStartScene = this.coldStartOptions["scene"].toString();
334
+ this._coldStartScene = this.coldStartOptions["scene"].toString();
325
335
  }
326
336
  }
327
337
 
328
338
  LogUtils.Instance.info(PlatformAdapterTapTap.TAG, "冷启动场景更新", {
329
339
  operation: "updateColdStartScene",
330
- scene: this.coldStartScene
340
+ scene: this._coldStartScene
331
341
  });
332
342
  }
333
343
 
@@ -389,17 +399,8 @@ export class PlatformAdapterTapTap extends AbsPlatformAdapter {
389
399
 
390
400
  }
391
401
 
392
- public isLaunchFromRecentUse(): boolean {
393
- return false;
394
- }
395
402
 
396
- public isLaunchFromDesktopShortcut(): boolean {
397
- return false;
398
- }
399
403
 
400
- public isLaunchFromAdvertisement(): boolean {
401
- return false;
402
- }
403
404
 
404
405
  public checkSession(callback: (isValid: boolean) => void): void {
405
406
  if (window["tap"] && window["tap"].checkSession) {
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
4
5
  import { ScreenInfo } from '../../Definition/SystemDefinition';
@@ -6,6 +7,15 @@ import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
6
7
 
7
8
  export class PlatformAdapterVivo extends AbsPlatformAdapter {
8
9
  static TAG: string = "PlatformAdapterVivo";
10
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
11
+ [LaunchCategory.RecentUse, new Set([])],
12
+ [LaunchCategory.Desktop, new Set([])],
13
+ [LaunchCategory.Search, new Set([])],
14
+ [LaunchCategory.Chat, new Set([])],
15
+ [LaunchCategory.Share, new Set([])],
16
+ [LaunchCategory.Ad, new Set([])],
17
+ [LaunchCategory.Other, new Set([])],
18
+ ]);
9
19
 
10
20
  // Common
11
21
  public init(): void {
@@ -279,7 +289,7 @@ export class PlatformAdapterVivo extends AbsPlatformAdapter {
279
289
 
280
290
  public onGameColdStart(): void {
281
291
  this.coldStartOptions = null;
282
- this.coldStartScene = "";
292
+ this._coldStartScene = "";
283
293
  }
284
294
 
285
295
  public onGameShowCallback(warmStartOptions: any): void {
@@ -331,17 +341,8 @@ export class PlatformAdapterVivo extends AbsPlatformAdapter {
331
341
 
332
342
  }
333
343
 
334
- public isLaunchFromRecentUse(): boolean {
335
- return false;
336
- }
337
344
 
338
- public isLaunchFromDesktopShortcut(): boolean {
339
- return false;
340
- }
341
345
 
342
- public isLaunchFromAdvertisement(): boolean {
343
- return false;
344
- }
345
346
 
346
347
  public checkSession(callback: (isValid: boolean) => void): void {
347
348
  // Vivo不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -87,6 +88,15 @@ class WeiXinPlatformBusiness {
87
88
  export class PlatformAdapterWeiXin extends AbsPlatformAdapter {
88
89
 
89
90
  static TAG: string = "PlatformAdapterWeiXin";
91
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
92
+ [LaunchCategory.RecentUse, new Set(["1001", "1089", "1090", "1256", "1271"])],
93
+ [LaunchCategory.Desktop, new Set(["1023", "1113", "1114", "1223"])],
94
+ [LaunchCategory.Search, new Set(["1005", "1006", "1027", "1053", "1106", "1183"])],
95
+ [LaunchCategory.Chat, new Set(["1007", "1008", "1036", "1096"])],
96
+ [LaunchCategory.Share, new Set(["1044", "1073", "1074"])],
97
+ [LaunchCategory.Ad, new Set(["1045", "1046", "1067", "1084", "1095", "1200", "1201", "1228", "1232", "1238", "1274", "1295", "1387"])],
98
+ [LaunchCategory.Other, new Set([])],
99
+ ]);
90
100
 
91
101
  private portalGame: PortalGame = new PortalGame();
92
102
  private gameClub: GameClub = new GameClub();
@@ -503,18 +513,18 @@ export class PlatformAdapterWeiXin extends AbsPlatformAdapter {
503
513
 
504
514
  public onGameColdStart(): void {
505
515
  this.coldStartOptions = null;
506
- this.coldStartScene = "";
516
+ this._coldStartScene = "";
507
517
 
508
518
  if (window["wx"] && window["wx"].getLaunchOptionsSync) {
509
519
  this.coldStartOptions = window["wx"].getLaunchOptionsSync();
510
520
  if (this.coldStartOptions !== null && this.coldStartOptions["scene"]) {
511
- this.coldStartScene = this.coldStartOptions["scene"].toString();
521
+ this._coldStartScene = this.coldStartOptions["scene"].toString();
512
522
  }
513
523
  }
514
524
 
515
525
  LogUtils.Instance.info(PlatformAdapterWeiXin.TAG, "冷启动场景更新", {
516
526
  operation: "updateColdStartScene",
517
- scene: this.coldStartScene
527
+ scene: this._coldStartScene
518
528
  });
519
529
  }
520
530
 
@@ -576,52 +586,8 @@ export class PlatformAdapterWeiXin extends AbsPlatformAdapter {
576
586
 
577
587
  }
578
588
 
579
- public isLaunchFromRecentUse(): boolean {
580
- let recentUseSceneSet: Set<string> = new Set<string>([
581
- "1001",
582
- "1089",
583
- "1256",
584
- "1103",
585
- "1104",
586
- "1257",
587
- ]);
588
-
589
- let isLaunchFromRecentUse: boolean = recentUseSceneSet.has(this.coldStartScene) || recentUseSceneSet.has(this.warmStartScene);
590
- LogUtils.Instance.info(PlatformAdapterWeiXin.TAG, "判断是否最近使用启动", {
591
- operation: "isLaunchFromRecentUse",
592
- result: isLaunchFromRecentUse
593
- });
594
- return isLaunchFromRecentUse;
595
- }
596
589
 
597
- public isLaunchFromDesktopShortcut(): boolean {
598
- let desktopShortcutSceneSet: Set<string> = new Set<string>([
599
- "1023",
600
- "1223",
601
- ]);
602
590
 
603
- let isLaunchFromDesktopShortcut: boolean = desktopShortcutSceneSet.has(this.coldStartScene) || desktopShortcutSceneSet.has(this.warmStartScene);
604
- LogUtils.Instance.info(PlatformAdapterWeiXin.TAG, "判断是否桌面快捷方式启动", {
605
- operation: "isLaunchFromDesktopShortcut",
606
- result: isLaunchFromDesktopShortcut
607
- });
608
- return isLaunchFromDesktopShortcut;
609
- }
610
-
611
- public isLaunchFromAdvertisement(): boolean {
612
- let advertisementSceneSet: Set<string> = new Set<string>([
613
- "1045", "1046", "1067", "1068", "1084", "1095",
614
- "1189", "1200", "1201", "1215", "1228", "1230",
615
- "1232", "1238", "1274", "1295",
616
- ]);
617
-
618
- let isLaunchFromAdvertisement: boolean = advertisementSceneSet.has(this.coldStartScene);
619
- LogUtils.Instance.info(PlatformAdapterWeiXin.TAG, "判断是否广告启动", {
620
- operation: "isLaunchFromAdvertisement",
621
- result: isLaunchFromAdvertisement
622
- });
623
- return isLaunchFromAdvertisement;
624
- }
625
591
 
626
592
  public checkSession(callback: (isValid: boolean) => void): void {
627
593
  if (window["wx"] && window["wx"].checkSession) {
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -7,6 +8,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
7
8
  export class PlatformAdapterXiaoMi extends AbsPlatformAdapter {
8
9
 
9
10
  static TAG: string = "PlatformAdapterXiaoMi";
11
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
12
+ [LaunchCategory.RecentUse, new Set([])],
13
+ [LaunchCategory.Desktop, new Set([])],
14
+ [LaunchCategory.Search, new Set([])],
15
+ [LaunchCategory.Chat, new Set([])],
16
+ [LaunchCategory.Share, new Set([])],
17
+ [LaunchCategory.Ad, new Set([])],
18
+ [LaunchCategory.Other, new Set([])],
19
+ ]);
10
20
 
11
21
  // Common
12
22
  public init(): void {
@@ -284,11 +294,11 @@ export class PlatformAdapterXiaoMi extends AbsPlatformAdapter {
284
294
 
285
295
  public onGameColdStart(): void {
286
296
  this.coldStartOptions = null;
287
- this.coldStartScene = "";
297
+ this._coldStartScene = "";
288
298
 
289
299
  LogUtils.Instance.info(PlatformAdapterXiaoMi.TAG, "冷启动场景更新", {
290
300
  operation: "updateColdStartScene",
291
- scene: this.coldStartScene
301
+ scene: this._coldStartScene
292
302
  });
293
303
  }
294
304
 
@@ -346,17 +356,8 @@ export class PlatformAdapterXiaoMi extends AbsPlatformAdapter {
346
356
 
347
357
  }
348
358
 
349
- public isLaunchFromRecentUse(): boolean {
350
- return false;
351
- }
352
359
 
353
- public isLaunchFromDesktopShortcut(): boolean {
354
- return false;
355
- }
356
360
 
357
- public isLaunchFromAdvertisement(): boolean {
358
- return false;
359
- }
360
361
 
361
362
  public checkSession(callback: (isValid: boolean) => void): void {
362
363
  // XiaoMi不支持这个方法,直接返回true
@@ -1,4 +1,5 @@
1
1
  import { AbsPlatformAdapter } from './AbsPlatformAdapter';
2
+ import { LaunchCategory } from "../../Definition/AnalyticsDefinition";
2
3
  import { LogUtils } from '../../Utils/LogUtils';
3
4
  import { FwkErrorCode } from '../../Definition/FwkErrorDefinition';
4
5
  import { AuthorizeResult, GetSettingResult } from '../../Definition/PrivacyDefinition';
@@ -7,6 +8,15 @@ import { ScreenInfo } from '../../Definition/SystemDefinition';
7
8
  export class PlatformAdapterZhiFuBao extends AbsPlatformAdapter {
8
9
 
9
10
  static TAG: string = "PlatformAdapterZhiFuBao";
11
+ protected launchSceneCategoryMap: Map<LaunchCategory, Set<string>> = new Map([
12
+ [LaunchCategory.RecentUse, new Set(["1000", "1001", "1002", "1003"])],
13
+ [LaunchCategory.Desktop, new Set(["1023"])],
14
+ [LaunchCategory.Search, new Set([])],
15
+ [LaunchCategory.Chat, new Set([])],
16
+ [LaunchCategory.Share, new Set([])],
17
+ [LaunchCategory.Ad, new Set(["1400"])],
18
+ [LaunchCategory.Other, new Set([])],
19
+ ]);
10
20
 
11
21
  // Common
12
22
  public init(): void {
@@ -314,18 +324,18 @@ export class PlatformAdapterZhiFuBao extends AbsPlatformAdapter {
314
324
 
315
325
  public onGameColdStart(): void {
316
326
  this.coldStartOptions = null;
317
- this.coldStartScene = "";
327
+ this._coldStartScene = "";
318
328
 
319
329
  if (window["my"] && window["my"].getLaunchOptionsSync) {
320
330
  this.coldStartOptions = window["my"].getLaunchOptionsSync();
321
331
  if (this.coldStartOptions !== null && this.coldStartOptions["scene"]) {
322
- this.coldStartScene = this.coldStartOptions["scene"];
332
+ this._coldStartScene = this.coldStartOptions["scene"];
323
333
  }
324
334
  }
325
335
 
326
336
  LogUtils.Instance.info(PlatformAdapterZhiFuBao.TAG, "冷启动场景更新", {
327
337
  operation: "updateColdStartScene",
328
- scene: this.coldStartScene
338
+ scene: this._coldStartScene
329
339
  });
330
340
  }
331
341
 
@@ -387,47 +397,8 @@ export class PlatformAdapterZhiFuBao extends AbsPlatformAdapter {
387
397
 
388
398
  }
389
399
 
390
- public isLaunchFromRecentUse(): boolean {
391
- let recentUseSceneSet: Set<string> = new Set<string>([
392
- "1000",
393
- "1001",
394
- "1002",
395
- "1003",
396
- ]);
397
400
 
398
- let isLaunchFromRecentUse: boolean = recentUseSceneSet.has(this.coldStartScene) || recentUseSceneSet.has(this.warmStartScene);
399
- LogUtils.Instance.info(PlatformAdapterZhiFuBao.TAG, "判断是否最近使用启动", {
400
- operation: "isLaunchFromRecentUse",
401
- result: isLaunchFromRecentUse
402
- });
403
- return isLaunchFromRecentUse;
404
- }
405
-
406
- public isLaunchFromDesktopShortcut(): boolean {
407
- let desktopShortcutSceneSet: Set<string> = new Set<string>([
408
- "1023",
409
- ]);
410
401
 
411
- let isLaunchFromDesktopShortcut: boolean = desktopShortcutSceneSet.has(this.coldStartScene) || desktopShortcutSceneSet.has(this.warmStartScene);
412
- LogUtils.Instance.info(PlatformAdapterZhiFuBao.TAG, "判断是否桌面快捷方式启动", {
413
- operation: "isLaunchFromDesktopShortcut",
414
- result: isLaunchFromDesktopShortcut
415
- });
416
- return isLaunchFromDesktopShortcut;
417
- }
418
-
419
- public isLaunchFromAdvertisement(): boolean {
420
- let advertisementSceneSet: Set<string> = new Set<string>([
421
- "1400",
422
- ]);
423
-
424
- let isLaunchFromAdvertisement: boolean = advertisementSceneSet.has(this.coldStartScene);
425
- LogUtils.Instance.info(PlatformAdapterZhiFuBao.TAG, "判断是否广告启动", {
426
- operation: "isLaunchFromAdvertisement",
427
- result: isLaunchFromAdvertisement
428
- });
429
- return isLaunchFromAdvertisement;
430
- }
431
402
 
432
403
  public checkSession(callback: (isValid: boolean) => void): void {
433
404
  // ZhiFuBao不支持这个方法,直接返回true
@@ -66,35 +66,111 @@ export interface UmaSDK {
66
66
  shareAppMessage(options: object): void;
67
67
  }
68
68
 
69
- // ==================== 预定义事件 ID ====================
69
+ // ==================== 事件 ID 与参数 ====================
70
70
 
71
- /** 预定义事件 ID */
71
+ /** 事件 ID(按业务分类) */
72
72
  export enum AnalyticsEventId {
73
+ // ==================== 留存 ====================
74
+ /** 游戏启动(DAU / 留存基数) */
75
+ GameLaunch = "game_launch",
76
+
77
+ // ==================== 关卡 ====================
78
+ /** 关卡开始 */
79
+ StageStart = "stage_start",
80
+ /** 关卡结束(成功 / 失败 / 放弃) */
81
+ StageEnd = "stage_end",
82
+ /** 复活成功 */
83
+ StageRevive = "stage_revive",
84
+
85
+ // ==================== 广告 ====================
86
+ /** 广告加载成功 */
87
+ AdLoadSuccess = "ad_load_success",
88
+ /** 广告加载失败 */
89
+ AdLoadError = "ad_load_error",
90
+ /** 广告展示 */
73
91
  AdShow = "ad_show",
74
- AdClick = "ad_click",
75
- AdComplete = "ad_complete",
76
- AdSkip = "ad_skip",
77
- AdError = "ad_error",
78
- Purchase = "purchase",
92
+ /** 广告观看完成(isEnded=true) */
93
+ AdShowComplete = "ad_show_complete",
94
+ /** 广告跳过(isEnded=false) */
95
+ AdShowSkip = "ad_show_skip",
96
+ }
97
+
98
+ /** 关卡结束结果 */
99
+ export enum StageResult {
100
+ Success = "success",
101
+ Fail = "fail",
102
+ Abandon = "abandon",
103
+ }
104
+
105
+ /** 复活方式 */
106
+ export enum ReviveMethod {
107
+ /** 广告复活 */
108
+ Ad = "ad",
109
+ /** 道具复活 */
110
+ Item = "item",
111
+ }
112
+
113
+ /** 启动场景分类 */
114
+ export enum LaunchCategory {
115
+ /** 最近使用/我的小程序 */
116
+ RecentUse = "recent",
117
+ /** 桌面图标/快捷方式 */
118
+ Desktop = "desktop",
119
+ /** 搜索 */
120
+ Search = "search",
121
+ /** 聊天消息卡片 */
122
+ Chat = "chat",
123
+ /** 分享卡片 */
79
124
  Share = "share",
80
- Login = "login",
81
- GameLaunch = "game_launch",
82
- GameError = "game_error",
125
+ /** 广告 */
126
+ Ad = "ad",
127
+ /** 其他/未知 */
128
+ Other = "other",
129
+ }
130
+
131
+ /** 冷启动场景信息 */
132
+ export interface LaunchSceneInfo {
133
+ /** 原始场景值 */
134
+ scene: string;
135
+ /** 归并后的场景分类 */
136
+ category: LaunchCategory;
83
137
  }
84
138
 
85
- /** 事件参数键名 */
139
+ /** 事件参数键名(按业务分类) */
86
140
  export enum AnalyticsParamKey {
87
- Score = "score",
141
+ // ==================== 通用 ====================
142
+ /** 时长(毫秒),关卡耗时等通用场景 */
88
143
  Duration = "duration",
89
- Reason = "reason",
90
- AdType = "ad_type",
91
- AdId = "ad_id",
92
- ItemId = "item_id",
93
- ItemName = "item_name",
94
- Price = "price",
95
- Currency = "currency",
96
- ShareType = "share_type",
97
- ShareContent = "share_content",
98
- ErrorCode = "error_code",
99
- ErrorMsg = "error_msg",
144
+
145
+ // ==================== 留存 ====================
146
+ /** 原始启动场景值 */
147
+ LaunchScene = "launch_scene",
148
+ /** 归并后的场景分类 */
149
+ LaunchCategory = "launch_category",
150
+ /** 启动小时(0-23) */
151
+ LaunchHour = "launch_hour",
152
+
153
+ // ==================== 关卡 ====================
154
+ /** 关卡ID */
155
+ StageId = "stage_id",
156
+ /** 关卡名称 */
157
+ StageName = "stage_name",
158
+ /** 是否首次进入(1=首次, 0=重玩) */
159
+ IsFirst = "is_first",
160
+ /** 关卡结束结果(success / fail / abandon) */
161
+ Result = "result",
162
+ /** 关卡进度(0-1) */
163
+ Progress = "progress",
164
+ /** 是否复活后通关(1=是, 0=否) */
165
+ IsRevived = "is_revived",
166
+ /** 复活方式(ad / item) */
167
+ Method = "method",
168
+
169
+ // ==================== 广告 ====================
170
+ /** 广告场景(业务自定义,如 revive / daily_bonus) */
171
+ AdScene = "ad_scene",
172
+ /** 广告错误码 */
173
+ ErrCode = "err_code",
174
+ /** 广告错误信息 */
175
+ ErrMsg = "err_msg",
100
176
  }
@@ -3,7 +3,7 @@ import { LogUtils } from "../Utils/LogUtils";
3
3
  import { ServiceLocator } from "../Utils/ServiceLocator";
4
4
  import { FwkErrorCode } from "../Definition/FwkErrorDefinition";
5
5
  import { PlatformID } from "../Definition/SystemDefinition";
6
- import { UmengConfig, EventParams, AnalyticsEventId, AnalyticsParamKey, UmaSDK, CommonParams } from "../Definition/AnalyticsDefinition";
6
+ import { UmengConfig, EventParams, AnalyticsEventId, AnalyticsParamKey, StageResult, ReviveMethod, LaunchCategory, UmaSDK, CommonParams } from "../Definition/AnalyticsDefinition";
7
7
  import { EventMgr } from "./EventMgr";
8
8
  import { FrameworkBase } from "../Definition/FrameworkBase";
9
9
  import type { SystemMgr } from "./SystemMgr";
@@ -23,6 +23,12 @@ export class AnalyticsMgr extends BaseMgr {
23
23
  /** 通用属性(trackEvent 自动合并) */
24
24
  private _commonParams: CommonParams = null;
25
25
 
26
+ /** 当前会话已进入过的关卡(用于 is_first 判重) */
27
+ private _sessionEnteredStages: Set<string> = new Set();
28
+
29
+ /** 各关卡的开始时间戳(用于自动计算 duration) */
30
+ private _stageStartTimestamps: Map<string, number> = new Map();
31
+
26
32
  onLoad(): void {
27
33
  super.onLoad();
28
34
 
@@ -295,24 +301,156 @@ export class AnalyticsMgr extends BaseMgr {
295
301
 
296
302
  // ==================== 游戏特定事件 ====================
297
303
 
298
- /** 广告展示 */
299
- public trackAdShow(adType: string, adId: string, extraParams?: EventParams): void {
300
- const params: Record<string, any> = {
301
- [AnalyticsParamKey.AdType]: adType,
302
- [AnalyticsParamKey.AdId]: adId,
303
- ...this._flattenParams(extraParams),
304
- };
305
- this.trackEvent(AnalyticsEventId.AdShow, params);
304
+ /**
305
+ * 关卡开始上报
306
+ * 自动判重,is_first=1 仅在该用户当前会话内首次进入该关卡时上报。
307
+ * 同时记录开始时间戳,供 stageTrackEnd 自动计算 duration。
308
+ * @param stageId 关卡ID(必传)
309
+ * @param stageName 关卡名称(必传)
310
+ */
311
+ public stageTrackStart(stageId: string, stageName: string): void {
312
+ if (!this._isEnabled) return;
313
+
314
+ const isFirst = this._sessionEnteredStages.has(stageId) ? 0 : 1;
315
+ if (isFirst === 1) {
316
+ this._sessionEnteredStages.add(stageId);
317
+ }
318
+
319
+ // 记录开始时间戳(毫秒)
320
+ this._stageStartTimestamps.set(stageId, Date.now());
321
+
322
+ this.trackEvent(AnalyticsEventId.StageStart, {
323
+ [AnalyticsParamKey.StageId]: stageId,
324
+ [AnalyticsParamKey.StageName]: stageName,
325
+ [AnalyticsParamKey.IsFirst]: isFirst,
326
+ });
306
327
  }
307
328
 
308
- /** 广告点击 */
309
- public trackAdClick(adType: string, adId: string, extraParams?: EventParams): void {
310
- const params: Record<string, any> = {
311
- [AnalyticsParamKey.AdType]: adType,
312
- [AnalyticsParamKey.AdId]: adId,
313
- ...this._flattenParams(extraParams),
314
- };
315
- this.trackEvent(AnalyticsEventId.AdClick, params);
329
+ /**
330
+ * 关卡结束上报
331
+ * 规则:只有“最终结局”才上报。复活成功后的关卡仍在进行中,不报 stage_end。
332
+ * duration 由框架自动计算(当前时间戳 - stageTrackStart 记录的时间戳)。
333
+ * @param stageId 关卡ID
334
+ * @param result 结果:success / fail / abandon
335
+ * @param progress 关卡进度(0-1),成功时=1
336
+ * @param isRevived 是否为复活后通关(0=原始,1=复活后),默认 0
337
+ */
338
+ public stageTrackEnd(
339
+ stageId: string,
340
+ result: StageResult,
341
+ progress: number,
342
+ isRevived: number = 0,
343
+ ): void {
344
+ if (!this._isEnabled) return;
345
+
346
+ // 自动计算 duration(毫秒)
347
+ const startTs = this._stageStartTimestamps.get(stageId);
348
+ const duration = startTs ? Date.now() - startTs : 0;
349
+ // 上报后清除,避免内存泄漏
350
+ this._stageStartTimestamps.delete(stageId);
351
+
352
+ this.trackEvent(AnalyticsEventId.StageEnd, {
353
+ [AnalyticsParamKey.StageId]: stageId,
354
+ [AnalyticsParamKey.Result]: result,
355
+ [AnalyticsParamKey.Duration]: duration,
356
+ [AnalyticsParamKey.Progress]: progress,
357
+ [AnalyticsParamKey.IsRevived]: isRevived,
358
+ });
359
+ }
360
+
361
+ /**
362
+ * 复活成功上报
363
+ * 触发时机:玩家选择复活(看广告或使用道具)并成功复活后上报一次。
364
+ * 复活前的失败不报 stage_end(还未到最终结局)。
365
+ * @param stageId 关卡ID
366
+ * @param method 复活方式
367
+ */
368
+ public stageTrackRevive(stageId: string, method: ReviveMethod): void {
369
+ if (!this._isEnabled) return;
370
+
371
+ this.trackEvent(AnalyticsEventId.StageRevive, {
372
+ [AnalyticsParamKey.StageId]: stageId,
373
+ [AnalyticsParamKey.Method]: method,
374
+ });
375
+ }
376
+
377
+ // ==================== 留存事件 ====================
378
+
379
+ /**
380
+ * 游戏启动上报(DAU / 留存基数)
381
+ * 由 LifeCycleMgr.onGameColdStart() 自动调用,业务层无需手动上报。
382
+ * @param launchScene 原始启动场景值
383
+ * @param launchCategory 归并后的场景分类
384
+ * @param launchHour 启动小时(0-23)
385
+ */
386
+ public trackGameLaunch(launchScene: string, launchCategory: LaunchCategory, launchHour: number): void {
387
+ if (!this._isEnabled) return;
388
+ this.trackEvent(AnalyticsEventId.GameLaunch, {
389
+ [AnalyticsParamKey.LaunchScene]: launchScene,
390
+ [AnalyticsParamKey.LaunchCategory]: launchCategory,
391
+ [AnalyticsParamKey.LaunchHour]: launchHour,
392
+ });
393
+ }
394
+
395
+ // ==================== 广告事件 ====================
396
+
397
+ /**
398
+ * 广告加载成功
399
+ * @param adScene 广告场景(业务自定义,如 revive / daily_bonus)
400
+ */
401
+ public trackAdLoadSuccess(adScene: string): void {
402
+ if (!this._isEnabled) return;
403
+ this.trackEvent(AnalyticsEventId.AdLoadSuccess, {
404
+ [AnalyticsParamKey.AdScene]: adScene,
405
+ });
406
+ }
407
+
408
+ /**
409
+ * 广告加载失败
410
+ * @param adScene 广告场景
411
+ * @param errCode 错误码
412
+ * @param errMsg 错误信息
413
+ */
414
+ public trackAdLoadError(adScene: string, errCode: number, errMsg: string): void {
415
+ if (!this._isEnabled) return;
416
+ this.trackEvent(AnalyticsEventId.AdLoadError, {
417
+ [AnalyticsParamKey.AdScene]: adScene,
418
+ [AnalyticsParamKey.ErrCode]: errCode,
419
+ [AnalyticsParamKey.ErrMsg]: errMsg,
420
+ });
421
+ }
422
+
423
+ /**
424
+ * 广告展示成功
425
+ * @param adScene 广告场景
426
+ */
427
+ public trackAdShow(adScene: string): void {
428
+ if (!this._isEnabled) return;
429
+ this.trackEvent(AnalyticsEventId.AdShow, {
430
+ [AnalyticsParamKey.AdScene]: adScene,
431
+ });
432
+ }
433
+
434
+ /**
435
+ * 广告观看完成(isEnded=true)
436
+ * @param adScene 广告场景
437
+ */
438
+ public trackAdShowComplete(adScene: string): void {
439
+ if (!this._isEnabled) return;
440
+ this.trackEvent(AnalyticsEventId.AdShowComplete, {
441
+ [AnalyticsParamKey.AdScene]: adScene,
442
+ });
443
+ }
444
+
445
+ /**
446
+ * 广告跳过(isEnded=false)
447
+ * @param adScene 广告场景
448
+ */
449
+ public trackAdShowSkip(adScene: string): void {
450
+ if (!this._isEnabled) return;
451
+ this.trackEvent(AnalyticsEventId.AdShowSkip, {
452
+ [AnalyticsParamKey.AdScene]: adScene,
453
+ });
316
454
  }
317
455
 
318
456
  // ==================== 状态查询 ====================
@@ -3,6 +3,7 @@ import { LogUtils } from "../Utils/LogUtils";
3
3
  import { ServiceLocator } from "../Utils/ServiceLocator";
4
4
  import { BaseMgr } from "./BaseMgr";
5
5
  import { EventMgr } from "./EventMgr";
6
+ import { AnalyticsMgr } from "./AnalyticsMgr";
6
7
 
7
8
  /** 生命周期管理器 */
8
9
  export class LifeCycleMgr extends BaseMgr {
@@ -121,6 +122,11 @@ export class LifeCycleMgr extends BaseMgr {
121
122
  }
122
123
 
123
124
  this.getPlatformAdapter().onGameColdStart();
125
+
126
+ // 上报 GameLaunch 事件
127
+ const info = this.getPlatformAdapter().getColdStartSceneInfo();
128
+ const launchHour = new Date().getHours();
129
+ AnalyticsMgr.Instance.trackGameLaunch(info.scene, info.category, launchHour);
124
130
  }
125
131
 
126
132
  /**
@@ -147,30 +153,6 @@ export class LifeCycleMgr extends BaseMgr {
147
153
  EventMgr.Instance.emit(FrameworkBase.Message.LifeCycle_onGameHide);
148
154
  }
149
155
 
150
- /**
151
- * 是否从最近使用启动
152
- * @return 是否从最近使用启动
153
- */
154
- public isLaunchFromRecentUse(): boolean {
155
- if (this.getPlatformAdapter() === null) {
156
- return false;
157
- }
158
-
159
- return this.getPlatformAdapter().isLaunchFromRecentUse();
160
- }
161
-
162
- /**
163
- * 是否从桌面快捷方式启动
164
- * @return 是否从桌面快捷方式启动
165
- */
166
- public isLaunchFromDesktopShortcut(): boolean {
167
- if (this.getPlatformAdapter() === null) {
168
- return false;
169
- }
170
-
171
- return this.getPlatformAdapter().isLaunchFromDesktopShortcut();
172
- }
173
-
174
156
  /**
175
157
  * 是否支持跳转至最近使用
176
158
  * @param callback 回调函数
@@ -195,15 +177,12 @@ export class LifeCycleMgr extends BaseMgr {
195
177
  this.getPlatformAdapter().navigateToRecentUse();
196
178
  }
197
179
 
198
- /**
199
- * 是否从广告启动
200
- * @return 是否从广告启动
201
- */
202
- public isLaunchFromAdvertisement(): boolean {
180
+ /** 获取冷启动场景信息 */
181
+ public getColdStartSceneInfo(): { scene: string; category: string } | null {
203
182
  if (this.getPlatformAdapter() === null) {
204
- return false;
183
+ return null;
205
184
  }
206
185
 
207
- return this.getPlatformAdapter().isLaunchFromAdvertisement();
186
+ return this.getPlatformAdapter().getColdStartSceneInfo();
208
187
  }
209
188
  }