app.hypergames.hypersdk 1.4.11 → 1.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.4.12](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.11...v1.4.12) (2025-12-23)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Improve session reliability and security handling in HyperSDK ([e39ed3e](https://github.com/mvmhyper/hyper-sdk/commit/e39ed3e2beccc271b0aaf5bf27c9c1a6ba6e6c92))
7
+
1
8
  ## [1.4.11](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.10...v1.4.11) (2025-12-20)
2
9
 
3
10
 
package/HyperLoader.unity CHANGED
@@ -840,7 +840,7 @@ GameObject:
840
840
  m_Component:
841
841
  - component: {fileID: 1064166296}
842
842
  m_Layer: 0
843
- m_Name: __HyperSDK_BuildMarker_638997386571830226
843
+ m_Name: __HyperSDK_BuildMarker_639020542296075009
844
844
  m_TagString: Untagged
845
845
  m_Icon: {fileID: 0}
846
846
  m_NavMeshLayer: 0
@@ -456,6 +456,7 @@ namespace Hyper.Internal.Managers
456
456
  if (_gameManager.HasGameStarted)
457
457
  {
458
458
  _gameManager?.ShowConnectionRestored();
459
+ SendGameResumed();
459
460
  }
460
461
  else
461
462
  {
@@ -511,13 +512,8 @@ namespace Hyper.Internal.Managers
511
512
  {
512
513
  _gameResumed = true;
513
514
 
514
- if (_sendGameResumedCoroutine != null)
515
- {
516
- StopCoroutine(_sendGameResumedCoroutine);
517
- _sendGameResumedCoroutine = null;
518
- }
519
-
520
515
  TryUpdateCSRFToken(message);
516
+ ResumeScoreSending();
521
517
  }
522
518
 
523
519
  public void OnSocketMessage(string message)
@@ -552,6 +548,15 @@ namespace Hyper.Internal.Managers
552
548
  }
553
549
  }
554
550
 
551
+ private void ResumeScoreSending()
552
+ {
553
+ if (isSocketConnected && !_gameManager.HasGameEnded)
554
+ {
555
+ _dataManager.StartCapturingScores();
556
+ StartSendingScores();
557
+ }
558
+ }
559
+
555
560
  #endregion
556
561
 
557
562
  #region Reconnection
@@ -679,6 +684,20 @@ namespace Hyper.Internal.Managers
679
684
  yield break;
680
685
  }
681
686
 
687
+ if (_sendGameResumedCoroutine == null)
688
+ {
689
+ _sendGameResumedCoroutine = StartCoroutine(SendGameResumedCoroutine());
690
+
691
+ //? Ensure game is resumed to get new CSRF token before final score submission
692
+ yield return _sendGameResumedCoroutine;
693
+
694
+ _sendGameResumedCoroutine = null;
695
+ }
696
+ else
697
+ {
698
+ yield return _sendGameResumedCoroutine;
699
+ }
700
+
682
701
  object encryptedObject = JsonConvert.DeserializeObject(encryptedScoreData);
683
702
  var payload = new { encryptedData = encryptedObject };
684
703
  string jsonData = JsonConvert.SerializeObject(payload);
@@ -699,7 +718,7 @@ namespace Hyper.Internal.Managers
699
718
  if (request.result == UnityWebRequest.Result.Success)
700
719
  {
701
720
  _gameManager?.GameOverModalComponent?.ScoreHasBeenSubmitted();
702
- TryUpdateCSRFToken(request.downloadHandler.text);
721
+ // TryUpdateCSRFToken(request.downloadHandler.text);
703
722
  StopWebSocket();
704
723
  _endGameCoroutine = null;
705
724
  yield break;
@@ -152,10 +152,18 @@ namespace Hyper.Internal.Managers
152
152
  internal ControlBarLayout ControlBarLayout { get; private set; }
153
153
  internal StartCTA StartCTA { get; private set; }
154
154
 
155
+ #region Game Pause Management
156
+
155
157
  internal void PauseGame()
156
158
  {
157
159
  if (!_hasGameStarted || _isPaused || _hasGameEnded) return;
158
160
 
161
+ if (_backendManager.isSocketConnected)
162
+ {
163
+ _dataManager.StopCapturingScores();
164
+ _backendManager.StopSendingScores();
165
+ }
166
+
159
167
  _isPaused = true;
160
168
  _isFrozenBeforePause = Time.timeScale == 0;
161
169
  Time.timeScale = 0;
@@ -173,7 +181,7 @@ namespace Hyper.Internal.Managers
173
181
  {
174
182
  _backendManager.SendGameResumed();
175
183
  }
176
-
184
+
177
185
  _isPaused = false;
178
186
 
179
187
  if (!_isFrozenBeforePause)
@@ -188,6 +196,30 @@ namespace Hyper.Internal.Managers
188
196
  _eventManager.InvokeGameResumedEvent();
189
197
  }
190
198
 
199
+ void OnApplicationFocus(bool hasFocus)
200
+ {
201
+ HandlePauseState(!hasFocus);
202
+ }
203
+
204
+ void OnApplicationPause(bool pauseStatus)
205
+ {
206
+ HandlePauseState(pauseStatus);
207
+ }
208
+
209
+ void HandlePauseState(bool shouldPause)
210
+ {
211
+ if (shouldPause && !_isPaused)
212
+ {
213
+ PauseGame();
214
+ }
215
+ else if (!shouldPause && _isPaused)
216
+ {
217
+ // ResumeGame();
218
+ }
219
+ }
220
+
221
+ #endregion
222
+
191
223
  internal void UpdateScoreLabel()
192
224
  {
193
225
  _controlBarModal?.UpdateScoreLabel();
@@ -741,7 +773,7 @@ namespace Hyper.Internal.Managers
741
773
 
742
774
  string menuSceneName = HyperRuntime.GameContent.IsPracticeMenu ?
743
775
  HyperRuntime.GameContent.PracticeScene?.SceneName : null;
744
-
776
+
745
777
  string transitionSceneName = HyperRuntime.GameContent.TransitionScene?.SceneName;
746
778
 
747
779
  if ((!string.IsNullOrEmpty(menuSceneName) && scene.name.Equals(menuSceneName, StringComparison.OrdinalIgnoreCase)) ||
@@ -1336,7 +1368,7 @@ namespace Hyper.Internal.Managers
1336
1368
  private void ShowTimeUpModalInternal()
1337
1369
  {
1338
1370
  _hasGameEnded = true;
1339
-
1371
+
1340
1372
  if (_timeUpModal == null)
1341
1373
  {
1342
1374
  EnsureTimeUpModal();
@@ -35,8 +35,8 @@ namespace Hyper.Internal.Managers
35
35
  private float _fiveSecondTimer = 5f;
36
36
  private bool _isFiveSecondTimerRunning;
37
37
  private bool _startDeadlineTriggered;
38
-
39
38
  private float _sessionTimer = SESSION_DURATION;
39
+ private bool _isPreSessionRunning;
40
40
  private bool _isSessionRunning;
41
41
  private bool _sessionWarningTriggered;
42
42
  private bool _timeUpTriggered;
@@ -70,8 +70,6 @@ namespace Hyper.Internal.Managers
70
70
 
71
71
  public int SessionTimeRemaining => (int)_sessionTimer;
72
72
 
73
- public bool IsSessionActive => _isSessionRunning;
74
-
75
73
  private GameManager _gameManager;
76
74
  private EventManager _eventManager;
77
75
 
@@ -153,14 +151,24 @@ namespace Hyper.Internal.Managers
153
151
 
154
152
  internal void StartSessionTimer(bool isPreSessionTimer = false)
155
153
  {
154
+ if(_isPreSessionRunning && _isSessionRunning) return; // Already running both timers
155
+
156
156
  #if UNITY_WEBGL && !UNITY_EDITOR
157
157
  StartHTMLSessionTimer();
158
158
  #endif
159
159
  _sessionTimer = SESSION_DURATION;
160
- _isSessionRunning = true;
161
160
  _sessionWarningTriggered = false;
162
161
  _startDeadlineTriggered = false;
163
162
  _lastUnscaledTime = Time.unscaledTime;
163
+
164
+ if (!isPreSessionTimer)
165
+ {
166
+ _isSessionRunning = true;
167
+ }
168
+ else
169
+ {
170
+ _isPreSessionRunning = true;
171
+ }
164
172
  }
165
173
 
166
174
  #endregion
@@ -207,7 +215,7 @@ namespace Hyper.Internal.Managers
207
215
 
208
216
  private void UpdateSessionTimer(float unscaledDelta)
209
217
  {
210
- if (!_isSessionRunning) return;
218
+ if (!_isPreSessionRunning) return;
211
219
 
212
220
  _sessionTimer -= unscaledDelta;
213
221
 
@@ -233,6 +241,7 @@ namespace Hyper.Internal.Managers
233
241
  {
234
242
  _sessionTimer = 0;
235
243
  _isSessionRunning = false;
244
+ _isPreSessionRunning = false;
236
245
  _eventManager?.InvokeSessionTimeOutEvent();
237
246
  }
238
247
  }
@@ -30,14 +30,7 @@ namespace Hyper.Internal
30
30
  lost.SetActive(true);
31
31
  restored.SetActive(false);
32
32
 
33
- rectTransform.DOAnchorPosY(13f, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad).OnComplete(() =>
34
- {
35
- // // After 2 seconds, move it back up
36
- // HyperTween.DelayedCall(4f, () =>
37
- // {
38
- // rectTransform.DOAnchorPosY(-100f, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad);
39
- // });
40
- });
33
+ rectTransform.DOAnchorPosY(0f, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad);
41
34
  }
42
35
 
43
36
  void ConnectionRestored()
@@ -45,9 +38,8 @@ namespace Hyper.Internal
45
38
  lost.SetActive(false);
46
39
  restored.SetActive(true);
47
40
 
48
- rectTransform.DOAnchorPosY(13f, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad).OnComplete(() =>
41
+ rectTransform.DOAnchorPosY(0, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad).OnComplete(() =>
49
42
  {
50
- // After 2 seconds, move it back up
51
43
  HyperTween.DelayedCall(4f, () =>
52
44
  {
53
45
  rectTransform.DOAnchorPosY(-100f, 0.5f).SetUpdate(true).SetEase(HyperTween.Ease.InQuad);
@@ -56,7 +56,7 @@ namespace Hyper.Internal
56
56
 
57
57
  void HandleTutorialLoadingComplete()
58
58
  {
59
- Debug.Log($"Tutorial Loading Completed!");
59
+ // Debug.Log($"Tutorial Loading Completed!");
60
60
 
61
61
  // Fade out and disable
62
62
  tutorialLoaderModalCG.DOFade(0, 0.15f).SetDelay(2f).SetUpdate(true).OnComplete(() =>
@@ -75,7 +75,6 @@ mergeInto(LibraryManager.library, {
75
75
  }
76
76
 
77
77
  window.socketInstance.emit(payload.event, payload.data, (ackResponse) => {
78
- // console.log("[WebSocket] ACK received:", ackResponse);
79
78
  try {
80
79
  const ackJson = JSON.stringify(ackResponse);
81
80
  SendMessage('HyperSDKSingleton', 'OnSocketMessage', ackJson);
@@ -26,17 +26,17 @@ RectTransform:
26
26
  m_GameObject: {fileID: 1048866143089788928}
27
27
  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
28
28
  m_LocalPosition: {x: 0, y: 0, z: 0}
29
- m_LocalScale: {x: 1, y: 1, z: 1}
30
- m_ConstrainProportionsScale: 0
29
+ m_LocalScale: {x: 0.8, y: 0.8, z: 0.8}
30
+ m_ConstrainProportionsScale: 1
31
31
  m_Children:
32
32
  - {fileID: 8309774266759315490}
33
33
  - {fileID: 737453627717873146}
34
- m_Father: {fileID: 169989670260607081}
34
+ m_Father: {fileID: 5674028873514353123}
35
35
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
36
- m_AnchorMin: {x: 1, y: 0.5}
37
- m_AnchorMax: {x: 1, y: 0.5}
38
- m_AnchoredPosition: {x: -182, y: 13}
39
- m_SizeDelta: {x: 100, y: 100}
36
+ m_AnchorMin: {x: 0.5, y: 0.5}
37
+ m_AnchorMax: {x: 0.5, y: 0.5}
38
+ m_AnchoredPosition: {x: 0, y: 0}
39
+ m_SizeDelta: {x: 103.8133, y: 108.9792}
40
40
  m_Pivot: {x: 0.5, y: 0.5}
41
41
  --- !u!114 &8174422555707274544
42
42
  MonoBehaviour:
@@ -85,7 +85,7 @@ RectTransform:
85
85
  - {fileID: 4203918634244751565}
86
86
  - {fileID: 3751917781741926748}
87
87
  - {fileID: 2951596604433264409}
88
- - {fileID: 3038526082762213112}
88
+ - {fileID: 5674028873514353123}
89
89
  - {fileID: 19893713024797808}
90
90
  m_Father: {fileID: 4867582869548686450}
91
91
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -160,15 +160,15 @@ RectTransform:
160
160
  m_GameObject: {fileID: 2473909893973907380}
161
161
  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
162
162
  m_LocalPosition: {x: 0, y: 0, z: 0}
163
- m_LocalScale: {x: 0.75, y: 0.75, z: 0.75}
164
- m_ConstrainProportionsScale: 0
163
+ m_LocalScale: {x: 1, y: 1, z: 1}
164
+ m_ConstrainProportionsScale: 1
165
165
  m_Children: []
166
166
  m_Father: {fileID: 3038526082762213112}
167
167
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
168
168
  m_AnchorMin: {x: 0, y: 0}
169
169
  m_AnchorMax: {x: 1, y: 1}
170
- m_AnchoredPosition: {x: 0, y: 0}
171
- m_SizeDelta: {x: 0, y: 0}
170
+ m_AnchoredPosition: {x: 0.17333984, y: 1.8095093}
171
+ m_SizeDelta: {x: -3.8133545, y: -5.839813}
172
172
  m_Pivot: {x: 0.5, y: 0.5}
173
173
  --- !u!222 &4904993199147460690
174
174
  CanvasRenderer:
@@ -200,7 +200,7 @@ MonoBehaviour:
200
200
  m_Calls: []
201
201
  m_Sprite: {fileID: 21300000, guid: 4fb89f5103c371a439c5f81fdced2c0c, type: 3}
202
202
  m_Type: 0
203
- m_PreserveAspect: 0
203
+ m_PreserveAspect: 1
204
204
  m_FillCenter: 1
205
205
  m_FillMethod: 4
206
206
  m_FillAmount: 1
@@ -215,7 +215,7 @@ MonoBehaviour:
215
215
  m_PrefabInstance: {fileID: 0}
216
216
  m_PrefabAsset: {fileID: 0}
217
217
  m_GameObject: {fileID: 2473909893973907380}
218
- m_Enabled: 1
218
+ m_Enabled: 0
219
219
  m_EditorHideFlags: 0
220
220
  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
221
221
  m_Name:
@@ -247,7 +247,7 @@ MonoBehaviour:
247
247
  m_PressedTrigger: Pressed
248
248
  m_SelectedTrigger: Selected
249
249
  m_DisabledTrigger: Disabled
250
- m_Interactable: 0
250
+ m_Interactable: 1
251
251
  m_TargetGraphic: {fileID: 8771623675020164658}
252
252
  m_OnClick:
253
253
  m_PersistentCalls:
@@ -504,15 +504,15 @@ RectTransform:
504
504
  m_GameObject: {fileID: 4434394802318301849}
505
505
  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
506
506
  m_LocalPosition: {x: 0, y: 0, z: 0}
507
- m_LocalScale: {x: 0.75, y: 0.75, z: 0.75}
508
- m_ConstrainProportionsScale: 0
507
+ m_LocalScale: {x: 1, y: 1, z: 1}
508
+ m_ConstrainProportionsScale: 1
509
509
  m_Children: []
510
510
  m_Father: {fileID: 3038526082762213112}
511
511
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
512
512
  m_AnchorMin: {x: 0, y: 0}
513
513
  m_AnchorMax: {x: 1, y: 1}
514
- m_AnchoredPosition: {x: 0, y: 0}
515
- m_SizeDelta: {x: 0, y: 0}
514
+ m_AnchoredPosition: {x: 0.17333984, y: 1.8095093}
515
+ m_SizeDelta: {x: -3.8133545, y: -5.839813}
516
516
  m_Pivot: {x: 0.5, y: 0.5}
517
517
  --- !u!222 &5308926542114210481
518
518
  CanvasRenderer:
@@ -544,7 +544,7 @@ MonoBehaviour:
544
544
  m_Calls: []
545
545
  m_Sprite: {fileID: 21300000, guid: 2ed7d5715e8d9804982046f22fd6d4e8, type: 3}
546
546
  m_Type: 0
547
- m_PreserveAspect: 0
547
+ m_PreserveAspect: 1
548
548
  m_FillCenter: 1
549
549
  m_FillMethod: 4
550
550
  m_FillAmount: 1
@@ -1062,6 +1062,96 @@ MonoBehaviour:
1062
1062
  pauseBarsDark: {fileID: 21300000, guid: 023ea868e45992b46ab65bc4b6fb72c7, type: 3}
1063
1063
  livesDisplayPrefab: {fileID: 5031749136894004241, guid: b7f1d0f9e3734df4c9feb3385b835f4b, type: 3}
1064
1064
  healthBarDisplayPrefab: {fileID: 1417749867448633337, guid: 22043bd14ddce8947800ab23f5fdff24, type: 3}
1065
+ --- !u!1 &7998827318738212946
1066
+ GameObject:
1067
+ m_ObjectHideFlags: 0
1068
+ m_CorrespondingSourceObject: {fileID: 0}
1069
+ m_PrefabInstance: {fileID: 0}
1070
+ m_PrefabAsset: {fileID: 0}
1071
+ serializedVersion: 6
1072
+ m_Component:
1073
+ - component: {fileID: 5674028873514353123}
1074
+ - component: {fileID: 5207791156461544556}
1075
+ - component: {fileID: 6042180838967743657}
1076
+ - component: {fileID: 4550745912745357072}
1077
+ m_Layer: 5
1078
+ m_Name: ConnStatusIcon Holder
1079
+ m_TagString: Untagged
1080
+ m_Icon: {fileID: 0}
1081
+ m_NavMeshLayer: 0
1082
+ m_StaticEditorFlags: 0
1083
+ m_IsActive: 1
1084
+ --- !u!224 &5674028873514353123
1085
+ RectTransform:
1086
+ m_ObjectHideFlags: 0
1087
+ m_CorrespondingSourceObject: {fileID: 0}
1088
+ m_PrefabInstance: {fileID: 0}
1089
+ m_PrefabAsset: {fileID: 0}
1090
+ m_GameObject: {fileID: 7998827318738212946}
1091
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
1092
+ m_LocalPosition: {x: 0, y: 0, z: 0}
1093
+ m_LocalScale: {x: 1, y: 1, z: 1}
1094
+ m_ConstrainProportionsScale: 0
1095
+ m_Children:
1096
+ - {fileID: 3038526082762213112}
1097
+ m_Father: {fileID: 169989670260607081}
1098
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
1099
+ m_AnchorMin: {x: 1, y: 0.5}
1100
+ m_AnchorMax: {x: 1, y: 0.5}
1101
+ m_AnchoredPosition: {x: -182, y: 12.215299}
1102
+ m_SizeDelta: {x: 83.05066, y: 87.183365}
1103
+ m_Pivot: {x: 0.5, y: 0.5}
1104
+ --- !u!222 &5207791156461544556
1105
+ CanvasRenderer:
1106
+ m_ObjectHideFlags: 0
1107
+ m_CorrespondingSourceObject: {fileID: 0}
1108
+ m_PrefabInstance: {fileID: 0}
1109
+ m_PrefabAsset: {fileID: 0}
1110
+ m_GameObject: {fileID: 7998827318738212946}
1111
+ m_CullTransparentMesh: 1
1112
+ --- !u!114 &6042180838967743657
1113
+ MonoBehaviour:
1114
+ m_ObjectHideFlags: 0
1115
+ m_CorrespondingSourceObject: {fileID: 0}
1116
+ m_PrefabInstance: {fileID: 0}
1117
+ m_PrefabAsset: {fileID: 0}
1118
+ m_GameObject: {fileID: 7998827318738212946}
1119
+ m_Enabled: 1
1120
+ m_EditorHideFlags: 0
1121
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
1122
+ m_Name:
1123
+ m_EditorClassIdentifier:
1124
+ m_Material: {fileID: 0}
1125
+ m_Color: {r: 0, g: 0, b: 0, a: 1}
1126
+ m_RaycastTarget: 1
1127
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
1128
+ m_Maskable: 1
1129
+ m_OnCullStateChanged:
1130
+ m_PersistentCalls:
1131
+ m_Calls: []
1132
+ m_Sprite: {fileID: 0}
1133
+ m_Type: 0
1134
+ m_PreserveAspect: 0
1135
+ m_FillCenter: 1
1136
+ m_FillMethod: 4
1137
+ m_FillAmount: 1
1138
+ m_FillClockwise: 1
1139
+ m_FillOrigin: 0
1140
+ m_UseSpriteMesh: 0
1141
+ m_PixelsPerUnitMultiplier: 1
1142
+ --- !u!114 &4550745912745357072
1143
+ MonoBehaviour:
1144
+ m_ObjectHideFlags: 0
1145
+ m_CorrespondingSourceObject: {fileID: 0}
1146
+ m_PrefabInstance: {fileID: 0}
1147
+ m_PrefabAsset: {fileID: 0}
1148
+ m_GameObject: {fileID: 7998827318738212946}
1149
+ m_Enabled: 1
1150
+ m_EditorHideFlags: 0
1151
+ m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
1152
+ m_Name:
1153
+ m_EditorClassIdentifier:
1154
+ m_ShowMaskGraphic: 0
1065
1155
  --- !u!1 &8984078937237801384
1066
1156
  GameObject:
1067
1157
  m_ObjectHideFlags: 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app.hypergames.hypersdk",
3
- "version": "1.4.11",
3
+ "version": "1.4.12",
4
4
  "displayName": "HyperSDK",
5
5
  "description": "Official Unity SDK for Hyper: multiplayer battles, leaderboards, deterministic RNG, session management, tutorials, and WebGL optimizations for production-ready games.",
6
6
  "unity": "6000.0",