baxi 2 недель назад
Родитель
Сommit
627d9802ad
50 измененных файлов с 2492 добавлено и 1120 удалено
  1. 13 13
      assets/lobbyRes/scenes/Lobby.scene
  2. BIN
      assets/lobbyRes/textures/store/STORE_bg.png
  3. 21 21
      assets/lobbyRes/textures/store/STORE_bg.png.meta
  4. 36 36
      assets/lobbyRes/ui/dialog/UIDialog.prefab
  5. 181 160
      assets/lobbyRes/ui/home/HomeView.prefab
  6. 9 0
      assets/lobbyRes/ui/invite.meta
  7. 749 0
      assets/lobbyRes/ui/invite/UIInvite.prefab
  8. 13 0
      assets/lobbyRes/ui/invite/UIInvite.prefab.meta
  9. 176 155
      assets/lobbyRes/ui/login/LoginView.prefab
  10. 181 160
      assets/lobbyRes/ui/store/StoreView.prefab
  11. 322 310
      assets/lobbyRes/ui/store/UIFirstPack.prefab
  12. 222 62
      assets/scenes/Launch.scene
  13. 2 0
      assets/scripts/api/LobbyApi.ts
  14. 7 0
      assets/scripts/api/PaymentApi.ts
  15. 9 0
      assets/scripts/components/adapter.meta
  16. 56 0
      assets/scripts/components/adapter/BackgroundAdapter.ts
  17. 1 1
      assets/scripts/components/adapter/BackgroundAdapter.ts.meta
  18. 8 1
      assets/scripts/define/UIDefine.ts
  19. 32 16
      assets/scripts/framework/ui/UIManager.ts
  20. 4 4
      assets/scripts/framework/ui/UIView.ts
  21. 6 1
      assets/scripts/i18n/en/en1.ts
  22. 22 86
      assets/scripts/modules/launch/LaunchController.ts
  23. 0 3
      assets/scripts/modules/launch/LaunchStateMachine.ts
  24. 1 1
      assets/scripts/modules/launch/states/CheckVersionState.ts
  25. 0 11
      assets/scripts/modules/launch/states/CompleteState.ts
  26. 2 2
      assets/scripts/modules/launch/states/EnterLobbyState.ts
  27. 25 12
      assets/scripts/modules/launch/states/HotUpdateState.ts
  28. 1 0
      assets/scripts/modules/launch/states/LaunchState.ts
  29. 17 3
      assets/scripts/modules/launch/states/PreloadLobbyState.ts
  30. 1 0
      assets/scripts/modules/lobby/ui/HomeView/GameItem.ts
  31. 144 0
      assets/scripts/modules/lobby/ui/HomeView/HomeNotices.ts
  32. 9 0
      assets/scripts/modules/lobby/ui/HomeView/HomeNotices.ts.meta
  33. 18 25
      assets/scripts/modules/lobby/ui/HomeView/HomeView.ts
  34. 2 2
      assets/scripts/modules/lobby/ui/LoadingView.ts
  35. 30 3
      assets/scripts/modules/lobby/ui/StoreView/UIFirstPack.ts
  36. 4 4
      assets/scripts/modules/lobby/ui/UIDialog.ts
  37. 9 0
      assets/scripts/modules/lobby/ui/invite.meta
  38. 16 0
      assets/scripts/modules/lobby/ui/invite/UIInvite.ts
  39. 9 0
      assets/scripts/modules/lobby/ui/invite/UIInvite.ts.meta
  40. 5 5
      assets/scripts/platform/Google/GoogleAndroidImpl.ts
  41. 3 3
      assets/scripts/platform/Google/GoogleIOSImpl.ts
  42. 9 2
      assets/scripts/services/AppLobby.ts
  43. 1 1
      assets/scripts/services/hotupdate/HotUpdateService.ts
  44. 11 2
      assets/scripts/store/gameStore/GameStore.ts
  45. 9 0
      assets/scripts/store/gameStore/data.ts
  46. 21 3
      assets/scripts/store/mainStore/MainStore.ts
  47. 5 0
      assets/scripts/store/mainStore/data.ts
  48. 24 0
      assets/scripts/store/payStore/PayStore.ts
  49. 34 9
      assets/scripts/store/payStore/data.ts
  50. 12 3
      assets/scripts/utils/Helper.ts

+ 13 - 13
assets/lobbyRes/scenes/Lobby.scene

@@ -79,7 +79,7 @@
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 812,
+      "x": 811.9999999999999,
       "y": 375,
       "y": 375,
       "z": 1000
       "z": 1000
     },
     },
@@ -120,14 +120,14 @@
     "_priority": 0,
     "_priority": 0,
     "_fov": 45,
     "_fov": 45,
     "_fovAxis": 0,
     "_fovAxis": 0,
-    "_orthoHeight": 538.6293706293706,
+    "_orthoHeight": 423.80395528804814,
     "_near": 1,
     "_near": 1,
     "_far": 2000,
     "_far": 2000,
     "_color": {
     "_color": {
       "__type__": "cc.Color",
       "__type__": "cc.Color",
-      "r": 51,
-      "g": 51,
-      "b": 51,
+      "r": 0,
+      "g": 0,
+      "b": 0,
       "a": 255
       "a": 255
     },
     },
     "_depth": 1,
     "_depth": 1,
@@ -198,7 +198,7 @@
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 812,
+      "x": 811.9999999999999,
       "y": 375,
       "y": 375,
       "z": 0
       "z": 0
     },
     },
@@ -871,7 +871,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -971,7 +971,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -1071,7 +1071,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -1286,7 +1286,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -1560,7 +1560,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -1660,7 +1660,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -1712,7 +1712,7 @@
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 1624,
+      "width": 1623.9999999999998,
       "height": 750
       "height": 750
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {

BIN
assets/lobbyRes/textures/store/STORE_bg.png


+ 21 - 21
assets/lobbyRes/textures/store/STORE_bg.png.meta

@@ -45,10 +45,10 @@
         "offsetY": 0,
         "offsetY": 0,
         "trimX": 0,
         "trimX": 0,
         "trimY": 0,
         "trimY": 0,
-        "width": 97,
-        "height": 45,
-        "rawWidth": 97,
-        "rawHeight": 45,
+        "width": 1624,
+        "height": 750,
+        "rawWidth": 1624,
+        "rawHeight": 750,
         "borderTop": 0,
         "borderTop": 0,
         "borderBottom": 0,
         "borderBottom": 0,
         "borderLeft": 0,
         "borderLeft": 0,
@@ -60,17 +60,17 @@
         "meshType": 0,
         "meshType": 0,
         "vertices": {
         "vertices": {
           "rawPosition": [
           "rawPosition": [
-            -48.5,
-            -22.5,
+            -812,
+            -375,
             0,
             0,
-            48.5,
-            -22.5,
+            812,
+            -375,
             0,
             0,
-            -48.5,
-            22.5,
+            -812,
+            375,
             0,
             0,
-            48.5,
-            22.5,
+            812,
+            375,
             0
             0
           ],
           ],
           "indexes": [
           "indexes": [
@@ -83,12 +83,12 @@
           ],
           ],
           "uv": [
           "uv": [
             0,
             0,
-            45,
-            97,
-            45,
+            750,
+            1624,
+            750,
             0,
             0,
             0,
             0,
-            97,
+            1624,
             0
             0
           ],
           ],
           "nuv": [
           "nuv": [
@@ -102,13 +102,13 @@
             1
             1
           ],
           ],
           "minPos": [
           "minPos": [
-            -48.5,
-            -22.5,
+            -812,
+            -375,
             0
             0
           ],
           ],
           "maxPos": [
           "maxPos": [
-            48.5,
-            22.5,
+            812,
+            375,
             0
             0
           ]
           ]
         },
         },
@@ -128,7 +128,7 @@
   "userData": {
   "userData": {
     "type": "sprite-frame",
     "type": "sprite-frame",
     "fixAlphaTransparencyArtifacts": false,
     "fixAlphaTransparencyArtifacts": false,
-    "hasAlpha": true,
+    "hasAlpha": false,
     "redirect": "42e3e0e7-c84b-4c83-80b9-b76f460a8c6d@6c48a"
     "redirect": "42e3e0e7-c84b-4c83-80b9-b76f460a8c6d@6c48a"
   }
   }
 }
 }

+ 36 - 36
assets/lobbyRes/ui/dialog/UIDialog.prefab

@@ -63,7 +63,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -119,7 +119,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -311,8 +311,8 @@
     },
     },
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 0,
-      "y": 0,
+      "x": -7.5,
+      "y": -7.5,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -329,7 +329,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -362,7 +362,7 @@
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
-      "y": 15,
+      "y": 50,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -379,7 +379,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -402,8 +402,8 @@
     },
     },
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 909.287,
-      "height": 374.03900000000004
+      "width": 625,
+      "height": 263
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
       "__type__": "cc.Vec2",
       "__type__": "cc.Vec2",
@@ -504,8 +504,8 @@
     },
     },
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 155,
-      "y": -237,
+      "x": 0,
+      "y": -147.5,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -522,7 +522,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -572,7 +572,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -595,7 +595,7 @@
     },
     },
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 128.65625,
+      "width": 54,
       "height": 56.4
       "height": 56.4
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -631,7 +631,7 @@
       "b": 255,
       "b": 255,
       "a": 255
       "a": 255
     },
     },
-    "_string": "Confirm",
+    "_string": "OK",
     "_horizontalAlign": 1,
     "_horizontalAlign": 1,
     "_verticalAlign": 1,
     "_verticalAlign": 1,
     "_actualFontSize": 32,
     "_actualFontSize": 32,
@@ -704,7 +704,7 @@
     },
     },
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 280,
+      "width": 334,
       "height": 94
       "height": 94
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -746,7 +746,7 @@
     },
     },
     "_type": 0,
     "_type": 0,
     "_fillType": 0,
     "_fillType": 0,
-    "_sizeMode": 0,
+    "_sizeMode": 2,
     "_fillCenter": {
     "_fillCenter": {
       "__type__": "cc.Vec2",
       "__type__": "cc.Vec2",
       "x": 0,
       "x": 0,
@@ -845,7 +845,7 @@
         "__id__": 34
         "__id__": 34
       }
       }
     ],
     ],
-    "_active": true,
+    "_active": false,
     "_components": [
     "_components": [
       {
       {
         "__id__": 40
         "__id__": 40
@@ -880,7 +880,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -930,7 +930,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -1216,8 +1216,8 @@
     },
     },
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 480,
-      "y": 283,
+      "x": 328.5,
+      "y": 199.5,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -1234,7 +1234,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -1394,7 +1394,7 @@
       "__id__": 12
       "__id__": 12
     },
     },
     "_children": [],
     "_children": [],
-    "_active": true,
+    "_active": false,
     "_components": [
     "_components": [
       {
       {
         "__id__": 56
         "__id__": 56
@@ -1426,7 +1426,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -1567,8 +1567,8 @@
     },
     },
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 0,
-      "y": 15,
+      "x": 0.9209999999999994,
+      "y": 50,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -1585,7 +1585,7 @@
       "z": 1
       "z": 1
     },
     },
     "_mobility": 0,
     "_mobility": 0,
-    "_layer": 1073741824,
+    "_layer": 33554432,
     "_euler": {
     "_euler": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -1608,8 +1608,8 @@
     },
     },
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 846,
-      "height": 310
+      "width": 550,
+      "height": 200
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
       "__type__": "cc.Vec2",
       "__type__": "cc.Vec2",
@@ -1644,11 +1644,11 @@
       "b": 255,
       "b": 255,
       "a": 255
       "a": 255
     },
     },
-    "_string": "",
+    "_string": "1111111t1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
     "_horizontalAlign": 1,
     "_horizontalAlign": 1,
     "_verticalAlign": 1,
     "_verticalAlign": 1,
-    "_actualFontSize": 36,
-    "_fontSize": 36,
+    "_actualFontSize": 24,
+    "_fontSize": 24,
     "_fontFamily": "Arial",
     "_fontFamily": "Arial",
     "_lineHeight": 50,
     "_lineHeight": 50,
     "_overflow": 1,
     "_overflow": 1,
@@ -1717,8 +1717,8 @@
     },
     },
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 978,
-      "height": 601
+      "width": 691,
+      "height": 436
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
       "__type__": "cc.Vec2",
       "__type__": "cc.Vec2",
@@ -1754,7 +1754,7 @@
       "a": 255
       "a": 255
     },
     },
     "_spriteFrame": {
     "_spriteFrame": {
-      "__uuid__": "79040ba5-8b4f-45f4-8ec3-9c858e662fd4@f9941",
+      "__uuid__": "c380ae6b-c7bd-4505-97d4-96ab52e5416d@f9941",
       "__expectedType__": "cc.SpriteFrame"
       "__expectedType__": "cc.SpriteFrame"
     },
     },
     "_type": 0,
     "_type": 0,

Разница между файлами не показана из-за своего большого размера
+ 181 - 160
assets/lobbyRes/ui/home/HomeView.prefab


+ 9 - 0
assets/lobbyRes/ui/invite.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "72fbe6e1-3566-441c-a671-5a3cc452365f",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 749 - 0
assets/lobbyRes/ui/invite/UIInvite.prefab

@@ -0,0 +1,749 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "UIInvite",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "persistent": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "UIInvite",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 14
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 28
+      },
+      {
+        "__id__": 30
+      },
+      {
+        "__id__": 32
+      },
+      {
+        "__id__": 34
+      }
+    ],
+    "_prefab": {
+      "__id__": 36
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "shadow",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 3
+      },
+      {
+        "__id__": 5
+      },
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 9
+      },
+      {
+        "__id__": 11
+      }
+    ],
+    "_prefab": {
+      "__id__": 13
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 4
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1624,
+      "height": 750
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "7fjmvG2lRLF46wS2+3Qccb"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 6
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 191
+    },
+    "_spriteFrame": {
+      "__uuid__": "b730527c-3233-41c2-aaf7-7cdab58f9749@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 1,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "60ZMlFeUtCVIIOTs1FFJaX"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 8
+    },
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 40,
+    "_originalHeight": 36,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "6ewFNc+npN3ZWaJG0RT33t"
+  },
+  {
+    "__type__": "cc.BlockInputEvents",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 10
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "b8CaI/KZVJE7Q1aDJEcGon"
+  },
+  {
+    "__type__": "cc.UIOpacity",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 12
+    },
+    "_opacity": 255,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "adRKMZt7FEBKK7kA6UxJEA"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "ac/GNYdWVPL6zTG9eUigXp",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "container",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 15
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 23
+      },
+      {
+        "__id__": 25
+      }
+    ],
+    "_prefab": {
+      "__id__": 27
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": -6.5,
+      "y": -11.5,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "btnClose",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 14
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 16
+      },
+      {
+        "__id__": 18
+      },
+      {
+        "__id__": 20
+      }
+    ],
+    "_prefab": {
+      "__id__": 22
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 473,
+      "y": 288,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 15
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 17
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 68,
+      "height": 68
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "82iewEkn1MHYovjAo205RK"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 15
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 19
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "233c0fe1-a3cf-4309-8fb4-622e35ad4c4b@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "48oUb391pMmIofhAJLorPo"
+  },
+  {
+    "__type__": "cc.Button",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 15
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 21
+    },
+    "clickEvents": [],
+    "_interactable": true,
+    "_transition": 3,
+    "_normalColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_hoverColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "_pressedColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_disabledColor": {
+      "__type__": "cc.Color",
+      "r": 124,
+      "g": 124,
+      "b": 124,
+      "a": 255
+    },
+    "_normalSprite": null,
+    "_hoverSprite": null,
+    "_pressedSprite": null,
+    "_disabledSprite": null,
+    "_duration": 0.1,
+    "_zoomScale": 1.2,
+    "_target": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "a2ibj2prZAzqEj+/skjfEV"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "c9M/TTuAZACaTtryJQmP6s",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 14
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 24
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 978,
+      "height": 601
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "69LOGUiT1KQ503VsEFkmng"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 14
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 26
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "79040ba5-8b4f-45f4-8ec3-9c858e662fd4@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "ca2WLMIn5OBooDAI8XXcrM"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "b8hKCnuzZLr6DDcCHGKPKG",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 29
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1624,
+      "height": 750
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "5aBEukxvlL5LVptNC3T3RT"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 31
+    },
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 40,
+    "_originalHeight": 36,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "80Aw4YRQ5IzbizA27x8uyI"
+  },
+  {
+    "__type__": "cc.BlockInputEvents",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 33
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "e8NSFT2SNOIJRMu0bD6Ees"
+  },
+  {
+    "__type__": "45b206y4iNK551HPNOcxA35",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 35
+    },
+    "popupMask": {
+      "__id__": 11
+    },
+    "popupRoot": {
+      "__id__": 14
+    },
+    "btnClose": {
+      "__id__": 15
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "62FmsvmOxP2qCfd4ueJGTm"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "073EN45qVO75Lrl3dUyoRr",
+    "instance": null,
+    "targetOverrides": null
+  }
+]

+ 13 - 0
assets/lobbyRes/ui/invite/UIInvite.prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.50",
+  "importer": "prefab",
+  "imported": true,
+  "uuid": "a2eabdc2-4694-4f9c-9619-c284c442f24b",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {
+    "syncNodeName": "UIInvite"
+  }
+}

Разница между файлами не показана из-за своего большого размера
+ 176 - 155
assets/lobbyRes/ui/login/LoginView.prefab


Разница между файлами не показана из-за своего большого размера
+ 181 - 160
assets/lobbyRes/ui/store/StoreView.prefab


Разница между файлами не показана из-за своего большого размера
+ 322 - 310
assets/lobbyRes/ui/store/UIFirstPack.prefab


+ 222 - 62
assets/scenes/Launch.scene

@@ -22,7 +22,9 @@
     ],
     ],
     "_active": true,
     "_active": true,
     "_components": [],
     "_components": [],
-    "_prefab": null,
+    "_prefab": {
+      "__id__": 30
+    },
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
       "x": 0,
       "x": 0,
@@ -52,7 +54,7 @@
     },
     },
     "autoReleaseAssets": false,
     "autoReleaseAssets": false,
     "_globals": {
     "_globals": {
-      "__id__": 25
+      "__id__": 31
     },
     },
     "_id": "9f2682fb-c657-4518-99a6-10a3af34a002"
     "_id": "9f2682fb-c657-4518-99a6-10a3af34a002"
   },
   },
@@ -72,25 +74,31 @@
         "__id__": 5
         "__id__": 5
       },
       },
       {
       {
-        "__id__": 9
+        "__id__": 10
       },
       },
       {
       {
-        "__id__": 12
+        "__id__": 13
       },
       },
       {
       {
-        "__id__": 19
+        "__id__": 20
+      },
+      {
+        "__id__": 23
       }
       }
     ],
     ],
     "_active": true,
     "_active": true,
     "_components": [
     "_components": [
       {
       {
-        "__id__": 22
+        "__id__": 26
       },
       },
       {
       {
-        "__id__": 23
+        "__id__": 27
       },
       },
       {
       {
-        "__id__": 24
+        "__id__": 28
+      },
+      {
+        "__id__": 29
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
@@ -182,14 +190,14 @@
     "_priority": 0,
     "_priority": 0,
     "_fov": 45,
     "_fov": 45,
     "_fovAxis": 0,
     "_fovAxis": 0,
-    "_orthoHeight": 538.6293706293706,
+    "_orthoHeight": 446.8724832214765,
     "_near": 1,
     "_near": 1,
     "_far": 2000,
     "_far": 2000,
     "_color": {
     "_color": {
       "__type__": "cc.Color",
       "__type__": "cc.Color",
-      "r": 51,
-      "g": 51,
-      "b": 51,
+      "r": 0,
+      "g": 0,
+      "b": 0,
       "a": 255
       "a": 255
     },
     },
     "_depth": 1,
     "_depth": 1,
@@ -206,7 +214,7 @@
     "_shutter": 7,
     "_shutter": 7,
     "_iso": 0,
     "_iso": 0,
     "_screenScale": 1,
     "_screenScale": 1,
-    "_visibility": 1117782015,
+    "_visibility": 33554432,
     "_targetTexture": null,
     "_targetTexture": null,
     "_postProcess": null,
     "_postProcess": null,
     "_usePostProcess": false,
     "_usePostProcess": false,
@@ -233,12 +241,15 @@
       },
       },
       {
       {
         "__id__": 8
         "__id__": 8
+      },
+      {
+        "__id__": 9
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 0,
+      "x": -1.1368683772161603e-13,
       "y": 0,
       "y": 0,
       "z": 0
       "z": 0
     },
     },
@@ -338,6 +349,18 @@
     "__prefab": null,
     "__prefab": null,
     "_id": "bchma5q9dFPLu9/Xz2096n"
     "_id": "bchma5q9dFPLu9/Xz2096n"
   },
   },
+  {
+    "__type__": "b9d427SFYhBgYvBWvMbdp8M",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 5
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_id": "1c/VCbErdGcIVlUDi8V7rR"
+  },
   {
   {
     "__type__": "cc.Node",
     "__type__": "cc.Node",
     "_name": "sptLogo",
     "_name": "sptLogo",
@@ -350,17 +373,17 @@
     "_active": true,
     "_active": true,
     "_components": [
     "_components": [
       {
       {
-        "__id__": 10
+        "__id__": 11
       },
       },
       {
       {
-        "__id__": 11
+        "__id__": 12
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": 3,
-      "y": 241,
+      "x": -1.1050000000001319,
+      "y": 244.59500000000003,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -392,7 +415,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 9
+      "__id__": 10
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -414,7 +437,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 9
+      "__id__": 10
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -457,26 +480,26 @@
     },
     },
     "_children": [
     "_children": [
       {
       {
-        "__id__": 13
+        "__id__": 14
       }
       }
     ],
     ],
     "_active": true,
     "_active": true,
     "_components": [
     "_components": [
-      {
-        "__id__": 16
-      },
       {
       {
         "__id__": 17
         "__id__": 17
       },
       },
       {
       {
         "__id__": 18
         "__id__": 18
+      },
+      {
+        "__id__": 19
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": -4,
-      "y": -219,
+      "x": -8.105000000000132,
+      "y": -215.405,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -508,16 +531,16 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "_parent": {
     "_parent": {
-      "__id__": 12
+      "__id__": 13
     },
     },
     "_children": [],
     "_children": [],
     "_active": true,
     "_active": true,
     "_components": [
     "_components": [
       {
       {
-        "__id__": 14
+        "__id__": 15
       },
       },
       {
       {
-        "__id__": 15
+        "__id__": 16
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
@@ -556,7 +579,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 13
+      "__id__": 14
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -578,7 +601,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 13
+      "__id__": 14
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -605,7 +628,7 @@
       "y": 0
       "y": 0
     },
     },
     "_fillStart": 0,
     "_fillStart": 0,
-    "_fillRange": 1,
+    "_fillRange": 0,
     "_isTrimmedMode": true,
     "_isTrimmedMode": true,
     "_useGrayscale": false,
     "_useGrayscale": false,
     "_atlas": null,
     "_atlas": null,
@@ -617,7 +640,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 12
+      "__id__": 13
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -639,7 +662,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 12
+      "__id__": 13
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -678,16 +701,16 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 12
+      "__id__": 13
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
     "_barSprite": {
     "_barSprite": {
-      "__id__": 15
+      "__id__": 16
     },
     },
     "_mode": 2,
     "_mode": 2,
     "_totalLength": 1,
     "_totalLength": 1,
-    "_progress": 1,
+    "_progress": 0,
     "_reverse": false,
     "_reverse": false,
     "_id": "90UqLDIMpEOpygSCsR9jFF"
     "_id": "90UqLDIMpEOpygSCsR9jFF"
   },
   },
@@ -703,17 +726,17 @@
     "_active": true,
     "_active": true,
     "_components": [
     "_components": [
       {
       {
-        "__id__": 20
+        "__id__": 21
       },
       },
       {
       {
-        "__id__": 21
+        "__id__": 22
       }
       }
     ],
     ],
     "_prefab": null,
     "_prefab": null,
     "_lpos": {
     "_lpos": {
       "__type__": "cc.Vec3",
       "__type__": "cc.Vec3",
-      "x": -4.5,
-      "y": -217,
+      "x": -8.605000000000132,
+      "y": -213.405,
       "z": 0
       "z": 0
     },
     },
     "_lrot": {
     "_lrot": {
@@ -745,13 +768,13 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 19
+      "__id__": 20
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
     "_contentSize": {
     "_contentSize": {
       "__type__": "cc.Size",
       "__type__": "cc.Size",
-      "width": 62.041015625,
+      "width": 46.46875,
       "height": 56.4
       "height": 56.4
     },
     },
     "_anchorPoint": {
     "_anchorPoint": {
@@ -767,7 +790,7 @@
     "_objFlags": 0,
     "_objFlags": 0,
     "__editorExtras__": {},
     "__editorExtras__": {},
     "node": {
     "node": {
-      "__id__": 19
+      "__id__": 20
     },
     },
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
@@ -781,7 +804,7 @@
       "b": 255,
       "b": 255,
       "a": 255
       "a": 255
     },
     },
-    "_string": "50%",
+    "_string": "0%",
     "_horizontalAlign": 1,
     "_horizontalAlign": 1,
     "_verticalAlign": 1,
     "_verticalAlign": 1,
     "_actualFontSize": 28,
     "_actualFontSize": 28,
@@ -823,6 +846,106 @@
     "_shadowBlur": 2,
     "_shadowBlur": 2,
     "_id": "6dtbAFVRFOwqiTWEJObdAK"
     "_id": "6dtbAFVRFOwqiTWEJObdAK"
   },
   },
+  {
+    "__type__": "cc.Node",
+    "_name": "dialog",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 24
+      },
+      {
+        "__id__": 25
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "c7gP/pPrJPxL3If4pJe5r1"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 23
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1624,
+      "height": 750
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "06ojAte+ZOfZ1m7zmWcTgX"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 23
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 100,
+    "_originalHeight": 100,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": "a6ghARmqJM3a10B8LErgYe"
+  },
   {
   {
     "__type__": "cc.UITransform",
     "__type__": "cc.UITransform",
     "_name": "",
     "_name": "",
@@ -845,6 +968,36 @@
     },
     },
     "_id": "d3qy7wFplAWqbGQkl9WXlz"
     "_id": "d3qy7wFplAWqbGQkl9WXlz"
   },
   },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 1624,
+    "_originalHeight": 750,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": "d33UQ82CVLSKcH2Rh2gZdh"
+  },
   {
   {
     "__type__": "cc.Canvas",
     "__type__": "cc.Canvas",
     "_name": "",
     "_name": "",
@@ -859,7 +1012,7 @@
       "__id__": 4
       "__id__": 4
     },
     },
     "_alignCanvasWithScreen": true,
     "_alignCanvasWithScreen": true,
-    "_id": "f38TXpLhxJCojn6E8ssVt/"
+    "_id": "9e/rsRLNVO0anMgpRCyhox"
   },
   },
   {
   {
     "__type__": "4a90aRFfXJBQa+QvSJ3Gy4Z",
     "__type__": "4a90aRFfXJBQa+QvSJ3Gy4Z",
@@ -872,46 +1025,53 @@
     "_enabled": true,
     "_enabled": true,
     "__prefab": null,
     "__prefab": null,
     "canvas": {
     "canvas": {
-      "__id__": 23
+      "__id__": 28
     },
     },
     "progressLabel": {
     "progressLabel": {
-      "__id__": 21
+      "__id__": 22
     },
     },
     "progressMsg": null,
     "progressMsg": null,
     "progressBar": {
     "progressBar": {
-      "__id__": 18
+      "__id__": 19
+    },
+    "dialogNode": {
+      "__id__": 23
     },
     },
-    "dialogNode": null,
-    "dialogLabel": null,
-    "dialogConfirmButton": null,
-    "dialogCancelButton": null,
-    "_id": "0d67yrpedDj5dxqWvFI9UK"
+    "_id": "c4kWxC3Q9MeKu8HhVgXBc2"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": null,
+    "asset": null,
+    "fileId": "9f2682fb-c657-4518-99a6-10a3af34a002",
+    "instance": null,
+    "targetOverrides": null
   },
   },
   {
   {
     "__type__": "cc.SceneGlobals",
     "__type__": "cc.SceneGlobals",
     "ambient": {
     "ambient": {
-      "__id__": 26
+      "__id__": 32
     },
     },
     "shadows": {
     "shadows": {
-      "__id__": 27
+      "__id__": 33
     },
     },
     "_skybox": {
     "_skybox": {
-      "__id__": 28
+      "__id__": 34
     },
     },
     "fog": {
     "fog": {
-      "__id__": 29
+      "__id__": 35
     },
     },
     "octree": {
     "octree": {
-      "__id__": 30
+      "__id__": 36
     },
     },
     "skin": {
     "skin": {
-      "__id__": 31
+      "__id__": 37
     },
     },
     "lightProbeInfo": {
     "lightProbeInfo": {
-      "__id__": 32
+      "__id__": 38
     },
     },
     "postSettings": {
     "postSettings": {
-      "__id__": 33
+      "__id__": 39
     },
     },
     "bakedWithStationaryMainLight": false,
     "bakedWithStationaryMainLight": false,
     "bakedWithHighpLightmap": false
     "bakedWithHighpLightmap": false

+ 2 - 0
assets/scripts/api/LobbyApi.ts

@@ -3,6 +3,8 @@ import { API_BASE_PREFIX, get, post } from './Config';
 export const APP_ROUTES = get('routes');
 export const APP_ROUTES = get('routes');
 export const APP_PAGE_MODULE = API_BASE_PREFIX + 'pageModules/';
 export const APP_PAGE_MODULE = API_BASE_PREFIX + 'pageModules/';
 export const APP_GAME_LIST = get('sc/game/list');
 export const APP_GAME_LIST = get('sc/game/list');
+export const APP_GAME_LAUNCH = get('sc/game/launch');
+
 export const APP_GAME_CARD_INFO = get('gameinfo');
 export const APP_GAME_CARD_INFO = get('gameinfo');
 export const APP_GAME_ENTER_RECORD = get('game_enter/record');
 export const APP_GAME_ENTER_RECORD = get('game_enter/record');
 
 

+ 7 - 0
assets/scripts/api/PaymentApi.ts

@@ -7,6 +7,13 @@ export const APP_PAYMENT_ORDER = get("payment_entry/pay");
 
 
 export const APP_PAY_ORDER_LIST = get("pay/orderList");
 export const APP_PAY_ORDER_LIST = get("pay/orderList");
 
 
+/** 首冲礼包详细情况 (打开礼包是调用, 调用后自动开启首冲礼包计时) */
+export const APP_FIRST_PACK = get("recharge/sc/first_pack");
+
+/** 首冲礼包入口是否可见 */
+export const APP_FIRST_PACK_VISIBLE = get('recharge/sc/first_pack_visible');
+
+
 
 
 export const APP_WITHDRAW_BASE_INFO = post("withDraw/baseInfo");
 export const APP_WITHDRAW_BASE_INFO = post("withDraw/baseInfo");
 
 

+ 9 - 0
assets/scripts/components/adapter.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "2634b88d-6fa1-42bd-a247-3d2e28f33b5f",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 56 - 0
assets/scripts/components/adapter/BackgroundAdapter.ts

@@ -0,0 +1,56 @@
+import { _decorator, Component, Node, screen, UITransform, Vec3, view } from 'cc';
+
+const { ccclass } = _decorator;
+
+/**
+ * 使背景图始终覆盖父容器的高度,并保持图片原有宽高比。
+ *
+ * 建议挂在 Canvas(或全屏容器)下的背景节点上,且不要同时给该节点配置纵向拉伸 Widget。
+ */
+@ccclass('BackgroundAdapter')
+export class BackgroundAdapter extends Component {
+  private readonly baseScale = new Vec3();
+  private uiTransform: UITransform | null = null;
+  private targetTransform: UITransform | null = null;
+  private sourceHeight = 0;
+  private lastTargetHeight = -1;
+
+  protected onLoad(): void {
+    this.uiTransform = this.getComponent(UITransform);
+    this.targetTransform = this.node.parent?.getComponent(UITransform) ?? null;
+    if (!this.uiTransform) {
+      console.warn('[BackgroundAdapter] 缺少 UITransform,无法进行背景适配。', this.node.name);
+      return;
+    }
+
+    this.baseScale.set(this.node.scale);
+    this.sourceHeight = this.uiTransform.height * Math.abs(this.baseScale.y);
+  }
+
+  protected onEnable(): void {
+    screen.on('window-resize', this.adaptHeight, this);
+    this.targetTransform?.node.on(Node.EventType.SIZE_CHANGED, this.adaptHeight, this);
+    this.scheduleOnce(this.adaptHeight);
+  }
+
+  protected onDisable(): void {
+    screen.off('window-resize', this.adaptHeight, this);
+    this.targetTransform?.node.off(Node.EventType.SIZE_CHANGED, this.adaptHeight, this);
+  }
+
+  private readonly adaptHeight = (): void => {
+    if (!this.uiTransform || this.sourceHeight <= 0) return;
+
+    const targetHeight = this.targetTransform?.height ?? view.getVisibleSize().height;
+    if (targetHeight <= 0 || Math.abs(targetHeight - this.lastTargetHeight) < 0.01) return;
+
+    // 背景只放大不缩小:较矮屏幕裁剪上下区域,较高屏幕补足可见区域。
+    const scale = Math.max(1, targetHeight / this.sourceHeight);
+    this.node.setScale(
+      this.baseScale.x * scale,
+      this.baseScale.y * scale,
+      this.baseScale.z * scale,
+    );
+    this.lastTargetHeight = targetHeight;
+  };
+}

+ 1 - 1
assets/scripts/modules/launch/states/CompleteState.ts.meta → assets/scripts/components/adapter/BackgroundAdapter.ts.meta

@@ -2,7 +2,7 @@
   "ver": "4.0.24",
   "ver": "4.0.24",
   "importer": "typescript",
   "importer": "typescript",
   "imported": true,
   "imported": true,
-  "uuid": "5a5e9018-f507-4bad-a35b-c57838f30048",
+  "uuid": "b9d42ed2-1588-4181-8bc1-5af31b769f0c",
   "files": [],
   "files": [],
   "subMetas": {},
   "subMetas": {},
   "userData": {}
   "userData": {}

+ 8 - 1
assets/scripts/define/UIDefine.ts

@@ -24,6 +24,7 @@ export const UIViewID = {
     ChangeAvatar: "ChangeAvatar",
     ChangeAvatar: "ChangeAvatar",
     BindPhone: "BindPhone",
     BindPhone: "BindPhone",
     BindEmail: "BindEmail",
     BindEmail: "BindEmail",
+    UIInvite: "UIInvite",
 } as const;
 } as const;
 
 
 export type UIViewID = typeof UIViewID[keyof typeof UIViewID];
 export type UIViewID = typeof UIViewID[keyof typeof UIViewID];
@@ -70,6 +71,7 @@ export const UIViewConfigs: Record<string, UIViewConfig> = {
     [UIViewID.UIDialog]: {
     [UIViewID.UIDialog]: {
         id: UIViewID.UIDialog,
         id: UIViewID.UIDialog,
         prefabPath: 'ui/dialog/UIDialog',
         prefabPath: 'ui/dialog/UIDialog',
+        ignoreLoading: true,
         layer: UILayer.System,
         layer: UILayer.System,
         cache: UICachePolicy.Persist,
         cache: UICachePolicy.Persist,
     },
     },
@@ -162,7 +164,12 @@ export const UIViewConfigs: Record<string, UIViewConfig> = {
         id: UIViewID.BindEmail,
         id: UIViewID.BindEmail,
         prefabPath: 'ui/userInfo/BindEmail',
         prefabPath: 'ui/userInfo/BindEmail',
         layer: UILayer.Popup
         layer: UILayer.Popup
-    }
+    },
+    [UIViewID.UIInvite]: {
+        id: UIViewID.UIInvite,
+        prefabPath: 'ui/invite/UIInvite',
+        layer: UILayer.Popup
+    },
 
 
 };
 };
 
 

+ 32 - 16
assets/scripts/framework/ui/UIManager.ts

@@ -177,7 +177,10 @@ export class UIManager {
 
 
     const config = getUIViewConfig(viewId);
     const config = getUIViewConfig(viewId);
     const root = this.roots.get(config.layer);
     const root = this.roots.get(config.layer);
-    if (!root?.isValid) throw new Error(`[UIManager] UILayer is not bound: ${config.layer}`);
+    if (!root?.isValid) {
+      console.error(`[UIManager] UILayer is not bound: ${config.layer}`);
+      return null;
+    }
 
 
     record = record ?? {
     record = record ?? {
       config,
       config,
@@ -254,38 +257,51 @@ export class UIManager {
     const prefabView = prefab.data?.getComponent?.(UIView) as UIView | null;
     const prefabView = prefab.data?.getComponent?.(UIView) as UIView | null;
     if (!prefabView) {
     if (!prefabView) {
       record.state = UIViewState.None;
       record.state = UIViewState.None;
-      throw new Error(`[UIManager] Prefab has no UIView component: ${record.config.id}`);
-    }
-
-    let allowOpen: boolean;
-    try {
-      allowOpen = await prefabView.internalOpenBefore(params);
-    } catch (error) {
-      if (generation === record.generation) record.state = UIViewState.None;
-      throw error;
-    }
-    if (generation !== record.generation) return null;
-    if (!allowOpen) {
-      record.state = UIViewState.None;
+      console.error(`[UIManager] Prefab has no UIView component: ${record.config.id}`);
       return null;
       return null;
     }
     }
 
 
     record.state = UIViewState.Creating;
     record.state = UIViewState.Creating;
     const node = instantiate(prefab);
     const node = instantiate(prefab);
+    node.active = false;
     root.addChild(node);
     root.addChild(node);
     const view = node.getComponent(UIView);
     const view = node.getComponent(UIView);
     if (!view) {
     if (!view) {
       node.destroy();
       node.destroy();
-      throw new Error(`[UIManager] Prefab has no UIView component: ${record.config.id}`);
+      console.error(`[UIManager] Prefab has no UIView component: ${record.config.id}`);
+      return null;
     }
     }
 
 
     record.view = view;
     record.view = view;
-    await view.internalCreate();
+    view.internalCreate();
+
+    if (generation !== record.generation || !node.isValid) {
+      node.destroy();
+      record.view = null;
+      return null;
+    }
+
+    let allowOpen: boolean;
+    try {
+      allowOpen = await view.internalOpenBefore(params);
+    } catch (error) {
+      console.error(error, record.config.id)
+      node.destroy();
+      record.view = null;
+      if (generation === record.generation) record.state = UIViewState.None;
+      return null;
+    }
     if (generation !== record.generation || !node.isValid) {
     if (generation !== record.generation || !node.isValid) {
       node.destroy();
       node.destroy();
       record.view = null;
       record.view = null;
       return null;
       return null;
     }
     }
+    if (!allowOpen) {
+      node.destroy();
+      record.view = null;
+      record.state = UIViewState.None;
+      return null;
+    }
 
 
     await this.closeMutexViews(record.config);
     await this.closeMutexViews(record.config);
     record.state = UIViewState.Opening;
     record.state = UIViewState.Opening;

+ 4 - 4
assets/scripts/framework/ui/UIView.ts

@@ -18,15 +18,15 @@ export class UIView<TParams = unknown> extends Component {
   }
   }
 
 
   /**
   /**
-   * 在界面实例化(首次打开)或显示(缓存界面再次打开)之前执行。
-   * 首次打开时 this 是 Prefab 模板组件,只应进行鉴权、请求数据等无节点状态操作。
+   * 在界面创建完成后、显示前执行;首次打开与缓存界面再次打开时,
+   * this 都是同一个实际的 UIView 实例。
    */
    */
   async internalOpenBefore(params: TParams): Promise<boolean> {
   async internalOpenBefore(params: TParams): Promise<boolean> {
     return (await this.onBeforeOpen(params)) !== false;
     return (await this.onBeforeOpen(params)) !== false;
   }
   }
 
 
-  async internalCreate(): Promise<void> {
-    await this.onCreate();
+  internalCreate() {
+    this.onCreate();
   }
   }
 
 
   async internalOpen(params: TParams): Promise<void> {
   async internalOpen(params: TParams): Promise<void> {

+ 6 - 1
assets/scripts/i18n/en/en1.ts

@@ -17,11 +17,16 @@ export const home = {
     logout: {
     logout: {
         title: "Log Out",
         title: "Log Out",
         content: "Are you sure you want to log out?"
         content: "Are you sure you want to log out?"
-    }
+    },
+    notices: "{nickName} won {coin} {value}"
 };
 };
 
 
 export const dialog = {
 export const dialog = {
     tips: "TIPS",
     tips: "TIPS",
     confirm: "Confirm",
     confirm: "Confirm",
     cancel: "Cancel"
     cancel: "Cancel"
+}
+
+export const store = {
+    buynow: "BUYNOW ${0}"
 }
 }

+ 22 - 86
assets/scripts/modules/launch/LaunchController.ts

@@ -7,13 +7,16 @@ import {
   Component,
   Component,
   director,
   director,
   Director,
   Director,
+  find,
   Label,
   Label,
   Node,
   Node,
   ProgressBar,
   ProgressBar,
+  UITransform,
 } from 'cc';
 } from 'cc';
 import { AppKernel } from '../../app/AppKernel';
 import { AppKernel } from '../../app/AppKernel';
 import { LaunchProgress, LaunchStateMachine } from './LaunchStateMachine';
 import { LaunchProgress, LaunchStateMachine } from './LaunchStateMachine';
 import { LaunchDialog } from './states/LaunchState';
 import { LaunchDialog } from './states/LaunchState';
+import { UILayer } from '@scripts/framework/ui/UILayer';
 
 
 const { ccclass, property } = _decorator;
 const { ccclass, property } = _decorator;
 
 
@@ -34,33 +37,23 @@ export class LaunchController extends Component {
   @property(Node)
   @property(Node)
   dialogNode: Node | null = null;
   dialogNode: Node | null = null;
 
 
-  @property(Label)
-  dialogLabel: Label | null = null;
-
-  @property(Button)
-  dialogConfirmButton: Button | null = null;
-
-  @property(Button)
-  dialogCancelButton: Button | null = null;
-
   private launchStateMachine: LaunchStateMachine | null = null;
   private launchStateMachine: LaunchStateMachine | null = null;
-  private dialogResolve: ((confirmed: boolean) => void) | null = null;
 
 
   protected onLoad(): void {
   protected onLoad(): void {
     director.addPersistRootNode(this.node);
     director.addPersistRootNode(this.node);
     AppKernel.initialize();
     AppKernel.initialize();
-    this.initEvents();
 
 
+    this.initEvents();
     this.launchStateMachine = new LaunchStateMachine({
     this.launchStateMachine = new LaunchStateMachine({
       kernel: AppKernel.Instance,
       kernel: AppKernel.Instance,
       error: null,
       error: null,
+      totalProgress: 0,
       progress: (value) => this.updateProgress(value),
       progress: (value) => this.updateProgress(value),
       dialog: (message) => this.showDialog(message),
       dialog: (message) => this.showDialog(message),
     });
     });
   }
   }
 
 
   private initEvents(): void {
   private initEvents(): void {
-    director.on(Director.EVENT_AFTER_SCENE_LAUNCH, this.onChangeScene, this,);
     AppKernel.events.once('launch:completed', this.onLaunchCompleted, this);
     AppKernel.events.once('launch:completed', this.onLaunchCompleted, this);
   }
   }
 
 
@@ -79,86 +72,29 @@ export class LaunchController extends Component {
   }
   }
 
 
   protected onDestroy(): void {
   protected onDestroy(): void {
-    this.finishDialog(false);
     AppKernel.events.offTarget(this);
     AppKernel.events.offTarget(this);
-    director.off(Director.EVENT_AFTER_SCENE_LAUNCH, this.onChangeScene, this);
   }
   }
 
 
-  private readonly onChangeScene = (): void => {
-    if (!this.node.isValid) return;
-
-    const scene = director.getScene();
-    const lobbyCanvas = scene?.getComponentsInChildren(Canvas)?.find(item => item != this.canvas);
-
-    if (lobbyCanvas) {
-      this.node.setParent(lobbyCanvas.node, true);
-      this.node.setSiblingIndex(lobbyCanvas.node.children.length - 1);
-    }
-  };
-
   private updateProgress(value: LaunchProgress): void {
   private updateProgress(value: LaunchProgress): void {
-    const progress = value.progress || 0;
-    this.progressBar.progress = progress;
-    this.progressLabel.string = `${Math.floor(progress * 100)}%`;
-    if (this.progressMsg) this.progressMsg.string = value.title || "";
-  }
-
-  private showDialog({ message }: LaunchDialog): Promise<boolean> {
-    if (
-      !this.dialogNode
-      || !this.dialogLabel
-      || !this.dialogConfirmButton
-      || !this.dialogCancelButton
-    ) {
-      if (typeof globalThis.confirm === 'function') {
-        return Promise.resolve(globalThis.confirm(message));
-      }
-      console.warn('[LaunchController] dialog nodes are not configured');
-      return Promise.resolve(false);
+    if (value.progress !== undefined) {
+      const progress = value.progress || 0;
+      this.progressBar.progress = progress;
+      this.progressLabel.string = `${Math.floor(progress * 100)}%`;
     }
     }
-
-    this.finishDialog(false);
-    this.dialogLabel.string = message;
-    this.dialogNode.active = true;
-
-    return new Promise<boolean>((resolve) => {
-      this.dialogResolve = resolve;
-      this.dialogConfirmButton?.node.once(
-        Button.EventType.CLICK,
-        this.onDialogConfirm,
-        this,
-      );
-      this.dialogCancelButton?.node.once(
-        Button.EventType.CLICK,
-        this.onDialogCancel,
-        this,
-      );
-    });
+    if (this.progressMsg) this.progressMsg.string = value.title || "";
   }
   }
 
 
-  private readonly onDialogConfirm = (): void => {
-    this.finishDialog(true);
-  };
-
-  private readonly onDialogCancel = (): void => {
-    this.finishDialog(false);
-  };
-
-  private finishDialog(confirmed: boolean): void {
-    this.dialogConfirmButton?.node.off(
-      Button.EventType.CLICK,
-      this.onDialogConfirm,
-      this,
-    );
-    this.dialogCancelButton?.node.off(
-      Button.EventType.CLICK,
-      this.onDialogCancel,
-      this,
-    );
-    if (this.dialogNode) this.dialogNode.active = false;
-
-    const resolve = this.dialogResolve;
-    this.dialogResolve = null;
-    resolve?.(confirmed);
+  private showDialog(dialog: LaunchDialog): Promise<boolean> {
+    AppKernel.ui.bindLayer(UILayer.System, this.dialogNode);
+    return new Promise<boolean>((resolve, reject) => {
+      AppKernel.ui.dialog({
+        message: dialog.message,
+        lblConfirm: dialog.lblOK,
+        callBack: (res) => {
+          resolve(res);
+          return true
+        }
+      })
+    })
   }
   }
 }
 }

+ 0 - 3
assets/scripts/modules/launch/LaunchStateMachine.ts

@@ -1,7 +1,5 @@
-import { AppKernel } from '../../app/AppKernel';
 import { AsyncStateMachine } from '../../framework/state/AsyncStateMachine';
 import { AsyncStateMachine } from '../../framework/state/AsyncStateMachine';
 import { CheckVersionState } from './states/CheckVersionState';
 import { CheckVersionState } from './states/CheckVersionState';
-import { CompleteState } from './states/CompleteState';
 import { EnterLobbyState } from './states/EnterLobbyState';
 import { EnterLobbyState } from './states/EnterLobbyState';
 import { FailedState } from './states/FailedState';
 import { FailedState } from './states/FailedState';
 import { HotUpdateState } from './states/HotUpdateState';
 import { HotUpdateState } from './states/HotUpdateState';
@@ -48,7 +46,6 @@ export class LaunchStateMachine {
       new HotUpdateState(),
       new HotUpdateState(),
       new PreloadLobbyState(),
       new PreloadLobbyState(),
       new EnterLobbyState(),
       new EnterLobbyState(),
-      new CompleteState(),
       new FailedState(),
       new FailedState(),
     ];
     ];
 
 

+ 1 - 1
assets/scripts/modules/launch/states/CheckVersionState.ts

@@ -5,7 +5,7 @@ export class CheckVersionState implements LaunchState {
 
 
   async enter(context: LaunchContext): Promise<LaunchStateId> {
   async enter(context: LaunchContext): Promise<LaunchStateId> {
     const i18n = context.kernel.i18n;
     const i18n = context.kernel.i18n;
-    context.progress({ state: this.id, title: i18n.t('launch.check_app_version') });
+    context.progress({ state: this.id, title: i18n.t('launch.check_app_version'), progress: 0 });
     await context.kernel.version.check();
     await context.kernel.version.check();
     return LaunchStateId.HotUpdate;
     return LaunchStateId.HotUpdate;
   }
   }

+ 0 - 11
assets/scripts/modules/launch/states/CompleteState.ts

@@ -1,11 +0,0 @@
-import { LaunchContext, LaunchState, LaunchStateId } from './LaunchState';
-
-export class CompleteState implements LaunchState {
-  readonly id = LaunchStateId.Complete;
-
-  async enter(context: LaunchContext): Promise<null> {
-    const i18n = context.kernel.i18n;
-    context.progress({ state: this.id, title: i18n.t('launch.finished'), progress: 1 });
-    return null;
-  }
-}

+ 2 - 2
assets/scripts/modules/launch/states/EnterLobbyState.ts

@@ -5,8 +5,8 @@ export class EnterLobbyState implements LaunchState {
 
 
   async enter(context: LaunchContext): Promise<LaunchStateId> {
   async enter(context: LaunchContext): Promise<LaunchStateId> {
     const i18n = context.kernel.i18n;
     const i18n = context.kernel.i18n;
-    context.progress({ state: this.id, title: i18n.t('launch.open_lobby'), progress: 1 });
+    context.progress({ state: this.id, title: i18n.t('launch.finished'), progress: 1 });
     await context.kernel.scenes.goToLobby();
     await context.kernel.scenes.goToLobby();
-    return LaunchStateId.Complete;
+    return null;
   }
   }
 }
 }

+ 25 - 12
assets/scripts/modules/launch/states/HotUpdateState.ts

@@ -1,17 +1,21 @@
 import { LaunchContext, LaunchState, LaunchStateId } from './LaunchState';
 import { LaunchContext, LaunchState, LaunchStateId } from './LaunchState';
 import AppConfig from '../../../app/AppConfig';
 import AppConfig from '../../../app/AppConfig';
 import { NATIVE } from 'cc/env';
 import { NATIVE } from 'cc/env';
+import { math } from 'cc';
 
 
 export class HotUpdateState implements LaunchState {
 export class HotUpdateState implements LaunchState {
   readonly id = LaunchStateId.HotUpdate;
   readonly id = LaunchStateId.HotUpdate;
 
 
+  private _context: LaunchContext;
+
   async enter(context: LaunchContext): Promise<LaunchStateId | null> {
   async enter(context: LaunchContext): Promise<LaunchStateId | null> {
     if (!AppConfig.HotUpdateEnable || !NATIVE) {
     if (!AppConfig.HotUpdateEnable || !NATIVE) {
       return LaunchStateId.PreloadLobby;
       return LaunchStateId.PreloadLobby;
     }
     }
 
 
+    this._context = context;
     const i18n = context.kernel.i18n;
     const i18n = context.kernel.i18n;
-    context.progress({ state: this.id, title: i18n.t('launch.check_res_version') });
+    this.setProgress(0, i18n.t('launch.check_res_version'));
     const result = await context.kernel.hotUpdate.update(
     const result = await context.kernel.hotUpdate.update(
       AppConfig.HotUpdateUrl,
       AppConfig.HotUpdateUrl,
       (progress) => {
       (progress) => {
@@ -24,25 +28,34 @@ export class HotUpdateState implements LaunchState {
               ? i18n.t('launch.updating_res', progress.downloadedFiles, progress.totalFiles)
               ? i18n.t('launch.updating_res', progress.downloadedFiles, progress.totalFiles)
               : i18n.t('launch.check_res_version');
               : i18n.t('launch.check_res_version');
 
 
-        context.progress({
-          state: this.id,
-          title,
-          progress: percent * 0.4,
-        });
+        this.setProgress(percent, title);
       },
       },
     );
     );
 
 
     if (result.restartRequired) {
     if (result.restartRequired) {
-      context.progress({
-        state: this.id,
-        title: i18n.t('launch.update_finished'),
-        progress: 0.65,
-      });
+      this.setProgress(1, i18n.t('launch.update_finished'));
       context.kernel.hotUpdate.restart();
       context.kernel.hotUpdate.restart();
       return null;
       return null;
     }
     }
 
 
-    context.progress({ state: this.id, progress: 0.65 });
+    this.setProgress(1, i18n.t('launch.update_finished'));
     return LaunchStateId.PreloadLobby;
     return LaunchStateId.PreloadLobby;
   }
   }
+
+  private setProgress(percent: number, title?: string) {
+    if (percent >= 1) {
+      this._context.totalProgress = 0.65;
+    }
+
+    const progress = math.lerp(0, 0.65, percent);
+    this._context.progress({
+      state: this.id,
+      progress,
+      title
+    });
+  }
+
+  private getProgress(percent: number) {
+    return math.lerp(0, 0.65, percent);
+  }
 }
 }

+ 1 - 0
assets/scripts/modules/launch/states/LaunchState.ts

@@ -27,6 +27,7 @@ export interface LaunchContext {
   error: unknown;
   error: unknown;
   progress(value: LaunchProgress): void;
   progress(value: LaunchProgress): void;
   dialog(message: LaunchDialog): Promise<boolean>;
   dialog(message: LaunchDialog): Promise<boolean>;
+  totalProgress: number;
 }
 }
 
 
 export interface LaunchState {
 export interface LaunchState {

+ 17 - 3
assets/scripts/modules/launch/states/PreloadLobbyState.ts

@@ -1,20 +1,28 @@
+import { math } from 'cc';
 import { SceneId } from '../../../framework/scene/SceneNavigator';
 import { SceneId } from '../../../framework/scene/SceneNavigator';
 import { LaunchContext, LaunchState, LaunchStateId } from './LaunchState';
 import { LaunchContext, LaunchState, LaunchStateId } from './LaunchState';
 
 
 export class PreloadLobbyState implements LaunchState {
 export class PreloadLobbyState implements LaunchState {
   readonly id = LaunchStateId.PreloadLobby;
   readonly id = LaunchStateId.PreloadLobby;
 
 
+  private _context: LaunchContext;
+
   async enter(context: LaunchContext): Promise<LaunchStateId> {
   async enter(context: LaunchContext): Promise<LaunchStateId> {
+    this._context = context;
     const i18n = context.kernel.i18n;
     const i18n = context.kernel.i18n;
 
 
-    context.progress({ state: this.id, title: i18n.t('launch.preload_res') });
+    let last_percent = 0;
+    this.setProgress(0, i18n.t('launch.preload_res'));
     const kernel = context.kernel;
     const kernel = context.kernel;
     try {
     try {
       await Promise.all([
       await Promise.all([
         await kernel.sound.preload(),
         await kernel.sound.preload(),
         await kernel.scenes.preload(SceneId.Lobby, {
         await kernel.scenes.preload(SceneId.Lobby, {
           onProgress: (percent) => {
           onProgress: (percent) => {
-            context.progress({ state: this.id, progress: percent });
+            /// web preload 进度会回退
+            if (percent < last_percent) return;
+            last_percent = percent;
+            this.setProgress(percent);
           }
           }
         }),
         }),
       ]);
       ]);
@@ -30,7 +38,13 @@ export class PreloadLobbyState implements LaunchState {
       }
       }
       throw error;
       throw error;
     }
     }
-    context.progress({ state: this.id, progress: 1 });
+    this.setProgress(1);
     return LaunchStateId.EnterLobby;
     return LaunchStateId.EnterLobby;
   }
   }
+
+  private setProgress(percent: number, title?: string) {
+    const from = this._context.totalProgress;
+    const progress = math.lerp(from, 1, percent);
+    this._context.progress({ state: this.id, title, progress })
+  }
 }
 }

+ 1 - 0
assets/scripts/modules/lobby/ui/HomeView/GameItem.ts

@@ -44,6 +44,7 @@ export class GameItem extends Component {
     }
     }
 
 
     private onClick() {
     private onClick() {
+        AppKernel.appLobby.openGame(this._data);
         // AppKernel.appLobby.openGame(this._gameConfig.id);
         // AppKernel.appLobby.openGame(this._gameConfig.id);
     }
     }
 
 

+ 144 - 0
assets/scripts/modules/lobby/ui/HomeView/HomeNotices.ts

@@ -0,0 +1,144 @@
+import { AppKernel } from '@scripts/app/AppKernel';
+import { INoticeData } from '@scripts/store/mainStore/data';
+import { formatMaskNickName, formatSCNum } from '@scripts/utils/Helper';
+import { _decorator, Component, Input, input, instantiate, KeyCode, Label, Node, NodePool, tween, Tween, UITransform, Vec3 } from 'cc';
+const { ccclass, property } = _decorator;
+
+const MIN_MESSAGE_GAP = 50;
+const SCROLL_SPEED = 120;
+
+interface INoticeNode {
+    label: Label,
+    trans: UITransform,
+}
+
+@ccclass('HomeNotices')
+export class HomeNotices extends Component {
+    @property(Node)
+    itemNode: Node = null;
+
+    @property(UITransform)
+    content: UITransform = null;
+
+    private readonly pool = new NodePool('HomeNotices');
+    private readonly activeItems: Node[] = [];
+    private readonly noticeNodes = new WeakMap<Node, INoticeNode>();
+
+    protected onLoad(): void {
+        if (this.itemNode) this.itemNode.active = false;
+        this.node.active = false;
+        // input.on(Input.EventType.KEY_DOWN, (event) => {
+        //     if (event.keyCode === KeyCode.KEY_W) {
+        //         let data: INoticeData = {
+        //             nickName: `User${Math.floor(Math.random() * 8999 + 1000)}`,
+        //             value: Math.random() * 10000
+        //         }
+        //         const mainStore = AppKernel.stores.mainStore;
+        //         mainStore['_noticesList'].push(data);
+        //         this.startNotify();
+        //     }
+        // })
+    }
+
+    protected onDestroy(): void {
+        for (let index = 0; index < this.activeItems.length; index += 1) {
+            Tween.stopAllByTarget(this.activeItems[index]);
+        }
+        this.activeItems.length = 0;
+    }
+
+    startNotify(): void {
+        if (this.activeItems.length > 0) {
+            const last = this.activeItems[this.activeItems.length - 1];
+            if (last.x >= this.content.width) return;
+        }
+
+        const mainStore = AppKernel.stores.mainStore;
+        const data = mainStore.getNoticeData();
+        if (!data) {
+            // 队列已空且没有正在移动的消息时,隐藏整个公告区域。
+            if (this.activeItems.length === 0) this.node.active = false;
+            return;
+        }
+
+        this.node.active = true;
+        this.onNotify(data);
+    }
+
+    onNotify(data: INoticeData): void {
+        if (!this.itemNode || !this.content) return;
+
+        const msg = `${formatMaskNickName(data.nickName)} won SC ${formatSCNum(data.value)}`;
+
+        const item = this.pool.get() || instantiate(this.itemNode);
+        const noticeNode = this.getNoticeNode(item);
+        const lblNotices = noticeNode.label;
+        const itemTransform = noticeNode.trans;
+
+        Tween.stopAllByTarget(item);
+        item.setParent(this.content.node);
+        item.active = true;
+        lblNotices.string = msg;
+        lblNotices.updateRenderData(true);
+
+        const itemWidth = itemTransform.width * Math.abs(item.scale.x);
+        if (itemWidth <= 0) {
+            this.recycle(item);
+            return;
+        }
+
+        const startX = this.getStartX(this.content.width);
+        const endX = -itemWidth;
+        item.setPosition(startX, 0, item.position.z);
+        this.activeItems.push(item);
+
+        tween(item)
+            .to((startX - endX) / SCROLL_SPEED, {
+                position: new Vec3(endX, 0, item.position.z),
+            }, { easing: 'linear' })
+            .call(() => {
+                this.recycle(item);
+                this.startNotify();
+            })
+            .start();
+    }
+
+    private getNoticeNode(item: Node) {
+        let notices = this.noticeNodes.get(item);
+        if (!notices) {
+            notices = {
+                label: item.getComponent(Label),
+                trans: item.getComponent(UITransform),
+            }
+
+            this.noticeNodes.set(item, notices);
+        }
+        return notices;
+    }
+
+    private getStartX(contentWidth: number): number {
+        let startX = contentWidth;
+        for (let index = 0; index < this.activeItems.length; index += 1) {
+            const item = this.activeItems[index];
+            if (!item.isValid) continue;
+
+            const transform = this.noticeNodes.get(item)?.trans;
+            if (!transform) continue;
+
+            const rightX = item.position.x + transform.width * Math.abs(item.scale.x);
+            startX = Math.max(startX, rightX + MIN_MESSAGE_GAP);
+        }
+        return startX;
+    }
+
+    private recycle(item: Node): void {
+        Tween.stopAllByTarget(item);
+        const index = this.activeItems.indexOf(item);
+        if (index !== -1) this.activeItems.splice(index, 1);
+        if (!item.isValid) return;
+
+        item.active = false;
+        item.removeFromParent();
+        this.pool.put(item);
+    }
+}

+ 9 - 0
assets/scripts/modules/lobby/ui/HomeView/HomeNotices.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "96bcb87f-d993-4df0-80c7-39aeedcc2878",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 18 - 25
assets/scripts/modules/lobby/ui/HomeView/HomeView.ts

@@ -1,4 +1,4 @@
-import { _decorator, Button, EventTouch, find, instantiate, Label, Node, Prefab, ScrollView, size, Size, Sprite, Toggle, UIOpacity } from 'cc';
+import { _decorator, find, Label, Node, Prefab, Sprite, Toggle, UIOpacity } from 'cc';
 import { AppKernel } from '@scripts/app/AppKernel';
 import { AppKernel } from '@scripts/app/AppKernel';
 import { UIView } from '@scripts/framework/ui/UIView';
 import { UIView } from '@scripts/framework/ui/UIView';
 import { UIViewID } from '@scripts/define/UIDefine';
 import { UIViewID } from '@scripts/define/UIDefine';
@@ -10,8 +10,7 @@ import VirtualList from '@scripts/components/virtualList/VirtualList';
 import { IGameInfo } from '@scripts/store/gameStore/data';
 import { IGameInfo } from '@scripts/store/gameStore/data';
 import { GameItem } from './GameItem';
 import { GameItem } from './GameItem';
 import { RED_POINTS } from '@scripts/app/AppRedpoint';
 import { RED_POINTS } from '@scripts/app/AppRedpoint';
-import { formatGCNum, formatSCNum, localStorageGet, localStorageSet } from '@scripts/utils/Helper';
-import { LOCAL_CURRENCY_MODE } from '@scripts/constants/Localkey';
+import { formatGCNum, formatSCNum } from '@scripts/utils/Helper';
 
 
 const { ccclass, property } = _decorator;
 const { ccclass, property } = _decorator;
 
 
@@ -53,10 +52,10 @@ export class HomeView extends UIView {
     private tabGameFlags: { [key: string]: Node } = {};
     private tabGameFlags: { [key: string]: Node } = {};
 
 
     private gameTabIndex = -1;
     private gameTabIndex = -1;
-    private coinModel: CurrencyType = CURRENCY_TYPE.GC;
     private gameDatas: IGameInfo[] = [];
     private gameDatas: IGameInfo[] = [];
 
 
     private menuPopup: MenuPopup;
     private menuPopup: MenuPopup;
+    private btnFirst: Node;
 
 
     protected onCreate(): void | Promise<void> {
     protected onCreate(): void | Promise<void> {
         AppKernel.events.on('login:success', this.updateView, this);
         AppKernel.events.on('login:success', this.updateView, this);
@@ -95,7 +94,7 @@ export class HomeView extends UIView {
         addBtnClick(favsTab.node, this.onFavsTabClick, this);
         addBtnClick(favsTab.node, this.onFavsTabClick, this);
 
 
         const btnBuy = find("topNode/btnBuy", this.node);
         const btnBuy = find("topNode/btnBuy", this.node);
-        const btnFirst = find("topNode/btnFirst", this.node);
+        this.btnFirst = find("topNode/btnFirst", this.node);
         const btnInvite = find("topNode/btnInvite", this.node);
         const btnInvite = find("topNode/btnInvite", this.node);
         const btnMail = find("topNode/btnMail", this.node);
         const btnMail = find("topNode/btnMail", this.node);
         const btnService = find("topNode/btnService", this.node);
         const btnService = find("topNode/btnService", this.node);
@@ -111,7 +110,7 @@ export class HomeView extends UIView {
         addBtnClick(this.scModel.node, this.onSCModelClick, this);
         addBtnClick(this.scModel.node, this.onSCModelClick, this);
 
 
         addBtnClick(btnBuy, this.onBtnBuyClick, this);
         addBtnClick(btnBuy, this.onBtnBuyClick, this);
-        addBtnClick(btnFirst, this.onBtnFirstClick, this);
+        addBtnClick(this.btnFirst, this.onBtnFirstClick, this);
         addBtnClick(btnInvite, this.onBtnInviteClick, this);
         addBtnClick(btnInvite, this.onBtnInviteClick, this);
         addBtnClick(btnMail, this.onBtnMailClick, this);
         addBtnClick(btnMail, this.onBtnMailClick, this);
         addBtnClick(btnService, this.onBtnServiceClick, this);
         addBtnClick(btnService, this.onBtnServiceClick, this);
@@ -128,8 +127,6 @@ export class HomeView extends UIView {
         AppKernel.redpoint.on(RED_POINTS.Mail, mailPoint, this);
         AppKernel.redpoint.on(RED_POINTS.Mail, mailPoint, this);
         AppKernel.redpoint.on(RED_POINTS.DailyTask, taskPoint, this);
         AppKernel.redpoint.on(RED_POINTS.DailyTask, taskPoint, this);
         AppKernel.redpoint.on(RED_POINTS.DailyReward, dailyPoint, this);
         AppKernel.redpoint.on(RED_POINTS.DailyReward, dailyPoint, this);
-
-        this.coinModel = localStorageGet(LOCAL_CURRENCY_MODE, CURRENCY_TYPE.GC) as CurrencyType;
     }
     }
 
 
     protected onDestroy(): void {
     protected onDestroy(): void {
@@ -137,8 +134,8 @@ export class HomeView extends UIView {
     }
     }
 
 
     private updateGameModel(type: CurrencyType) {
     private updateGameModel(type: CurrencyType) {
-        this.coinModel = type;
-        localStorageSet(LOCAL_CURRENCY_MODE, type);
+        const mainStore = AppKernel.stores.mainStore;
+        mainStore.currencyKind = type;
 
 
         this.gcModel.setActive(type === CURRENCY_TYPE.GC);
         this.gcModel.setActive(type === CURRENCY_TYPE.GC);
         this.scModel.setActive(type === CURRENCY_TYPE.SC);
         this.scModel.setActive(type === CURRENCY_TYPE.SC);
@@ -155,7 +152,7 @@ export class HomeView extends UIView {
     }
     }
 
 
     private updateGameList() {
     private updateGameList() {
-        const currency = this.coinModel;
+        const currency = AppKernel.stores.mainStore.currencyKind;
         const tag = GameTabValus[this.gameTabIndex];
         const tag = GameTabValus[this.gameTabIndex];
         const isHome = tag === GAME_TABS.Home;
         const isHome = tag === GAME_TABS.Home;
         const gameStore = AppKernel.stores.gameStore;
         const gameStore = AppKernel.stores.gameStore;
@@ -219,7 +216,8 @@ export class HomeView extends UIView {
     }
     }
 
 
     private onBtnRedeemClick() {
     private onBtnRedeemClick() {
-        if (this.coinModel !== CURRENCY_TYPE.SC) {
+        const coinModel = AppKernel.stores.mainStore.currencyKind;
+        if (coinModel !== CURRENCY_TYPE.SC) {
             AppKernel.ui.toast("Redeem is only available in SC mode.");
             AppKernel.ui.toast("Redeem is only available in SC mode.");
             return;
             return;
         }
         }
@@ -244,7 +242,7 @@ export class HomeView extends UIView {
     }
     }
 
 
     private onBtnInviteClick() {
     private onBtnInviteClick() {
-
+        AppKernel.ui.open(UIViewID.UIInvite);
     }
     }
 
 
     private onBtnFirstClick() {
     private onBtnFirstClick() {
@@ -260,11 +258,15 @@ export class HomeView extends UIView {
     }
     }
 
 
     private onGCModelClick() {
     private onGCModelClick() {
+        const coinModel = AppKernel.stores.mainStore.currencyKind;
+        if (coinModel === CURRENCY_TYPE.GC) return;
         this.updateGameModel(CURRENCY_TYPE.GC);
         this.updateGameModel(CURRENCY_TYPE.GC);
         this.updateGameList();
         this.updateGameList();
     }
     }
 
 
     private onSCModelClick() {
     private onSCModelClick() {
+        const coinModel = AppKernel.stores.mainStore.currencyKind;
+        if (coinModel === CURRENCY_TYPE.SC) return;
         this.updateGameModel(CURRENCY_TYPE.SC);
         this.updateGameModel(CURRENCY_TYPE.SC);
         this.updateGameList();
         this.updateGameList();
     }
     }
@@ -276,26 +278,17 @@ export class HomeView extends UIView {
         this.scModel.lblValue.string = formatSCNum(mainStore.scScore);
         this.scModel.lblValue.string = formatSCNum(mainStore.scScore);
         this.gcModel.lblValue.string = formatGCNum(mainStore.gcScore);
         this.gcModel.lblValue.string = formatGCNum(mainStore.gcScore);
         this.updateGameTabs(0);
         this.updateGameTabs(0);
-        this.updateGameModel(this.coinModel);
+        this.updateGameModel(mainStore.currencyKind);
         this.updateGameList();
         this.updateGameList();
         this.bannerNode.init(5);
         this.bannerNode.init(5);
 
 
-        // // this.gameRoot.destroyAllChildren();
-        // const gameStore = AppKernel.stores.gameStore;
-        // const gameList = gameStore.getGameList();
-        // // gameList.map(game => this.initGameItem(game));
-
-        // LoopList.ins<IGameInfo>("HomeGameList").init(this.gameScroll, this.gameRender, 20);
-        // LoopList.ins<IGameInfo>("HomeGameList").initData(gameList, this.gamePrefab, size(115, 140))
+        const payStore = AppKernel.stores.payStore;
+        this.btnFirst.active = payStore.firstPackVisible;
     }
     }
 
 
     private onBtnMailClick() {
     private onBtnMailClick() {
         AppKernel.ui.open(UIViewID.MailView);
         AppKernel.ui.open(UIViewID.MailView);
     }
     }
-
-    private onBtnStoreClick() {
-        AppKernel.ui.open(UIViewID.StoreView);
-    }
 }
 }
 
 
 class UserNode {
 class UserNode {

+ 2 - 2
assets/scripts/modules/lobby/ui/LoadingView.ts

@@ -18,9 +18,9 @@ export class LoadingView extends UIView {
         Tween.stopAllByTarget(this.circleNode);
         Tween.stopAllByTarget(this.circleNode);
         tween(this.circleNode).by(0.5, { angle: -200 }).repeatForever().start();
         tween(this.circleNode).by(0.5, { angle: -200 }).repeatForever().start();
 
 
+        Tween.stopAllByTarget(this.uiOpacity);
+        this.uiOpacity.opacity = delay > 0 ? 0 : 255;
         if (delay > 0) {
         if (delay > 0) {
-            this.uiOpacity.opacity = 0;
-            Tween.stopAllByTarget(this.uiOpacity);
             tween(this.uiOpacity).to(0.2, { opacity: 255 }).delay(delay).start();
             tween(this.uiOpacity).to(0.2, { opacity: 255 }).delay(delay).start();
         }
         }
     }
     }

+ 30 - 3
assets/scripts/modules/lobby/ui/StoreView/UIFirstPack.ts

@@ -1,5 +1,9 @@
+import { AppKernel } from '@scripts/app/AppKernel';
 import { UIPopup } from '@scripts/framework/ui/UIPopup';
 import { UIPopup } from '@scripts/framework/ui/UIPopup';
+import { IFirstPack } from '@scripts/store/payStore/data';
+import { formatGCNum, formatSCNum } from '@scripts/utils/Helper';
 import { addBtnClick } from '@scripts/utils/UIHelper';
 import { addBtnClick } from '@scripts/utils/UIHelper';
+import { formatVip } from '@scripts/utils/VipHelper';
 import { _decorator, Button, Component, Label, Node } from 'cc';
 import { _decorator, Button, Component, Label, Node } from 'cc';
 const { ccclass, property } = _decorator;
 const { ccclass, property } = _decorator;
 
 
@@ -14,25 +18,48 @@ export class UIFirstPack extends UIPopup {
     @property(Label)
     @property(Label)
     lblVIP: Label;
     lblVIP: Label;
 
 
+    @property(Label)
+    lblButton: Label;
+
     @property(Button)
     @property(Button)
     btnClose: Button;
     btnClose: Button;
 
 
     @property(Button)
     @property(Button)
     btnPay: Button;
     btnPay: Button;
 
 
+    private _packInfo: IFirstPack;
+
     protected onCreate(): void | Promise<void> {
     protected onCreate(): void | Promise<void> {
         addBtnClick(this.btnClose, this.closeSelf, this);
         addBtnClick(this.btnClose, this.closeSelf, this);
         addBtnClick(this.btnPay, this.onBtnPayClick, this);
         addBtnClick(this.btnPay, this.onBtnPayClick, this);
     }
     }
 
 
+    protected async onBeforeOpen(_params: unknown) {
+        const payStore = AppKernel.stores.payStore;
+        const pack = await payStore.reqFirstPackInfo();
+        this._packInfo = pack;
+        return !!pack;
+    }
+
     private onBtnPayClick() {
     private onBtnPayClick() {
 
 
     }
     }
 
 
     protected onOpen(_params: unknown): void | Promise<void> {
     protected onOpen(_params: unknown): void | Promise<void> {
-        this.lblGC.string = "";
-        this.lblSC.string = "";
-        this.lblVIP.string = "";
+        if (!this._packInfo) {
+            this.lblGC.string = "";
+            this.lblSC.string = "";
+            this.lblVIP.string = "";
+            return;
+        }
+        const next_sequence = this._packInfo.next_sequence;
+        const current = next_sequence - 1;
+        const data = this._packInfo.list[current];
+        this.lblGC.string = formatGCNum(data.gc);
+        this.lblSC.string = formatSCNum(data.sc);
+        this.lblVIP.string = data.cp.toString();
+
+        this.lblButton.string = AppKernel.i18n.t("store.buynow", Number(data.money));
     }
     }
 }
 }
 
 

+ 4 - 4
assets/scripts/modules/lobby/ui/UIDialog.ts

@@ -16,11 +16,11 @@ export interface IDialogConfig {
     /** 隐藏确定按钮 */
     /** 隐藏确定按钮 */
     hideConfirm?: boolean;
     hideConfirm?: boolean;
     /** 隐藏取消按钮 */
     /** 隐藏取消按钮 */
-    hideCancel?: boolean;
+    showCancel?: boolean;
     /** 显示右上角关闭按钮 */
     /** 显示右上角关闭按钮 */
     showClose?: boolean;
     showClose?: boolean;
-    /** 对话框回调 */
-    callBack?: (res: boolean) => Promise<boolean>;
+    /** 对话框回调  返回true则关闭dialog*/
+    callBack?: (res: boolean) => Promise<boolean> | boolean;
 }
 }
 
 
 @ccclass('UIDialog')
 @ccclass('UIDialog')
@@ -65,7 +65,7 @@ export class UIDialog extends UIPopup<IDialogConfig> {
         this.lblCancenl.string = config.lblCancel ?? AppKernel.i18n.t("dialog.cancel");
         this.lblCancenl.string = config.lblCancel ?? AppKernel.i18n.t("dialog.cancel");
 
 
         this.btnConfirm.active = !config.hideConfirm;
         this.btnConfirm.active = !config.hideConfirm;
-        this.btnCancel.active = !config.hideCancel && !config.showClose;
+        this.btnCancel.active = config.showCancel && !config.showClose;
         this.btnClose.active = config.showClose;
         this.btnClose.active = config.showClose;
 
 
 
 

+ 9 - 0
assets/scripts/modules/lobby/ui/invite.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "2efc79bb-da2f-4d82-9902-c43e806f9faa",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 16 - 0
assets/scripts/modules/lobby/ui/invite/UIInvite.ts

@@ -0,0 +1,16 @@
+import { UIPopup } from '@scripts/framework/ui/UIPopup';
+import { addBtnClick } from '@scripts/utils/UIHelper';
+import { _decorator, Component, Node } from 'cc';
+const { ccclass, property } = _decorator;
+
+@ccclass('UIInvite')
+export class UIInvite extends UIPopup {
+    @property(Node)
+    btnClose: Node;
+
+    protected onCreate(): void | Promise<void> {
+        addBtnClick(this.btnClose, this.closeSelf, this);
+    }
+}
+
+

+ 9 - 0
assets/scripts/modules/lobby/ui/invite/UIInvite.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "45b20eb2-e223-4ae7-9d47-3cd39cc40df9",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 5 - 5
assets/scripts/platform/Google/GoogleAndroidImpl.ts

@@ -2,13 +2,13 @@ import { GoogleImpl, IGoogleLoginRes } from "./GoogleImpl";
 
 
 export class GoogleAndroidImpl extends GoogleImpl {
 export class GoogleAndroidImpl extends GoogleImpl {
     init() {
     init() {
-        throw new Error("Method not implemented.");
+
     }
     }
-    protected onLogin(): Promise<IGoogleLoginRes> {
-        throw new Error("Method not implemented.");
+    protected async onLogin(): Promise<IGoogleLoginRes> {
+        return null;
     }
     }
-    logOut(): Promise<boolean> {
-        throw new Error("Method not implemented.");
+    async logOut(): Promise<boolean> {
+        return true
     }
     }
 
 
 }
 }

+ 3 - 3
assets/scripts/platform/Google/GoogleIOSImpl.ts

@@ -2,14 +2,14 @@ import { GoogleImpl, IGoogleLoginRes } from "./GoogleImpl";
 
 
 export class GoogleIOSImpl extends GoogleImpl {
 export class GoogleIOSImpl extends GoogleImpl {
     init() {
     init() {
-        throw new Error("Method not implemented.");
+        throw new Error("[Google IOS] Method not implemented.");
     }
     }
     
     
     protected onLogin(): Promise<IGoogleLoginRes> {
     protected onLogin(): Promise<IGoogleLoginRes> {
-        throw new Error("Method not implemented.");
+        throw new Error("[Google IOS] Method not implemented.");
     }
     }
 
 
     logOut(): Promise<boolean> {
     logOut(): Promise<boolean> {
-        throw new Error("Method not implemented.");
+        throw new Error("[Google IOS] Method not implemented.");
     }
     }
 }
 }

+ 9 - 2
assets/scripts/services/AppLobby.ts

@@ -41,6 +41,7 @@ class AppLobby {
         await Promise.all([
         await Promise.all([
             gameStore.reqAllGames(),
             gameStore.reqAllGames(),
             payStore.reqRechargeConfig(),
             payStore.reqRechargeConfig(),
+            payStore.reqFirstPackVisible(),
         ])
         ])
         await AppKernel.ui.closeAll();
         await AppKernel.ui.closeAll();
         AppKernel.ui.open(UIViewID.HomeView);
         AppKernel.ui.open(UIViewID.HomeView);
@@ -62,12 +63,18 @@ class AppLobby {
 
 
     }
     }
 
 
-    async openGame(gameID: number) {
+    async openGame(game: IGameInfo) {
+        AppKernel.ui.loading(true);
         const hallClient = AppKernel.services.hallClient;
         const hallClient = AppKernel.services.hallClient;
+        const mainStore = AppKernel.stores.mainStore;
         const gameStore = AppKernel.stores.gameStore;
         const gameStore = AppKernel.stores.gameStore;
-        gameStore.gameID = gameID
+        gameStore.gameID = game.gameID;
         hallClient.sendState();
         hallClient.sendState();
 
 
+        const url = await gameStore.reqLaunchGame(game.gameCode, mainStore.currencyKind);
+        AppKernel.ui.loading(false);
+        console.log('game url: ', url);
+
         // const gameInfo = await mainStore.getGameCardInfo(gameID);
         // const gameInfo = await mainStore.getGameCardInfo(gameID);
         // if (!gameInfo) {
         // if (!gameInfo) {
         //     console.error('进入游戏失败');
         //     console.error('进入游戏失败');

+ 1 - 1
assets/scripts/services/hotupdate/HotUpdateService.ts

@@ -400,7 +400,7 @@ function compareVersions(versionA: string, versionB: string): number {
     const partA = Number.parseInt(a[index] || '0', 10);
     const partA = Number.parseInt(a[index] || '0', 10);
     const partB = Number.parseInt(b[index] || '0', 10);
     const partB = Number.parseInt(b[index] || '0', 10);
     if (partA !== partB) {
     if (partA !== partB) {
-      return partA - partB;
+      return -1;//partA - partB;
     }
     }
   }
   }
   return 0;
   return 0;

+ 11 - 2
assets/scripts/store/gameStore/GameStore.ts

@@ -1,6 +1,6 @@
-import { APP_FAVO_ADD, APP_FAVO_REMOVE, APP_GAME_LIST, success } from "@scripts/api";
+import { APP_FAVO_ADD, APP_FAVO_REMOVE, APP_GAME_LAUNCH, APP_GAME_LIST, success } from "@scripts/api";
 import { Http } from "@scripts/request";
 import { Http } from "@scripts/request";
-import { IGameInfo, IGameListParams } from "./data";
+import { IGameInfo, IGameLaunch, IGameListParams } from "./data";
 import { CURRENCY_TYPE, CurrencyType, GAME_TABS, GameTabType } from "@scripts/define/Define";
 import { CURRENCY_TYPE, CurrencyType, GAME_TABS, GameTabType } from "@scripts/define/Define";
 
 
 const UPDATE_LIST_CD = 10 * 60 * 1000;
 const UPDATE_LIST_CD = 10 * 60 * 1000;
@@ -119,6 +119,15 @@ class GameStore {
         }
         }
         return gameList.filter(v => v.currencies.includes(currency));
         return gameList.filter(v => v.currencies.includes(currency));
     }
     }
+
+    async reqLaunchGame(gameCode: string, currency: string) {
+        const res = await Http.call<IGameLaunch>(APP_GAME_LAUNCH, { gameCode, currency });
+        if (res && res.data && res.data.launchUrl) {
+            return res.data.launchUrl;
+        }
+
+        return null;
+    }
 }
 }
 
 
 export const gameStore = new GameStore();
 export const gameStore = new GameStore();

+ 9 - 0
assets/scripts/store/gameStore/data.ts

@@ -16,6 +16,7 @@ export interface IGameTag {
 export interface IGameInfo {
 export interface IGameInfo {
     gameID: number;
     gameID: number;
     gameName: string;
     gameName: string;
+    gameCode: string;
     isFavorite: number;
     isFavorite: number;
     providerID: number;
     providerID: number;
     providerName: string;
     providerName: string;
@@ -25,4 +26,12 @@ export interface IGameInfo {
     type: string;
     type: string;
     RTP: number;
     RTP: number;
     currencies: string[];
     currencies: string[];
+}
+
+export interface IGameLaunch {
+    gameCode: string;
+    providerCode: string;
+    providerGameId: string;
+    currency: string;
+    launchUrl: string;
 }
 }

+ 21 - 3
assets/scripts/store/mainStore/MainStore.ts

@@ -12,12 +12,13 @@ import {
     APP_LOGOUT,
     APP_LOGOUT,
 } from "../../api";
 } from "../../api";
 import { AppKernel } from "../../app/AppKernel";
 import { AppKernel } from "../../app/AppKernel";
-import { Login3rdType, APP_LOGIN_TYPE, COUNTRY_CODE } from "../../define/Define";
-import { LOCAL_SIGN } from "../../constants/Localkey";
+import { Login3rdType, APP_LOGIN_TYPE, COUNTRY_CODE, CurrencyType, CURRENCY_TYPE } from "../../define/Define";
+import { LOCAL_CURRENCY_MODE, LOCAL_SIGN } from "../../constants/Localkey";
 import { ApiEnvelope, Http } from "../../request";
 import { ApiEnvelope, Http } from "../../request";
-import { getEnterPlatform, localStorageSet } from "../../utils/Helper";
+import { getEnterPlatform, localStorageGet, localStorageSet } from "../../utils/Helper";
 import {
 import {
     IForgetPassReq,
     IForgetPassReq,
+    INoticeData,
     IProtectInfo,
     IProtectInfo,
     IRoutesResponse,
     IRoutesResponse,
     IUserData,
     IUserData,
@@ -42,7 +43,15 @@ class MainStore {
     private _serverKick: boolean;
     private _serverKick: boolean;
     private _protectInfo: IProtectInfo = null;
     private _protectInfo: IProtectInfo = null;
     private _lastOtpTs = 0;
     private _lastOtpTs = 0;
+    private _noticesList: INoticeData[] = [];
+    private _currencyKind: CurrencyType;
 
 
+    public set currencyKind(value: CurrencyType) {
+        this._currencyKind = value;
+        localStorageSet(LOCAL_CURRENCY_MODE, value);
+    }
+
+    public get currencyKind() { return this._currencyKind };
 
 
     public get firstLaunch() { return this._firstLaunch; }
     public get firstLaunch() { return this._firstLaunch; }
 
 
@@ -88,6 +97,10 @@ class MainStore {
         return APP_OTP_INTERVAL - times;
         return APP_OTP_INTERVAL - times;
     }
     }
 
 
+    constructor() {
+        this._currencyKind = localStorageGet(LOCAL_CURRENCY_MODE, CURRENCY_TYPE.GC) as CurrencyType;
+    }
+
     async reqGetRoutes() {
     async reqGetRoutes() {
         const platform = AppKernel.platform;
         const platform = AppKernel.platform;
         const params: any = {
         const params: any = {
@@ -395,8 +408,13 @@ class MainStore {
     }
     }
 
 
     onUserLogout() {
     onUserLogout() {
+        this._noticesList = [];
         console.log('mainStore onLogout!!!');
         console.log('mainStore onLogout!!!');
     }
     }
+
+    getNoticeData() {
+        return this._noticesList.shift();
+    }
 }
 }
 
 
 
 

+ 5 - 0
assets/scripts/store/mainStore/data.ts

@@ -67,4 +67,9 @@ export interface IForgetPassReq {
     newpassword: string;
     newpassword: string;
     renewpassword?: string;
     renewpassword?: string;
     country?: string | number;
     country?: string | number;
+}
+
+export interface INoticeData {
+    nickName: string,
+    value: number,
 }
 }

+ 24 - 0
assets/scripts/store/payStore/PayStore.ts

@@ -1,4 +1,6 @@
 import {
 import {
+    APP_FIRST_PACK,
+    APP_FIRST_PACK_VISIBLE,
     APP_PAYMENT_ORDER,
     APP_PAYMENT_ORDER,
     APP_PAY_ORDER_LIST,
     APP_PAY_ORDER_LIST,
     APP_RECHARGE_CONFIG,
     APP_RECHARGE_CONFIG,
@@ -10,6 +12,8 @@ import {
 } from '@scripts/api';
 } from '@scripts/api';
 import { ApiEnvelope, Http } from '@scripts/request';
 import { ApiEnvelope, Http } from '@scripts/request';
 import {
 import {
+    IFirstPack,
+    IFirstPackVisible,
     IGoodsConfig,
     IGoodsConfig,
     IPaymentOrder,
     IPaymentOrder,
     IPaymentOrderRequest,
     IPaymentOrderRequest,
@@ -30,6 +34,7 @@ class PayStore {
     private _payOrderList: IPayOrderItem[] = [];
     private _payOrderList: IPayOrderItem[] = [];
     private _withdrawBaseInfo: IWithdrawBaseInfo = null;
     private _withdrawBaseInfo: IWithdrawBaseInfo = null;
     private _withdrawRecord: IWithdrawRecordItem[] = [];
     private _withdrawRecord: IWithdrawRecordItem[] = [];
+    private _firstPackVisible = false;
 
 
     public get config() { return this._config; }
     public get config() { return this._config; }
 
 
@@ -39,6 +44,8 @@ class PayStore {
 
 
     public get withdrawRecord() { return this._withdrawRecord; }
     public get withdrawRecord() { return this._withdrawRecord; }
 
 
+    public get firstPackVisible() { return this._firstPackVisible; }
+
     async reqRechargeConfig() {
     async reqRechargeConfig() {
         const res = await Http.call<IRechargeConfigData>(APP_RECHARGE_CONFIG);
         const res = await Http.call<IRechargeConfigData>(APP_RECHARGE_CONFIG);
         if (success(res) && res.data) {
         if (success(res) && res.data) {
@@ -81,6 +88,23 @@ class PayStore {
         return false;
         return false;
     }
     }
 
 
+    /** 首冲入口是否可见 */
+    async reqFirstPackVisible() {
+        const res = await Http.call<IFirstPackVisible>(APP_FIRST_PACK_VISIBLE);
+        if (success(res)) {
+            this._firstPackVisible = res.data.show;
+            return res.data.show;
+        }
+        return false;
+    }
+
+    async reqFirstPackInfo() {
+        const res = await Http.call<IFirstPack>(APP_FIRST_PACK);
+        if (success(res)) {
+            return res.data;
+        }
+    }
+
     async reqWithdrawBaseInfo(arg: IWithdrawBaseInfoRequest = {}): Promise<boolean> {
     async reqWithdrawBaseInfo(arg: IWithdrawBaseInfoRequest = {}): Promise<boolean> {
         const res = await Http.call<IWithdrawBaseInfo>(APP_WITHDRAW_BASE_INFO, {
         const res = await Http.call<IWithdrawBaseInfo>(APP_WITHDRAW_BASE_INFO, {
             paypass: arg.paypass || '',
             paypass: arg.paypass || '',

+ 34 - 9
assets/scripts/store/payStore/data.ts

@@ -2,21 +2,21 @@ export interface IGoodsConfig {
     /** 展示标签,如 GC ONLY */
     /** 展示标签,如 GC ONLY */
     badge?: string;
     badge?: string;
     /** 基础 Club Points 奖励 */
     /** 基础 Club Points 奖励 */
-    cp: number;
+    cp: number | string;
     /** 额外 Club Points 奖励 */
     /** 额外 Club Points 奖励 */
-    cp_reward: number;
+    cp_reward: number | string;
     /** Club Points 额外奖励客户端展示百分比 */
     /** Club Points 额外奖励客户端展示百分比 */
-    cp_reward_display_percent: number;
+    cp_reward_display_percent: number | string;
     /** 结束时间(Unix 时间戳,秒) */
     /** 结束时间(Unix 时间戳,秒) */
     end_time?: number;
     end_time?: number;
     /** 档位类型:0 普通充值,1 首充档位 */
     /** 档位类型:0 普通充值,1 首充档位 */
     first_pay: number;
     first_pay: number;
     /** 基础 GC 奖励 */
     /** 基础 GC 奖励 */
-    gc: number;
+    gc: number | string;
     /** 额外 GC 奖励 */
     /** 额外 GC 奖励 */
-    gc_reward: number;
+    gc_reward: number | string;
     /** GC 额外奖励客户端展示百分比 */
     /** GC 额外奖励客户端展示百分比 */
-    gc_reward_display_percent: number;
+    gc_reward_display_percent: number | string;
     gear: string;
     gear: string;
     /** 支付方式列表 */
     /** 支付方式列表 */
     gears: IGoodsGear[],
     gears: IGoodsGear[],
@@ -33,11 +33,11 @@ export interface IGoodsConfig {
     /** 0 下架,1 上架,2 售罄(接口仅返回 1 或 2) */
     /** 0 下架,1 上架,2 售罄(接口仅返回 1 或 2) */
     sale_status: number,
     sale_status: number,
     /** 基础 SC 奖励 */
     /** 基础 SC 奖励 */
-    sc: number,
+    sc: number | string,
     /** 额外 SC 奖励 */
     /** 额外 SC 奖励 */
-    sc_reward: number,
+    sc_reward: number | string,
     /** SC 额外奖励客户端展示百分比 */
     /** SC 额外奖励客户端展示百分比 */
-    sc_reward_display_percent: number,
+    sc_reward_display_percent: number | string,
     /** 服务端当前时间 */
     /** 服务端当前时间 */
     server_time: number,
     server_time: number,
     /** 生效时间 */
     /** 生效时间 */
@@ -164,3 +164,28 @@ export interface IWithdrawPayoutRequest {
     paypass?: string;
     paypass?: string;
     score: string | number;
     score: string | number;
 }
 }
+
+export interface IFirstPackVisible {
+    show: boolean;
+    gift_id: number;
+}
+
+export interface IFirstPackGoods extends IGoodsConfig {
+    /** 第几份(1~3) */
+    sequence: number;
+    /** 是否已购买 */
+    purchased: boolean;
+    /** 当前是否可买 */
+    can_buy: boolean;
+}
+
+export interface IFirstPack {
+    /** 活动是否仍可展示 / 购买 */
+    available: boolean;
+    /** 三份是否已全部购买 */
+    finished: boolean;
+    /** 下一份可购买序号(1~3);已买完为 0 */
+    next_sequence: number;
+    gift_id: number;
+    list: IFirstPackGoods[]
+}

+ 12 - 3
assets/scripts/utils/Helper.ts

@@ -9,7 +9,8 @@ const STORAGE_ENCRYPTION_ENABLED = true;
  * 将数字格式化为财务展示格式:使用千位分隔符并保留两位小数。
  * 将数字格式化为财务展示格式:使用千位分隔符并保留两位小数。
  * 例如:1234567.8 -> 1,234,567.80。
  * 例如:1234567.8 -> 1,234,567.80。
  */
  */
-export function formatCurrency(value: number, decimal = 0): string {
+export function formatCurrency(value: number | string, decimal = 0): string {
+    if (typeof value === 'string') value = Number(value);
     if (!Number.isFinite(value)) value = 0;
     if (!Number.isFinite(value)) value = 0;
 
 
     return value.toLocaleString('en-US', {
     return value.toLocaleString('en-US', {
@@ -19,11 +20,11 @@ export function formatCurrency(value: number, decimal = 0): string {
     });
     });
 }
 }
 
 
-export function formatSCNum(value: number) {
+export function formatSCNum(value: number | string) {
     return formatCurrency(value, 2);
     return formatCurrency(value, 2);
 }
 }
 
 
-export function formatGCNum(value: number) {
+export function formatGCNum(value: number | string) {
     return formatCurrency(value, 0);
     return formatCurrency(value, 0);
 }
 }
 
 
@@ -252,3 +253,11 @@ export function waitForSeconds(duration: number) {
         setTimeout(resolve, duration * 1000)
         setTimeout(resolve, duration * 1000)
     })
     })
 }
 }
+
+export function formatMaskNickName(nickName: string, prefix = 2, suffix = 1) {
+    const startIdx = Math.min(prefix, nickName.length);
+    const endIdx = nickName.length - suffix;
+    const first = nickName.substring(0, startIdx);
+    const last = nickName.substring(endIdx, nickName.length)
+    return `${first}***${last}`
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов