Merge branch 'develop' into feature/skill-set-shortcut
# Conflicts: # Assets/PerfectWorld/Resources/UI/DialogScriptTableObject.asset
This commit is contained in:
@@ -1,5 +1,126 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &99051929539797809
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4915293664251870536}
|
||||
- component: {fileID: 7416811990837147698}
|
||||
- component: {fileID: 6809282891346298764}
|
||||
- component: {fileID: 7010901635634620631}
|
||||
m_Layer: 5
|
||||
m_Name: ButtonNo
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4915293664251870536
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 99051929539797809}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 2385775756193422540}
|
||||
m_Father: {fileID: 2782318616460798463}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 205.9258, y: 56.2433}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7416811990837147698
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 99051929539797809}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &6809282891346298764
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 99051929539797809}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.14578143, g: 0.7924528, b: 0.1864423, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &7010901635634620631
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 99051929539797809}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 6809282891346298764}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &1448650841350251410
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -168,10 +289,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7906706137011413807}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -81}
|
||||
m_SizeDelta: {x: 200, y: 50}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5808684862484431307
|
||||
CanvasRenderer:
|
||||
@@ -201,7 +322,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: OK
|
||||
m_text: "\u0110\u1ED3ng \xDD(Y)"
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
@@ -228,10 +349,10 @@ MonoBehaviour:
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 36
|
||||
m_fontSize: 44.25
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
@@ -272,6 +393,70 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &4140524140714306011
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2782318616460798463}
|
||||
- component: {fileID: 6567280976245013390}
|
||||
m_Layer: 5
|
||||
m_Name: Buttons
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2782318616460798463
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4140524140714306011}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4915293664251870536}
|
||||
- {fileID: 7906706137011413807}
|
||||
m_Father: {fileID: 8578995796031649400}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 41.609}
|
||||
m_SizeDelta: {x: 0, y: 83.217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &6567280976245013390
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4140524140714306011}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 0
|
||||
m_Right: 0
|
||||
m_Top: 0
|
||||
m_Bottom: 0
|
||||
m_ChildAlignment: 4
|
||||
m_Spacing: 11.43
|
||||
m_ChildForceExpandWidth: 0
|
||||
m_ChildForceExpandHeight: 1
|
||||
m_ChildControlWidth: 0
|
||||
m_ChildControlHeight: 0
|
||||
m_ChildScaleWidth: 0
|
||||
m_ChildScaleHeight: 0
|
||||
m_ReverseArrangement: 0
|
||||
--- !u!1 &4839074738306786208
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -285,7 +470,7 @@ GameObject:
|
||||
- component: {fileID: 8250962023850685786}
|
||||
- component: {fileID: 7766051278568089760}
|
||||
m_Layer: 5
|
||||
m_Name: ButtonExit
|
||||
m_Name: ButtonOk
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
@@ -298,18 +483,18 @@ RectTransform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4839074738306786208}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 7677644201189461152}
|
||||
m_Father: {fileID: 8578995796031649400}
|
||||
m_Father: {fileID: 2782318616460798463}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 160, y: 30}
|
||||
m_SizeDelta: {x: 205.9258, y: 56.2433}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8280971203118505009
|
||||
CanvasRenderer:
|
||||
@@ -332,7 +517,7 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_Color: {r: 0.14578143, g: 0.7924528, b: 0.1864423, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
@@ -425,10 +610,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8578995796031649400}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 3}
|
||||
m_SizeDelta: {x: 200, y: 50}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 50}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &655909173274991632
|
||||
CanvasRenderer:
|
||||
@@ -487,10 +672,10 @@ MonoBehaviour:
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 36
|
||||
m_fontSize: 44.75
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
@@ -562,15 +747,15 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 7906706137011413807}
|
||||
- {fileID: 1931146730219979515}
|
||||
- {fileID: 6428994832978992641}
|
||||
- {fileID: 2782318616460798463}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 30.6318}
|
||||
m_SizeDelta: {x: 434.6896, y: 248.9211}
|
||||
m_SizeDelta: {x: 1067.9689, y: 248.9211}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2243330050876855902
|
||||
CanvasRenderer:
|
||||
@@ -625,3 +810,140 @@ MonoBehaviour:
|
||||
titleText: {fileID: 5031655611580643013}
|
||||
messageText: {fileID: 7448521238108099750}
|
||||
okButton: {fileID: 7766051278568089760}
|
||||
_noButton: {fileID: 7010901635634620631}
|
||||
--- !u!1 &5664175764923475105
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2385775756193422540}
|
||||
- component: {fileID: 8838082653881325633}
|
||||
- component: {fileID: 438315464709753381}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2385775756193422540
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5664175764923475105}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4915293664251870536}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8838082653881325633
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5664175764923475105}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &438315464709753381
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5664175764923475105}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: "H\u1EE7y(N)"
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4278190080
|
||||
m_fontColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 50.3
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 0
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
|
||||
@@ -999,6 +999,7 @@ RectTransform:
|
||||
- {fileID: 3483809415181351540}
|
||||
- {fileID: 7451658084820611230}
|
||||
- {fileID: 807958754388851913}
|
||||
- {fileID: 7749074831901819156}
|
||||
m_Father: {fileID: 2780428059708698453}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
@@ -2282,6 +2283,151 @@ MonoBehaviour:
|
||||
- {fileID: 2554621538146193444}
|
||||
- {fileID: 5079395126799912635}
|
||||
- {fileID: 2024142370080989935}
|
||||
--- !u!1 &5525441299837637062
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7749074831901819156}
|
||||
- component: {fileID: 7710645045682326551}
|
||||
- component: {fileID: 4846176155215941588}
|
||||
- component: {fileID: 2039217357137269515}
|
||||
- component: {fileID: 354882936729747584}
|
||||
m_Layer: 0
|
||||
m_Name: BackToSelect_btn
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7749074831901819156
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5525441299837637062}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3233441867675090637}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 49, y: -229.8}
|
||||
m_SizeDelta: {x: 85, y: 92}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7710645045682326551
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5525441299837637062}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4846176155215941588
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5525441299837637062}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 052d4b5b3b147d04cbd00f737f5c7c53, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &2039217357137269515
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5525441299837637062}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 4846176155215941588}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 354882936729747584}
|
||||
m_TargetAssemblyTypeName: BrewMonster.UI.BtnBackToSelectRole, Assembly-CSharp
|
||||
m_MethodName: OnClick
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!114 &354882936729747584
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5525441299837637062}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f9aed6caec10d2a44a39e3b9c458c5c5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &5539920506348156658
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -39,5 +39,5 @@ MonoBehaviour:
|
||||
prefab: {fileID: 6310702841431484757, guid: 6620f766cee7c8f4cb00dd457ac77675, type: 3}
|
||||
- id: Win_ArrangeTeam
|
||||
prefab: {fileID: 2452003196178065293, guid: 5a3e828efd5c542469d1f17565205ded, type: 3}
|
||||
- id: CDlgInfoTooltip
|
||||
prefab: {fileID: 6830833846243993097, guid: 97dd1de3aba08a04980849e40d5c1ea4, type: 3}
|
||||
- id: DlgMessageBox
|
||||
prefab: {fileID: 5492547392745930423, guid: 54cccb2c6a758a24183474cd385ccb2c, type: 3}
|
||||
|
||||
@@ -16,6 +16,13 @@ namespace BrewMonster
|
||||
{
|
||||
if (_instance.IsValueCreated)
|
||||
throw new InvalidOperationException($"Singleton<{typeof(T).Name}> already created!");
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,8 +165,9 @@ namespace PerfectWorld.Scripts.Managers
|
||||
}
|
||||
|
||||
// Get item cool time
|
||||
public int GetCoolTime(ref int piMax)
|
||||
public override int GetCoolTime(out int piMax)
|
||||
{
|
||||
piMax = 0;
|
||||
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
||||
return pHost != null ? pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_AUTOMP, out piMax) : 0;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ namespace PerfectWorld.Scripts.Managers
|
||||
{
|
||||
public class EC_IvtrGeneralCard : EC_IvtrItem
|
||||
{
|
||||
private IVTR_ESSENCE_GENERALCARD m_Essence;
|
||||
|
||||
/// <summary>
|
||||
/// Not create logic yet (add summary later)
|
||||
/// </summary>
|
||||
@@ -15,6 +17,11 @@ namespace PerfectWorld.Scripts.Managers
|
||||
public EC_IvtrGeneralCard(EC_IvtrGeneralCard other) : base(other)
|
||||
{
|
||||
}
|
||||
|
||||
public IVTR_ESSENCE_GENERALCARD GetEssence()
|
||||
{
|
||||
return m_Essence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@ namespace PerfectWorld.Scripts.Managers
|
||||
{
|
||||
return m_pDBEssence.FileMatter;
|
||||
}
|
||||
|
||||
public TASKDICE_ESSENCE GetDBEssence()
|
||||
{
|
||||
return m_pDBEssence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace BrewMonster.Scripts.Managers
|
||||
public struct IVTR_ESSENCE_GENERALCARD
|
||||
{
|
||||
// TODO : implement data later
|
||||
// int type;
|
||||
public int type;
|
||||
// int rank;
|
||||
// int require_level;
|
||||
// int require_leadership;
|
||||
|
||||
@@ -1600,6 +1600,12 @@ namespace CSNetwork.S2CCommand
|
||||
public int strength;
|
||||
public int agility;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SevClearEmbeddedChipContent
|
||||
{
|
||||
public int iEquipIdx;
|
||||
public int tidEquip;
|
||||
}
|
||||
}
|
||||
|
||||
// Player and NPC state
|
||||
@@ -269,6 +269,15 @@ namespace CSNetwork.C2SCommand
|
||||
};
|
||||
return SerializeCommand(CommandID.STOP_MOVE, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreatePlayerLogoutCmd(int outType)
|
||||
{
|
||||
var cmd = new CMD_PlayerLogout
|
||||
{
|
||||
outType = outType
|
||||
};
|
||||
return SerializeCommand(CommandID.LOGOUT, cmd);
|
||||
}
|
||||
public static Octets CreatePlayerCastSkill(int idSkill, byte byPVPMask, int iNumTarget, int[] aTargets)
|
||||
{
|
||||
var cmd = new CMD_CastSkill
|
||||
@@ -993,5 +1002,19 @@ namespace CSNetwork.C2SCommand
|
||||
};
|
||||
return SerializeCommand(CommandID.SET_STATUS_POINT, pCmd);
|
||||
}
|
||||
public static Octets CreateNPCSevClearEmbeddedChipCmd(int iEquipIdx, int tidEquip)
|
||||
{
|
||||
var cmd = new cmd_sevnpc_serve
|
||||
{
|
||||
service_type = NPC_service_type.GP_NPCSEV_CLEAR_TESSERA,
|
||||
len = (uint)Marshal.SizeOf<SevClearEmbeddedChipContent>()
|
||||
};
|
||||
SevClearEmbeddedChipContent content = new SevClearEmbeddedChipContent()
|
||||
{
|
||||
iEquipIdx = iEquipIdx,
|
||||
tidEquip = tidEquip,
|
||||
};
|
||||
return SerializeCommand(CommandID.SEVNPC_SERVE, cmd, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ namespace CSNetwork
|
||||
public static SynchronizationContext Context;
|
||||
private CECC2SCmdCache m_CmdCache; // C2S command cache
|
||||
|
||||
/// <summary>Raised when server sends PROTOCOL_PLAYERLOGOUT(69).</summary>
|
||||
public event Action<playerlogout> PlayerLogoutReceived;
|
||||
|
||||
/// <summary>Raised when the underlying network disconnects.</summary>
|
||||
public event Action Disconnected;
|
||||
|
||||
private static void PostToUnityContext(Action action)
|
||||
{
|
||||
if (action == null) return;
|
||||
@@ -564,13 +570,16 @@ namespace CSNetwork
|
||||
OnPrtcPlayerBaseInfoRe(protocol);
|
||||
break;
|
||||
case ProtocolType.PROTOCOL_GETUICONFIG_RE: OnPrtcGetConfigRe(protocol); break;
|
||||
case ProtocolType.PROTOCOL_PLAYERLOGOUT:
|
||||
HandlePlayerLogout((playerlogout)protocol);
|
||||
break;
|
||||
|
||||
case ProtocolType.PROTOCOL_AUTOTEAMSETGOAL_RE:
|
||||
{
|
||||
// CECAutoTeam pAutoTeam = CECGameRun.Instance.GetHostPlayer().GetAutoTeam();
|
||||
// if( pAutoTeam !=null)
|
||||
// pAutoTeam.OnPrtcAutoTeamSetGoalRe((AutoTeamSetGoal_Re)protocol);
|
||||
}
|
||||
{
|
||||
// CECAutoTeam pAutoTeam = CECGameRun.Instance.GetHostPlayer().GetAutoTeam();
|
||||
// if( pAutoTeam !=null)
|
||||
// pAutoTeam.OnPrtcAutoTeamSetGoalRe((AutoTeamSetGoal_Re)protocol);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -579,6 +588,13 @@ namespace CSNetwork
|
||||
}
|
||||
}
|
||||
|
||||
private void HandlePlayerLogout(playerlogout protocol)
|
||||
{
|
||||
// Original client receives this before EVENT_DISCONNECT.
|
||||
// We just publish it to allow higher-level flow (UnityGameSession/UI) to react.
|
||||
PostToUnityContext(() => PlayerLogoutReceived?.Invoke(protocol));
|
||||
}
|
||||
|
||||
private void HandleServerDataSend(gamedatasend protocol)
|
||||
{
|
||||
int lenghtHeader = Marshal.SizeOf<ushort>();
|
||||
@@ -811,7 +827,7 @@ namespace CSNetwork
|
||||
#if UNITY_EDITOR
|
||||
BMLogger.LogError($"### GameDataSend: ERROR_MESSAGE: {errRaw}");
|
||||
#endif
|
||||
cmd_error_msg pCmd = GPDataTypeHelper.FromBytes<cmd_error_msg>(pDataBuf);
|
||||
cmd_error_msg pCmd = GPDataTypeHelper.FromBytes<cmd_error_msg>(pDataBuf);
|
||||
#if UNITY_EDITOR
|
||||
BMLogger.LogError($"### GameDataSend: ERROR_MESSAGE parsed iMessage={pCmd.iMessage}");
|
||||
#endif
|
||||
@@ -829,50 +845,50 @@ namespace CSNetwork
|
||||
// g_pGame.GetGameRun().AddChatMessage(szMsg, GP_CHAT_MISC);
|
||||
}
|
||||
|
||||
if (pCmd.iMessage == 2)
|
||||
{
|
||||
// Attack target is too far
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TARGETISFAR, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
}
|
||||
else if (pCmd.iMessage == 20)
|
||||
{
|
||||
// Failed to cast skill
|
||||
//pGameRun.PostMessage(MSG_PM_CASTSKILL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd);
|
||||
}
|
||||
else if (pCmd.iMessage == 133 || pCmd.iMessage == 134)
|
||||
{
|
||||
// deal failed
|
||||
//pGameRun.PostMessage(MSG_HST_BUY_SELL_FAIL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd);
|
||||
}
|
||||
else if (pCmd.iMessage == 158)
|
||||
{
|
||||
// µ±Ç°»ãÂʲ»¶Ô£¬ÖØÐÂÈ¡»ãÂÊ
|
||||
//c2s_CmdGetCashMoneyRate();
|
||||
}
|
||||
else if (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().IsInKingService()*/)
|
||||
{
|
||||
/* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI)
|
||||
pGameUI.EndNPCService();*/
|
||||
}
|
||||
else if
|
||||
(pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().GetOfflineShopCtrl().GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/
|
||||
)
|
||||
{
|
||||
/* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI)
|
||||
pGameUI.EndNPCService();*/
|
||||
}
|
||||
else if (pCmd.iMessage == 175)
|
||||
{
|
||||
//c2s_CmdQueryParallelWorld();
|
||||
}
|
||||
else if (pCmd.iMessage == 6)
|
||||
{
|
||||
//AP_ActionEvent(AP_EVENT_CANNOTPICKUP);
|
||||
}
|
||||
if (pCmd.iMessage == 2)
|
||||
{
|
||||
// Attack target is too far
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TARGETISFAR, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
}
|
||||
else if (pCmd.iMessage == 20)
|
||||
{
|
||||
// Failed to cast skill
|
||||
//pGameRun.PostMessage(MSG_PM_CASTSKILL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd);
|
||||
}
|
||||
else if (pCmd.iMessage == 133 || pCmd.iMessage == 134)
|
||||
{
|
||||
// deal failed
|
||||
//pGameRun.PostMessage(MSG_HST_BUY_SELL_FAIL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd);
|
||||
}
|
||||
else if (pCmd.iMessage == 158)
|
||||
{
|
||||
// µ±Ç°»ãÂʲ»¶Ô£¬ÖØÐÂÈ¡»ãÂÊ
|
||||
//c2s_CmdGetCashMoneyRate();
|
||||
}
|
||||
else if (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().IsInKingService()*/)
|
||||
{
|
||||
/* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI)
|
||||
pGameUI.EndNPCService();*/
|
||||
}
|
||||
else if
|
||||
(pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().GetOfflineShopCtrl().GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/
|
||||
)
|
||||
{
|
||||
/* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI)
|
||||
pGameUI.EndNPCService();*/
|
||||
}
|
||||
else if (pCmd.iMessage == 175)
|
||||
{
|
||||
//c2s_CmdQueryParallelWorld();
|
||||
}
|
||||
else if (pCmd.iMessage == 6)
|
||||
{
|
||||
//AP_ActionEvent(AP_EVENT_CANNOTPICKUP);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case CommandID.SELECT_TARGET:
|
||||
case CommandID.UNSELECT:
|
||||
@@ -941,7 +957,7 @@ namespace CSNetwork
|
||||
case CommandID.OBJECT_CAST_INSTANT_SKILL:
|
||||
case CommandID.OBJECT_CAST_POS_SKILL:
|
||||
{
|
||||
cmd_object_cast_skill pCmd2 = GPDataTypeHelper.FromBytes<cmd_object_cast_skill>(pDataBuf, true);
|
||||
cmd_object_cast_skill pCmd2 = GPDataTypeHelper.FromBytes<cmd_object_cast_skill>(pDataBuf,true);
|
||||
if (ISPLAYERID(pCmd2.caster))
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_CASTSKILL, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
|
||||
else if (ISNPCID(pCmd2.caster))
|
||||
@@ -1141,6 +1157,7 @@ namespace CSNetwork
|
||||
FailRoleListInProgress("Disconnected");
|
||||
// Clear command cache
|
||||
m_CmdCache.RemoveAllCmds();
|
||||
PostToUnityContext(() => Disconnected?.Invoke());
|
||||
}
|
||||
|
||||
// --- Protocol Handling Logic ---
|
||||
@@ -1200,7 +1217,7 @@ namespace CSNetwork
|
||||
|
||||
var callback = _loginCallback;
|
||||
_loginCallback = null;
|
||||
callback?.Invoke(true);
|
||||
PostToUnityContext(() => callback?.Invoke(true));
|
||||
}
|
||||
|
||||
private void RequestRoleListInternal(int lastHandle = -1)
|
||||
@@ -1396,6 +1413,18 @@ namespace CSNetwork
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNakeCmd(C2SCommand.CommandID.CONTINUE_ACTION);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Client logout request. Mirrors original client behavior:
|
||||
/// - outType=1: back to select role
|
||||
/// - outType=0: logout account
|
||||
/// </summary>
|
||||
public void SendPlayerLogout(int outType, Action complete = null)
|
||||
{
|
||||
var g = new gamedatasend();
|
||||
g.Data = C2SCommandFactory.CreatePlayerLogoutCmd(outType);
|
||||
SendProtocol(g, complete);
|
||||
}
|
||||
public void c2s_SendCmdStopMove(in Vector3 vDest, float fSpeed, int iMoveMode,
|
||||
byte byDir, ushort wStamp, int iTime)
|
||||
{
|
||||
@@ -1479,24 +1508,24 @@ namespace CSNetwork
|
||||
|
||||
// Get referral name for adding friend or other display
|
||||
//TODO: a Hung lam phan select role info di
|
||||
/* RoleInfo info = EC_Game.GetGameRun().GetSelectedRoleInfo();
|
||||
if (info.referrer_role > 0)
|
||||
GetPlayerBriefInfo(1, info.referrer_role, 2);*/
|
||||
/* RoleInfo info = EC_Game.GetGameRun().GetSelectedRoleInfo();
|
||||
if (info.referrer_role > 0)
|
||||
GetPlayerBriefInfo(1, info.referrer_role, 2);*/
|
||||
}
|
||||
|
||||
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
||||
pHost.OnAllInitDataReady();
|
||||
|
||||
/* if (pHost.IsGM())
|
||||
{
|
||||
CDlgCountryMap pDlgCountryMap = (CDlgCountryMap)pGameUI.GetDialog("Win_CountryMap");
|
||||
pDlgCountryMap.GetConfig();
|
||||
}
|
||||
/* if (pHost.IsGM())
|
||||
{
|
||||
CDlgCountryMap pDlgCountryMap = (CDlgCountryMap)pGameUI.GetDialog("Win_CountryMap");
|
||||
pDlgCountryMap.GetConfig();
|
||||
}
|
||||
|
||||
g_pGame.GetConfigs().ApplyOptimizeSetting();
|
||||
g_pGame.GetConfigs().ApplyOptimizeSetting();
|
||||
|
||||
if (g_pGame.GetConfigs().IsMiniClient())
|
||||
CECMCDownload::GetInstance().SendGetDownloadOK();*/
|
||||
if (g_pGame.GetConfigs().IsMiniClient())
|
||||
CECMCDownload::GetInstance().SendGetDownloadOK();*/
|
||||
}
|
||||
}
|
||||
private void OnPrtcPlayerBaseInfoRe(Protocol pProtocol)
|
||||
@@ -1703,7 +1732,8 @@ namespace CSNetwork
|
||||
public void c2s_SendCmdTaskNotify(byte[] pData, uint dwDataSize)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateTaskNotifyCmd(pData, dwDataSize);
|
||||
gamedatasend.Data = C2SCommandFactory.CreateTaskNotifyCmd( pData, dwDataSize);
|
||||
BMLogger.Log($"[MH Task] c2s_SendCmdTaskNotify Command ID : {pData[0]} Size: {dwDataSize}");
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
@@ -1713,11 +1743,11 @@ namespace CSNetwork
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNakeCmd(C2SCommand.CommandID.STAND_UP);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
|
||||
public void c2s_SendCmdAutoTeamSetGoal(int type, int goal_id, int op)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateAutoTeamSetGoalCommand(type, goal_id, op);
|
||||
gamedatasend.Data = C2SCommandFactory.CreateAutoTeamSetGoalCommand(type,goal_id, op);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
@@ -1773,14 +1803,14 @@ namespace CSNetwork
|
||||
|
||||
public void c2s_CmdGoto(float x, float y, float z)
|
||||
{
|
||||
c2s_SendCmdGoto(x, y, z);
|
||||
c2s_SendCmdGoto(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
// Send C2S::GOTO command data
|
||||
void c2s_SendCmdGoto(float x, float y, float z)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateGoToCommed(x, y, z);
|
||||
gamedatasend.Data = C2SCommandFactory.CreateGoToCommed( x, y, z);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
@@ -1858,5 +1888,11 @@ namespace CSNetwork
|
||||
gamedatasend.Data = C2SCommandFactory.CreateSetStatusPtCmd(vitality, energy, strength, agility);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
public void c2s_CmdNPCSevClearEmbeddedChip(int iEquipIdx, int tidEquip)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNPCSevClearEmbeddedChipCmd(iEquipIdx, tidEquip);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,10 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BrewMonster.Scripts.Task;
|
||||
using BrewMonster.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using BrewMonster.Scripts;
|
||||
|
||||
namespace BrewMonster.Network
|
||||
{
|
||||
@@ -24,6 +26,8 @@ namespace BrewMonster.Network
|
||||
// 2. Login
|
||||
public class UnityGameSession : MonoSingleton<UnityGameSession>
|
||||
{
|
||||
private const string WorldSceneName = "a61";
|
||||
private const string LoginSceneName = "LoginScene";
|
||||
private GameSession _gameSession;
|
||||
|
||||
private bool _isInitialized = false;
|
||||
@@ -82,6 +86,28 @@ namespace BrewMonster.Network
|
||||
Instance._ip = ip;
|
||||
Instance._port = port;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Origin-like: In-game can only return to Select Role (LOGOUT(1)).
|
||||
/// This will load LoginScene and auto-login (using saved creds) to show the Select Role UI.
|
||||
/// </summary>
|
||||
public static void ReturnToSelectRole()
|
||||
{
|
||||
if (Instance == null) return;
|
||||
// Origin-like: in-game only returns to Select Role (auto-login using saved creds).
|
||||
// Keep world scene loaded (a61) but cleaned.
|
||||
_ = Instance.LogoutAndReturnAsync(outType: 1, entryTarget: LogoutFlowState.LoginEntryTarget.SelectRole, clearSavedCreds: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Origin-like: Account logout from Select Role (LOGOUT(0)).
|
||||
/// This will clear saved creds and load LoginScene showing username/password UI.
|
||||
/// </summary>
|
||||
public static void LogoutAccount()
|
||||
{
|
||||
if (Instance == null) return;
|
||||
_ = Instance.LogoutAndReturnAsync(outType: 0, entryTarget: LogoutFlowState.LoginEntryTarget.LoginUI, clearSavedCreds: true);
|
||||
}
|
||||
public static void c2s_CmdCastSkill(int idSkill, byte byPVPMask, int iNumTarget, int[] aTargets)
|
||||
{
|
||||
Instance._gameSession.CmdCache.SendCmdCastSkill(idSkill, byPVPMask, iNumTarget, aTargets);
|
||||
@@ -146,6 +172,169 @@ namespace BrewMonster.Network
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
private async Task LogoutAndReturnAsync(int outType, LogoutFlowState.LoginEntryTarget entryTarget, bool clearSavedCreds)
|
||||
{
|
||||
// Tell LoginScene what to show next.
|
||||
LogoutFlowState.NextLoginEntry = entryTarget;
|
||||
|
||||
if (clearSavedCreds)
|
||||
{
|
||||
PlayerPrefs.DeleteKey("username");
|
||||
PlayerPrefs.DeleteKey("password");
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_gameSession != null && _gameSession.IsConnected)
|
||||
{
|
||||
// Send LOGOUT(outType) like the original client.
|
||||
_gameSession.SendPlayerLogout(outType);
|
||||
|
||||
// Wait briefly for server-driven disconnect.
|
||||
await WaitForDisconnectAsync(timeoutMs: 4000);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BMLogger.LogError($"LogoutAndReturnAsync exception: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Fallback: if server didn't close, close locally.
|
||||
if (_gameSession != null && _gameSession.IsConnected)
|
||||
{
|
||||
_gameSession.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// Return to LoginScene.
|
||||
// IMPORTANT: for outType=1 we must keep the world scene (a61) loaded; only "clean" runtime objects.
|
||||
await Task.Yield();
|
||||
// Requirement: even on account logout, keep a61 loaded (do not delete the world scene),
|
||||
// just clean runtime objects and show LoginScene UI.
|
||||
CleanRuntimeObjectsKeepWorld();
|
||||
await EnsureSceneLoadedAdditiveAsync(WorldSceneName);
|
||||
await EnsureLoginSceneAdditiveAndActivateAsync(keepSceneName: WorldSceneName);
|
||||
|
||||
// When LoginScene is already loaded additively, Start() won't re-run.
|
||||
// Force the login UI to refresh to the correct entry state immediately.
|
||||
ApplyLoginEntryToUI(entryTarget);
|
||||
|
||||
// now we have to logout from Tech3C SDK
|
||||
Tech3CSDKWrapper.Instance.Logout();
|
||||
}
|
||||
|
||||
private static void ApplyLoginEntryToUI(LogoutFlowState.LoginEntryTarget entryTarget)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find even if inactive (Resources.FindObjectsOfTypeAll returns inactive objects too).
|
||||
var all = Resources.FindObjectsOfTypeAll<LoginScreenUI>();
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
var ui = all[i];
|
||||
if (ui == null) continue;
|
||||
if (!ui.gameObject.scene.IsValid() || ui.gameObject.scene.name != LoginSceneName) continue;
|
||||
// Avoid hard dependency on method existence (merges may edit LoginScreenUI).
|
||||
ui.SendMessage("ApplyLoginEntry", entryTarget, SendMessageOptions.DontRequireReceiver);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BMLogger.LogError($"ApplyLoginEntryToUI error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanRuntimeObjectsKeepWorld()
|
||||
{
|
||||
// Spawned runtime objects (player/monsters/vfx) are parented under ObjectSpawner.
|
||||
// Destroying them "cleans" the world without unloading the scene (a61 remains loaded).
|
||||
try
|
||||
{
|
||||
var spawner = BrewMonster.ObjectSpawner.Instance;
|
||||
if (spawner == null) return;
|
||||
|
||||
var root = spawner.transform;
|
||||
for (int i = root.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = root.GetChild(i);
|
||||
if (child != null)
|
||||
UnityEngine.Object.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BMLogger.LogError($"CleanRuntimeObjectsKeepWorld error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task EnsureSceneLoadedAdditiveAsync(string sceneName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sceneName)) return;
|
||||
var s = SceneManager.GetSceneByName(sceneName);
|
||||
if (s.IsValid() && s.isLoaded) return;
|
||||
|
||||
var op = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
|
||||
while (op != null && !op.isDone)
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
private static async Task EnsureLoginSceneAdditiveAndActivateAsync(string keepSceneName)
|
||||
{
|
||||
// Load LoginScene additively if needed (do not unload keepSceneName, e.g., a61).
|
||||
var loginScene = SceneManager.GetSceneByName(LoginSceneName);
|
||||
if (!loginScene.IsValid() || !loginScene.isLoaded)
|
||||
{
|
||||
var op = SceneManager.LoadSceneAsync(LoginSceneName, LoadSceneMode.Additive);
|
||||
while (op != null && !op.isDone)
|
||||
await Task.Yield();
|
||||
loginScene = SceneManager.GetSceneByName(LoginSceneName);
|
||||
}
|
||||
|
||||
if (loginScene.IsValid() && loginScene.isLoaded)
|
||||
{
|
||||
SceneManager.SetActiveScene(loginScene);
|
||||
}
|
||||
|
||||
// Optionally unload other non-world scenes (keep a61 + LoginScene).
|
||||
// This prevents extra scenes like NPCRender staying around.
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
var s = SceneManager.GetSceneAt(i);
|
||||
if (!s.IsValid() || !s.isLoaded) continue;
|
||||
if (s.name == LoginSceneName) continue;
|
||||
if (!string.IsNullOrEmpty(keepSceneName) && s.name == keepSceneName) continue;
|
||||
|
||||
// Only unload if it's not the active scene (we already switched active to LoginScene above).
|
||||
if (SceneManager.GetActiveScene() == s) continue;
|
||||
_ = SceneManager.UnloadSceneAsync(s);
|
||||
}
|
||||
}
|
||||
|
||||
private Task WaitForDisconnectAsync(int timeoutMs)
|
||||
{
|
||||
if (_gameSession == null || !_gameSession.IsConnected)
|
||||
return Task.CompletedTask;
|
||||
|
||||
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
void OnDisc() => tcs.TrySetResult(true);
|
||||
_gameSession.Disconnected += OnDisc;
|
||||
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.WhenAny(tcs.Task, Task.Delay(timeoutMs));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_gameSession.Disconnected -= OnDisc;
|
||||
}
|
||||
});
|
||||
}
|
||||
public RoleInfo GetRoleInfo()
|
||||
{
|
||||
return _gameSession.GetRoleInfo();
|
||||
@@ -499,5 +688,38 @@ namespace BrewMonster.Network
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdGetItemInfo(byPackage, bySlot);
|
||||
}
|
||||
public static void c2s_CmdNPCSevClearEmbeddedChip(int iEquipIdx, int tidEquip)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdNPCSevClearEmbeddedChip(iEquipIdx, tidEquip);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Small cross-scene state to tell LoginScene what to show after a logout flow.
|
||||
/// This mirrors the original client: in-game can only return to Select Role; Account Logout happens from Select Role.
|
||||
/// </summary>
|
||||
public static class LogoutFlowState
|
||||
{
|
||||
public enum LoginEntryTarget
|
||||
{
|
||||
LoginUI = 0,
|
||||
SelectRole = 1,
|
||||
}
|
||||
|
||||
private static LoginEntryTarget _nextEntry = LoginEntryTarget.LoginUI;
|
||||
|
||||
public static LoginEntryTarget NextLoginEntry
|
||||
{
|
||||
get => _nextEntry;
|
||||
set => _nextEntry = value;
|
||||
}
|
||||
|
||||
/// <summary>Consume and reset to default (LoginUI).</summary>
|
||||
public static LoginEntryTarget ConsumeNextLoginEntry()
|
||||
{
|
||||
var v = _nextEntry;
|
||||
_nextEntry = LoginEntryTarget.LoginUI;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cfabbaaddd233a4a9d4f07a3577d3a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,208 @@
|
||||
using Tech3C;
|
||||
using BrewMonster;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public enum LOGIN_ERROR_CODE
|
||||
{
|
||||
SUCCESS = 0,
|
||||
CANCELLED = -1
|
||||
}
|
||||
|
||||
public class Tech3CSDKWrapper : Singleton<Tech3CSDKWrapper>
|
||||
{
|
||||
public string clientId = "tghh";
|
||||
public string clientSecret = "1nBnWnUJadlqzlcd7x7uibXZwW9Bxx9h";
|
||||
|
||||
private AuthCallback authCallback;
|
||||
private LogoutCallback logoutCallback;
|
||||
|
||||
/// <summary>
|
||||
/// After Tech3C SDK returns result, this callback will be called. <br/>
|
||||
/// (errorCode, userId, password)
|
||||
/// </summary>
|
||||
public Action<int, string, string> onLoginCallback;
|
||||
public Action<int, string> onLogOutCallback;
|
||||
|
||||
public bool isInitialized = false;
|
||||
public bool isProcessing = false; // true if the SDK is processing a request (login or logout)
|
||||
|
||||
#region private functions
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SetupCallbacks();
|
||||
|
||||
// Auto-initialize SDK
|
||||
if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
BMLogger.Log($"Initializing Tech3C SDK...\n Client ID: {clientId}");
|
||||
Tech3CSDK.Instance.Initialize(clientId, clientSecret);
|
||||
|
||||
if (Tech3CSDK.Instance.IsInitialized)
|
||||
{
|
||||
BMLogger.Log("[SDK] SDK Initialized Successfully!");
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log("[SDK] Failed to initialize SDK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log("[SDK] Client ID and/or Client Secret not set. Please configure in Inspector.");
|
||||
}
|
||||
|
||||
BMLogger.Log("[SDK] Tech3C SDK Started");
|
||||
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
private void SetupCallbacks()
|
||||
{
|
||||
// Auth callback
|
||||
authCallback = new AuthCallback();
|
||||
authCallback.OnAuthSuccessEvent += OnAuthSuccessEvent;
|
||||
authCallback.OnAuthCancelledEvent += OnAuthCancelledEvent;
|
||||
authCallback.OnAuthErrorEvent += OnAuthErrorEvent;
|
||||
|
||||
// Logout callback
|
||||
logoutCallback = new LogoutCallback();
|
||||
logoutCallback.OnLogoutSuccessEvent += OnLogoutSuccessEvent;
|
||||
logoutCallback.OnLogoutErrorEvent += OnLogoutErrorEvent;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SDK Callbacks
|
||||
private void OnAuthSuccessEvent(string userId, string password, string accessToken, string refreshToken, LoginType loginType, long expiryTime)
|
||||
{
|
||||
isProcessing = false;
|
||||
BMLogger.Log($"[SDK] Auth Success!\n User ID: {userId}\n Password: {password}\n Login Type: {loginType}\n Token: {accessToken?.Substring(0, Mathf.Min(20, accessToken?.Length ?? 0))}...");
|
||||
onLoginCallback?.Invoke((byte)LOGIN_ERROR_CODE.SUCCESS, userId, password);
|
||||
}
|
||||
|
||||
private void OnAuthCancelledEvent()
|
||||
{
|
||||
isProcessing = false;
|
||||
BMLogger.Log("[SDK] Auth Cancelled by user");
|
||||
onLoginCallback?.Invoke((int)LOGIN_ERROR_CODE.CANCELLED, "", "");
|
||||
}
|
||||
|
||||
private void OnAuthErrorEvent(int errorCode, string errorMessage)
|
||||
{
|
||||
isProcessing = false;
|
||||
BMLogger.Log($"[SDK] Auth Error [{errorCode}]: {errorMessage}");
|
||||
onLoginCallback?.Invoke(errorCode, errorMessage, string.Empty);
|
||||
}
|
||||
|
||||
private void OnLogoutSuccessEvent()
|
||||
{
|
||||
isProcessing = false;
|
||||
BMLogger.Log("[SDK] Logout Successful");
|
||||
onLogOutCallback?.Invoke((int)LOGIN_ERROR_CODE.SUCCESS, "");
|
||||
}
|
||||
|
||||
private void OnLogoutErrorEvent(int errorCode, string errorMessage)
|
||||
{
|
||||
isProcessing = false;
|
||||
BMLogger.Log($"[SDK] Logout Error [{errorCode}]: {errorMessage}");
|
||||
onLogOutCallback?.Invoke(errorCode, errorMessage);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region public functions
|
||||
|
||||
public void SetLoginCallback(Action<int, string, string> callback)
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
BMLogger.LogWarning("[SDK] Login callback is already set, it will be overridden");
|
||||
}
|
||||
onLoginCallback = callback;
|
||||
}
|
||||
|
||||
public void RemoveLoginCallback()
|
||||
{
|
||||
onLoginCallback = null;
|
||||
}
|
||||
|
||||
public void SetLogoutCallback(Action<int, string> callback)
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
BMLogger.LogWarning("[SDK] Logout callback is already set, it will be overridden");
|
||||
}
|
||||
onLogOutCallback = callback;
|
||||
}
|
||||
|
||||
public void RemoveLogoutCallback()
|
||||
{
|
||||
onLogOutCallback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show Tech3C SDK login screen.
|
||||
/// Callback will be called after login success or failed.
|
||||
/// </summary>
|
||||
public bool Login()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Login] SDK is not initialized, please call Initialize() first");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isProcessing)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Login] SDK is already processing a request, please wait for the current request to complete");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (onLoginCallback == null)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Login] Login callback is not set, please set it using SetLoginCallback");
|
||||
return false;
|
||||
}
|
||||
|
||||
isProcessing = true;
|
||||
|
||||
Tech3CSDK.Instance.ShowAuth(authCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Logout()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Logout] SDK is not initialized, please call Initialize() first");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isProcessing)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Logout] SDK is already processing a request, please wait for the current request to complete");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (onLogOutCallback == null)
|
||||
{
|
||||
BMLogger.LogError("[SDK] [Logout] Logout callback is not set, please set it using SetLogoutCallback");
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: Check again after 3C resolve the callback issue.
|
||||
// isProcessing = true;
|
||||
|
||||
Tech3CSDK.Instance.Logout(logoutCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61795692226b05849aec56bf168c905a
|
||||
@@ -4,8 +4,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static UnityEditor.AddressableAssets.Build.Layout.BuildLayout;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
|
||||
@@ -1,28 +1,80 @@
|
||||
using BrewMonster.UI;
|
||||
using System;
|
||||
using BrewMonster.UI;
|
||||
using UnityEngine;
|
||||
using static CECUIManager;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public enum MessageBoxType
|
||||
{
|
||||
YesButton,
|
||||
NoButton,
|
||||
BothYesNoButton,
|
||||
}
|
||||
public struct MessageBoxData
|
||||
{
|
||||
public string Title;
|
||||
public string Message;
|
||||
public AUIDialog Dlg;
|
||||
public MessageBoxType MessageBoxType;
|
||||
public Action OnClickedYes;
|
||||
public Action OnClickedNo;
|
||||
}
|
||||
public class CDlgMessageBox : AUIDialog
|
||||
{
|
||||
[SerializeField] private TMPro.TextMeshProUGUI titleText;
|
||||
[SerializeField] private TMPro.TextMeshProUGUI messageText;
|
||||
[SerializeField] private UnityEngine.UI.Button okButton;
|
||||
private void Awake()
|
||||
[SerializeField] private UnityEngine.UI.Button _noButton;
|
||||
|
||||
private MessageBoxData _messageData;
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
okButton.onClick.RemoveAllListeners();
|
||||
base.OnEnable();
|
||||
okButton.onClick.AddListener(OnOkClicked);
|
||||
_noButton.onClick.AddListener(OnNoClicked);
|
||||
}
|
||||
|
||||
public override void OnDisable()
|
||||
{
|
||||
okButton.onClick.RemoveListener(OnOkClicked);
|
||||
_noButton.onClick.RemoveListener(OnNoClicked);
|
||||
}
|
||||
|
||||
private void OnOkClicked()
|
||||
{
|
||||
EventBus.Publish(new MessageBoxEvent(1,this));
|
||||
EventBus.Publish(new MessageBoxEvent(1,_messageData.Dlg));
|
||||
_messageData.OnClickedYes?.Invoke();
|
||||
Show(false);
|
||||
}
|
||||
public void ShowMessageBox(string title, string message)
|
||||
private void OnNoClicked()
|
||||
{
|
||||
SetName(title);
|
||||
messageText.text = message;
|
||||
EventBus.Publish(new MessageBoxEvent(0,_messageData.Dlg));
|
||||
_messageData.OnClickedNo?.Invoke();
|
||||
Show(false);
|
||||
}
|
||||
public void ShowMessageBox(MessageBoxData messageBoxData)
|
||||
{
|
||||
_messageData = messageBoxData;
|
||||
SetName(messageBoxData.Title);
|
||||
messageText.text = messageBoxData.Message;
|
||||
|
||||
okButton.gameObject.SetActive(false);
|
||||
_noButton.gameObject.SetActive(false);
|
||||
switch (_messageData.MessageBoxType)
|
||||
{
|
||||
case MessageBoxType.YesButton:
|
||||
okButton.gameObject.SetActive(true);
|
||||
break;
|
||||
case MessageBoxType.NoButton:
|
||||
_noButton.gameObject.SetActive(true);
|
||||
break;
|
||||
case MessageBoxType.BothYesNoButton:
|
||||
okButton.gameObject.SetActive(true);
|
||||
_noButton.gameObject.SetActive(true);
|
||||
break;
|
||||
}
|
||||
Show(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace BrewMonster
|
||||
[SerializeField] private Button m_BtnCancel;
|
||||
|
||||
[SerializeField] private Sprite khung_item;
|
||||
[SerializeField] private Transform itemInventoryRoot;
|
||||
|
||||
private EC_IvtrItem m_SelectedEquip;
|
||||
private EC_IvtrItem m_SelectedMaterial;
|
||||
@@ -50,12 +51,28 @@ namespace BrewMonster
|
||||
RegisterClick(m_SlotSecondlParent, OnClickMaterialSlot);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
CheckHidePanel(Input.mousePosition);
|
||||
}
|
||||
#else
|
||||
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
|
||||
{
|
||||
CheckHidePanel(Input.GetTouch(0).position);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
//todo need to set from other class
|
||||
// SetName("Win_Enchase");
|
||||
m_BtnMerge.onClick.AddListener(OnClickedMerge);
|
||||
m_BtnCancel.onClick.AddListener(OnClickedCancel);
|
||||
m_install_price = -1;
|
||||
}
|
||||
|
||||
@@ -63,11 +80,7 @@ namespace BrewMonster
|
||||
{
|
||||
base.OnDisable();
|
||||
m_BtnMerge.onClick.RemoveListener(OnClickedMerge);
|
||||
}
|
||||
|
||||
public void OpenInstall(uint npcId)
|
||||
{
|
||||
|
||||
m_BtnCancel.onClick.RemoveListener(OnClickedCancel);
|
||||
}
|
||||
|
||||
public void CloseInstall()
|
||||
@@ -217,6 +230,12 @@ namespace BrewMonster
|
||||
else
|
||||
detailedItem.GetDetailDataFromLocal();
|
||||
|
||||
if (m_FirstInvSlot >= 0)
|
||||
{
|
||||
var previosBtn = FindInventoryButtonBySlot(m_FirstInvSlot);
|
||||
SetInventorySlotGray(previosBtn, false);
|
||||
}
|
||||
|
||||
m_SelectedEquip?.Freeze(false);
|
||||
m_SelectedEquip = detailedItem;
|
||||
m_FirstInvSlot = slotIndex;
|
||||
@@ -227,8 +246,6 @@ namespace BrewMonster
|
||||
SetInventorySlotGray(btn, true);
|
||||
|
||||
detailedItem.Freeze(true);
|
||||
|
||||
Debug.Log($"[Install] Equipment: {detailedItem.m_tid} from slot {slotIndex}");
|
||||
}
|
||||
|
||||
private void OnDropMaterial(PointerEventData eventData)
|
||||
@@ -252,6 +269,12 @@ namespace BrewMonster
|
||||
else
|
||||
detailedItem.GetDetailDataFromLocal();
|
||||
|
||||
if (m_SecondInvSlot >= 0)
|
||||
{
|
||||
var previosBtn = FindInventoryButtonBySlot(m_SecondInvSlot);
|
||||
SetInventorySlotGray(previosBtn, false);
|
||||
}
|
||||
|
||||
m_SelectedMaterial?.Freeze(false);
|
||||
m_SelectedMaterial = detailedItem;
|
||||
m_SelectedMaterial?.Freeze(true);
|
||||
@@ -297,8 +320,6 @@ namespace BrewMonster
|
||||
// a_sprintf(szText, _AL("%d"), nAmount);
|
||||
// m_pTxtGold->SetText(szText);
|
||||
// }
|
||||
|
||||
Debug.Log($"[Install] Material: {detailedItem.m_tid} from slot {slotIndex}");
|
||||
}
|
||||
|
||||
private void SetInventorySlotGray(Button btn, bool gray)
|
||||
@@ -343,23 +364,19 @@ namespace BrewMonster
|
||||
private void ClearEquipSlot()
|
||||
{
|
||||
m_SelectedEquip?.Freeze(false);
|
||||
m_SelectedMaterial?.Freeze(false);
|
||||
m_SelectedEquip = null;
|
||||
m_FirstInvSlot = -1;
|
||||
m_TxtFirstName.text = "___";
|
||||
ClearSlotIcon(m_SlotFirstParent);
|
||||
|
||||
Debug.Log("[Install] Equipment slot cleared");
|
||||
}
|
||||
|
||||
private void ClearMaterialSlot()
|
||||
{
|
||||
m_SelectedMaterial?.Freeze(false);
|
||||
m_SelectedMaterial = null;
|
||||
m_SecondInvSlot = -1;
|
||||
m_TxtSecondName.text = "___";
|
||||
ClearSlotIcon(m_SlotSecondlParent);
|
||||
|
||||
Debug.Log("[Install] Material slot cleared");
|
||||
}
|
||||
|
||||
private void ClearSlotIcon(Transform slot)
|
||||
@@ -385,8 +402,8 @@ namespace BrewMonster
|
||||
if( nMoney > pHost.GetMoneyAmount() )
|
||||
{
|
||||
message = GetGameUIMan().GetStringFromTable(226);
|
||||
Debug.LogError(message);
|
||||
// GetGameUIMan()->MessageBox("", GetGameUIMan().GetStringFromTable(226), MB_OK,
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().GetDialog("")
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox->SetLife(3);
|
||||
return;
|
||||
@@ -396,7 +413,7 @@ namespace BrewMonster
|
||||
if( !pIvtrA.IsEquipment() )
|
||||
{
|
||||
message = GetGameUIMan().GetStringFromTable(223);
|
||||
Debug.LogError(message);
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().MessageBox("", GetGameUIMan().GetStringFromTable(223), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox.SetLife(3);
|
||||
@@ -410,7 +427,7 @@ namespace BrewMonster
|
||||
if( pEquipA.GetEmptyHoleNum() <= 0 )
|
||||
{
|
||||
message = GetGameUIMan().GetStringFromTable(224);
|
||||
Debug.LogError(message);
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().MessageBox("", GetGameUIMan()->GetStringFromTable(224), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox.SetLife(3);
|
||||
@@ -421,7 +438,7 @@ namespace BrewMonster
|
||||
if(pIvtrB == null || !pIvtrB.IsEmbeddable() )
|
||||
{
|
||||
message = GetGameUIMan().GetStringFromTable(225);
|
||||
Debug.LogError(message);
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().MessageBox("", GetGameUIMan().GetStringFromTable(225), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox.SetLife(3);
|
||||
@@ -449,7 +466,7 @@ namespace BrewMonster
|
||||
if( nStoneLevel > nEquipLevel )
|
||||
{
|
||||
message = GetGameUIMan().GetStringFromTable(300);
|
||||
Debug.LogError(message);
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().MessageBox("", GetGameUIMan().GetStringFromTable(300), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox.SetLife(3);
|
||||
@@ -464,7 +481,7 @@ namespace BrewMonster
|
||||
pHost.GetPack(InventoryConst.IVTRTYPE_PACK).UnfreezeAllItems();
|
||||
|
||||
message = GetGameUIMan().GetStringFromTable(228);
|
||||
Debug.LogError(message);
|
||||
CECUIManager.Instance.ShowMessageBox("", message);
|
||||
// GetGameUIMan().MessageBox("", GetGameUIMan().GetStringFromTable(228),
|
||||
// MB_OK, A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox.SetLife(3);
|
||||
@@ -484,5 +501,41 @@ namespace BrewMonster
|
||||
// MB_OKCANCEL, A3DCOLORRGBA(255, 255, 255, 160));
|
||||
// }
|
||||
}
|
||||
private void OnClickedCancel()
|
||||
{
|
||||
Show(false);
|
||||
}
|
||||
|
||||
public void ResetInstallUI()
|
||||
{
|
||||
RestoreInventoryColors();
|
||||
|
||||
m_SelectedEquip = null;
|
||||
m_SelectedMaterial = null;
|
||||
|
||||
m_FirstInvSlot = -1;
|
||||
m_SecondInvSlot = -1;
|
||||
|
||||
m_TxtFirstName.text = "___";
|
||||
m_TxtSecondName.text = "___";
|
||||
m_TxtMoney.text = "0";
|
||||
m_install_price = -1;
|
||||
|
||||
ClearSlotIcon(m_SlotFirstParent);
|
||||
ClearSlotIcon(m_SlotSecondlParent);
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void CheckHidePanel(Vector2 screenPos)
|
||||
{
|
||||
if (!RectTransformUtility.RectangleContainsScreenPoint(
|
||||
itemInventoryRoot as RectTransform, screenPos,
|
||||
Camera.main))
|
||||
{
|
||||
if(itemInventoryRoot!=null)
|
||||
itemInventoryRoot.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3406,27 +3406,9 @@ namespace BrewMonster.UI
|
||||
if (pCurNPCEssence.HasValue)
|
||||
{
|
||||
uint npcID = pCurNPCEssence.Value.id;
|
||||
DlgInstall dlgInstall = FindFirstObjectByType<DlgInstall>();
|
||||
if (dlgInstall == null)
|
||||
{
|
||||
CECGameUIMan gameUIMan = GetGameUIMan();
|
||||
DialogScriptTableObject dialogResource = gameUIMan.GetDialogResource();
|
||||
Canvas canvas = gameUIMan.GetCanvas();
|
||||
|
||||
if(dialogResource != null && canvas != null)
|
||||
{
|
||||
GameObject ob = dialogResource.GetPrefabDialog("Win_Enchase");
|
||||
if (ob != null)
|
||||
{
|
||||
dlgInstall = GameObject.Instantiate(ob, canvas.transform).GetComponent<DlgInstall>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dlgInstall != null)
|
||||
{
|
||||
dlgInstall.OpenInstall(npcID);
|
||||
}
|
||||
|
||||
var dlgInstall =GetGameUIMan().GetDialog("Win_Enchase");
|
||||
dlgInstall.Show(true);
|
||||
}
|
||||
//pShow1 = m_pAUIManager.GetDialog("Win_Enchase");
|
||||
//pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts.Skills;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.VisualScripting;
|
||||
using static BrewMonster.SkillArrayWrapper;
|
||||
using UnityEngine;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEditorInternal.Profiling.Memory.Experimental;
|
||||
using BrewMonster.Scripts;
|
||||
|
||||
namespace BrewMonster
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
using BrewMonster.Network;
|
||||
|
||||
namespace BrewMonster.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Attach to the in-game button: sends LOGOUT(1) and returns to Select Role.
|
||||
/// </summary>
|
||||
public class BtnBackToSelectRole : MonoBehaviour
|
||||
{
|
||||
public void OnClick()
|
||||
{
|
||||
UnityGameSession.ReturnToSelectRole();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9aed6caec10d2a44a39e3b9c458c5c5
|
||||
@@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
using BrewMonster.Network;
|
||||
|
||||
namespace BrewMonster.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Attach to the Select Role screen button: sends LOGOUT(0) and returns to Login UI.
|
||||
/// </summary>
|
||||
public class BtnLogoutAccount : MonoBehaviour
|
||||
{
|
||||
public void OnClick()
|
||||
{
|
||||
UnityGameSession.LogoutAccount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 725d0d91266148944894d6c831bf2650
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using CSNetwork.Protocols;
|
||||
using CSNetwork.Protocols.RPCData;
|
||||
using TMPro;
|
||||
@@ -29,19 +30,51 @@ namespace BrewMonster.UI
|
||||
private List<RoleInfo> _roleInfos;
|
||||
private List<RoleInfo> _currentRoles;
|
||||
private RoleInfo _pendingCreatedRole;
|
||||
private bool _loginInProgress;
|
||||
bool isDoneWorldRender = false;
|
||||
bool isDoneNPCRender = false;
|
||||
private SynchronizationContext context;
|
||||
public AudioClip loginBGM;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// Ensure wrapper created early (Tech3C SDK).
|
||||
_ = Tech3CSDKWrapper.Instance;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
Tech3CSDKWrapper.Instance.SetLoginCallback(OnLoginCallback);
|
||||
Tech3CSDKWrapper.Instance.SetLogoutCallback(OnLogoutCallback);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Tech3CSDKWrapper.Instance.RemoveLoginCallback();
|
||||
Tech3CSDKWrapper.Instance.RemoveLogoutCallback();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
AudioManager.Instance.PlayBGM(loginBGM, 1.5f);
|
||||
_loginButton.onClick.AddListener(OnLoginButtonClicked);
|
||||
context = SynchronizationContext.Current;
|
||||
|
||||
// Requirement: Login UI should also have a61 loaded.
|
||||
var world = SceneManager.GetSceneByName("a61");
|
||||
if (!world.IsValid() || !world.isLoaded)
|
||||
{
|
||||
SceneManager.LoadSceneAsync("a61", LoadSceneMode.Additive);
|
||||
}
|
||||
|
||||
_usernameInputField.text = PlayerPrefs.GetString("username", "");
|
||||
_passwordInputField.text = PlayerPrefs.GetString("password", "");
|
||||
|
||||
|
||||
// Default: login UI first, select-role hidden until login succeeds.
|
||||
if (_selectCharacterScreen != null)
|
||||
_selectCharacterScreen.gameObject.SetActive(false);
|
||||
|
||||
ApplyLoginEntry(LogoutFlowState.ConsumeNextLoginEntry());
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
@@ -69,18 +102,86 @@ namespace BrewMonster.UI
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public async void OnLoginButtonClicked()
|
||||
{
|
||||
if (_loginInProgress)
|
||||
{
|
||||
BMLogger.LogWarning("[LoginScreenUI] Login already in progress (ignored click).");
|
||||
return;
|
||||
}
|
||||
|
||||
_loginInProgress = true;
|
||||
if (_loginButton != null) _loginButton.interactable = false;
|
||||
|
||||
// If username or password is empty, use Tech3C SDK login UI.
|
||||
if (string.IsNullOrEmpty(_usernameInputField.text) || string.IsNullOrEmpty(_passwordInputField.text))
|
||||
{
|
||||
// Use Tech3C SDK login UI.
|
||||
bool started = Tech3CSDKWrapper.Instance.Login();
|
||||
if (!started)
|
||||
{
|
||||
// Fallback: manual username/password login (useful in dev if SDK not configured).
|
||||
BMLogger.LogWarning("[LoginScreenUI] Tech3CSDKWrapper.Login() failed, fallback to manual login.");
|
||||
await BeginGameLoginAsync(_usernameInputField.text, _passwordInputField.text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise use manual username/password login.
|
||||
BMLogger.LogError("[LoginScreenUI] Username/password empty.");
|
||||
await BeginGameLoginAsync(_usernameInputField.text, _passwordInputField.text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task BeginGameLoginAsync(string username, string password)
|
||||
{
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
|
||||
{
|
||||
BMLogger.LogError("[LoginScreenUI] Username/password empty.");
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null) _loginButton.interactable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
BMLogger.Log("OnLoginButtonClicked");
|
||||
string username = _usernameInputField.text;
|
||||
string password = _passwordInputField.text;
|
||||
// UnityGameSession.SetConnectionInfo("103.182.22.52", 29000);
|
||||
UnityGameSession.SetConnectionInfo("103.51.120.195", 29000);
|
||||
PlayerPrefs.SetString("username", username);
|
||||
PlayerPrefs.SetString("password", password);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
BMLogger.Log($"[LoginScreenUI] Connecting+login start user='{username}'");
|
||||
await UnityGameSession.Login(username, password, OnLoginComplete);
|
||||
_selectCharacterScreen.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply how LoginScene should look after a logout flow.
|
||||
/// Call this when LoginScene is already loaded (additive) and you need to switch UI without reloading the scene.
|
||||
/// </summary>
|
||||
public void ApplyLoginEntry(BrewMonster.Network.LogoutFlowState.LoginEntryTarget entry)
|
||||
{
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null) _loginButton.interactable = true;
|
||||
|
||||
// Always refresh fields from PlayerPrefs (LogoutAccount clears them).
|
||||
if (_usernameInputField != null) _usernameInputField.text = PlayerPrefs.GetString("username", "");
|
||||
if (_passwordInputField != null) _passwordInputField.text = PlayerPrefs.GetString("password", "");
|
||||
|
||||
if (_selectCharacterScreen != null)
|
||||
_selectCharacterScreen.gameObject.SetActive(false);
|
||||
|
||||
if (entry == BrewMonster.Network.LogoutFlowState.LoginEntryTarget.SelectRole)
|
||||
{
|
||||
// Auto-login to reach Select Role like the original client, without showing Tech3C auth UI again.
|
||||
if (!string.IsNullOrEmpty(_usernameInputField.text) && !string.IsNullOrEmpty(_passwordInputField.text))
|
||||
{
|
||||
BMLogger.Log("[LoginScreenUI] Auto-login triggered (return-to-select-role).");
|
||||
_loginInProgress = true;
|
||||
if (_loginButton != null) _loginButton.interactable = false;
|
||||
_ = BeginGameLoginAsync(_usernameInputField.text, _passwordInputField.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,12 +190,19 @@ namespace BrewMonster.UI
|
||||
/// </summary>
|
||||
private void OnLoginComplete(bool result)
|
||||
{
|
||||
BMLogger.Log($"[LoginScreenUI] OnLoginComplete result={result}");
|
||||
if (!result)
|
||||
{
|
||||
BMLogger.LogError("Login failed");
|
||||
if (_selectCharacterScreen != null)
|
||||
_selectCharacterScreen.gameObject.SetActive(false);
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null) _loginButton.interactable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_selectCharacterScreen != null)
|
||||
_selectCharacterScreen.gameObject.SetActive(true);
|
||||
UnityGameSession.GetRoleListAsync(OnGetRoleListComplete);
|
||||
}
|
||||
|
||||
@@ -108,6 +216,8 @@ namespace BrewMonster.UI
|
||||
{
|
||||
BMLogger.LogError("OnGetRoleListComplete: roleInfos is null");
|
||||
// Keep whatever is currently shown; don't overwrite UI state with null.
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null) _loginButton.interactable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,6 +252,9 @@ namespace BrewMonster.UI
|
||||
BMLogger.Log($"OnGetRoleListComplete: roles={roleInfos.Count}");
|
||||
_roleInfos = roleInfos;
|
||||
_currentRoles = roleInfos;
|
||||
|
||||
// Login flow finished; keep login button disabled (origin-like) once you're at select role.
|
||||
_loginInProgress = false;
|
||||
}
|
||||
|
||||
private void OnClickSelectCharacter(RoleInfo roleInfo)
|
||||
@@ -278,5 +391,38 @@ namespace BrewMonster.UI
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private async void OnLoginCallback(int errorCode, string userId, string password)
|
||||
{
|
||||
if (errorCode == 0)
|
||||
{
|
||||
BMLogger.Log($"Login success -- userId: {userId} - {password}");
|
||||
// UnityGameSession.SetConnectionInfo("103.182.22.52", 29000);
|
||||
UnityGameSession.SetConnectionInfo("103.51.120.195", 29000);
|
||||
PlayerPrefs.SetString("username", userId);
|
||||
PlayerPrefs.SetString("password", password);
|
||||
PlayerPrefs.Save();
|
||||
await BeginGameLoginAsync(userId, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it failed, the userId will be the error message
|
||||
BMLogger.LogError($"Login failed -- errorCode: {errorCode}: {userId}");
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null) _loginButton.interactable = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLogoutCallback(int errorCode, string errorMessage)
|
||||
{
|
||||
if (errorCode == 0)
|
||||
{
|
||||
BMLogger.Log("Logout success");
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.LogError($"Logout failed -- errorCode: {errorCode}: {errorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f45408c4c89289d498475d0e1e1e5b7e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application>
|
||||
<!--Used when Application Entry is set to Activity, otherwise remove this activity block-->
|
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity"
|
||||
android:theme="@style/Tech3CTheme.LoginGame">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
<!--Used when Application Entry is set to GameActivity, otherwise remove this activity block-->
|
||||
<activity android:name="com.unity3d.player.UnityPlayerGameActivity"
|
||||
android:theme="@style/BaseUnityGameActivityTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
<meta-data android:name="android.app.lib_name" android:value="game" />
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11f5d7426047d6048a47d330b02103d9
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
|
||||
// See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
|
||||
// See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
|
||||
// To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
|
||||
id 'com.android.application' version '7.4.2' apply false
|
||||
id 'com.android.library' version '7.4.2' apply false
|
||||
**BUILD_SCRIPT_DEPS**
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7736ab544ec5cab4a89af84ac45b5a75
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: '../shared/keepUnitySymbols.gradle'
|
||||
**APPLY_PLUGINS**
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "androidx.appcompat:appcompat:1.6.1"
|
||||
implementation "com.google.android.material:material:1.11.0"
|
||||
**DEPS**}
|
||||
|
||||
android {
|
||||
ndkVersion "**NDKVERSION**"
|
||||
namespace "com.unity3d.player"
|
||||
ndkPath "**NDKPATH**"
|
||||
compileSdk **APIVERSION**
|
||||
buildToolsVersion '**BUILDTOOLS**'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
**DEFAULT_CONFIG_SETUP**
|
||||
minSdk **MINSDK**
|
||||
targetSdk **TARGETSDK**
|
||||
ndk {
|
||||
debugSymbolLevel **DEBUGSYMBOLLEVEL**
|
||||
abiFilters **ABIFILTERS**
|
||||
}
|
||||
versionCode **VERSIONCODE**
|
||||
versionName '**VERSIONNAME**'
|
||||
consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD**
|
||||
}
|
||||
|
||||
lint {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
androidResources {
|
||||
noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
|
||||
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
|
||||
}**PACKAGING**
|
||||
}
|
||||
**IL_CPP_BUILD_SETUP**
|
||||
**SOURCE_BUILD_SETUP**
|
||||
**EXTERNAL_SOURCES**
|
||||
@@ -0,0 +1,47 @@
|
||||
apply plugin: 'com.android.library'
|
||||
**APPLY_PLUGINS**
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "androidx.appcompat:appcompat:1.6.1"
|
||||
implementation "com.google.android.material:material:1.11.0"
|
||||
**DEPS**}
|
||||
|
||||
android {
|
||||
namespace "com.unity3d.player"
|
||||
ndkPath "**NDKPATH**"
|
||||
compileSdkVersion **APIVERSION**
|
||||
buildToolsVersion '**BUILDTOOLS**'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion **MINSDKVERSION**
|
||||
targetSdkVersion **TARGETSDKVERSION**
|
||||
ndk {
|
||||
abiFilters **ABIFILTERS**
|
||||
}
|
||||
versionCode **VERSIONCODE**
|
||||
versionName '**VERSIONNAME**'
|
||||
consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD**
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
|
||||
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
|
||||
}**PACKAGING_OPTIONS**
|
||||
}
|
||||
**IL_CPP_BUILD_SETUP**
|
||||
**SOURCE_BUILD_SETUP**
|
||||
**EXTERNAL_SOURCES**
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3bedb9070cd041a2bb8a27d9751aada
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 950fdc575e5b3b74ea1d3f1c60322d4f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1660,7 +1660,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: 10000000000000
|
||||
m_text: 0
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
@@ -10577,6 +10577,7 @@ MonoBehaviour:
|
||||
m_BtnMerge: {fileID: 8208092408021918524}
|
||||
m_BtnCancel: {fileID: 4503836757578509720}
|
||||
khung_item: {fileID: 21300000, guid: a5366f3bce011c046902e39b6bd3a077, type: 3}
|
||||
itemInventoryRoot: {fileID: 7750009739432212686}
|
||||
--- !u!1 &5641506892578507279
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14989,7 +14990,7 @@ MonoBehaviour:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 2206910701173095729}
|
||||
m_TargetAssemblyTypeName: BrewMonster.DlgInstall, Assembly-CSharp
|
||||
m_MethodName: CloseInstall
|
||||
m_MethodName: ResetInstallUI
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
|
||||
@@ -142,7 +142,7 @@ RectTransform:
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0.0009808608, y: -0.00012207031}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: -474.1602, y: -682.9546}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!114 &8239567059120679520
|
||||
MonoBehaviour:
|
||||
@@ -504,7 +504,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &5968911800527563993
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -580,7 +580,7 @@ MonoBehaviour:
|
||||
characterItemPrefab: {fileID: 5263746738484752443, guid: 726ee9eade6587245ac1b55d2335e9b9, type: 3}
|
||||
addCharacterItemPrefab: {fileID: 5263746738484752443, guid: a0b31ed0940ec9942b243a0b8cec8ad3, type: 3}
|
||||
parentItems: {fileID: 2643174602035272289}
|
||||
createCharacterButton: {fileID: 0}
|
||||
createCharacterButton: {fileID: 2685968509838782728}
|
||||
createCharacterScreen: {fileID: 0}
|
||||
--- !u!1 &7510180475820570348
|
||||
GameObject:
|
||||
@@ -594,6 +594,7 @@ GameObject:
|
||||
- component: {fileID: 8869589995078313987}
|
||||
- component: {fileID: 1038588709929429120}
|
||||
- component: {fileID: 1166159884785039946}
|
||||
- component: {fileID: 1481527591792018053}
|
||||
m_Layer: 5
|
||||
m_Name: back_btn
|
||||
m_TagString: Untagged
|
||||
@@ -701,7 +702,31 @@ MonoBehaviour:
|
||||
m_TargetGraphic: {fileID: 1038588709929429120}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1481527591792018053}
|
||||
m_TargetAssemblyTypeName: BrewMonster.UI.BtnLogoutAccount, Assembly-CSharp
|
||||
m_MethodName: OnClick
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!114 &1481527591792018053
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7510180475820570348}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 725d0d91266148944894d6c831bf2650, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &7885375190050319286
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
+224
-73
@@ -802,19 +802,26 @@ namespace BrewMonster
|
||||
if (pCmd.cooldown_index == (int)CoolTimeIndex.GP_CT_CAST_ELF_SKILL)
|
||||
{
|
||||
int i;
|
||||
// other goblin skills should be set public cool down, 1 second
|
||||
/* for (i = 0; i < m_aGoblinSkills.GetSize(); i++)
|
||||
{
|
||||
if (m_aGoblinSkills[i] && m_aGoblinSkills[i]->GetCoolingCnt() == 0)
|
||||
m_aGoblinSkills[i]->StartCooling(GetCoolTime(GP_CT_CAST_ELF_SKILL), GetCoolTime(GP_CT_CAST_ELF_SKILL));
|
||||
}*/
|
||||
for (i = 0; i < m_aGoblinSkills.Count; i++)
|
||||
{
|
||||
if (m_aGoblinSkills[i] != null && m_aGoblinSkills[i].GetCoolingCnt() == 0)
|
||||
{
|
||||
int fakeRef = 0;
|
||||
int coolTime = GetCoolTime((int)CoolTimeIndex.GP_CT_CAST_ELF_SKILL, out fakeRef);
|
||||
m_aGoblinSkills[i].StartCooling(coolTime, coolTime);
|
||||
}
|
||||
}
|
||||
|
||||
/* for (i = 0; i < m_aPsSkills.Count; i++)
|
||||
{
|
||||
CECSkill pSkill = GetPassiveSkillByIndex(i);
|
||||
if (pSkill && (pSkill->GetCommonCoolDown() & (1 << (pCmd->cooldown_index - GP_CT_SKILLCOMMONCOOLDOWN0))))
|
||||
pSkill->StartCooling(GetCoolTime(pCmd->cooldown_index), GetCoolTime(pCmd->cooldown_index));
|
||||
}*/
|
||||
for (i = 0; i < m_aPsSkills.Count; i++)
|
||||
{
|
||||
CECSkill pSkill = GetPassiveSkillByIndex(i);
|
||||
if (pSkill != null && (pSkill.GetCommonCoolDown() & (1 << (pCmd.cooldown_index - (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN0))) != 0)
|
||||
{
|
||||
int fakeRef = 0;
|
||||
int coolTime = GetCoolTime(pCmd.cooldown_time, out fakeRef);
|
||||
pSkill.StartCooling(coolTime, coolTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pCmd.cooldown_index >= (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN0 && pCmd.cooldown_index <= (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN4)
|
||||
@@ -826,7 +833,11 @@ namespace BrewMonster
|
||||
CECSkill pSkill = GetPositiveSkillByIndex(i);
|
||||
int fakeRef = 0;
|
||||
if (pSkill != null && (pSkill.GetCommonCoolDown() & mask) != 0)
|
||||
pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index, out fakeRef), GetCoolTime(pCmd.cooldown_index, out fakeRef));
|
||||
{
|
||||
int coolTime = GetCoolTime(pCmd.cooldown_index, out fakeRef);
|
||||
pSkill.StartCooling(coolTime, coolTime);
|
||||
//pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index, out fakeRef), GetCoolTime(pCmd.cooldown_index, out fakeRef));
|
||||
}
|
||||
}
|
||||
/*const std::map<unsigned int, CECSkill*>&inherentSkillMap = CECComboSkillState::Instance().GetInherentSkillMap();
|
||||
std::map < unsigned int, CECSkill*>::const_iterator it;
|
||||
@@ -849,7 +860,9 @@ namespace BrewMonster
|
||||
}
|
||||
ct.iCurTime = pCmd.cooldown_time;
|
||||
ct.iMaxTime = pCmd.cooldown_time;
|
||||
Math.Clamp(ct.iCurTime, 0, ct.iMaxTime);
|
||||
ct.iCurTime = Math.Clamp(ct.iCurTime, 0, ct.iMaxTime);
|
||||
m_skillCoolTime[idSkill] = ct;
|
||||
//Math.Clamp(ct.iCurTime, 0, ct.iMaxTime);
|
||||
|
||||
CECSkill pSkill = GetNormalSkill(idSkill);
|
||||
if (pSkill != null)
|
||||
@@ -864,6 +877,18 @@ namespace BrewMonster
|
||||
{
|
||||
BMLogger.LogError("HoangDev: pSkill " + pSkill);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSkill = CECComboSkillState.Instance.GetInherentSkillByID((uint)idSkill);
|
||||
if (pSkill != null)
|
||||
{
|
||||
pSkill.StartCooling(pCmd.cooldown_time, pCmd.cooldown_time);
|
||||
}
|
||||
else if (GetEquipSkillByID(idSkill) == null)
|
||||
{
|
||||
Debug.LogWarning($"OnMsgHstSetCoolTime: Skill {idSkill} not found in nomal/equip skills");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -874,6 +899,11 @@ namespace BrewMonster
|
||||
UpdateEquipSkillCoolDown(pCmd.cooldown_index);
|
||||
}
|
||||
|
||||
private CECSkill GetPassiveSkillByIndex(int n)
|
||||
{
|
||||
return m_aPsSkills[n];
|
||||
}
|
||||
|
||||
private void OnMsgHstCoolTimeData(ECMSG Msg)
|
||||
{
|
||||
cmd_cooltime_data pCmd = default;
|
||||
@@ -7493,16 +7523,97 @@ namespace BrewMonster
|
||||
CECGameRun pGameRun = EC_Game.GetGameRun();
|
||||
//CECGameSession pSession = g_pGame.GetGameSession();
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_FIREWORK)
|
||||
{
|
||||
if (GetProfession() == (int)PROFESSION.PROF_GHOST && IsInvisible())
|
||||
{
|
||||
if (showMsg)
|
||||
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_WHEN_INVISIBLE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_INCSKILLABILITY)
|
||||
{
|
||||
EC_IvtrIncSkillAbility pIncSkill = pItem as EC_IvtrIncSkillAbility;
|
||||
//if (pIncSkill != null)
|
||||
//{
|
||||
// var pDBEssence = pIncSkill.GetDBEssence();
|
||||
// CECSkill pSkill = GetNormalSkill(pDBEssence.id_skill);
|
||||
// if (pSkill != null)
|
||||
// {
|
||||
// if (pSkill.GetSkillLevel() != pDBEssence.level_required)
|
||||
// {
|
||||
// if (showMsg)
|
||||
// pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_PRODUCE_LEVEL_INVALID);
|
||||
// return false;
|
||||
// }
|
||||
// if (GetSkillAbilityPercent(pDBEssence.id_skill) >= 100)
|
||||
// {
|
||||
// if (showMsg)
|
||||
// pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_PRODUCE_ABILITY_FULL);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TRANSMITSCROLL)
|
||||
{
|
||||
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI != null && !IsFighting())
|
||||
{
|
||||
// TODO: Implement travel map dialog
|
||||
//CDlgWorldMap* pMap = (CDlgWorldMap*)pGameUI->GetDialog("Win_WorldMapTravel");
|
||||
//pMap->BuildTravelMap(DT_TRANSMITSCROLL_ESSENCE, (void*)iSlot);
|
||||
//pMap->Show(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_SHOPTOKEN)
|
||||
{
|
||||
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI != null && !IsFighting())
|
||||
{
|
||||
//CDlgTokenShop* pDlg = dynamic_cast<CDlgTokenShop*>(pGameUI->GetDialog("Win_TokenShop"));
|
||||
//if (pDlg)
|
||||
//{
|
||||
// pDlg->InitTokenShopItem(pItem->GetTemplateID());
|
||||
// pDlg->Show(!pDlg->IsShow());
|
||||
//}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_UNIVERSAL_TOKEN)
|
||||
{
|
||||
// TODO: Implement universal token when available
|
||||
EC_IvtrUniversalToken pUniversalToken = pItem as EC_IvtrUniversalToken;
|
||||
//if (pUniversalToken != null && pUniversalToken.HasAnyUsage())
|
||||
//{
|
||||
// CECUseUniversalTokenCommandManager.Instance.Use(pUniversalToken, pUniversalToken.UsageIndexAt(0));
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TASKDICE)
|
||||
{
|
||||
EC_IvtrTaskDice pTaskDice = pItem as EC_IvtrTaskDice;
|
||||
if (pTaskDice != null)
|
||||
{
|
||||
if (pTaskDice != null)
|
||||
{
|
||||
if (IsFlying() && pTaskDice.GetDBEssence().no_use_in_combat == 1)
|
||||
{
|
||||
if(showMsg)
|
||||
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_IN_BATTLE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TARGETITEM)
|
||||
{
|
||||
EC_IvtrTargetItem pTargetItem = pItem as EC_IvtrTargetItem;
|
||||
@@ -7521,7 +7632,7 @@ namespace BrewMonster
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pTargetItem.GetDBEssence().use_in_sanctuary_only != 0 && !IsInSanctuary())
|
||||
if (essence.use_in_sanctuary_only != 0 && !IsInSanctuary())
|
||||
{
|
||||
if (showMsg)
|
||||
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_USE_IN_SANCTUARY_ONLY);
|
||||
@@ -7662,6 +7773,24 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pSkill.GetType() == (int)CECSkill.SkillType.TYPE_BLESS)
|
||||
{
|
||||
// TODO: Implement pet blessing when petsystem is available
|
||||
//CECSCPet pPet = EC_Game.GetGameRun().GetWorld().GetPetByID(m_idSelTarget);
|
||||
//if (pPet == null || pPet.GetMasterID() == GetCharacterID())
|
||||
//{
|
||||
// CECPetData pPetData = m_pPetCorral.GetActivePet();
|
||||
// if (pPetData == null ||
|
||||
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_COMBAT &&
|
||||
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_SUMMON &&
|
||||
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
|
||||
// return false;
|
||||
|
||||
// idCastTarget = m_pPetCorral.GetActivePetNPCID();
|
||||
//}
|
||||
//if(iTargetType != 0 && idCastTarget == 0)
|
||||
// return false;
|
||||
}
|
||||
|
||||
if (iTargetType != 0)
|
||||
{
|
||||
@@ -7684,9 +7813,8 @@ namespace BrewMonster
|
||||
|
||||
if (!pSkill.IsInstant() && pSkill.GetType() != (int)CECSkill.SkillType.TYPE_FLASHMOVE)
|
||||
{
|
||||
// TODO: Implement NaturallyStopMoving
|
||||
//if (!NaturallyStopMoving())
|
||||
// return false;
|
||||
if (!NaturallyStopMoving())
|
||||
return false;
|
||||
}
|
||||
else if (pSkill.GetType() == (int)CECSkill.SkillType.TYPE_FLASHMOVE)
|
||||
{
|
||||
@@ -7749,6 +7877,16 @@ namespace BrewMonster
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_DYNSKILLEQUIP)
|
||||
{
|
||||
int iSameIDPos = m_pEquipPack.FindItem(pItem.GetTemplateID());
|
||||
if (iSameIDPos >= 0)
|
||||
{
|
||||
iDst = iSameIDPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_ARROW ||
|
||||
pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_DYNSKILLEQUIP)
|
||||
{
|
||||
@@ -7757,6 +7895,7 @@ namespace BrewMonster
|
||||
UnityGameSession.RequestEquipItemAsync((byte)iSlot, (byte)iDst, null);
|
||||
else
|
||||
{
|
||||
// TODO: Implement c2s_CmdMoveItemToEquip when available
|
||||
//UnityGameSession.c2s_CmdMoveItemToEquip((byte)iSlot, (byte)iDst);
|
||||
}
|
||||
}
|
||||
@@ -7765,6 +7904,11 @@ namespace BrewMonster
|
||||
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD)
|
||||
{
|
||||
//TODO: Add general card equip request
|
||||
EC_IvtrGeneralCard pCard = pItem as EC_IvtrGeneralCard;
|
||||
if (pCard != null)
|
||||
{
|
||||
iDst = InventoryConst.EQUIPIVTR_GENERALCARD1 + pCard.GetEssence().type;
|
||||
}
|
||||
}
|
||||
UnityGameSession.RequestEquipItemAsync((byte)iSlot, (byte)iDst, null);
|
||||
}
|
||||
@@ -7826,19 +7970,21 @@ namespace BrewMonster
|
||||
|
||||
float fDist = 0, fTargetRag = 0;
|
||||
CECObject pObject = null;
|
||||
//if (CalcDist(m_idSelTarget, ref fDist, ref pObject))
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
if (CalcDist(m_idSelTarget, out fDist, out pObject))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(m_idSelTarget))
|
||||
{
|
||||
pObject = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(m_idSelTarget);
|
||||
CECNPC pNPC = pObject as CECNPC;
|
||||
if (pNPC != null)
|
||||
fTargetRag = pNPC.GetTouchRadius();
|
||||
}
|
||||
else if (GPDataTypeHelper.ISPLAYERID(m_idSelTarget))
|
||||
{
|
||||
pObject = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_idSelTarget);
|
||||
EC_ElsePlayer pPlayer = pObject as EC_ElsePlayer;
|
||||
if (pPlayer != null)
|
||||
fTargetRag = pPlayer.GetTouchRadius();
|
||||
@@ -7869,6 +8015,7 @@ namespace BrewMonster
|
||||
if (showMsg)
|
||||
{
|
||||
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
|
||||
//pGameUI.MessageBox("", pGameUI.GetStringFromTable(828), MB_OK, new Color32(1, 1, 1, 0.6));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -7891,14 +8038,12 @@ namespace BrewMonster
|
||||
EC_Inventory pPack = GetPack(pCmd.byPackage);
|
||||
if (pPack == null)
|
||||
{
|
||||
Debug.LogError("[OnMsgHstUseItem] Pack not found");
|
||||
return;
|
||||
}
|
||||
|
||||
EC_IvtrItem pItem = pPack.GetItem(pCmd.bySlot, false);
|
||||
if (pItem == null || pItem.GetTemplateID() != pCmd.item_id)
|
||||
{
|
||||
Debug.LogError($"[OnMsgHstUseItem] Item mismatch at slot {pCmd.bySlot}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7911,12 +8056,12 @@ namespace BrewMonster
|
||||
{
|
||||
if (pPack.GetItem(pCmd.bySlot, false) == null)
|
||||
{
|
||||
Debug.Log($"[OnMsgHstUseItem] Item {pCmd.item_id} removed from slot {pCmd.bySlot}");
|
||||
//Debug.Log($"[OnMsgHstUseItem] Item {pCmd.item_id} removed from slot {pCmd.bySlot}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[OnMsgHstUseItem] Failed to remove item {pCmd.item_id} from slot {pCmd.bySlot}");
|
||||
//Debug.LogError($"[OnMsgHstUseItem] Failed to remove item {pCmd.item_id} from slot {pCmd.bySlot}");
|
||||
}
|
||||
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
@@ -7927,7 +8072,7 @@ namespace BrewMonster
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[OnMsgHstUseItem] EC_InventoryUI not found, UI may not update");
|
||||
//Debug.LogError("[OnMsgHstUseItem] EC_InventoryUI not found, UI may not update");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7944,58 +8089,64 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate distance to an object and optionally retrieve the object reference
|
||||
/// 计算到对象的距离,并可选地获取对象引用
|
||||
/// </summary>
|
||||
/// <param name="idObject">Target object ID / 目标对象ID</param>
|
||||
/// <param name="pfDist">Output distance / 输出距离</param>
|
||||
/// <param name="ppObject">Output object reference (optional) / 输出对象引用(可选)</param>
|
||||
/// <returns>True if calculation succeeded / 计算成功返回true</returns>
|
||||
//public bool CalcDist(int idObject, ref float pfDist, out CECObject ppObject)
|
||||
//{
|
||||
// ppObject = null;
|
||||
// <summary>
|
||||
// Calculate distance to an object and optionally retrieve the object reference
|
||||
// 计算到对象的距离,并可选地获取对象引用
|
||||
// </summary>
|
||||
// <param name="idObject">Target object ID / 目标对象ID</param>
|
||||
// <param name="pfDist">Output distance / 输出距离</param>
|
||||
// <param name="ppObject">Output object reference (optional) / 输出对象引用(可选)</param>
|
||||
// <returns>True if calculation succeeded / 计算成功返回true</returns>
|
||||
public bool CalcDist(int idObject, out float pfDist, out CECObject ppObject)
|
||||
{
|
||||
pfDist = 0.0f;
|
||||
ppObject = null;
|
||||
|
||||
// if (idObject == 0 || idObject == m_PlayerInfo.cid)
|
||||
// return false;
|
||||
if (idObject == 0 || idObject == m_PlayerInfo.cid)
|
||||
return false;
|
||||
|
||||
// CECObject pObject = CECGameRun.Instance.GetWorld()?.GetObject(idObject, 1);
|
||||
// if (pObject == null)
|
||||
// return false;
|
||||
CECWorld pWorld = CECGameRun.Instance.GetWorld();
|
||||
if(pWorld == null)
|
||||
return false;
|
||||
|
||||
// ppObject = pObject;
|
||||
// float fDist = 0.0f;
|
||||
CECObject pObject = pWorld.GetObject(idObject, 1);
|
||||
if(ppObject == null)
|
||||
return false;
|
||||
|
||||
// if (ISNPCID(idObject))
|
||||
// {
|
||||
// CECNPC pNPC = (CECNPC)pObject;
|
||||
// fDist = pNPC.CalcDist(GetPos(), true);
|
||||
// }
|
||||
// else if (ISPLAYERID(idObject))
|
||||
// {
|
||||
// Debug.Assert(pObject.GetClassID() == CECObject.OCID_ELSEPLAYER);
|
||||
// EC_ElsePlayer pPlayer = (EC_ElsePlayer)pObject;
|
||||
// fDist = pPlayer.CalcDist(GetPos(), true);
|
||||
// }
|
||||
// else if (ISMATTERID(idObject))
|
||||
// {
|
||||
// Debug.Assert(pObject.GetClassID() == CECObject.OCID_MATTER);
|
||||
// CECMatter pMatter = (CECMatter)pObject;
|
||||
// fDist = (pMatter.GetPos() - GetPos()).magnitude;
|
||||
// }
|
||||
// else
|
||||
// return false;
|
||||
ppObject = pObject;
|
||||
float fDist = 0.0f;
|
||||
|
||||
// pfDist = fDist;
|
||||
// return true;
|
||||
//}
|
||||
if (GPDataTypeHelper.ISNPCID(idObject))
|
||||
{
|
||||
CECNPC pNPC = pObject as CECNPC;
|
||||
if (pNPC == null)
|
||||
return false;
|
||||
fDist = pNPC.CalcDist(GetPos(), true);
|
||||
}
|
||||
else if (GPDataTypeHelper.ISMATTERID(idObject))
|
||||
{
|
||||
Debug.Assert(pObject.GetClassID() == Class_ID.OCID_MATTER);
|
||||
CECMatter pMatter = pObject as CECMatter;
|
||||
if (pMatter == null)
|
||||
return false;
|
||||
A3DVECTOR3 vDelta = pMatter.GetPos() - GetPos();
|
||||
fDist = A3d_Magnitude(vDelta);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//// Helper method overload without object output
|
||||
//public bool CalcDist(int idObject, ref float pfDist)
|
||||
//{
|
||||
// CECObject pObject;
|
||||
// return CalcDist(idObject, ref pfDist, out pObject);
|
||||
//}
|
||||
pfDist = fDist;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper method overload without object output
|
||||
public bool CalcDist(int idObject, out float pfDist)
|
||||
{
|
||||
CECObject pObject;
|
||||
return CalcDist(idObject, out pfDist, out pObject);
|
||||
}
|
||||
|
||||
//// ID checking helper methods
|
||||
//private bool ISNPCID(int id) => ((id & 0x80000000) != 0) && ((id & 0x40000000) == 0);
|
||||
|
||||
@@ -4,6 +4,7 @@ using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UIElements;
|
||||
@@ -109,7 +110,12 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
|
||||
if (msgBox != null)
|
||||
{
|
||||
msgBox.ShowMessageBox(title, message);
|
||||
msgBox.ShowMessageBox(new MessageBoxData()
|
||||
{
|
||||
Title = title,
|
||||
Message = message,
|
||||
MessageBoxType = MessageBoxType.YesButton
|
||||
});
|
||||
return msgBox;
|
||||
}
|
||||
else
|
||||
@@ -230,6 +236,25 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
}
|
||||
|
||||
}
|
||||
else if(string.CompareOrdinal("Game_Disenchase",pDlg.GetName())==0 && DialogBoxCommandIDs.IDOK == iRetVal)
|
||||
{
|
||||
// PAUIDIALOG pMsgBox;
|
||||
var clearEmbeddedChipDlg = GetInGameUIMan().GetDialog("Game_Disenchase");
|
||||
// EC_IvtrItem pIvtr = (EC_IvtrItem)m_pDlgUninstall->m_pItema->GetDataPtr("ptr_CECIvtrItem");
|
||||
//
|
||||
// pSession.c2s_CmdNPCSevClearEmbeddedChip(
|
||||
// (WORD)m_pDlgUninstall->m_pItema->GetData(), pIvtr->GetTemplateID());
|
||||
//
|
||||
// m_pDlgUninstall->Show(false);
|
||||
// pHost->EndNPCService();
|
||||
// m_pCurNPCEssence = NULL;
|
||||
// m_pDlgInventory->Show(false);
|
||||
// pHost->GetPack(IVTRTYPE_PACK)->UnfreezeAllItems();
|
||||
//
|
||||
// MessageBox("", GetStringFromTable(228), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox->SetLife(3);
|
||||
}
|
||||
}
|
||||
|
||||
private bool OnNewMessageBox(int iRetVal)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86378052e9798924e8ee14f4fa780f0f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c935d070fff35741adebc5424c4e02b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2111256da5c2b2a469d98ce0f103cdb7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,184 @@
|
||||
package vn.tech3c.sdk.unity;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import vn.tech3c.sdk.auth.callback.OnAuthCallback;
|
||||
import vn.tech3c.sdk.auth.controller.Tech3CIdController;
|
||||
import vn.tech3c.sdk.auth.entities.enums.LoginType;
|
||||
import vn.tech3c.sdk.auth.exceptions.Tech3CIdException;
|
||||
|
||||
import com.unity3d.player.UnityPlayer;
|
||||
|
||||
/**
|
||||
* Unity Bridge for Tech3C SDK
|
||||
* This class receives callbacks from Tech3C SDK and sends them to Unity via UnitySendMessage
|
||||
*/
|
||||
public class Tech3CUnityBridge implements OnAuthCallback {
|
||||
private static final String TAG = "Tech3CUnityBridge";
|
||||
private static final String UNITY_GAME_OBJECT = "Tech3CSDKBridge";
|
||||
|
||||
private static Tech3CUnityBridge instance;
|
||||
|
||||
private OnUnityAuthCallback unityAuthCallback;
|
||||
private OnUnityLogoutCallback unityLogoutCallback;
|
||||
private OnUnityUserInfoCallback unityUserInfoCallback;
|
||||
|
||||
// Singleton
|
||||
public static synchronized Tech3CUnityBridge getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new Tech3CUnityBridge();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Interfaces for Unity callbacks
|
||||
public interface OnUnityAuthCallback {
|
||||
void onAuthSuccess(String userId, String password, String accessToken, String refreshToken, LoginType loginType, long expiryTime);
|
||||
void onAuthCancelled();
|
||||
void onAuthError(int errorCode, String errorMessage);
|
||||
}
|
||||
|
||||
public interface OnUnityLogoutCallback {
|
||||
void onLogoutSuccess();
|
||||
void onLogoutError(int errorCode, String errorMessage);
|
||||
}
|
||||
|
||||
public interface OnUnityUserInfoCallback {
|
||||
void onUserInfoReceived(String userId, String username, String email, String phone);
|
||||
void onUserInfoCancelled();
|
||||
void onUserInfoError(int errorCode, String errorMessage);
|
||||
}
|
||||
|
||||
// Set callbacks
|
||||
public void setUnityAuthCallback(OnUnityAuthCallback callback) {
|
||||
this.unityAuthCallback = callback;
|
||||
}
|
||||
|
||||
public void setUnityLogoutCallback(OnUnityLogoutCallback callback) {
|
||||
this.unityLogoutCallback = callback;
|
||||
}
|
||||
|
||||
public void setUnityUserInfoCallback(OnUnityUserInfoCallback callback) {
|
||||
this.unityUserInfoCallback = callback;
|
||||
}
|
||||
|
||||
// Send message to Unity
|
||||
private void sendToUnity(String methodName, String message) {
|
||||
try {
|
||||
UnityPlayer.UnitySendMessage(UNITY_GAME_OBJECT, methodName, message);
|
||||
Log.d(TAG, "Sent to Unity: " + methodName + " - " + message);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error sending to Unity: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ========== OnAuthCallback Implementation ==========
|
||||
|
||||
@Override
|
||||
public void onLoginSuccess(String userId, String password, String accessToken, String refreshToken, LoginType loginType, long expiryTime) {
|
||||
Log.d(TAG, "onLoginSuccess: " + userId);
|
||||
|
||||
// Send to Unity
|
||||
String message = userId + "|" + password + "|" + accessToken + "|" + refreshToken + "|" + loginType.name() + "|" + expiryTime;
|
||||
sendToUnity("OnAuthSuccess", message);
|
||||
|
||||
// Also call Unity callback if set
|
||||
if (unityAuthCallback != null) {
|
||||
unityAuthCallback.onAuthSuccess(userId, password, accessToken, refreshToken, loginType, expiryTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegisterSuccess(String accessToken, String refreshToken, String userId, long expiryTime) {
|
||||
Log.d(TAG, "onRegisterSuccess: " + userId);
|
||||
|
||||
// Treat register success as auth success (password is empty for register)
|
||||
String message = userId + "|" + "" + "|" + accessToken + "|" + refreshToken + "|REGISTER|" + expiryTime;
|
||||
sendToUnity("OnAuthSuccess", message);
|
||||
|
||||
if (unityAuthCallback != null) {
|
||||
unityAuthCallback.onAuthSuccess(userId, "", accessToken, refreshToken, LoginType.ACCOUNT, expiryTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthCancelled() {
|
||||
Log.d(TAG, "onAuthCancelled");
|
||||
sendToUnity("OnAuthCancelled", "");
|
||||
|
||||
if (unityAuthCallback != null) {
|
||||
unityAuthCallback.onAuthCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthScreenOpened() {
|
||||
Log.d(TAG, "onAuthScreenOpened");
|
||||
// Optional: Send to Unity if needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Tech3CIdException exception) {
|
||||
Log.d(TAG, "onError: " + exception.getMessage());
|
||||
|
||||
String message = exception.getErrorCode() + "|" + exception.getMessage();
|
||||
sendToUnity("OnAuthError", message);
|
||||
|
||||
if (unityAuthCallback != null) {
|
||||
unityAuthCallback.onAuthError(exception.getErrorCode(), exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ========== Additional Callback Methods ==========
|
||||
|
||||
public void onLogoutSuccess() {
|
||||
Log.d(TAG, "onLogoutSuccess");
|
||||
sendToUnity("OnLogoutSuccess", "");
|
||||
|
||||
if (unityLogoutCallback != null) {
|
||||
unityLogoutCallback.onLogoutSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
public void onLogoutError(int errorCode, String errorMessage) {
|
||||
Log.d(TAG, "onLogoutError: " + errorMessage);
|
||||
|
||||
String message = errorCode + "|" + errorMessage;
|
||||
sendToUnity("OnLogoutError", message);
|
||||
|
||||
if (unityLogoutCallback != null) {
|
||||
unityLogoutCallback.onLogoutError(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public void onUserInfoReceived(String userId, String username, String email, String phone) {
|
||||
Log.d(TAG, "onUserInfoReceived: " + userId);
|
||||
|
||||
String message = userId + "|" + username + "|" + email + "|" + phone;
|
||||
sendToUnity("OnUserInfoReceived", message);
|
||||
|
||||
if (unityUserInfoCallback != null) {
|
||||
unityUserInfoCallback.onUserInfoReceived(userId, username, email, phone);
|
||||
}
|
||||
}
|
||||
|
||||
public void onUserInfoCancelled() {
|
||||
Log.d(TAG, "onUserInfoCancelled");
|
||||
sendToUnity("OnUserInfoCancelled", "");
|
||||
|
||||
if (unityUserInfoCallback != null) {
|
||||
unityUserInfoCallback.onUserInfoCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
public void onUserInfoError(int errorCode, String errorMessage) {
|
||||
Log.d(TAG, "onUserInfoError: " + errorMessage);
|
||||
|
||||
String message = errorCode + "|" + errorMessage;
|
||||
sendToUnity("OnUserInfoError", message);
|
||||
|
||||
if (unityUserInfoCallback != null) {
|
||||
unityUserInfoCallback.onUserInfoError(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e32ed25f4a2155a4f8106c56c82bb7fc
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3385cda9ff7dcd74ebc47f50d2e8196c
|
||||
@@ -0,0 +1,2 @@
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b51400b9b30374459987374d5fb2a0a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
apply plugin: 'com.android.library'
|
||||
**APPLY_PLUGINS**
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "androidx.appcompat:appcompat:1.6.1"
|
||||
implementation "com.google.android.material:material:1.11.0"
|
||||
**DEPS**}
|
||||
|
||||
android {
|
||||
namespace "com.unity3d.player"
|
||||
ndkPath "**NDKPATH**"
|
||||
compileSdkVersion **APIVERSION**
|
||||
buildToolsVersion '**BUILDTOOLS**'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion **MINSDKVERSION**
|
||||
targetSdkVersion **TARGETSDKVERSION**
|
||||
ndk {
|
||||
abiFilters **ABIFILTERS**
|
||||
}
|
||||
versionCode **VERSIONCODE**
|
||||
versionName '**VERSIONNAME**'
|
||||
consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD**
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
|
||||
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
|
||||
}**PACKAGING_OPTIONS**
|
||||
}
|
||||
**IL_CPP_BUILD_SETUP**
|
||||
**SOURCE_BUILD_SETUP**
|
||||
**EXTERNAL_SOURCES**
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68ef4c077c6bfee47ad1aa16645a896d
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
#### Proguard class tech3c
|
||||
-keep public class vn.tech3c.sdk.auth.entities.* {
|
||||
public *;
|
||||
}
|
||||
-keep public class vn.tech3c.sdk.auth.entities.enums.* {
|
||||
public *;
|
||||
}
|
||||
-keep public class vn.tech3c.sdk.auth.entities.response.* {
|
||||
public *;
|
||||
}
|
||||
-keep public class vn.tech3c.sdk.auth.entities.request.* {
|
||||
public *;
|
||||
}
|
||||
|
||||
-keep public interface vn.tech3c.sdk.auth.** { *; }
|
||||
|
||||
-keep public class vn.tech3c.sdk.auth.controller.Tech3CIdController { public *;}
|
||||
-keep public class vn.tech3c.sdk.auth.exceptions.Tech3CIdException { public *;}
|
||||
|
||||
-keep public class vn.tech3c.sdk.auth.Tech3CIdAuthentication {
|
||||
public *;
|
||||
}
|
||||
|
||||
-keep public class vn.tech3c.sdk.auth.config.Tech3CIdConfig {
|
||||
public *;
|
||||
}
|
||||
|
||||
-keep public class vn.tech3c.sdk.example.Tech3CUnityBridge { public *;}
|
||||
-keep public class vn.tech3c.sdk.example.Tech3CUnityBridge$** { *; }
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a1d44356c1df074d8cd78bee53cbafa
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5469f93c69421146854ce74deba7931
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,452 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Bridge class for Android platform to communicate with Tech3C native SDK
|
||||
/// </summary>
|
||||
public class Tech3CAndroidBridge : ITech3CNativeBridge
|
||||
{
|
||||
private const string CLASS_NAME = "vn.tech3c.sdk.auth.controller.Tech3CIdController";
|
||||
private const string BRIDGE_CLASS = "vn.tech3c.sdk.unity.Tech3CUnityBridge";
|
||||
|
||||
private AndroidJavaObject controller;
|
||||
private AndroidJavaObject unityBridge;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the Tech3C SDK
|
||||
/// </summary>
|
||||
public void Initialize(string clientId, string clientSecret, Tech3CConfig config)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log("[Tech3C] Bridge GameObject initialized");
|
||||
|
||||
// Initialize Unity Bridge for callbacks first
|
||||
using (AndroidJavaClass bridgeClass = new AndroidJavaClass(BRIDGE_CLASS))
|
||||
{
|
||||
unityBridge = bridgeClass.CallStatic<AndroidJavaObject>("getInstance");
|
||||
}
|
||||
|
||||
// Initialize controller with method chaining to set callback
|
||||
if (controller == null)
|
||||
{
|
||||
using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||||
using (AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
|
||||
using (AndroidJavaClass controllerClass = new AndroidJavaClass(CLASS_NAME))
|
||||
{
|
||||
// Chain methods like MainActivity: initialize() -> setDebug() -> setOnAuthCallback()
|
||||
controller = controllerClass.CallStatic<AndroidJavaObject>(
|
||||
"initialize",
|
||||
activity,
|
||||
clientId,
|
||||
clientSecret
|
||||
)
|
||||
// .Call<AndroidJavaObject>("setDebug", true)
|
||||
// .Call<AndroidJavaObject>("setDisableExitLogin", false)
|
||||
// .Call<AndroidJavaObject>("setEnableMaintenanceCheck", true)
|
||||
.Call<AndroidJavaObject>("setOnAuthCallback", unityBridge);
|
||||
|
||||
Debug.Log("[Tech3C] Unity Bridge registered with native SDK");
|
||||
}
|
||||
}
|
||||
|
||||
if (controller != null)
|
||||
{
|
||||
// Apply configuration
|
||||
ApplyConfig(config);
|
||||
Debug.Log("[Tech3C] Initialized successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[Tech3C] Failed to initialize controller");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] Initialize error: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply configuration settings to the SDK
|
||||
/// </summary>
|
||||
private void ApplyConfig(Tech3CConfig config)
|
||||
{
|
||||
if (controller == null || config == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Set debug mode (returns Tech3CIdController for chaining)
|
||||
controller = controller.Call<AndroidJavaObject>("setDebug", config.debugMode);
|
||||
|
||||
// Set language - pass Java Language enum
|
||||
using (AndroidJavaClass languageEnumClass = new AndroidJavaClass("vn.tech3c.sdk.auth.entities.enums.Language"))
|
||||
{
|
||||
string javaEnumValue = config.language == Language.Vietnamese ? "VIETNAMESE" : "ENGLISH";
|
||||
AndroidJavaObject javaLanguage = languageEnumClass.GetStatic<AndroidJavaObject>(javaEnumValue);
|
||||
controller = controller.Call<AndroidJavaObject>("setLanguageDisplay", javaLanguage);
|
||||
}
|
||||
|
||||
// Set UI mode - pass Java UiMode enum
|
||||
using (AndroidJavaClass uiModeEnumClass = new AndroidJavaClass("vn.tech3c.sdk.auth.entities.enums.UiMode"))
|
||||
{
|
||||
string javaEnumValue = config.uiMode == UiMode.Fullscreen ? "FULLSCREEN" : "DIALOG";
|
||||
AndroidJavaObject javaUiMode = uiModeEnumClass.GetStatic<AndroidJavaObject>(javaEnumValue);
|
||||
controller = controller.Call<AndroidJavaObject>("setUiMode", javaUiMode);
|
||||
}
|
||||
|
||||
// Set orientation - pass Java OrientationMode enum
|
||||
using (AndroidJavaClass orientationEnumClass = new AndroidJavaClass("vn.tech3c.sdk.auth.entities.enums.OrientationMode"))
|
||||
{
|
||||
string javaEnumValue = config.screenOrientation.ToString().ToUpper();
|
||||
AndroidJavaObject javaOrientation = orientationEnumClass.GetStatic<AndroidJavaObject>(javaEnumValue);
|
||||
controller = controller.Call<AndroidJavaObject>("setOrientation", javaOrientation);
|
||||
}
|
||||
|
||||
// Set guest login
|
||||
controller = controller.Call<AndroidJavaObject>("setEnableGuestLogin", config.enableGuestLogin);
|
||||
|
||||
// Set OTP requirement
|
||||
controller = controller.Call<AndroidJavaObject>("setRequireOtp", config.requireOtp);
|
||||
|
||||
// Set disable exit login
|
||||
controller = controller.Call<AndroidJavaObject>("setDisableExitLogin", config.disableExitLogin);
|
||||
|
||||
// Set maintenance check
|
||||
controller = controller.Call<AndroidJavaObject>("setEnableMaintenanceCheck", config.enableMaintenanceCheck);
|
||||
|
||||
if (!string.IsNullOrEmpty(config.maintenanceCheckUrl))
|
||||
{
|
||||
controller = controller.Call<AndroidJavaObject>("setMaintenanceCheckUrl", config.maintenanceCheckUrl);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(config.serverIp))
|
||||
{
|
||||
controller = controller.Call<AndroidJavaObject>("setIpMaintenanceCheck", config.serverIp);
|
||||
}
|
||||
|
||||
Debug.Log("[Tech3C] Configuration applied successfully");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] ApplyConfig error: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show authentication screen
|
||||
/// </summary>
|
||||
public void ShowAuth(IAuthCallback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
Debug.LogError("[Tech3C] Controller not initialized");
|
||||
callback?.OnAuthError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
// Register callback with bridge
|
||||
Tech3CSDKBridge.SetAuthCallback(callback);
|
||||
|
||||
using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||||
using (AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
|
||||
{
|
||||
controller.Call("showAuth", activity);
|
||||
Debug.Log("[Tech3C] Auth screen shown");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] ShowAuth error: {e.Message}");
|
||||
callback?.OnAuthError(-1, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logout current user
|
||||
/// </summary>
|
||||
public void Logout(ILogoutCallback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
Debug.LogError("[Tech3C] Controller not initialized");
|
||||
callback?.OnLogoutError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
// Register callback with bridge
|
||||
Tech3CSDKBridge.SetLogoutCallback(callback);
|
||||
|
||||
controller.Call("logout");
|
||||
Debug.Log("[Tech3C] Logout initiated");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] Logout error: {e.Message}");
|
||||
callback?.OnLogoutError(-1, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user information
|
||||
/// </summary>
|
||||
public void GetUserInfo(IUserInfoCallback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
Debug.LogError("[Tech3C] Controller not initialized");
|
||||
callback?.OnUserInfoError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
// Register callback with bridge
|
||||
Tech3CSDKBridge.SetUserInfoCallback(callback);
|
||||
|
||||
controller.Call("getUserInfo");
|
||||
Debug.Log("[Tech3C] GetUserInfo called");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetUserInfo error: {e.Message}");
|
||||
callback?.OnUserInfoError(-1, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if user is logged in
|
||||
/// </summary>
|
||||
public bool IsLoggedIn()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return false;
|
||||
|
||||
return controller.Call<bool>("isLogin");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] IsLoggedIn error: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get access token
|
||||
/// </summary>
|
||||
public string GetAccessToken()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
return controller.Call<string>("getAccessToken");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetAccessToken error: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get refresh token
|
||||
/// </summary>
|
||||
public string GetRefreshToken()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
return controller.Call<string>("getRefreshToken");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetRefreshToken error: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user ID
|
||||
/// </summary>
|
||||
public string GetUserId()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
return controller.Call<string>("getUserId");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetUserId error: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get device ID
|
||||
/// </summary>
|
||||
public string GetDeviceId()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
return controller.Call<string>("getDeviceId");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetDeviceId error: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get login time
|
||||
/// </summary>
|
||||
public long GetLoginTime()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return 0;
|
||||
|
||||
return controller.Call<long>("getLoginTime");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetLoginTime error: {e.Message}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get token expiry time
|
||||
/// </summary>
|
||||
public long GetTokenExpiry()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return 0;
|
||||
|
||||
return controller.Call<long>("getTokenExpiry");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] GetTokenExpiry error: {e.Message}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if token is expired
|
||||
/// </summary>
|
||||
public bool IsTokenExpired()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return false;
|
||||
|
||||
return controller.Call<bool>("isTokenExpired");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] IsTokenExpired error: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set language
|
||||
/// </summary>
|
||||
public void SetLanguage(Language language)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return;
|
||||
|
||||
// Set language - pass Java Language enum
|
||||
using (AndroidJavaClass languageEnumClass = new AndroidJavaClass("vn.tech3c.sdk.auth.entities.enums.Language"))
|
||||
{
|
||||
string javaEnumValue = language == Language.Vietnamese ? "VIETNAMESE" : "ENGLISH";
|
||||
AndroidJavaObject javaLanguage = languageEnumClass.GetStatic<AndroidJavaObject>(javaEnumValue);
|
||||
controller = controller.Call<AndroidJavaObject>("setLanguageDisplay", javaLanguage);
|
||||
}
|
||||
Debug.Log($"[Tech3C] Language set to {language}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] SetLanguage error: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set debug mode
|
||||
/// </summary>
|
||||
public void SetDebug(bool debug)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller == null) return;
|
||||
|
||||
controller = controller.Call<AndroidJavaObject>("setDebug", debug);
|
||||
Debug.Log($"[Tech3C] Debug mode set to {debug}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] SetDebug error: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup resources
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (controller != null)
|
||||
{
|
||||
controller.Call("cleanup");
|
||||
controller.Dispose();
|
||||
controller = null;
|
||||
Debug.Log("[Tech3C] Cleanup completed");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C] Cleanup error: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for native bridge implementations
|
||||
/// </summary>
|
||||
public interface ITech3CNativeBridge
|
||||
{
|
||||
void Initialize(string clientId, string clientSecret, Tech3CConfig config);
|
||||
void ShowAuth(IAuthCallback callback);
|
||||
void Logout(ILogoutCallback callback);
|
||||
void GetUserInfo(IUserInfoCallback callback);
|
||||
bool IsLoggedIn();
|
||||
string GetAccessToken();
|
||||
string GetRefreshToken();
|
||||
string GetUserId();
|
||||
string GetDeviceId();
|
||||
long GetLoginTime();
|
||||
long GetTokenExpiry();
|
||||
bool IsTokenExpired();
|
||||
void SetLanguage(Language language);
|
||||
void SetDebug(bool debug);
|
||||
void Cleanup();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50744a202f3e9e24a80e10aecf427dac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback for authentication operations (login, register, etc.)
|
||||
/// </summary>
|
||||
public interface IAuthCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when authentication is successful
|
||||
/// </summary>
|
||||
/// <param name="userId">The authenticated user ID</param>
|
||||
/// <param name="password">The user password</param>
|
||||
/// <param name="accessToken">The access token</param>
|
||||
/// <param name="refreshToken">The refresh token</param>
|
||||
/// <param name="loginType">The type of login used</param>
|
||||
/// <param name="expiryTime">Token expiry timestamp</param>
|
||||
void OnAuthSuccess(string userId, string password, string accessToken, string refreshToken, LoginType loginType, long expiryTime);
|
||||
|
||||
/// <summary>
|
||||
/// Called when authentication is cancelled by the user
|
||||
/// </summary>
|
||||
void OnAuthCancelled();
|
||||
|
||||
/// <summary>
|
||||
/// Called when an error occurs during authentication
|
||||
/// </summary>
|
||||
/// <param name="errorCode">The error code</param>
|
||||
/// <param name="errorMessage">The error message</param>
|
||||
void OnAuthError(int errorCode, string errorMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for logout operations
|
||||
/// </summary>
|
||||
public interface ILogoutCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when logout is successful
|
||||
/// </summary>
|
||||
void OnLogoutSuccess();
|
||||
|
||||
/// <summary>
|
||||
/// Called when an error occurs during logout
|
||||
/// </summary>
|
||||
/// <param name="errorCode">The error code</param>
|
||||
/// <param name="errorMessage">The error message</param>
|
||||
void OnLogoutError(int errorCode, string errorMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for user info operations
|
||||
/// </summary>
|
||||
public interface IUserInfoCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when user info is successfully retrieved
|
||||
/// </summary>
|
||||
/// <param name="userId">The user ID</param>
|
||||
/// <param name="username">The username</param>
|
||||
/// <param name="email">The email address</param>
|
||||
/// <param name="phone">The phone number</param>
|
||||
void OnUserInfoReceived(string userId, string username, string email, string phone);
|
||||
|
||||
/// <summary>
|
||||
/// Called when user info retrieval is cancelled
|
||||
/// </summary>
|
||||
void OnUserInfoCancelled();
|
||||
|
||||
/// <summary>
|
||||
/// Called when an error occurs while retrieving user info
|
||||
/// </summary>
|
||||
/// <param name="errorCode">The error code</param>
|
||||
/// <param name="errorMessage">The error message</param>
|
||||
void OnUserInfoError(int errorCode, string errorMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation of IAuthCallback using Unity events
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AuthCallback : IAuthCallback
|
||||
{
|
||||
public event Action<string, string, string, string, LoginType, long> OnAuthSuccessEvent;
|
||||
public event Action OnAuthCancelledEvent;
|
||||
public event Action<int, string> OnAuthErrorEvent;
|
||||
|
||||
public void OnAuthSuccess(string userId, string password, string accessToken, string refreshToken, LoginType loginType, long expiryTime)
|
||||
{
|
||||
OnAuthSuccessEvent?.Invoke(userId, password, accessToken, refreshToken, loginType, expiryTime);
|
||||
}
|
||||
|
||||
public void OnAuthCancelled()
|
||||
{
|
||||
OnAuthCancelledEvent?.Invoke();
|
||||
}
|
||||
|
||||
public void OnAuthError(int errorCode, string errorMessage)
|
||||
{
|
||||
OnAuthErrorEvent?.Invoke(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation of ILogoutCallback using Unity events
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class LogoutCallback : ILogoutCallback
|
||||
{
|
||||
public event Action OnLogoutSuccessEvent;
|
||||
public event Action<int, string> OnLogoutErrorEvent;
|
||||
|
||||
public void OnLogoutSuccess()
|
||||
{
|
||||
OnLogoutSuccessEvent?.Invoke();
|
||||
}
|
||||
|
||||
public void OnLogoutError(int errorCode, string errorMessage)
|
||||
{
|
||||
OnLogoutErrorEvent?.Invoke(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation of IUserInfoCallback using Unity events
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class UserInfoCallback : IUserInfoCallback
|
||||
{
|
||||
public event Action<string, string, string, string> OnUserInfoReceivedEvent;
|
||||
public event Action OnUserInfoCancelledEvent;
|
||||
public event Action<int, string> OnUserInfoErrorEvent;
|
||||
|
||||
public void OnUserInfoReceived(string userId, string username, string email, string phone)
|
||||
{
|
||||
OnUserInfoReceivedEvent?.Invoke(userId, username, email, phone);
|
||||
}
|
||||
|
||||
public void OnUserInfoCancelled()
|
||||
{
|
||||
OnUserInfoCancelledEvent?.Invoke();
|
||||
}
|
||||
|
||||
public void OnUserInfoError(int errorCode, string errorMessage)
|
||||
{
|
||||
OnUserInfoErrorEvent?.Invoke(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed5aa8a6da34849438530838098c8ca0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,114 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration class for Tech3C SDK
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "Tech3CConfig", menuName = "Tech3C SDK/Configuration", order = 1)]
|
||||
public class Tech3CConfig : ScriptableObject
|
||||
{
|
||||
[Header("Client Credentials")]
|
||||
[Tooltip("Client ID for Tech3C authentication")]
|
||||
public string clientId;
|
||||
|
||||
[Tooltip("Client Secret for Tech3C authentication")]
|
||||
public string clientSecret;
|
||||
|
||||
[Header("General Settings")]
|
||||
[Tooltip("Enable debug mode for detailed logging")]
|
||||
public bool debugMode = false;
|
||||
|
||||
[Tooltip("Display language for the SDK")]
|
||||
public Language language = Language.English;
|
||||
|
||||
[Tooltip("Environment for the SDK")]
|
||||
public Environment environment = Environment.Production;
|
||||
|
||||
[Header("UI Settings")]
|
||||
[Tooltip("UI mode for authentication (Fullscreen or Dialog)")]
|
||||
public UiMode uiMode = UiMode.Fullscreen;
|
||||
|
||||
[Tooltip("Dialog size when UI mode is Dialog")]
|
||||
public DialogSize dialogSize = DialogSize.Medium;
|
||||
|
||||
[Tooltip("Screen orientation for authentication")]
|
||||
public OrientationMode screenOrientation = OrientationMode.Auto;
|
||||
|
||||
[Tooltip("Disable exit button on login screen")]
|
||||
public bool disableExitLogin = false;
|
||||
|
||||
[Header("Authentication Settings")]
|
||||
[Tooltip("Enable guest login")]
|
||||
public bool enableGuestLogin = false;
|
||||
|
||||
[Tooltip("Require OTP for authentication")]
|
||||
public bool requireOtp = false;
|
||||
|
||||
[Tooltip("Enable Google login")]
|
||||
public bool enableGoogleLogin = false;
|
||||
|
||||
[Tooltip("Enable Facebook login")]
|
||||
public bool enableFacebookLogin = false;
|
||||
|
||||
[Tooltip("Enable Apple login")]
|
||||
public bool enableAppleLogin = false;
|
||||
|
||||
[Header("Maintenance Settings")]
|
||||
[Tooltip("Enable maintenance check")]
|
||||
public bool enableMaintenanceCheck = false;
|
||||
|
||||
[Tooltip("Maintenance check URL")]
|
||||
public string maintenanceCheckUrl;
|
||||
|
||||
[Tooltip("Server IP for maintenance check")]
|
||||
public string serverIp;
|
||||
|
||||
[Header("Network Settings")]
|
||||
[Tooltip("Timeout in seconds for network requests")]
|
||||
public int timeoutSeconds = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a default Tech3CConfig asset
|
||||
/// </summary>
|
||||
public static Tech3CConfig CreateDefault()
|
||||
{
|
||||
var config = CreateInstance<Tech3CConfig>();
|
||||
config.clientId = "";
|
||||
config.clientSecret = "";
|
||||
config.debugMode = false;
|
||||
config.language = Language.English;
|
||||
config.environment = Environment.Production;
|
||||
config.uiMode = UiMode.Fullscreen;
|
||||
config.dialogSize = DialogSize.Medium;
|
||||
config.screenOrientation = OrientationMode.Auto;
|
||||
config.disableExitLogin = false;
|
||||
config.enableGuestLogin = false;
|
||||
config.requireOtp = false;
|
||||
config.enableGoogleLogin = false;
|
||||
config.enableFacebookLogin = false;
|
||||
config.enableAppleLogin = false;
|
||||
config.enableMaintenanceCheck = false;
|
||||
config.maintenanceCheckUrl = "";
|
||||
config.serverIp = "";
|
||||
config.timeoutSeconds = 30;
|
||||
return config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configuration
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
return !string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the language code string
|
||||
/// </summary>
|
||||
public string GetLanguageCode()
|
||||
{
|
||||
return language == Language.Vietnamese ? "vi" : "en";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95a442ac7dacf8b4484a10035308bc31
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Language options for the SDK
|
||||
/// </summary>
|
||||
public enum Language
|
||||
{
|
||||
Vietnamese,
|
||||
English
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI mode for authentication dialog
|
||||
/// </summary>
|
||||
public enum UiMode
|
||||
{
|
||||
Fullscreen,
|
||||
Dialog
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Screen orientation for authentication
|
||||
/// </summary>
|
||||
public enum OrientationMode
|
||||
{
|
||||
Auto,
|
||||
Portrait,
|
||||
Landscape
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Login type for authentication
|
||||
/// Matches the native SDK's LoginType enum
|
||||
/// </summary>
|
||||
public enum LoginType
|
||||
{
|
||||
GUEST,
|
||||
ACCOUNT,
|
||||
SOCIAL,
|
||||
REGISTER // For register success handling
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Environment for the SDK
|
||||
/// </summary>
|
||||
public enum Environment
|
||||
{
|
||||
Production,
|
||||
Staging,
|
||||
Development
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dialog size for UI mode
|
||||
/// </summary>
|
||||
public enum DialogSize
|
||||
{
|
||||
Small,
|
||||
Medium,
|
||||
Large
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c35f3ea36736dfe439eb6f4b8a314dde
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,473 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Main API wrapper for Tech3C SDK
|
||||
/// This is the main entry point for using the SDK in Unity
|
||||
/// </summary>
|
||||
public class Tech3CSDK : MonoBehaviour
|
||||
{
|
||||
private static Tech3CSDK instance;
|
||||
private ITech3CNativeBridge nativeBridge;
|
||||
private Tech3CConfig config;
|
||||
private bool isInitialized = false;
|
||||
|
||||
#region Singleton
|
||||
|
||||
/// <summary>
|
||||
/// Get the singleton instance of Tech3CSDK
|
||||
/// </summary>
|
||||
public static Tech3CSDK Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
GameObject go = new GameObject("Tech3CSDK");
|
||||
instance = go.AddComponent<Tech3CSDK>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else if (instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the Tech3C SDK with configuration
|
||||
/// </summary>
|
||||
/// <param name="config">The configuration object</param>
|
||||
public void Initialize(Tech3CConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
Debug.LogError("[Tech3C] Config cannot be null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.IsValid())
|
||||
{
|
||||
Debug.LogError("[Tech3C] Invalid config: Client ID and Client Secret are required");
|
||||
return;
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
|
||||
// Ensure Tech3CSDKBridge is created to receive callbacks from native code
|
||||
var bridge = Tech3CSDKBridge.Instance;
|
||||
Debug.Log("[Tech3C] Tech3CSDKBridge ensured for callbacks");
|
||||
|
||||
// Create platform-specific bridge
|
||||
CreateNativeBridge();
|
||||
|
||||
if (nativeBridge != null)
|
||||
{
|
||||
nativeBridge.Initialize(config.clientId, config.clientSecret, config);
|
||||
isInitialized = true;
|
||||
Debug.Log("[Tech3C] Initialization completed successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[Tech3C] Failed to create native bridge");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the Tech3C SDK with client credentials
|
||||
/// </summary>
|
||||
/// <param name="clientId">The client ID</param>
|
||||
/// <param name="clientSecret">The client secret</param>
|
||||
public void Initialize(string clientId, string clientSecret)
|
||||
{
|
||||
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
Debug.LogError("[Tech3C] Client ID and Client Secret are required");
|
||||
return;
|
||||
}
|
||||
|
||||
config = Tech3CConfig.CreateDefault();
|
||||
config.clientId = clientId;
|
||||
config.clientSecret = clientSecret;
|
||||
|
||||
Initialize(config);
|
||||
}
|
||||
|
||||
private void CreateNativeBridge()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
nativeBridge = new Tech3CAndroidBridge();
|
||||
#elif UNITY_IOS && !UNITY_EDITOR
|
||||
nativeBridge = new Tech3CiOSBridge();
|
||||
#else
|
||||
#if UNITY_ANDROID
|
||||
nativeBridge = new Tech3CAndroidBridge();
|
||||
#elif UNITY_IOS
|
||||
nativeBridge = new Tech3CiOSBridge();
|
||||
#else
|
||||
Debug.LogWarning("[Tech3C] Running in Editor or unsupported platform. Using mock implementation.");
|
||||
nativeBridge = new MockBridge();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Authentication
|
||||
|
||||
/// <summary>
|
||||
/// Show authentication screen (login/register/forgot password)
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback for authentication result</param>
|
||||
public void ShowAuth(IAuthCallback callback)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogError("[Tech3C] SDK not initialized. Call Initialize() first.");
|
||||
callback?.OnAuthError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
nativeBridge?.ShowAuth(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show authentication screen without callback
|
||||
/// </summary>
|
||||
public void ShowAuth()
|
||||
{
|
||||
ShowAuth(null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region User Management
|
||||
|
||||
/// <summary>
|
||||
/// Logout current user
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback for logout result</param>
|
||||
public void Logout(ILogoutCallback callback)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogError("[Tech3C] SDK not initialized. Call Initialize() first.");
|
||||
callback?.OnLogoutError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
nativeBridge?.Logout(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logout current user without callback
|
||||
/// </summary>
|
||||
public void Logout()
|
||||
{
|
||||
Logout(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user information
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback for user info result</param>
|
||||
public void GetUserInfo(IUserInfoCallback callback)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogError("[Tech3C] SDK not initialized. Call Initialize() first.");
|
||||
callback?.OnUserInfoError(-1, "SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
nativeBridge?.GetUserInfo(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user information without callback
|
||||
/// </summary>
|
||||
public void GetUserInfo()
|
||||
{
|
||||
GetUserInfo(null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region State Checkers
|
||||
|
||||
/// <summary>
|
||||
/// Check if user is logged in
|
||||
/// </summary>
|
||||
public bool IsLoggedIn()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return nativeBridge?.IsLoggedIn() ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if access token is expired
|
||||
/// </summary>
|
||||
public bool IsTokenExpired()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return true;
|
||||
}
|
||||
|
||||
return nativeBridge?.IsTokenExpired() ?? true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Token Management
|
||||
|
||||
/// <summary>
|
||||
/// Get access token
|
||||
/// </summary>
|
||||
public string GetAccessToken()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetAccessToken();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get refresh token
|
||||
/// </summary>
|
||||
public string GetRefreshToken()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetRefreshToken();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region User Information
|
||||
|
||||
/// <summary>
|
||||
/// Get user ID
|
||||
/// </summary>
|
||||
public string GetUserId()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetUserId();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get device ID
|
||||
/// </summary>
|
||||
public string GetDeviceId()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetDeviceId();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get login timestamp
|
||||
/// </summary>
|
||||
public long GetLoginTime()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetLoginTime() ?? 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get token expiry timestamp
|
||||
/// </summary>
|
||||
public long GetTokenExpiry()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nativeBridge?.GetTokenExpiry() ?? 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
|
||||
/// <summary>
|
||||
/// Set display language
|
||||
/// </summary>
|
||||
/// <param name="language">The language to set</param>
|
||||
public void SetLanguage(Language language)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
nativeBridge?.SetLanguage(language);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set debug mode
|
||||
/// </summary>
|
||||
/// <param name="debug">Enable or disable debug mode</param>
|
||||
public void SetDebug(bool debug)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SDK not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
nativeBridge?.SetDebug(debug);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cleanup
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup SDK resources
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
nativeBridge?.Cleanup();
|
||||
nativeBridge = null;
|
||||
config = null;
|
||||
isInitialized = false;
|
||||
Debug.Log("[Tech3C] Cleanup completed");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Get the current configuration
|
||||
/// </summary>
|
||||
public Tech3CConfig Config => config;
|
||||
|
||||
/// <summary>
|
||||
/// Check if SDK is initialized
|
||||
/// </summary>
|
||||
public bool IsInitialized => isInitialized;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mock bridge for testing in editor or unsupported platforms
|
||||
/// </summary>
|
||||
internal class MockBridge : ITech3CNativeBridge
|
||||
{
|
||||
private bool isLoggedIn = false;
|
||||
private string accessToken = "mock_access_token";
|
||||
private string refreshToken = "mock_refresh_token";
|
||||
private string userId = "mock_user_id";
|
||||
|
||||
public void Initialize(string clientId, string clientSecret, Tech3CConfig config)
|
||||
{
|
||||
Debug.Log($"[Tech3C Mock] Initialized with Client ID: {clientId}");
|
||||
}
|
||||
|
||||
public void ShowAuth(IAuthCallback callback)
|
||||
{
|
||||
Debug.Log("[Mock3C Mock] ShowAuth called");
|
||||
isLoggedIn = true;
|
||||
string password = "mock_password";
|
||||
callback?.OnAuthSuccess(userId, password, accessToken, refreshToken, LoginType.ACCOUNT, DateTime.Now.Ticks + 3600000);
|
||||
}
|
||||
|
||||
public void Logout(ILogoutCallback callback)
|
||||
{
|
||||
Debug.Log("[Tech3C Mock] Logout called");
|
||||
isLoggedIn = false;
|
||||
callback?.OnLogoutSuccess();
|
||||
}
|
||||
|
||||
public void GetUserInfo(IUserInfoCallback callback)
|
||||
{
|
||||
Debug.Log("[Tech3C Mock] GetUserInfo called");
|
||||
callback?.OnUserInfoReceived(userId, "mock_username", "mock@example.com", "1234567890");
|
||||
}
|
||||
|
||||
public bool IsLoggedIn() => isLoggedIn;
|
||||
|
||||
public string GetAccessToken() => isLoggedIn ? accessToken : null;
|
||||
|
||||
public string GetRefreshToken() => isLoggedIn ? refreshToken : null;
|
||||
|
||||
public string GetUserId() => isLoggedIn ? userId : null;
|
||||
|
||||
public string GetDeviceId() => "mock_device_id";
|
||||
|
||||
public long GetLoginTime() => isLoggedIn ? DateTime.Now.Ticks : 0;
|
||||
|
||||
public long GetTokenExpiry() => isLoggedIn ? DateTime.Now.Ticks + 3600000 : 0;
|
||||
|
||||
public bool IsTokenExpired() => false;
|
||||
|
||||
public void SetLanguage(Language language)
|
||||
{
|
||||
Debug.Log($"[Tech3C Mock] Language set to {language}");
|
||||
}
|
||||
|
||||
public void SetDebug(bool debug)
|
||||
{
|
||||
Debug.Log($"[Tech3C Mock] Debug mode set to {debug}");
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
Debug.Log("[Tech3C Mock] Cleanup completed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3afb6189c673cea45a34e6e75c1f5ccb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,332 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Bridge component to receive callbacks from native Android/iOS SDK via Unity messaging
|
||||
/// This GameObject receives UnitySendMessage calls from native code
|
||||
/// </summary>
|
||||
public class Tech3CSDKBridge : MonoBehaviour
|
||||
{
|
||||
private static Tech3CSDKBridge instance;
|
||||
|
||||
// Callback references
|
||||
private static IAuthCallback authCallback;
|
||||
private static ILogoutCallback logoutCallback;
|
||||
private static IUserInfoCallback userInfoCallback;
|
||||
|
||||
#region Singleton
|
||||
|
||||
public static Tech3CSDKBridge Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
GameObject go = new GameObject("Tech3CSDKBridge");
|
||||
instance = go.AddComponent<Tech3CSDKBridge>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
Debug.Log("[Tech3C Bridge] Bridge initialized");
|
||||
}
|
||||
else if (instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Set Callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Set the auth callback to be invoked when auth events occur
|
||||
/// </summary>
|
||||
public static void SetAuthCallback(IAuthCallback callback)
|
||||
{
|
||||
authCallback = callback;
|
||||
Debug.Log("[Tech3C Bridge] Auth callback set");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the logout callback to be invoked when logout events occur
|
||||
/// </summary>
|
||||
public static void SetLogoutCallback(ILogoutCallback callback)
|
||||
{
|
||||
logoutCallback = callback;
|
||||
Debug.Log("[Tech3C Bridge] Logout callback set");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the user info callback to be invoked when user info events occur
|
||||
/// </summary>
|
||||
public static void SetUserInfoCallback(IUserInfoCallback callback)
|
||||
{
|
||||
userInfoCallback = callback;
|
||||
Debug.Log("[Tech3C Bridge] User info callback set");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Auth Callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when authentication is successful
|
||||
/// Message format: "userId|password|accessToken|refreshToken|loginType|expiryTime"
|
||||
/// </summary>
|
||||
public void OnAuthSuccess(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Bridge] OnAuthSuccess received: {message}");
|
||||
|
||||
if (authCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No auth callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string[] parts = message.Split('|');
|
||||
if (parts.Length >= 6)
|
||||
{
|
||||
string userId = parts[0];
|
||||
string password = parts[1];
|
||||
string accessToken = parts[2];
|
||||
string refreshToken = parts[3];
|
||||
LoginType loginType = (LoginType)Enum.Parse(typeof(LoginType), parts[4]);
|
||||
long expiryTime = long.Parse(parts[5]);
|
||||
|
||||
Debug.Log($"[Tech3C Bridge] Parsed auth success: userId={userId}, loginType={loginType}");
|
||||
authCallback.OnAuthSuccess(userId, password, accessToken, refreshToken, loginType, expiryTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Invalid message format: {message}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Error parsing auth success message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when authentication is cancelled
|
||||
/// </summary>
|
||||
public void OnAuthCancelled(string message)
|
||||
{
|
||||
Debug.Log("[Tech3C Bridge] OnAuthCancelled received");
|
||||
|
||||
if (authCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No auth callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
authCallback.OnAuthCancelled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when an authentication error occurs
|
||||
/// Message format: "errorCode|errorMessage"
|
||||
/// </summary>
|
||||
public void OnAuthError(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Bridge] OnAuthError received: {message}");
|
||||
|
||||
if (authCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No auth callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string[] parts = message.Split('|');
|
||||
int errorCode = -1;
|
||||
string errorMessage = "Unknown error";
|
||||
|
||||
if (parts.Length >= 1)
|
||||
{
|
||||
int.TryParse(parts[0], out errorCode);
|
||||
}
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
errorMessage = parts[1];
|
||||
}
|
||||
|
||||
Debug.Log($"[Tech3C Bridge] Parsed auth error: code={errorCode}, message={errorMessage}");
|
||||
authCallback.OnAuthError(errorCode, errorMessage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Error parsing auth error message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Logout Callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when logout is successful
|
||||
/// </summary>
|
||||
public void OnLogoutSuccess(string message)
|
||||
{
|
||||
Debug.Log("[Tech3C Bridge] OnLogoutSuccess received");
|
||||
|
||||
if (logoutCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No logout callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
logoutCallback.OnLogoutSuccess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when a logout error occurs
|
||||
/// Message format: "errorCode|errorMessage"
|
||||
/// </summary>
|
||||
public void OnLogoutError(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Bridge] OnLogoutError received: {message}");
|
||||
|
||||
if (logoutCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No logout callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string[] parts = message.Split('|');
|
||||
int errorCode = -1;
|
||||
string errorMessage = "Unknown error";
|
||||
|
||||
if (parts.Length >= 1)
|
||||
{
|
||||
int.TryParse(parts[0], out errorCode);
|
||||
}
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
errorMessage = parts[1];
|
||||
}
|
||||
|
||||
logoutCallback.OnLogoutError(errorCode, errorMessage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Error parsing logout error message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region User Info Callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when user info is received
|
||||
/// Message format: "userId|username|email|phone"
|
||||
/// </summary>
|
||||
public void OnUserInfoReceived(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Bridge] OnUserInfoReceived received: {message}");
|
||||
|
||||
if (userInfoCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No user info callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string[] parts = message.Split('|');
|
||||
if (parts.Length >= 4)
|
||||
{
|
||||
string userId = parts[0];
|
||||
string username = parts[1];
|
||||
string email = parts[2];
|
||||
string phone = parts[3];
|
||||
|
||||
Debug.Log($"[Tech3C Bridge] Parsed user info: userId={userId}, username={username}");
|
||||
userInfoCallback.OnUserInfoReceived(userId, username, email, phone);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Invalid message format: {message}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Error parsing user info message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when user info retrieval is cancelled
|
||||
/// </summary>
|
||||
public void OnUserInfoCancelled(string message)
|
||||
{
|
||||
Debug.Log("[Tech3C Bridge] OnUserInfoCancelled received");
|
||||
|
||||
if (userInfoCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No user info callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
userInfoCallback.OnUserInfoCancelled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from native code when a user info error occurs
|
||||
/// Message format: "errorCode|errorMessage"
|
||||
/// </summary>
|
||||
public void OnUserInfoError(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Bridge] OnUserInfoError received: {message}");
|
||||
|
||||
if (userInfoCallback == null)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C Bridge] No user info callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string[] parts = message.Split('|');
|
||||
int errorCode = -1;
|
||||
string errorMessage = "Unknown error";
|
||||
|
||||
if (parts.Length >= 1)
|
||||
{
|
||||
int.TryParse(parts[0], out errorCode);
|
||||
}
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
errorMessage = parts[1];
|
||||
}
|
||||
|
||||
userInfoCallback.OnUserInfoError(errorCode, errorMessage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[Tech3C Bridge] Error parsing user info error message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46cf26ff28457b04890e322b5b161a67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,147 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Bridge class for iOS platform to communicate with Tech3C native SDK
|
||||
/// Note: iOS implementation requires native framework. This is a placeholder.
|
||||
/// </summary>
|
||||
public class Tech3CiOSBridge : ITech3CNativeBridge
|
||||
{
|
||||
private bool initialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the Tech3C SDK
|
||||
/// </summary>
|
||||
public void Initialize(string clientId, string clientSecret, Tech3CConfig config)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] iOS platform is not yet supported. Please provide the native iOS framework.");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show authentication screen
|
||||
/// </summary>
|
||||
public void ShowAuth(IAuthCallback callback)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] ShowAuth is not implemented for iOS platform");
|
||||
callback?.OnAuthError(-1, "iOS platform not supported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logout current user
|
||||
/// </summary>
|
||||
public void Logout(ILogoutCallback callback)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] Logout is not implemented for iOS platform");
|
||||
callback?.OnLogoutError(-1, "iOS platform not supported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user information
|
||||
/// </summary>
|
||||
public void GetUserInfo(IUserInfoCallback callback)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetUserInfo is not implemented for iOS platform");
|
||||
callback?.OnUserInfoError(-1, "iOS platform not supported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if user is logged in
|
||||
/// </summary>
|
||||
public bool IsLoggedIn()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] IsLoggedIn is not implemented for iOS platform");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get access token
|
||||
/// </summary>
|
||||
public string GetAccessToken()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetAccessToken is not implemented for iOS platform");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get refresh token
|
||||
/// </summary>
|
||||
public string GetRefreshToken()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetRefreshToken is not implemented for iOS platform");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user ID
|
||||
/// </summary>
|
||||
public string GetUserId()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetUserId is not implemented for iOS platform");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get device ID
|
||||
/// </summary>
|
||||
public string GetDeviceId()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetDeviceId is not implemented for iOS platform");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get login time
|
||||
/// </summary>
|
||||
public long GetLoginTime()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetLoginTime is not implemented for iOS platform");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get token expiry time
|
||||
/// </summary>
|
||||
public long GetTokenExpiry()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] GetTokenExpiry is not implemented for iOS platform");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if token is expired
|
||||
/// </summary>
|
||||
public bool IsTokenExpired()
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] IsTokenExpired is not implemented for iOS platform");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set language
|
||||
/// </summary>
|
||||
public void SetLanguage(Language language)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SetLanguage is not implemented for iOS platform");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set debug mode
|
||||
/// </summary>
|
||||
public void SetDebug(bool debug)
|
||||
{
|
||||
Debug.LogWarning("[Tech3C] SetDebug is not implemented for iOS platform");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup resources
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
Debug.Log("[Tech3C] iOS bridge cleanup completed");
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7199bd7af3b75294c84f9d6451df86d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a947977eda82ae34b85413ea17ef265a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,473 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using System;
|
||||
|
||||
namespace Tech3C
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple demo that creates UI programmatically
|
||||
/// Just attach this script to any GameObject in your scene
|
||||
/// </summary>
|
||||
public class Tech3CSimpleDemo : MonoBehaviour
|
||||
{
|
||||
[Header("Configuration")]
|
||||
public string clientId = "your_client_id";
|
||||
public string clientSecret = "your_client_secret";
|
||||
|
||||
private Canvas canvas;
|
||||
private Text logText;
|
||||
private AuthCallback authCallback;
|
||||
private LogoutCallback logoutCallback;
|
||||
|
||||
private GameObject dialogPanel;
|
||||
private Text dialogText;
|
||||
private Button dialogCloseButton;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EnsureEventSystem();
|
||||
CreateUI();
|
||||
SetupCallbacks();
|
||||
|
||||
// Auto-initialize SDK
|
||||
if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
Log($"Initializing Tech3C SDK...\n Client ID: {clientId}");
|
||||
Tech3CSDK.Instance.Initialize(clientId, clientSecret);
|
||||
|
||||
if (Tech3CSDK.Instance.IsInitialized)
|
||||
{
|
||||
Log("✓ SDK Initialized Successfully!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("✗ Failed to initialize SDK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("⚠ Client ID and/or Client Secret not set. Please configure in Inspector.");
|
||||
}
|
||||
|
||||
Debug.Log("[Tech3C Demo] Tech3C SDK Simple Demo Started");
|
||||
}
|
||||
|
||||
private void EnsureEventSystem()
|
||||
{
|
||||
if (EventSystem.current == null)
|
||||
{
|
||||
GameObject eventSystemGO = new GameObject("EventSystem");
|
||||
eventSystemGO.AddComponent<EventSystem>();
|
||||
eventSystemGO.AddComponent<StandaloneInputModule>();
|
||||
Debug.Log("[Tech3C Demo] EventSystem created");
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateUI()
|
||||
{
|
||||
// Create Canvas
|
||||
GameObject canvasGO = new GameObject("Tech3CDemoCanvas");
|
||||
canvasGO.transform.SetParent(transform);
|
||||
canvas = canvasGO.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
// Configure CanvasScaler for responsive 16:9 ratio
|
||||
CanvasScaler canvasScaler = canvasGO.AddComponent<CanvasScaler>();
|
||||
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
canvasScaler.referenceResolution = new Vector2(1920, 1080); // 16:9 ratio
|
||||
canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
||||
canvasScaler.matchWidthOrHeight = 0.5f; // Balance between width and height
|
||||
|
||||
canvasGO.AddComponent<GraphicRaycaster>();
|
||||
|
||||
// Create Scroll Panel
|
||||
GameObject scrollPanel = new GameObject("ScrollPanel");
|
||||
scrollPanel.transform.SetParent(canvasGO.transform, false);
|
||||
RectTransform scrollPanelRect = scrollPanel.AddComponent<RectTransform>();
|
||||
scrollPanelRect.anchorMin = Vector2.zero;
|
||||
scrollPanelRect.anchorMax = Vector2.one;
|
||||
scrollPanelRect.sizeDelta = Vector2.zero;
|
||||
Image scrollPanelImage = scrollPanel.AddComponent<Image>();
|
||||
scrollPanelImage.color = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
|
||||
// Create ScrollRect
|
||||
ScrollRect scrollRect = scrollPanel.AddComponent<ScrollRect>();
|
||||
scrollRect.horizontal = false;
|
||||
scrollRect.vertical = true;
|
||||
scrollRect.scrollSensitivity = 50f;
|
||||
|
||||
// Create Content Panel
|
||||
GameObject panel = new GameObject("Content");
|
||||
panel.transform.SetParent(scrollPanel.transform, false);
|
||||
RectTransform panelRect = panel.AddComponent<RectTransform>();
|
||||
panelRect.anchorMin = new Vector2(0, 1);
|
||||
panelRect.anchorMax = new Vector2(1, 1);
|
||||
panelRect.pivot = new Vector2(0.5f, 1f);
|
||||
panelRect.sizeDelta = new Vector2(0, 0);
|
||||
scrollRect.content = panelRect;
|
||||
|
||||
// Create Vertical Layout Group
|
||||
VerticalLayoutGroup layoutGroup = panel.AddComponent<VerticalLayoutGroup>();
|
||||
layoutGroup.childControlHeight = false;
|
||||
layoutGroup.childControlWidth = true;
|
||||
layoutGroup.childForceExpandWidth = true;
|
||||
layoutGroup.childForceExpandHeight = false;
|
||||
layoutGroup.spacing = 15;
|
||||
layoutGroup.padding = new RectOffset(40, 40, 40, 40);
|
||||
ContentSizeFitter contentSizeFitter = panel.AddComponent<ContentSizeFitter>();
|
||||
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// Create Title
|
||||
CreateTextResponsive(panel.transform, "Tech3C SDK Demo", 28, TextAnchor.MiddleCenter, 60);
|
||||
|
||||
// Create Separator
|
||||
CreateTextResponsive(panel.transform, "--- Authentication ---", 18, TextAnchor.MiddleCenter, 30);
|
||||
|
||||
// Create Show Auth Button
|
||||
Button showAuthButton = CreateButtonResponsive(panel.transform, "Show Auth Screen", 70);
|
||||
showAuthButton.onClick.AddListener(OnShowAuthClick);
|
||||
|
||||
// Create Logout Button
|
||||
Button logoutButton = CreateButtonResponsive(panel.transform, "Logout", 70);
|
||||
logoutButton.onClick.AddListener(OnLogoutClick);
|
||||
|
||||
// Create Log Text
|
||||
CreateTextResponsive(panel.transform, "Logs:", 16, TextAnchor.MiddleLeft, 35);
|
||||
logText = CreateTextResponsive(panel.transform, "Ready...", 16, TextAnchor.MiddleLeft, 400);
|
||||
logText.color = Color.green;
|
||||
|
||||
// Reposition panel
|
||||
panelRect.anchoredPosition = Vector2.zero;
|
||||
}
|
||||
|
||||
private void SetupCallbacks()
|
||||
{
|
||||
// Auth callback
|
||||
authCallback = new AuthCallback();
|
||||
authCallback.OnAuthSuccessEvent += (userId, password, accessToken, refreshToken, loginType, expiryTime) =>
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] === AUTH SUCCESS CALLBACK FIRED ===");
|
||||
Debug.Log($"[Tech3C Demo] UserId: {userId}");
|
||||
Debug.Log($"[Tech3C Demo] Password: {password?.Substring(0, Math.Min(3, password?.Length ?? 0))}...");
|
||||
Debug.Log($"[Tech3C Demo] LoginType: {loginType}");
|
||||
Debug.Log($"[Tech3C Demo] AccessToken: {accessToken?.Substring(0, Math.Min(20, accessToken?.Length ?? 0))}...");
|
||||
Debug.Log($"[Tech3C Demo] RefreshToken: {refreshToken?.Substring(0, Math.Min(20, refreshToken?.Length ?? 0))}...");
|
||||
Debug.Log($"[Tech3C Demo] ExpiryTime: {expiryTime}");
|
||||
|
||||
Log($"✓ Auth Success!\n User ID: {userId}\n Password: {password}\n Login Type: {loginType}\n Token: {accessToken?.Substring(0, Math.Min(20, accessToken?.Length ?? 0))}...");
|
||||
|
||||
ShowAuthSuccessDialog(userId, password, loginType.ToString());
|
||||
};
|
||||
authCallback.OnAuthCancelledEvent += () =>
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] === AUTH CANCELLED CALLBACK FIRED ===");
|
||||
Log("✗ Auth Cancelled by user");
|
||||
};
|
||||
authCallback.OnAuthErrorEvent += (errorCode, errorMessage) =>
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] === AUTH ERROR CALLBACK FIRED ===");
|
||||
Debug.Log($"[Tech3C Demo] ErrorCode: {errorCode}");
|
||||
Debug.Log($"[Tech3C Demo] ErrorMessage: {errorMessage}");
|
||||
Log($"✗ Auth Error [{errorCode}]: {errorMessage}");
|
||||
};
|
||||
|
||||
// Logout callback
|
||||
logoutCallback = new LogoutCallback();
|
||||
logoutCallback.OnLogoutSuccessEvent += () =>
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] === LOGOUT SUCCESS CALLBACK FIRED ===");
|
||||
Log("✓ Logout Successful");
|
||||
};
|
||||
logoutCallback.OnLogoutErrorEvent += (errorCode, errorMessage) =>
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] === LOGOUT ERROR CALLBACK FIRED ===");
|
||||
Debug.Log($"[Tech3C Demo] ErrorCode: {errorCode}");
|
||||
Debug.Log($"[Tech3C Demo] ErrorMessage: {errorMessage}");
|
||||
Log($"✗ Logout Error [{errorCode}]: {errorMessage}");
|
||||
};
|
||||
}
|
||||
|
||||
#region Button Handlers
|
||||
|
||||
private void OnInitializeClick(string newClientId, string newClientSecret)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newClientId) || string.IsNullOrEmpty(newClientSecret))
|
||||
{
|
||||
Log("✗ Client ID and Client Secret are required!");
|
||||
return;
|
||||
}
|
||||
|
||||
clientId = newClientId;
|
||||
clientSecret = newClientSecret;
|
||||
|
||||
Log($"Initializing Tech3C SDK...\n Client ID: {clientId}");
|
||||
Tech3CSDK.Instance.Initialize(clientId, clientSecret);
|
||||
|
||||
if (Tech3CSDK.Instance.IsInitialized)
|
||||
{
|
||||
Log("✓ SDK Initialized Successfully!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("✗ Failed to initialize SDK");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShowAuthClick()
|
||||
{
|
||||
if (!Tech3CSDK.Instance.IsInitialized)
|
||||
{
|
||||
Log("✗ SDK not initialized. Click Initialize first!");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("Opening Auth Screen...");
|
||||
Tech3CSDK.Instance.ShowAuth(authCallback);
|
||||
}
|
||||
|
||||
private void OnLogoutClick()
|
||||
{
|
||||
if (!Tech3CSDK.Instance.IsInitialized)
|
||||
{
|
||||
Log("✗ SDK not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("Logging out...");
|
||||
Tech3CSDK.Instance.Logout(logoutCallback);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Helper Methods
|
||||
|
||||
private Button CreateButton(Transform parent, string text, float width, float height)
|
||||
{
|
||||
GameObject buttonGO = new GameObject(text.Replace(" ", "_"));
|
||||
buttonGO.transform.SetParent(parent, false);
|
||||
|
||||
RectTransform rect = buttonGO.AddComponent<RectTransform>();
|
||||
rect.sizeDelta = new Vector2(width, height);
|
||||
|
||||
Image image = buttonGO.AddComponent<Image>();
|
||||
image.color = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
|
||||
Button button = buttonGO.AddComponent<Button>();
|
||||
|
||||
// Set up button transition for visual feedback
|
||||
ColorBlock colors = button.colors;
|
||||
colors.normalColor = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
colors.highlightedColor = new Color(0.4f, 0.6f, 0.9f, 1f);
|
||||
colors.pressedColor = new Color(0.2f, 0.4f, 0.7f, 1f);
|
||||
colors.selectedColor = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
colors.colorMultiplier = 1f;
|
||||
button.colors = colors;
|
||||
|
||||
GameObject textGO = new GameObject("Text");
|
||||
textGO.transform.SetParent(buttonGO.transform, false);
|
||||
|
||||
RectTransform textRect = textGO.AddComponent<RectTransform>();
|
||||
textRect.anchorMin = Vector2.zero;
|
||||
textRect.anchorMax = Vector2.one;
|
||||
textRect.sizeDelta = Vector2.zero;
|
||||
|
||||
Text textComponent = textGO.AddComponent<Text>();
|
||||
textComponent.text = text;
|
||||
textComponent.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
textComponent.fontSize = 18;
|
||||
textComponent.alignment = TextAnchor.MiddleCenter;
|
||||
textComponent.color = Color.white;
|
||||
textComponent.raycastTarget = false; // Important: Allow click to pass through to button
|
||||
|
||||
Debug.Log($"[Tech3C Demo] Created button: {text}");
|
||||
return button;
|
||||
}
|
||||
|
||||
private Text CreateText(Transform parent, string text, int fontSize, TextAnchor alignment, float width, float height)
|
||||
{
|
||||
GameObject textGO = new GameObject("Text");
|
||||
textGO.transform.SetParent(parent, false);
|
||||
|
||||
RectTransform rect = textGO.AddComponent<RectTransform>();
|
||||
rect.sizeDelta = new Vector2(width, height);
|
||||
|
||||
Text textComponent = textGO.AddComponent<Text>();
|
||||
textComponent.text = text;
|
||||
textComponent.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
textComponent.fontSize = fontSize;
|
||||
textComponent.alignment = alignment;
|
||||
textComponent.color = Color.white;
|
||||
textComponent.raycastTarget = false; // Prevent text from blocking button clicks
|
||||
|
||||
return textComponent;
|
||||
}
|
||||
|
||||
private Text CreateLabel(Transform parent, string text)
|
||||
{
|
||||
return CreateText(parent, text, 14, TextAnchor.MiddleLeft, 500, 30);
|
||||
}
|
||||
|
||||
private InputField CreateInputField(Transform parent, string defaultValue)
|
||||
{
|
||||
GameObject inputGO = new GameObject("InputField");
|
||||
inputGO.transform.SetParent(parent, false);
|
||||
|
||||
RectTransform rect = inputGO.AddComponent<RectTransform>();
|
||||
rect.sizeDelta = new Vector2(500, 40);
|
||||
|
||||
Image image = inputGO.AddComponent<Image>();
|
||||
image.color = new Color(0.3f, 0.3f, 0.3f, 1f);
|
||||
|
||||
InputField inputField = inputGO.AddComponent<InputField>();
|
||||
inputField.textComponent = CreateText(inputGO.transform, defaultValue, 16, TextAnchor.MiddleLeft, 500, 40);
|
||||
inputField.textComponent.color = Color.black;
|
||||
inputField.textComponent.raycastTarget = false; // Prevent text from blocking input
|
||||
inputField.lineType = InputField.LineType.MultiLineSubmit;
|
||||
|
||||
Debug.Log($"[Tech3C Demo] Created input field with default value");
|
||||
return inputField;
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
Debug.Log($"[Tech3C Demo] {message}");
|
||||
if (logText != null)
|
||||
{
|
||||
string timestamp = System.DateTime.Now.ToString("HH:mm:ss");
|
||||
logText.text = $"[{timestamp}] {message}\n{logText.text}";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Responsive UI Helper Methods
|
||||
|
||||
private Button CreateButtonResponsive(Transform parent, string text, float height)
|
||||
{
|
||||
GameObject buttonGO = new GameObject(text.Replace(" ", "_"));
|
||||
buttonGO.transform.SetParent(parent, false);
|
||||
|
||||
RectTransform rect = buttonGO.AddComponent<RectTransform>();
|
||||
rect.anchorMin = new Vector2(0, 0);
|
||||
rect.anchorMax = new Vector2(1, 0);
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
rect.sizeDelta = new Vector2(-80, height); // -80 for left/right padding
|
||||
|
||||
Image image = buttonGO.AddComponent<Image>();
|
||||
image.color = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
|
||||
Button button = buttonGO.AddComponent<Button>();
|
||||
|
||||
// Set up button transition for visual feedback
|
||||
ColorBlock colors = button.colors;
|
||||
colors.normalColor = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
colors.highlightedColor = new Color(0.4f, 0.6f, 0.9f, 1f);
|
||||
colors.pressedColor = new Color(0.2f, 0.4f, 0.7f, 1f);
|
||||
colors.selectedColor = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||
colors.colorMultiplier = 1f;
|
||||
button.colors = colors;
|
||||
|
||||
GameObject textGO = new GameObject("Text");
|
||||
textGO.transform.SetParent(buttonGO.transform, false);
|
||||
|
||||
RectTransform textRect = textGO.AddComponent<RectTransform>();
|
||||
textRect.anchorMin = Vector2.zero;
|
||||
textRect.anchorMax = Vector2.one;
|
||||
textRect.sizeDelta = Vector2.zero;
|
||||
|
||||
Text textComponent = textGO.AddComponent<Text>();
|
||||
textComponent.text = text;
|
||||
textComponent.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
textComponent.fontSize = 22;
|
||||
textComponent.alignment = TextAnchor.MiddleCenter;
|
||||
textComponent.color = Color.white;
|
||||
textComponent.raycastTarget = false;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private Text CreateTextResponsive(Transform parent, string text, int fontSize, TextAnchor alignment, float height)
|
||||
{
|
||||
GameObject textGO = new GameObject("Text");
|
||||
textGO.transform.SetParent(parent, false);
|
||||
|
||||
RectTransform rect = textGO.AddComponent<RectTransform>();
|
||||
rect.anchorMin = new Vector2(0, 0);
|
||||
rect.anchorMax = new Vector2(1, 0);
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
rect.sizeDelta = new Vector2(0, height);
|
||||
|
||||
Text textComponent = textGO.AddComponent<Text>();
|
||||
textComponent.text = text;
|
||||
textComponent.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
textComponent.fontSize = fontSize;
|
||||
textComponent.alignment = alignment;
|
||||
textComponent.color = Color.white;
|
||||
textComponent.raycastTarget = false;
|
||||
|
||||
return textComponent;
|
||||
}
|
||||
|
||||
private void ShowAuthSuccessDialog(string userId, string password, string loginType)
|
||||
{
|
||||
// Remove existing dialog if any
|
||||
if (dialogPanel != null)
|
||||
{
|
||||
Destroy(dialogPanel);
|
||||
}
|
||||
|
||||
// Create dialog background (full screen overlay)
|
||||
GameObject overlayGO = new GameObject("DialogOverlay");
|
||||
overlayGO.transform.SetParent(canvas.transform, false);
|
||||
RectTransform overlayRect = overlayGO.AddComponent<RectTransform>();
|
||||
overlayRect.anchorMin = Vector2.zero;
|
||||
overlayRect.anchorMax = Vector2.one;
|
||||
overlayRect.sizeDelta = Vector2.zero;
|
||||
Image overlayImage = overlayGO.AddComponent<Image>();
|
||||
overlayImage.color = new Color(0, 0, 0, 0.7f); // Semi-transparent black
|
||||
|
||||
// Create dialog panel
|
||||
dialogPanel = new GameObject("AuthSuccessDialog");
|
||||
dialogPanel.transform.SetParent(overlayGO.transform, false);
|
||||
RectTransform dialogRect = dialogPanel.AddComponent<RectTransform>();
|
||||
dialogRect.anchorMin = new Vector2(0.3f, 0.4f);
|
||||
dialogRect.anchorMax = new Vector2(0.7f, 0.6f);
|
||||
dialogRect.offsetMin = Vector2.zero;
|
||||
dialogRect.offsetMax = Vector2.zero;
|
||||
Image dialogImage = dialogPanel.AddComponent<Image>();
|
||||
dialogImage.color = new Color(0.15f, 0.35f, 0.15f, 1f);
|
||||
|
||||
// Create vertical layout group for dialog
|
||||
VerticalLayoutGroup dialogLayout = dialogPanel.AddComponent<VerticalLayoutGroup>();
|
||||
dialogLayout.childControlHeight = false;
|
||||
dialogLayout.childControlWidth = true;
|
||||
dialogLayout.childForceExpandWidth = true;
|
||||
dialogLayout.childAlignment = TextAnchor.MiddleCenter;
|
||||
dialogLayout.spacing = 20;
|
||||
dialogLayout.padding = new RectOffset(20, 20, 20, 20);
|
||||
ContentSizeFitter dialogFitter = dialogPanel.AddComponent<ContentSizeFitter>();
|
||||
dialogFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// Create success message
|
||||
Text successTitle = CreateText(dialogPanel.transform, "✓ LOGIN SUCCESSFUL", 32, TextAnchor.MiddleCenter, 400, 50);
|
||||
successTitle.color = Color.green;
|
||||
|
||||
// Create user info
|
||||
string userInfoText = $"User ID: {userId}\nPassword: {password}\nLogin Type: {loginType}";
|
||||
Text userInfoComponent = CreateText(dialogPanel.transform, userInfoText, 20, TextAnchor.MiddleCenter, 400, 80);
|
||||
userInfoComponent.color = Color.white;
|
||||
|
||||
// Create close button
|
||||
dialogCloseButton = CreateButton(dialogPanel.transform, "OK", 200, 50);
|
||||
dialogCloseButton.onClick.AddListener(() =>
|
||||
{
|
||||
Debug.Log("[Tech3C Demo] Dialog close button clicked");
|
||||
Destroy(overlayGO);
|
||||
dialogPanel = null;
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00000000000000000000000000000003
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -23,6 +23,9 @@ EditorBuildSettings:
|
||||
- enabled: 0
|
||||
path: Assets/Scenes/MonsterRender.unity
|
||||
guid: fdaaa6dd81a1845a9826745163a927ef
|
||||
- enabled: 0
|
||||
path: Assets/Scenes/SampleScene.unity
|
||||
guid: 9fc0d4010bbf28b4594072e72b8655ab
|
||||
m_configObjects:
|
||||
com.unity.addressableassets: {fileID: 11400000, guid: 224e456928aaa4603b0c4a9ec48ee013, type: 2}
|
||||
m_UseUCBPForAssetBundles: 0
|
||||
|
||||
@@ -256,9 +256,9 @@ PlayerSettings:
|
||||
clonedFromGUID: 00000000000000000000000000000000
|
||||
templatePackageId:
|
||||
templateDefaultScene:
|
||||
useCustomMainManifest: 0
|
||||
useCustomMainManifest: 1
|
||||
useCustomLauncherManifest: 0
|
||||
useCustomMainGradleTemplate: 0
|
||||
useCustomMainGradleTemplate: 1
|
||||
useCustomLauncherGradleManifest: 0
|
||||
useCustomBaseGradleTemplate: 0
|
||||
useCustomGradlePropertiesTemplate: 0
|
||||
|
||||
Reference in New Issue
Block a user