mm with lrm
This commit is contained in:
parent
dcddade210
commit
4194d2decc
170
Assets/GUI PRO Kit - Casual Game/Prefabs/Loading_Rotate.prefab
Normal file
170
Assets/GUI PRO Kit - Casual Game/Prefabs/Loading_Rotate.prefab
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &2580113099039482007
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2580113099039482004}
|
||||
- component: {fileID: 2580113099039482010}
|
||||
- component: {fileID: 2580113099039482005}
|
||||
- component: {fileID: 3114295233361083281}
|
||||
m_Layer: 5
|
||||
m_Name: Loading_Rotate
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2580113099039482004
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113099039482007}
|
||||
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_Children:
|
||||
- {fileID: 2580113100926171462}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 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: 96.8}
|
||||
m_SizeDelta: {x: 192, y: 210}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2580113099039482010
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113099039482007}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &2580113099039482005
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113099039482007}
|
||||
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: bb129f0554ce5482e97e81f0688f3a7a, 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!111 &3114295233361083281
|
||||
Animation:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113099039482007}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Animation: {fileID: 7400000, guid: 9c20f215af6a84358874d19ece3f974a, type: 2}
|
||||
m_Animations:
|
||||
- {fileID: 7400000, guid: 9c20f215af6a84358874d19ece3f974a, type: 2}
|
||||
m_WrapMode: 0
|
||||
m_PlayAutomatically: 1
|
||||
m_AnimatePhysics: 0
|
||||
m_CullingType: 0
|
||||
--- !u!1 &2580113100926171457
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2580113100926171462}
|
||||
- component: {fileID: 2580113100926171460}
|
||||
- component: {fileID: 2580113100926171463}
|
||||
m_Layer: 5
|
||||
m_Name: Loading
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2580113100926171462
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113100926171457}
|
||||
m_LocalRotation: {x: 0, y: 0, z: -0.56160814, w: -0.82740337}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2580113099039482004}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 129.49689}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 1.9073324, y: -1.0168762}
|
||||
m_SizeDelta: {x: 116, y: 116}
|
||||
m_Pivot: {x: 0.51644206, y: 0.4912285}
|
||||
--- !u!222 &2580113100926171460
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113100926171457}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &2580113100926171463
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2580113100926171457}
|
||||
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: 3c211ed28a1254ad5be923faa2874f0e, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 1
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 81b526d5af23c3b44ab67aafb659aba1
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -162298,7 +162298,7 @@ PrefabInstance:
|
|||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2996527298064719087, guid: aaad26180fe71926d8e68c79e7a16f03, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: aaad26180fe71926d8e68c79e7a16f03, type: 3}
|
||||
|
|
@ -183493,11 +183493,23 @@ MonoBehaviour:
|
|||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 0
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 770816085}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 981460997}
|
||||
m_TargetAssemblyTypeName: GameManager, Assembly-CSharp
|
||||
m_MethodName: LoadRanked
|
||||
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 &770816085
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -254070,7 +254082,7 @@ PrefabInstance:
|
|||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4910625423430463544, guid: 34cd695a79f27f95cbce88b05dcf4f9f, type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 149.6
|
||||
value: 350
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4910625423430463544, guid: 34cd695a79f27f95cbce88b05dcf4f9f, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
|
|
@ -254128,6 +254140,10 @@ PrefabInstance:
|
|||
propertyPath: m_Name
|
||||
value: Button_Rewards
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4910625423430463551, guid: 34cd695a79f27f95cbce88b05dcf4f9f, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 34cd695a79f27f95cbce88b05dcf4f9f, type: 3}
|
||||
--- !u!224 &1132398514 stripped
|
||||
|
|
@ -481367,7 +481383,7 @@ GameObject:
|
|||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &1924897864
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
|||
342
Assets/Game/Scenes/GameScene/LoadingScreen.prefab
Normal file
342
Assets/Game/Scenes/GameScene/LoadingScreen.prefab
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &2978711258753279381
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2978711258753279370}
|
||||
- component: {fileID: 2978711258753279369}
|
||||
- component: {fileID: 2978711258753279368}
|
||||
- component: {fileID: 2978711258753279383}
|
||||
- component: {fileID: 2978711258753279382}
|
||||
- component: {fileID: 2978711258753279371}
|
||||
m_Layer: 5
|
||||
m_Name: LoadingScreen
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2978711258753279370
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 2978711259208510469}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
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: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2978711258753279369
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 1
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 25
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 2
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2978711258753279368
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 1
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 2560, y: 1440}
|
||||
m_ScreenMatchMode: 1
|
||||
m_MatchWidthOrHeight: 0.5
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
m_PresetInfoIsWorld: 0
|
||||
--- !u!114 &2978711258753279383
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!114 &2978711258753279382
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c5c8585324f167adeb5f7768975c64fa, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
loadingProgress: {fileID: 7778126637795575051}
|
||||
loadingProgressTxt: {fileID: 7778126636521892656}
|
||||
--- !u!225 &2978711258753279371
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711258753279381}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 0
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &2978711259208510468
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2978711259208510469}
|
||||
- component: {fileID: 2978711259208510520}
|
||||
- component: {fileID: 2978711259208510471}
|
||||
m_Layer: 5
|
||||
m_Name: minigame_loading
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2978711259208510469
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711259208510468}
|
||||
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_Children:
|
||||
- {fileID: 7778126637795575050}
|
||||
m_Father: {fileID: 2978711258753279370}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 1280, y: -720}
|
||||
m_SizeDelta: {x: 2560, y: 1440}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2978711259208510520
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711259208510468}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2978711259208510471
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2978711259208510468}
|
||||
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: a7c005ca94529964c90de50760de3824, 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!1001 &2978711258465328309
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 2978711259208510469}
|
||||
m_Modifications:
|
||||
- target: {fileID: 4803079023532308928, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMax.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079023532308928, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485820, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Slider_LoadingBar
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485822, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_Value
|
||||
value: 0.424
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_Pivot.x
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_Pivot.y
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMax.x
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMin.x
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_SizeDelta.x
|
||||
value: 1670.9839
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_SizeDelta.y
|
||||
value: 76
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 1.9
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: -608.19
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
--- !u!224 &7778126637795575050 stripped
|
||||
RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 4803079025088485823, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
m_PrefabInstance: {fileID: 2978711258465328309}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &7778126637795575051 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4803079025088485822, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
m_PrefabInstance: {fileID: 2978711258465328309}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &7778126636521892656 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4803079023815849861, guid: 64b4a7231bc790d4c9d8d9b1d5ef54b1, type: 3}
|
||||
m_PrefabInstance: {fileID: 2978711258465328309}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
7
Assets/Game/Scenes/GameScene/LoadingScreen.prefab.meta
Normal file
7
Assets/Game/Scenes/GameScene/LoadingScreen.prefab.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0eba14368cdf70da9b4c373af2ca26bb
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -223,6 +223,82 @@ RectTransform:
|
|||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!1 &148635108
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 148635109}
|
||||
- component: {fileID: 148635111}
|
||||
- component: {fileID: 148635110}
|
||||
m_Layer: 5
|
||||
m_Name: minigame_loading
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &148635109
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 148635108}
|
||||
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_Children:
|
||||
- {fileID: 235772954}
|
||||
m_Father: {fileID: 1652306576}
|
||||
m_RootOrder: 0
|
||||
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!114 &148635110
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 148635108}
|
||||
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: a7c005ca94529964c90de50760de3824, 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!222 &148635111
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 148635108}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &192624791 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 1122908927419026657, guid: f1c38827cf8d35ea8bb29a9d8d0ec0a8, type: 3}
|
||||
|
|
@ -234,6 +310,135 @@ MonoBehaviour:
|
|||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &235772953
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 235772954}
|
||||
- component: {fileID: 235772956}
|
||||
- component: {fileID: 235772955}
|
||||
- component: {fileID: 235772957}
|
||||
m_Layer: 5
|
||||
m_Name: Slider_LoadingBar
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &235772954
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 235772953}
|
||||
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_Children:
|
||||
- {fileID: 1365590398}
|
||||
- {fileID: 1055066937}
|
||||
m_Father: {fileID: 148635109}
|
||||
m_RootOrder: 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: 1.9, y: -608.19}
|
||||
m_SizeDelta: {x: 1670.9839, y: 76}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &235772955
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 235772953}
|
||||
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: f9e47d48ae68e48eab6bcdcc8fcac328, type: 3}
|
||||
m_Type: 1
|
||||
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!222 &235772956
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 235772953}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &235772957
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 235772953}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, 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: 5
|
||||
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: 235772955}
|
||||
m_FillRect: {fileID: 1365590398}
|
||||
m_HandleRect: {fileID: 0}
|
||||
m_Direction: 0
|
||||
m_MinValue: 0
|
||||
m_MaxValue: 1
|
||||
m_WholeNumbers: 0
|
||||
m_Value: 0.424
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &321877710
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -1175,6 +1380,140 @@ MonoBehaviour:
|
|||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!1 &1055066934
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1055066937}
|
||||
- component: {fileID: 1055066936}
|
||||
- component: {fileID: 1055066935}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1055066935
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055066934}
|
||||
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: 75%
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 50c12c23294124aa48490c44ac65a9e4, type: 2}
|
||||
m_sharedMaterial: {fileID: 7746803525459343344, guid: 50c12c23294124aa48490c44ac65a9e4, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, 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: 55
|
||||
m_fontSizeBase: 55
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
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_enableWordWrapping: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 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: 1
|
||||
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}
|
||||
--- !u!222 &1055066936
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055066934}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!224 &1055066937
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1055066934}
|
||||
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_Children: []
|
||||
m_Father: {fileID: 235772954}
|
||||
m_RootOrder: 1
|
||||
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: -1.1, y: 5.5}
|
||||
m_SizeDelta: {x: 252.96558, y: 65.000015}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &1069403981
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -1292,6 +1631,81 @@ Transform:
|
|||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1365590397
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1365590398}
|
||||
- component: {fileID: 1365590400}
|
||||
- component: {fileID: 1365590399}
|
||||
m_Layer: 5
|
||||
m_Name: Fill
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1365590398
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1365590397}
|
||||
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_Children: []
|
||||
m_Father: {fileID: 235772954}
|
||||
m_RootOrder: 0
|
||||
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: 3}
|
||||
m_SizeDelta: {x: -6, y: -12}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1365590399
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1365590397}
|
||||
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: 41f68bec7506344f19c4a2960cda7eb0, type: 3}
|
||||
m_Type: 1
|
||||
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!222 &1365590400
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1365590397}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1414273971 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 1122908926118697578, guid: f1c38827cf8d35ea8bb29a9d8d0ec0a8, type: 3}
|
||||
|
|
@ -1314,6 +1728,148 @@ MonoBehaviour:
|
|||
m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1652306570
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1652306576}
|
||||
- component: {fileID: 1652306575}
|
||||
- component: {fileID: 1652306574}
|
||||
- component: {fileID: 1652306573}
|
||||
- component: {fileID: 1652306572}
|
||||
- component: {fileID: 1652306571}
|
||||
- component: {fileID: 1652306577}
|
||||
m_Layer: 5
|
||||
m_Name: LoadingScreen
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!225 &1652306571
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 0
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!114 &1652306572
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c5c8585324f167adeb5f7768975c64fa, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
loadingProgress: {fileID: 235772957}
|
||||
loadingProgressTxt: {fileID: 1055066935}
|
||||
--- !u!114 &1652306573
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!114 &1652306574
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 1
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 2560, y: 1440}
|
||||
m_ScreenMatchMode: 1
|
||||
m_MatchWidthOrHeight: 0.5
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
m_PresetInfoIsWorld: 0
|
||||
--- !u!223 &1652306575
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 1
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 25
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 10
|
||||
m_TargetDisplay: 0
|
||||
--- !u!224 &1652306576
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 148635109}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
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: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!114 &1652306577
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1652306570}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0c9b3a77753892d388edbbaf63a3ff05, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
checkInterval: 10
|
||||
--- !u!1001 &1823654559
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
@ -4365,111 +4921,6 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1352124587237562812}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1001 &5241638030831850394
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 5241638032184726244, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMax.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032184726244, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_Pivot.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_Pivot.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMax.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMin.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_SizeDelta.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_SizeDelta.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515978, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5241638032470515984, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: LoadingScreen
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 8b73b4a53065db88da12ab1b9c4a5c5a, type: 3}
|
||||
--- !u!222 &5400831500666047900
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
|||
51879
Assets/Game/Scenes/Minigame/MinigameMatchmaking.unity
Normal file
51879
Assets/Game/Scenes/Minigame/MinigameMatchmaking.unity
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 59eddda8397341803b1134237eb697d7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62602
Assets/Game/Scenes/Minigame/MinigameRanked.unity
Normal file
62602
Assets/Game/Scenes/Minigame/MinigameRanked.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Game/Scenes/Minigame/MinigameRanked.unity.meta
Normal file
7
Assets/Game/Scenes/Minigame/MinigameRanked.unity.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a9d3dbf520f6a482b8a715db7a293e58
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
254
Assets/Game/Scenes/Minigame/NetworkManager.prefab
Normal file
254
Assets/Game/Scenes/Minigame/NetworkManager.prefab
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &5010164752306998726
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5010164752306998723}
|
||||
- component: {fileID: 5010164752306998724}
|
||||
- component: {fileID: 5010164752306998722}
|
||||
- component: {fileID: 5010164752306998721}
|
||||
- component: {fileID: 5010164752306998725}
|
||||
m_Layer: 0
|
||||
m_Name: NetworkManager
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &5010164752306998723
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164752306998726}
|
||||
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_Children:
|
||||
- {fileID: 5010164753989687231}
|
||||
- {fileID: 5010164753387733984}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &5010164752306998724
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164752306998726}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 8aab4c8111b7c411b9b92cf3dbc5bd4e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
autoStartServerBuild: 1
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 5010164752306998721}
|
||||
networkAddress: vps.playpoolstudios.com
|
||||
maxConnections: 100
|
||||
authenticator: {fileID: 0}
|
||||
playerPrefab: {fileID: 5431987895376475548, guid: e811a838f2ebb2f4fb8055331ed295e9, type: 3}
|
||||
autoCreatePlayer: 0
|
||||
playerSpawnMethod: 0
|
||||
spawnPrefabs:
|
||||
- {fileID: 5339383961425506408, guid: ad54ea1b437d2b344add56c18d1efb3e, type: 3}
|
||||
- {fileID: 8298505072154104440, guid: 8cfd89c315493e64782e167885b4b498, type: 3}
|
||||
--- !u!114 &5010164752306998722
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164752306998726}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 6442dc8070ceb41f094e44de0bf87274, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
offsetX: 0
|
||||
offsetY: 0
|
||||
--- !u!114 &5010164752306998721
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164752306998726}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7064b1b1d0671194baf55fa8d5f564d6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
clientToServerTransport: {fileID: 5010164753989687104}
|
||||
serverIP: 194.233.70.117
|
||||
serverPort: 7000
|
||||
endpointServerPort: 8250
|
||||
heartBeatInterval: 3
|
||||
connectOnAwake: 1
|
||||
authenticationKey: 4KiE8032f6RjX0FbPzf
|
||||
disconnectedFromRelay:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
connectedToRelay:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
useNATPunch: 1
|
||||
NATPunchtroughPort: 1
|
||||
useLoadBalancer: 0
|
||||
loadBalancerPort: 7070
|
||||
loadBalancerAddress: 127.0.0.1
|
||||
serverName: My awesome server!
|
||||
extraServerData: Map 1
|
||||
maxServerPlayers: 10
|
||||
isPublicServer: 1
|
||||
serverListUpdated:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
serverStatus: Not Started.
|
||||
serverId:
|
||||
region: 1
|
||||
--- !u!114 &5010164752306998725
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164752306998726}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9c4cbff877abc42448dd829920c6c233, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
directConnectTransport: {fileID: 5010164753387733985}
|
||||
showDebugLogs: 0
|
||||
--- !u!1 &5010164753387733986
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5010164753387733984}
|
||||
- component: {fileID: 5010164753387733985}
|
||||
m_Layer: 0
|
||||
m_Name: LRM - Direct Connect
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &5010164753387733984
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164753387733986}
|
||||
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_Children: []
|
||||
m_Father: {fileID: 5010164752306998723}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &5010164753387733985
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164753387733986}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Port: 7777
|
||||
DualMode: 1
|
||||
NoDelay: 1
|
||||
Interval: 10
|
||||
Timeout: 10000
|
||||
FastResend: 2
|
||||
CongestionWindow: 0
|
||||
SendWindowSize: 4096
|
||||
ReceiveWindowSize: 4096
|
||||
MaxRetransmit: 40
|
||||
NonAlloc: 1
|
||||
MaximizeSendReceiveBuffersToOSLimit: 1
|
||||
ReliableMaxMessageSize: 298449
|
||||
UnreliableMaxMessageSize: 1199
|
||||
debugLog: 0
|
||||
statisticsGUI: 0
|
||||
statisticsLog: 0
|
||||
--- !u!1 &5010164753989687105
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5010164753989687231}
|
||||
- component: {fileID: 5010164753989687104}
|
||||
m_Layer: 0
|
||||
m_Name: LRM - Connector
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &5010164753989687231
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164753989687105}
|
||||
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_Children: []
|
||||
m_Father: {fileID: 5010164752306998723}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &5010164753989687104
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5010164753989687105}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Port: 7000
|
||||
DualMode: 1
|
||||
NoDelay: 1
|
||||
Interval: 10
|
||||
Timeout: 10000
|
||||
FastResend: 2
|
||||
CongestionWindow: 0
|
||||
SendWindowSize: 4096
|
||||
ReceiveWindowSize: 4096
|
||||
MaxRetransmit: 40
|
||||
NonAlloc: 1
|
||||
MaximizeSendReceiveBuffersToOSLimit: 1
|
||||
ReliableMaxMessageSize: 298449
|
||||
UnreliableMaxMessageSize: 1199
|
||||
debugLog: 0
|
||||
statisticsGUI: 0
|
||||
statisticsLog: 0
|
||||
7
Assets/Game/Scenes/Minigame/NetworkManager.prefab.meta
Normal file
7
Assets/Game/Scenes/Minigame/NetworkManager.prefab.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 30b57505daea40fb7988344592a3252c
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -128,5 +128,9 @@ public class GameManager : MonoBehaviour
|
|||
// SceneManager.LoadScene("Minigame");
|
||||
LoadingScreen.instance.LoadLevel("Minigame");
|
||||
}
|
||||
|
||||
public void LoadRanked(){
|
||||
LoadingScreen.instance.LoadLevel("MinigameMatchmaking");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,60 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
using LightReflectiveMirror;
|
||||
public class AutoConnect : MonoBehaviour
|
||||
{
|
||||
public bool isClient;
|
||||
public static bool isRankedServer;
|
||||
public static string serverName;
|
||||
public bool isRanked;
|
||||
public LightReflectiveMirrorTransport lrm;
|
||||
void Start()
|
||||
{
|
||||
if(isClient){
|
||||
FindObjectOfType<NetworkManager>().networkAddress = RegionManager.selectedServer.ip;
|
||||
FindObjectOfType<NetworkManager>().StartClient();
|
||||
if(isRanked){
|
||||
|
||||
if(!isRankedServer){
|
||||
lrm.serverListUpdated.AddListener(OnServerListUpdated);
|
||||
StartCoroutine(refreshList());
|
||||
}else{
|
||||
StartCoroutine(startHost());
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
if(isClient){
|
||||
FindObjectOfType<NetworkManager>().networkAddress = RegionManager.selectedServer.ip;
|
||||
FindObjectOfType<NetworkManager>().StartClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator startHost(){
|
||||
while(!lrm.isConnectedToRelay){
|
||||
yield return new WaitForSeconds(1);
|
||||
}
|
||||
lrm.serverName = serverName;
|
||||
lrm.isPublicServer=true;
|
||||
NetworkManager.singleton.StartHost();
|
||||
}
|
||||
IEnumerator refreshList(){
|
||||
while(!lrm.isConnectedToRelay){
|
||||
yield return new WaitForSeconds(1);
|
||||
}
|
||||
while(!NetworkManager.singleton.isNetworkActive){
|
||||
yield return new WaitForSeconds(1);
|
||||
lrm.RequestServerList();
|
||||
}
|
||||
}
|
||||
|
||||
void OnServerListUpdated(){
|
||||
Debug.Log("Got new server list of " + lrm.relayServerList.Count);
|
||||
foreach(Room room in lrm.relayServerList){
|
||||
if(room.serverName == serverName){
|
||||
Debug.Log("Found server for me! Joining now");
|
||||
NetworkManager.singleton.networkAddress = room.serverId;
|
||||
NetworkManager.singleton.StartClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ public class Leaderboard : MonoBehaviour
|
|||
{
|
||||
public Text[] leaderboardItems;
|
||||
public float updateInterval = 0.5f;
|
||||
public bool isRanked;
|
||||
float t;
|
||||
void Start()
|
||||
{
|
||||
|
|
@ -35,7 +36,7 @@ public class Leaderboard : MonoBehaviour
|
|||
{
|
||||
for (int i = 0; i <= players.Length - 2; i++)
|
||||
{
|
||||
if (players[i].Scores > players[i + 1].Scores)
|
||||
if ( (isRanked ? players[i].moonsCollected : players[i].Scores) > (isRanked? players[i+1].moonsCollected : players[i + 1].Scores))
|
||||
{
|
||||
temp = players[i + 1];
|
||||
players[i + 1] = players[i];
|
||||
|
|
@ -43,13 +44,18 @@ public class Leaderboard : MonoBehaviour
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Populate leaderboard
|
||||
for(int i =0; i < leaderboardItems.Length; i++){
|
||||
if(i < players.Length){
|
||||
SpaceshipController thisPlayer = players[players.Length-i-1];
|
||||
leaderboardItems[i].gameObject.SetActive(true);
|
||||
leaderboardItems[i].text = (i+1) + ". " +thisPlayer.pname;
|
||||
leaderboardItems[i].transform.GetChild(0).GetComponent<Text>().text = thisPlayer.Scores.ToString();
|
||||
if(isRanked){
|
||||
leaderboardItems[i].transform.GetChild(0).GetComponent<Text>().text = thisPlayer.Scores.ToString();
|
||||
}else{
|
||||
leaderboardItems[i].transform.GetChild(0).GetComponent<Text>().text = (((float)Mathf.Clamp(thisPlayer.moonsCollected,0,30)/ 30f)*100f).ToString("n1") + " %";
|
||||
}
|
||||
}else{
|
||||
leaderboardItems[i].gameObject.SetActive(false);
|
||||
}
|
||||
|
|
|
|||
114
Assets/Game/Scripts/Minigame/MatchMaker.cs
Normal file
114
Assets/Game/Scripts/Minigame/MatchMaker.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using LightReflectiveMirror;
|
||||
using TMPro;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
using Mirror;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class MatchMaker : MonoBehaviour
|
||||
{
|
||||
public TMP_Text timerTxt;
|
||||
public Button btn_cancel;
|
||||
float timer;
|
||||
public string serverName;
|
||||
void Start()
|
||||
{
|
||||
if(!DBmanager.LoggedIn){
|
||||
SceneManager.LoadScene(0);
|
||||
}
|
||||
btn_cancel.onClick.AddListener(Cancel);
|
||||
|
||||
// StartCoroutine(StartMatchmaking());
|
||||
}
|
||||
|
||||
private void OnClientConnected()
|
||||
{
|
||||
Debug.Log("Hey look someone connected!");
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
float t=0;
|
||||
float connectTimeout = 0;
|
||||
bool loadedScene;
|
||||
void Update()
|
||||
{
|
||||
timer+=Time.deltaTime;
|
||||
timerTxt.text = SceneData.SecondsToText(timer);
|
||||
|
||||
if(t < 1){
|
||||
t += Time.deltaTime;
|
||||
}else{
|
||||
t=0;
|
||||
StartCoroutine(FetchMatchmake());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isServer =false;
|
||||
IEnumerator FetchMatchmake(){
|
||||
|
||||
WWWForm form = new WWWForm();
|
||||
form.AddField("name", DBmanager.username);
|
||||
form.AddField("region", RegionManager.selectedServer.name);
|
||||
|
||||
WWW req = new WWW(DBmanager.phpRoot+"matchmake.php", form);
|
||||
yield return req;
|
||||
Debug.Log(req.text);
|
||||
if(req.text.Contains(DBmanager.username) && !loadedScene){
|
||||
//Room created!
|
||||
isServer= req.text.Substring(0,DBmanager.username.Length) == DBmanager.username;
|
||||
serverName=req.text;
|
||||
AutoConnect.serverName = serverName;
|
||||
AutoConnect.isRankedServer = isServer;
|
||||
// AutoConnect.isRanked = true;
|
||||
Debug.Log($"Room created! [{req.text}] am I the server? : " + isServer);
|
||||
|
||||
LoadingScreen.instance.LoadLevel("MinigameRanked");
|
||||
|
||||
}else{
|
||||
//Waiting
|
||||
}
|
||||
}
|
||||
|
||||
// IEnumerator StartMatchmaking(){
|
||||
// StartCoroutine(StartLooking());
|
||||
|
||||
// yield return new WaitForSeconds(1);
|
||||
|
||||
|
||||
// lrm.serverName=DBmanager.username;
|
||||
// NetworkManager.singleton.StartHost();
|
||||
|
||||
// }
|
||||
// bool foundServer =false;
|
||||
// IEnumerator StartLooking(){
|
||||
// int counter =0;
|
||||
// while(counter < 3){
|
||||
// yield return new WaitForSeconds(1);
|
||||
// lrm.RequestServerList();
|
||||
// // counter++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void OnServerListUpdated(){
|
||||
// Debug.Log("Found " + lrm.relayServerList.Count + " Servers");
|
||||
// foreach(Room room in lrm.relayServerList){
|
||||
// Debug.Log(room.serverName);
|
||||
// if(!foundServer && room.serverName.Length>0 && room.serverName != DBmanager.username){
|
||||
// foundServer=true;
|
||||
// NetworkManager.singleton.networkAddress = room.serverName;
|
||||
// NetworkManager.singleton.StartClient();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void Cancel(){
|
||||
LoadingScreen.instance.LoadLevel("GameScene");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
Assets/Game/Scripts/Minigame/MatchMaker.cs.meta
Normal file
11
Assets/Game/Scripts/Minigame/MatchMaker.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fcd6bd76997f1842b886038d34d3093d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -9,6 +9,9 @@ using TMPro;
|
|||
public class MinigameManager : NetworkBehaviour
|
||||
{
|
||||
public static MinigameManager instance;
|
||||
public bool isRanked;
|
||||
public bool RankedGameStarted=false;
|
||||
public GameObject waitingScreen;
|
||||
public float mapRadius;
|
||||
public int maxMoons, maxStars = 100;
|
||||
public Transform pickupItemsParent;
|
||||
|
|
@ -27,12 +30,18 @@ public class MinigameManager : NetworkBehaviour
|
|||
instance = this;
|
||||
|
||||
DBmanager.OnStateChanged.AddListener(UpdateMaterialValues);
|
||||
UpdateMaterialValues();
|
||||
UpdateMaterialValues();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// if(!DBmanager.LoggedIn){SceneManager.LoadScene(0);} //Signed out, no game for u
|
||||
|
||||
if(isRanked){
|
||||
RankedGameStarted= (FindObjectsOfType<SpaceshipController>().Length >=2);
|
||||
waitingScreen.SetActive(!RankedGameStarted);
|
||||
}
|
||||
|
||||
if (!isServer) { return; }
|
||||
|
||||
HandlePickupSpawn();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ public class SpaceshipController : NetworkBehaviour
|
|||
public int Kills;
|
||||
[SyncVar(hook=nameof(OnTrailTimeChanged))]
|
||||
public float trailTime;
|
||||
[SyncVar]
|
||||
public int moonsCollected;
|
||||
public float trailIncrementRate = 0.5f;
|
||||
[SyncVar]
|
||||
public bool dead;
|
||||
|
|
@ -160,6 +162,7 @@ public class SpaceshipController : NetworkBehaviour
|
|||
int lastClientUpdateTime = 0;
|
||||
void FixedUpdate()
|
||||
{
|
||||
if(MinigameManager.instance.isRanked && !MinigameManager.instance.RankedGameStarted){return;}
|
||||
distanceFromCenter = Vector3.Distance(transform.position, Vector3.zero);
|
||||
pnameTxt.rectTransform.rotation = Quaternion.Euler(Vector3.zero);
|
||||
|
||||
|
|
@ -491,10 +494,11 @@ public class SpaceshipController : NetworkBehaviour
|
|||
}
|
||||
|
||||
public void CollectPickup(PickupItem.PickupType type){
|
||||
if(isClient){Debug.Log("Server function ran on client. That's illegal!");} // <-- What this log says
|
||||
if(!isServer){Debug.Log("Server function ran on client. That's illegal!");} // <-- What this log says
|
||||
switch(type){
|
||||
case PickupItem.PickupType.Moon:
|
||||
IncreaseTrail(trailIncrementRate);
|
||||
moonsCollected++;
|
||||
break;
|
||||
|
||||
case PickupItem.PickupType.Star:
|
||||
|
|
|
|||
8
Assets/Mirror/Runtime/Transport.meta
Normal file
8
Assets/Mirror/Runtime/Transport.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f45143bb41b0a0ad7904c6c2a6eab7e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Mirror/Runtime/Transport/LRM.meta
Normal file
8
Assets/Mirror/Runtime/Transport/LRM.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 78e5ef50787a62f8c862001c8b8cbc20
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
56
Assets/Mirror/Runtime/Transport/LRM/BiDictionary.cs
Normal file
56
Assets/Mirror/Runtime/Transport/LRM/BiDictionary.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Source: https://stackoverflow.com/questions/255341/getting-multiple-keys-of-specified-value-of-a-generic-dictionary#255630
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
class BiDictionary<TFirst, TSecond>
|
||||
{
|
||||
IDictionary<TFirst, TSecond> firstToSecond = new Dictionary<TFirst, TSecond>();
|
||||
IDictionary<TSecond, TFirst> secondToFirst = new Dictionary<TSecond, TFirst>();
|
||||
|
||||
public void Add(TFirst first, TSecond second)
|
||||
{
|
||||
if (firstToSecond.ContainsKey(first) ||
|
||||
secondToFirst.ContainsKey(second))
|
||||
{
|
||||
throw new ArgumentException("Duplicate first or second");
|
||||
}
|
||||
firstToSecond.Add(first, second);
|
||||
secondToFirst.Add(second, first);
|
||||
}
|
||||
|
||||
public bool TryGetByFirst(TFirst first, out TSecond second)
|
||||
{
|
||||
return firstToSecond.TryGetValue(first, out second);
|
||||
}
|
||||
|
||||
public void Remove(TFirst first)
|
||||
{
|
||||
secondToFirst.Remove(firstToSecond[first]);
|
||||
firstToSecond.Remove(first);
|
||||
}
|
||||
|
||||
public ICollection<TFirst> GetAllKeys()
|
||||
{
|
||||
return secondToFirst.Values;
|
||||
}
|
||||
|
||||
public bool TryGetBySecond(TSecond second, out TFirst first)
|
||||
{
|
||||
return secondToFirst.TryGetValue(second, out first);
|
||||
}
|
||||
|
||||
public TSecond GetByFirst(TFirst first)
|
||||
{
|
||||
return firstToSecond[first];
|
||||
}
|
||||
|
||||
public TFirst GetBySecond(TSecond second)
|
||||
{
|
||||
return secondToFirst[second];
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Mirror/Runtime/Transport/LRM/BiDictionary.cs.meta
Normal file
11
Assets/Mirror/Runtime/Transport/LRM/BiDictionary.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8914d2a366f983644878d8499a097f9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Mirror/Runtime/Transport/LRM/Editor.meta
Normal file
8
Assets/Mirror/Runtime/Transport/LRM/Editor.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 004a635febf369f4680466f8a57d4b3d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
329
Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs
Normal file
329
Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using Mirror;
|
||||
using Mirror.SimpleWeb;
|
||||
using System;
|
||||
using kcp2k;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(LightReflectiveMirrorTransport))]
|
||||
public class LRMInspector : Editor
|
||||
{
|
||||
int serverPort = 7777;
|
||||
string serverIP;
|
||||
float invalidServerIP = 0;
|
||||
bool usingLLB = false;
|
||||
LRMDirectConnectModule directModule;
|
||||
string[] tabs = new string[] { "LRM Settings", "NAT Punch", "Load Balancer", "Other" };
|
||||
int currentTab = 0;
|
||||
|
||||
#if !IGNORANCE
|
||||
Type[] supportedTransports = new Type[3] { typeof(KcpTransport), typeof(SimpleWebTransport), typeof(TelepathyTransport) };
|
||||
#else
|
||||
Type[] supportedTransports = new Type[4] { typeof(KcpTransport), typeof(SimpleWebTransport), typeof(TelepathyTransport), typeof(IgnoranceTransport.Ignorance) };
|
||||
#endif
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var lrm = (LightReflectiveMirrorTransport)target;
|
||||
directModule = lrm.GetComponent<LRMDirectConnectModule>();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label(Resources.Load<Texture>("LRM"), GUILayout.Height(50), GUILayout.Width(100));
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (string.IsNullOrEmpty(lrm.loadBalancerAddress))
|
||||
{
|
||||
// First setup screen, ask if they are using LLB or just a single LRM node.
|
||||
EditorGUILayout.HelpBox("Thank you for using LRM!\nTo get started, please select which setup you are using.", MessageType.None);
|
||||
|
||||
if (GUILayout.Button("Load Balancer Setup"))
|
||||
{
|
||||
usingLLB = true;
|
||||
lrm.loadBalancerAddress = "127.0.0.1";
|
||||
serverPort = 7070;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Single LRM Node Setup"))
|
||||
{
|
||||
lrm.loadBalancerAddress = "127.0.0.1";
|
||||
lrm.useLoadBalancer = false;
|
||||
usingLLB = false;
|
||||
serverIP = "172.105.109.117";
|
||||
}
|
||||
}
|
||||
else if (usingLLB)
|
||||
{
|
||||
// They said they are using LLB, configure it!
|
||||
EditorGUILayout.HelpBox("The Load Balancer is another server that is different than the LRM node. Please enter the IP address or domain name of your Load Balancer server, along with the port.", MessageType.None);
|
||||
EditorGUILayout.HelpBox("Acceptable Examples: 127.0.0.1, mydomain.com", MessageType.Info);
|
||||
if (Time.realtimeSinceStartup - invalidServerIP < 5)
|
||||
EditorGUILayout.HelpBox("Invalid Server Address!", MessageType.Error);
|
||||
|
||||
serverIP = EditorGUILayout.TextField("Server Address", serverIP);
|
||||
serverPort = Mathf.Clamp(EditorGUILayout.IntField("Server Port", serverPort), ushort.MinValue, ushort.MaxValue);
|
||||
|
||||
if (GUILayout.Button("Continue"))
|
||||
{
|
||||
if (IPAddress.TryParse(serverIP, out IPAddress serverAddr))
|
||||
{
|
||||
lrm.loadBalancerAddress = serverAddr.ToString();
|
||||
lrm.loadBalancerPort = (ushort)serverPort;
|
||||
lrm.serverIP = "127.0.0.1";
|
||||
lrm.useLoadBalancer = true;
|
||||
usingLLB = false;
|
||||
serverIP = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Dns.GetHostEntry(serverIP).AddressList.Length > 0)
|
||||
{
|
||||
lrm.loadBalancerAddress = serverIP;
|
||||
lrm.loadBalancerPort = (ushort)serverPort;
|
||||
lrm.serverIP = "127.0.0.1";
|
||||
usingLLB = false;
|
||||
serverIP = "";
|
||||
}
|
||||
else
|
||||
invalidServerIP = Time.realtimeSinceStartup;
|
||||
}
|
||||
catch
|
||||
{
|
||||
invalidServerIP = Time.realtimeSinceStartup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lrm.clientToServerTransport == null)
|
||||
{
|
||||
// next up, the actual transport. We are going to loop over all the transport types here and let them select one.
|
||||
EditorGUILayout.HelpBox("We need to use the same transport used on the server. Please select the same transport used on your LRM Node(s)", MessageType.None);
|
||||
|
||||
foreach (var transport in supportedTransports)
|
||||
{
|
||||
if (GUILayout.Button(transport.Name))
|
||||
{
|
||||
var newTransportGO = new GameObject("LRM - Connector");
|
||||
newTransportGO.transform.SetParent(lrm.transform);
|
||||
var newTransport = newTransportGO.AddComponent(transport);
|
||||
lrm.clientToServerTransport = (Transport)newTransport;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrEmpty(lrm.serverIP))
|
||||
{
|
||||
// Empty server IP, this is pretty important! Lets show the UI to require it.
|
||||
EditorGUILayout.HelpBox("For a single LRM node setup, we need the IP address or domain name of your LRM server.", MessageType.None);
|
||||
EditorGUILayout.HelpBox("Acceptable Examples: 172.105.109.117, mydomain.com", MessageType.Info);
|
||||
|
||||
if (Time.realtimeSinceStartup - invalidServerIP < 5)
|
||||
EditorGUILayout.HelpBox("Invalid Server Address!", MessageType.Error);
|
||||
|
||||
serverIP = EditorGUILayout.TextField("Server Address", serverIP);
|
||||
serverPort = Mathf.Clamp(EditorGUILayout.IntField("Server Port", serverPort), ushort.MinValue, ushort.MaxValue);
|
||||
|
||||
if (GUILayout.Button("Continue"))
|
||||
{
|
||||
if (IPAddress.TryParse(serverIP, out IPAddress serverAddr))
|
||||
{
|
||||
lrm.serverIP = serverAddr.ToString();
|
||||
lrm.SetTransportPort((ushort)serverPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Dns.GetHostEntry(serverIP).AddressList.Length > 0)
|
||||
{
|
||||
lrm.serverIP = serverIP;
|
||||
lrm.SetTransportPort((ushort)serverPort);
|
||||
}
|
||||
else
|
||||
invalidServerIP = Time.realtimeSinceStartup;
|
||||
}
|
||||
catch
|
||||
{
|
||||
invalidServerIP = Time.realtimeSinceStartup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lrm.NATPunchtroughPort < 0)
|
||||
{
|
||||
// NAT Punchthrough configuration.
|
||||
EditorGUILayout.HelpBox("Do you wish to use NAT Punchthrough? This can reduce load by up to 80% on your LRM nodes, but exposes players IP's to other players.", MessageType.None);
|
||||
|
||||
if (GUILayout.Button("Use NAT Punchthrough"))
|
||||
{
|
||||
lrm.NATPunchtroughPort = 1;
|
||||
lrm.useNATPunch = true;
|
||||
lrm.gameObject.AddComponent<LRMDirectConnectModule>();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Do NOT use NAT Punchthrough"))
|
||||
lrm.NATPunchtroughPort = 1;
|
||||
|
||||
}
|
||||
else if (directModule != null && directModule.directConnectTransport == null)
|
||||
{
|
||||
// NAT Punchthrough setup.
|
||||
EditorGUILayout.HelpBox("To use direct connecting, we need a transport to communicate with the other clients. Please select a transport to use.", MessageType.None);
|
||||
|
||||
foreach (var transport in supportedTransports)
|
||||
{
|
||||
#if !IGNORANCE
|
||||
if (lrm.useNATPunch && (transport != typeof(KcpTransport)))
|
||||
continue;
|
||||
#else
|
||||
bool isSupported = transport == typeof(KcpTransport) ||
|
||||
transport == typeof(IgnoranceTransport.Ignorance);
|
||||
|
||||
if (lrm.useNATPunch && !isSupported)
|
||||
continue;
|
||||
#endif
|
||||
if (GUILayout.Button(transport.Name))
|
||||
{
|
||||
var newTransportGO = new GameObject("LRM - Direct Connect");
|
||||
newTransportGO.transform.SetParent(lrm.transform);
|
||||
var newTransport = newTransportGO.AddComponent(transport);
|
||||
directModule.directConnectTransport = (Transport)newTransport;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// They have completed the "setup guide" Show them the main UI
|
||||
|
||||
// Remove unused transports...
|
||||
foreach (var transport in lrm.GetComponentsInChildren<Transport>())
|
||||
{
|
||||
if (!(transport is LightReflectiveMirrorTransport))
|
||||
{
|
||||
if (transport != lrm.clientToServerTransport && (directModule == null ? true : directModule.directConnectTransport != transport))
|
||||
{
|
||||
if (transport.gameObject == lrm.gameObject)
|
||||
DestroyImmediate(transport);
|
||||
else
|
||||
DestroyImmediate(transport.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTab = GUILayout.Toolbar(currentTab, tabs);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginVertical("Window");
|
||||
switch (currentTab)
|
||||
{
|
||||
case 0:
|
||||
using (var change = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
// They are in the LRM Settings tab.
|
||||
if (lrm.useLoadBalancer)
|
||||
{
|
||||
EditorGUILayout.HelpBox("While using a Load Balancer, you don't set the LRM node IP or port.", MessageType.Info);
|
||||
GUI.enabled = false;
|
||||
}
|
||||
lrm.serverIP = EditorGUILayout.TextField("LRM Node IP", lrm.serverIP);
|
||||
lrm.serverPort = (ushort)Mathf.Clamp(EditorGUILayout.IntField("LRM Node Port", lrm.serverPort), ushort.MinValue, ushort.MaxValue);
|
||||
lrm.endpointServerPort = (ushort)Mathf.Clamp(EditorGUILayout.IntField("Endpoint Port", lrm.endpointServerPort), ushort.MinValue, ushort.MaxValue);
|
||||
|
||||
if (lrm.useLoadBalancer)
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
lrm.authenticationKey = EditorGUILayout.TextField("LRM Auth Key", lrm.authenticationKey);
|
||||
lrm.heartBeatInterval = EditorGUILayout.Slider("Heartbeat Time", lrm.heartBeatInterval, 0.1f, 5f);
|
||||
lrm.connectOnAwake = EditorGUILayout.Toggle("Connect on Awake", lrm.connectOnAwake);
|
||||
lrm.clientToServerTransport = (Transport)EditorGUILayout.ObjectField("LRM Transport", lrm.clientToServerTransport, typeof(Transport), true);
|
||||
if (change.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(lrm);
|
||||
}
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
break;
|
||||
case 1:
|
||||
// NAT punch tab.
|
||||
if (directModule == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("NAT Punchthrough disabled, missing Direct Connect.", MessageType.Info);
|
||||
if (GUILayout.Button("Add Direct Connect"))
|
||||
lrm.gameObject.AddComponent<LRMDirectConnectModule>();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !IGNORANCE
|
||||
if (!(directModule.directConnectTransport is KcpTransport))
|
||||
{
|
||||
EditorGUILayout.HelpBox("NAT Punch only supports KCP currently.", MessageType.Info);
|
||||
#else
|
||||
bool isSupported = (directModule.directConnectTransport is KcpTransport) ||
|
||||
(directModule.directConnectTransport is IgnoranceTransport.Ignorance);
|
||||
|
||||
if (!isSupported)
|
||||
{
|
||||
EditorGUILayout.HelpBox("NAT Punch only supports KCP and Ignorance currently.", MessageType.Info);
|
||||
#endif
|
||||
GUI.enabled = false;
|
||||
lrm.useNATPunch = false;
|
||||
}
|
||||
|
||||
lrm.useNATPunch = EditorGUILayout.Toggle("Use NAT Punch", lrm.useNATPunch);
|
||||
GUI.enabled = true;
|
||||
directModule.directConnectTransport = (Transport)EditorGUILayout.ObjectField("Direct Transport", directModule.directConnectTransport, typeof(Transport), true);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
break;
|
||||
case 2:
|
||||
// Load balancer tab
|
||||
lrm.useLoadBalancer = EditorGUILayout.Toggle("Use Load Balancer", lrm.useLoadBalancer);
|
||||
if (!lrm.useLoadBalancer)
|
||||
GUI.enabled = false;
|
||||
lrm.loadBalancerAddress = EditorGUILayout.TextField("Load Balancer Address", lrm.loadBalancerAddress);
|
||||
lrm.loadBalancerPort = (ushort)Mathf.Clamp(EditorGUILayout.IntField("Load Balancer Port", lrm.loadBalancerPort), ushort.MinValue, ushort.MaxValue);
|
||||
lrm.region = (LRMRegions)EditorGUILayout.EnumPopup("Node Region", lrm.region);
|
||||
if (!lrm.useLoadBalancer)
|
||||
GUI.enabled = true;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
break;
|
||||
case 3:
|
||||
// Other tab...
|
||||
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.TextField("Server Status", lrm.serverStatus);
|
||||
EditorGUILayout.TextField("Server ID", string.IsNullOrEmpty(lrm.serverId) ? "Not Hosting." : lrm.serverId);
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
lrm.serverName = EditorGUILayout.TextField("Server Name", lrm.serverName);
|
||||
lrm.extraServerData = EditorGUILayout.TextField("Extra Server Data", lrm.extraServerData);
|
||||
lrm.maxServerPlayers = EditorGUILayout.IntField("Max Server Players", lrm.maxServerPlayers);
|
||||
lrm.isPublicServer = EditorGUILayout.Toggle("Is Public Server", lrm.isPublicServer);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("connectedToRelay"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("disconnectedFromRelay"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("serverListUpdated"));
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
break;
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ebe9be4a049785a41ac7c27b7b2c82d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
230
Assets/Mirror/Runtime/Transport/LRM/HelpAttribute.cs
Normal file
230
Assets/Mirror/Runtime/Transport/LRM/HelpAttribute.cs
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
||||
/// <copyright file="HelpAttribute.cs">
|
||||
/// <See cref="https://github.com/johnearnshaw/unity-inspector-help"></See>
|
||||
/// Copyright (c) 2017, John Earnshaw, reblGreen Software Limited
|
||||
/// <See cref="https://github.com/johnearnshaw/"></See>
|
||||
/// <See cref="https://bitbucket.com/juanshaf/"></See>
|
||||
/// <See cref="https://reblgreen.com/"></See>
|
||||
/// All rights reserved.
|
||||
/// Redistribution and use in source and binary forms, with or without modification, are
|
||||
/// permitted provided that the following conditions are met:
|
||||
/// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
/// conditions and the following disclaimer.
|
||||
/// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
/// of conditions and the following disclaimer in the documentation and/or other materials
|
||||
/// provided with the distribution.
|
||||
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
/// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE
|
||||
/// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
/// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
/// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
/// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
/// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field, Inherited = true)]
|
||||
public class HelpAttribute : PropertyAttribute
|
||||
{
|
||||
public readonly string text;
|
||||
|
||||
// MessageType exists in UnityEditor namespace and can throw an exception when used outside the editor.
|
||||
// We spoof MessageType at the bottom of this script to ensure that errors are not thrown when
|
||||
// MessageType is unavailable.
|
||||
public readonly MessageType type;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a HelpBox to the Unity property inspector above this field.
|
||||
/// </summary>
|
||||
/// <param name="text">The help text to be displayed in the HelpBox.</param>
|
||||
/// <param name="type">The icon to be displayed in the HelpBox.</param>
|
||||
public HelpAttribute(string text, MessageType type = MessageType.Info)
|
||||
{
|
||||
this.text = text;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomPropertyDrawer(typeof(HelpAttribute))]
|
||||
public class HelpDrawer : PropertyDrawer
|
||||
{
|
||||
// Used for top and bottom padding between the text and the HelpBox border.
|
||||
const int paddingHeight = 8;
|
||||
|
||||
// Used to add some margin between the the HelpBox and the property.
|
||||
const int marginHeight = 2;
|
||||
|
||||
// Global field to store the original (base) property height.
|
||||
float baseHeight = 0;
|
||||
|
||||
// Custom added height for drawing text area which has the MultilineAttribute.
|
||||
float addedHeight = 0;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper which returns the PropertyDrawer.attribute field as a HelpAttribute.
|
||||
/// </summary>
|
||||
HelpAttribute helpAttribute { get { return (HelpAttribute)attribute; } }
|
||||
|
||||
/// <summary>
|
||||
/// A helper property to check for RangeAttribute.
|
||||
/// </summary>
|
||||
RangeAttribute rangeAttribute
|
||||
{
|
||||
get
|
||||
{
|
||||
var attributes = fieldInfo.GetCustomAttributes(typeof(RangeAttribute), true);
|
||||
return attributes != null && attributes.Length > 0 ? (RangeAttribute)attributes[0] : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper property to check for MultiLineAttribute.
|
||||
/// </summary>
|
||||
MultilineAttribute multilineAttribute
|
||||
{
|
||||
get
|
||||
{
|
||||
var attributes = fieldInfo.GetCustomAttributes(typeof(MultilineAttribute), true);
|
||||
return attributes != null && attributes.Length > 0 ? (MultilineAttribute)attributes[0] : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
|
||||
{
|
||||
// We store the original property height for later use...
|
||||
baseHeight = base.GetPropertyHeight(prop, label);
|
||||
|
||||
// This stops icon shrinking if text content doesn't fill out the container enough.
|
||||
float minHeight = paddingHeight * 5;
|
||||
|
||||
// Calculate the height of the HelpBox using the GUIStyle on the current skin and the inspector
|
||||
// window's currentViewWidth.
|
||||
var content = new GUIContent(helpAttribute.text);
|
||||
var style = GUI.skin.GetStyle("helpbox");
|
||||
|
||||
var height = style.CalcHeight(content, EditorGUIUtility.currentViewWidth);
|
||||
|
||||
// We add tiny padding here to make sure the text is not overflowing the HelpBox from the top
|
||||
// and bottom.
|
||||
height += marginHeight * 2;
|
||||
|
||||
// Since we draw a custom text area with the label above if our property contains the
|
||||
// MultilineAttribute, we need to add some extra height to compensate. This is stored in a
|
||||
// seperate global field so we can use it again later.
|
||||
if (multilineAttribute != null && prop.propertyType == SerializedPropertyType.String)
|
||||
{
|
||||
addedHeight = 48f;
|
||||
}
|
||||
|
||||
// If the calculated HelpBox is less than our minimum height we use this to calculate the returned
|
||||
// height instead.
|
||||
return height > minHeight ? height + baseHeight + addedHeight : minHeight + baseHeight + addedHeight;
|
||||
}
|
||||
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
|
||||
{
|
||||
// We get a local reference to the MultilineAttribute as we use it twice in this method and it
|
||||
// saves calling the logic twice for minimal optimization, etc...
|
||||
var multiline = multilineAttribute;
|
||||
|
||||
EditorGUI.BeginProperty(position, label, prop);
|
||||
|
||||
// Copy the position out so we can calculate the position of our HelpBox without affecting the
|
||||
// original position.
|
||||
var helpPos = position;
|
||||
|
||||
helpPos.height -= baseHeight + marginHeight;
|
||||
|
||||
|
||||
if (multiline != null)
|
||||
{
|
||||
helpPos.height -= addedHeight;
|
||||
}
|
||||
|
||||
// Renders the HelpBox in the Unity inspector UI.
|
||||
EditorGUI.HelpBox(helpPos, helpAttribute.text, helpAttribute.type);
|
||||
|
||||
position.y += helpPos.height + marginHeight;
|
||||
position.height = baseHeight;
|
||||
|
||||
|
||||
// If we have a RangeAttribute on our field, we need to handle the PropertyDrawer differently to
|
||||
// keep the same style as Unity's default.
|
||||
var range = rangeAttribute;
|
||||
|
||||
if (range != null)
|
||||
{
|
||||
if (prop.propertyType == SerializedPropertyType.Float)
|
||||
{
|
||||
EditorGUI.Slider(position, prop, range.min, range.max, label);
|
||||
}
|
||||
else if (prop.propertyType == SerializedPropertyType.Integer)
|
||||
{
|
||||
EditorGUI.IntSlider(position, prop, (int)range.min, (int)range.max, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not numeric so draw standard property field as punishment for adding RangeAttribute to
|
||||
// a property which can not have a range :P
|
||||
EditorGUI.PropertyField(position, prop, label);
|
||||
}
|
||||
}
|
||||
else if (multiline != null)
|
||||
{
|
||||
// Here's where we handle the PropertyDrawer differently if we have a MultiLineAttribute, to try
|
||||
// and keep some kind of multiline text area. This is not identical to Unity's default but is
|
||||
// better than nothing...
|
||||
if (prop.propertyType == SerializedPropertyType.String)
|
||||
{
|
||||
var style = GUI.skin.label;
|
||||
var size = style.CalcHeight(label, EditorGUIUtility.currentViewWidth);
|
||||
|
||||
EditorGUI.LabelField(position, label);
|
||||
|
||||
position.y += size;
|
||||
position.height += addedHeight - size;
|
||||
|
||||
// Fixed text dissappearing thanks to: http://answers.unity3d.com/questions/244043/textarea-does-not-work-text-dissapears-solution-is.html
|
||||
prop.stringValue = EditorGUI.TextArea(position, prop.stringValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Again with a MultilineAttribute on a non-text field deserves for the standard property field
|
||||
// to be drawn as punishment :P
|
||||
EditorGUI.PropertyField(position, prop, label);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we get to here it means we're drawing the default property field below the HelpBox. More custom
|
||||
// and built in PropertyDrawers could be implemented to enable HelpBox but it could easily make for
|
||||
// hefty else/if block which would need refactoring!
|
||||
EditorGUI.PropertyField(position, prop, label);
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Replicate MessageType Enum if we are not in editor as this enum exists in UnityEditor namespace.
|
||||
// This should stop errors being logged the same as Shawn Featherly's commit in the Github repo but I
|
||||
// feel is cleaner than having the conditional directive in the middle of the HelpAttribute constructor.
|
||||
public enum MessageType
|
||||
{
|
||||
None,
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
#endif
|
||||
11
Assets/Mirror/Runtime/Transport/LRM/HelpAttribute.cs.meta
Normal file
11
Assets/Mirror/Runtime/Transport/LRM/HelpAttribute.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6a2112e9804bfdd4d8f1ad9bc5e4d168
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Mirror/Runtime/Transport/LRM/LRM.asmdef
Normal file
18
Assets/Mirror/Runtime/Transport/LRM/LRM.asmdef
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "LRM",
|
||||
"references": [
|
||||
"GUID:30817c1a0e6d646d99c048fc403f5979",
|
||||
"GUID:3b5390adca4e2bb4791cb930316d6f3e",
|
||||
"GUID:725ee7191c021de4dbf9269590ded755",
|
||||
"GUID:6806a62c384838046a3c66c44f06d75f"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Mirror/Runtime/Transport/LRM/LRM.asmdef.meta
Normal file
7
Assets/Mirror/Runtime/Transport/LRM/LRM.asmdef.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3e90199726a18bc488368938e8df23bf
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
199
Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs
Normal file
199
Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
// This is an optional module for adding direct connect support
|
||||
|
||||
using Mirror;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using LightReflectiveMirror;
|
||||
|
||||
[RequireComponent(typeof(LightReflectiveMirrorTransport))]
|
||||
public class LRMDirectConnectModule : MonoBehaviour
|
||||
{
|
||||
[HideInInspector]
|
||||
public Transport directConnectTransport;
|
||||
public bool showDebugLogs;
|
||||
private LightReflectiveMirrorTransport lightMirrorTransport;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
lightMirrorTransport = GetComponent<LightReflectiveMirrorTransport>();
|
||||
|
||||
if (directConnectTransport == null)
|
||||
{
|
||||
Debug.Log("Direct Connect Transport is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (directConnectTransport is LightReflectiveMirrorTransport)
|
||||
{
|
||||
Debug.Log("Direct Connect Transport Cannot be the relay, silly. :P");
|
||||
return;
|
||||
}
|
||||
|
||||
directConnectTransport.OnServerConnected = (OnServerConnected);
|
||||
directConnectTransport.OnServerDataReceived = (OnServerDataReceived);
|
||||
directConnectTransport.OnServerDisconnected = (OnServerDisconnected);
|
||||
directConnectTransport.OnServerError = (OnServerError);
|
||||
directConnectTransport.OnClientConnected = (OnClientConnected);
|
||||
directConnectTransport.OnClientDataReceived = (OnClientDataReceived);
|
||||
directConnectTransport.OnClientDisconnected = (OnClientDisconnected);
|
||||
directConnectTransport.OnClientError = (OnClientError);
|
||||
}
|
||||
|
||||
public void StartServer(int port)
|
||||
{
|
||||
if(port > 0)
|
||||
SetTransportPort(port);
|
||||
|
||||
directConnectTransport.ServerStart();
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Direct Connect Server Created!");
|
||||
}
|
||||
|
||||
public void StopServer()
|
||||
{
|
||||
directConnectTransport.ServerStop();
|
||||
}
|
||||
|
||||
public void JoinServer(string ip, int port)
|
||||
{
|
||||
if (SupportsNATPunch())
|
||||
SetTransportPort(port);
|
||||
|
||||
directConnectTransport.ClientConnect(ip);
|
||||
}
|
||||
|
||||
public void SetTransportPort(int port)
|
||||
{
|
||||
#if !IGNORANCE
|
||||
if (directConnectTransport is kcp2k.KcpTransport kcpTransport)
|
||||
kcpTransport.Port = (ushort)port;
|
||||
else
|
||||
{
|
||||
ThrowIfNotSupported();
|
||||
}
|
||||
#else
|
||||
if (directConnectTransport is kcp2k.KcpTransport kcpTransport)
|
||||
kcpTransport.Port = (ushort)port;
|
||||
else if (directConnectTransport is IgnoranceTransport.Ignorance ignorance)
|
||||
ignorance.port = (ushort)port;
|
||||
else
|
||||
{
|
||||
ThrowIfNotSupported();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public int GetTransportPort()
|
||||
{
|
||||
#if !IGNORANCE
|
||||
if (directConnectTransport is kcp2k.KcpTransport kcpTransport)
|
||||
return kcpTransport.Port;
|
||||
else
|
||||
{
|
||||
ThrowIfNotSupported();
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (directConnectTransport is kcp2k.KcpTransport kcpTransport)
|
||||
return kcpTransport.Port;
|
||||
else if (directConnectTransport is IgnoranceTransport.Ignorance ignorance)
|
||||
return ignorance.port;
|
||||
else
|
||||
{
|
||||
ThrowIfNotSupported();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static int ThrowIfNotSupported()
|
||||
{
|
||||
#if !IGNORANCE
|
||||
throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AT THE MOMENT.");
|
||||
#else
|
||||
throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AND IGNORANCE");
|
||||
#endif
|
||||
}
|
||||
|
||||
public bool SupportsNATPunch()
|
||||
{
|
||||
#if !IGNORANCE
|
||||
return directConnectTransport is kcp2k.KcpTransport;
|
||||
#else
|
||||
return directConnectTransport is kcp2k.KcpTransport || directConnectTransport is IgnoranceTransport.Ignorance;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void KickClient(int clientID)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Kicked direct connect client.");
|
||||
|
||||
directConnectTransport.ServerDisconnect(clientID);
|
||||
}
|
||||
|
||||
public void ClientDisconnect()
|
||||
{
|
||||
directConnectTransport.ClientDisconnect();
|
||||
}
|
||||
|
||||
public void ServerSend(int clientID, ArraySegment<byte> data, int channel)
|
||||
{
|
||||
directConnectTransport.ServerSend(clientID, data, channel);
|
||||
}
|
||||
|
||||
public void ClientSend(ArraySegment<byte> data, int channel)
|
||||
{
|
||||
directConnectTransport.ClientSend(data, channel);
|
||||
}
|
||||
|
||||
#region Transport Callbacks
|
||||
void OnServerConnected(int clientID)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Direct Connect Client Connected");
|
||||
lightMirrorTransport.DirectAddClient(clientID);
|
||||
}
|
||||
|
||||
void OnServerDataReceived(int clientID, ArraySegment<byte> data, int channel)
|
||||
{
|
||||
lightMirrorTransport.DirectReceiveData(data, channel, clientID);
|
||||
}
|
||||
|
||||
void OnServerDisconnected(int clientID)
|
||||
{
|
||||
lightMirrorTransport.DirectRemoveClient(clientID);
|
||||
}
|
||||
|
||||
void OnServerError(int client, Exception error)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Direct Server Error: " + error);
|
||||
}
|
||||
|
||||
void OnClientConnected()
|
||||
{
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Direct Connect Client Joined");
|
||||
|
||||
lightMirrorTransport.DirectClientConnected();
|
||||
}
|
||||
|
||||
void OnClientDisconnected()
|
||||
{
|
||||
lightMirrorTransport.DirectDisconnected();
|
||||
}
|
||||
|
||||
void OnClientDataReceived(ArraySegment<byte> data, int channel)
|
||||
{
|
||||
lightMirrorTransport.DirectReceiveData(data, channel);
|
||||
}
|
||||
|
||||
void OnClientError(Exception error)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
Debug.Log("Direct Client Error: " + error);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c4cbff877abc42448dd829920c6c233
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
198
Assets/Mirror/Runtime/Transport/LRM/LRMTools.cs
Normal file
198
Assets/Mirror/Runtime/Transport/LRM/LRMTools.cs
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public static class LRMTools
|
||||
{
|
||||
public static void WriteByte(this byte[] data, ref int position, byte value)
|
||||
{
|
||||
data[position] = value;
|
||||
position += 1;
|
||||
}
|
||||
|
||||
public static byte ReadByte(this byte[] data, ref int position)
|
||||
{
|
||||
byte value = data[position];
|
||||
position += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteBool(this byte[] data, ref int position, bool value)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* dataPtr = &data[position])
|
||||
{
|
||||
bool* valuePtr = (bool*)dataPtr;
|
||||
*valuePtr = value;
|
||||
position += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ReadBool(this byte[] data, ref int position)
|
||||
{
|
||||
bool value = BitConverter.ToBoolean(data, position);
|
||||
position += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteString(this byte[] data, ref int position, string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
data.WriteInt(ref position, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.WriteInt(ref position, value.Length);
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
data.WriteChar(ref position, value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadString(this byte[] data, ref int position)
|
||||
{
|
||||
string value = default;
|
||||
|
||||
int stringSize = data.ReadInt(ref position);
|
||||
|
||||
for (int i = 0; i < stringSize; i++)
|
||||
value += data.ReadChar(ref position);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteBytes(this byte[] data, ref int position, byte[] value)
|
||||
{
|
||||
data.WriteInt(ref position, value.Length);
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
data.WriteByte(ref position, value[i]);
|
||||
}
|
||||
|
||||
public static byte[] ReadBytes(this byte[] data, ref int position)
|
||||
{
|
||||
int byteSize = data.ReadInt(ref position);
|
||||
|
||||
byte[] value = new byte[byteSize];
|
||||
|
||||
for (int i = 0; i < byteSize; i++)
|
||||
value[i] = data.ReadByte(ref position);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteChar(this byte[] data, ref int position, char value)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* dataPtr = &data[position])
|
||||
{
|
||||
char* valuePtr = (char*)dataPtr;
|
||||
*valuePtr = value;
|
||||
position += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static char ReadChar(this byte[] data, ref int position)
|
||||
{
|
||||
char value = BitConverter.ToChar(data, position);
|
||||
position += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteInt(this byte[] data, ref int position, int value)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* dataPtr = &data[position])
|
||||
{
|
||||
int* valuePtr = (int*)dataPtr;
|
||||
*valuePtr = value;
|
||||
position += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int ReadInt(this byte[] data, ref int position)
|
||||
{
|
||||
int value = BitConverter.ToInt32(data, position);
|
||||
position += 4;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CompressorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Decompresses the string.
|
||||
/// </summary>
|
||||
/// <param name="compressedText">The compressed text.</param>
|
||||
/// <returns></returns>
|
||||
public static string Decompress(this string compressedText)
|
||||
{
|
||||
byte[] gZipBuffer = Convert.FromBase64String(compressedText);
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
|
||||
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
|
||||
|
||||
var buffer = new byte[dataLength];
|
||||
|
||||
memoryStream.Position = 0;
|
||||
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
|
||||
{
|
||||
gZipStream.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class JsonUtilityHelper
|
||||
{
|
||||
public static bool IsJsonArray(string json)
|
||||
{
|
||||
return json.StartsWith("[") && json.EndsWith("]");
|
||||
}
|
||||
|
||||
public static T[] FromJson<T>(string json)
|
||||
{
|
||||
if (!IsJsonArray(json))
|
||||
{
|
||||
throw new System.FormatException("The input json string is not a Json Array");
|
||||
}
|
||||
json = "{\"Items\":" + json + "}";
|
||||
JsonWrapper<T> wrapper = JsonUtility.FromJson<JsonWrapper<T>>(json);
|
||||
return wrapper.Items;
|
||||
}
|
||||
|
||||
public static string ToJson<T>(T[] array)
|
||||
{
|
||||
JsonWrapper<T> wrapper = new JsonWrapper<T>();
|
||||
wrapper.Items = array;
|
||||
return JsonUtility.ToJson(wrapper);
|
||||
}
|
||||
|
||||
public static string ToJson<T>(T[] array, bool prettyPrint)
|
||||
{
|
||||
JsonWrapper<T> wrapper = new JsonWrapper<T>();
|
||||
wrapper.Items = array;
|
||||
return JsonUtility.ToJson(wrapper, prettyPrint);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class JsonWrapper<T>
|
||||
{
|
||||
public T[] Items;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Mirror/Runtime/Transport/LRM/LRMTools.cs.meta
Normal file
11
Assets/Mirror/Runtime/Transport/LRM/LRMTools.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 603a99af3f33b8c4482f9908752ea561
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Mirror/Runtime/Transport/LRM/LRMTransport.meta
Normal file
8
Assets/Mirror/Runtime/Transport/LRM/LRMTransport.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 88f72e39589c77d6d92dca0d511c7d5a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
using Mirror;
|
||||
using System;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
public void DirectAddClient(int clientID)
|
||||
{
|
||||
if (!_isServer)
|
||||
return;
|
||||
|
||||
_connectedDirectClients.Add(clientID, _currentMemberId);
|
||||
OnServerConnected?.Invoke(_currentMemberId);
|
||||
_currentMemberId++;
|
||||
}
|
||||
|
||||
public void DirectRemoveClient(int clientID)
|
||||
{
|
||||
if (!_isServer)
|
||||
return;
|
||||
|
||||
OnServerDisconnected?.Invoke(_connectedDirectClients.GetByFirst(clientID));
|
||||
_connectedDirectClients.Remove(clientID);
|
||||
}
|
||||
|
||||
public void DirectReceiveData(ArraySegment<byte> data, int channel, int clientID = -1)
|
||||
{
|
||||
if (_isServer)
|
||||
OnServerDataReceived?.Invoke(_connectedDirectClients.GetByFirst(clientID), data, channel);
|
||||
|
||||
if (_isClient)
|
||||
OnClientDataReceived?.Invoke(data, channel);
|
||||
}
|
||||
|
||||
public void DirectClientConnected()
|
||||
{
|
||||
_directConnected = true;
|
||||
OnClientConnected?.Invoke();
|
||||
}
|
||||
|
||||
public void DirectDisconnected()
|
||||
{
|
||||
if (_directConnected)
|
||||
{
|
||||
_isClient = false;
|
||||
_directConnected = false;
|
||||
OnClientDisconnected?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
_directConnected = false;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.JoinServer);
|
||||
_clientSendBuffer.WriteString(ref pos, _cachedHostID);
|
||||
_clientSendBuffer.WriteBool(ref pos, false); // Direct failed, use relay
|
||||
|
||||
_isClient = true;
|
||||
|
||||
#if MIRROR_40_0_OR_NEWER
|
||||
clientToServerTransport.ClientSend(new System.ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
#else
|
||||
clientToServerTransport.ClientSend(0, new System.ArraySegment<byte>(_clientSendBuffer, 0, pos));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_clientProxy != null)
|
||||
{
|
||||
_clientProxy.Dispose();
|
||||
_clientProxy = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1e38dc8d43e06744484cf2962c017606
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
using Mirror;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Net;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
IEnumerator NATPunch(IPEndPoint remoteAddress)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_NATPuncher.Send(_punchData, 1, remoteAddress);
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
void RecvData(IAsyncResult result)
|
||||
{
|
||||
IPEndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
|
||||
var data = _NATPuncher.EndReceive(result, ref newClientEP);
|
||||
_NATPuncher.BeginReceive(new AsyncCallback(RecvData), _NATPuncher);
|
||||
|
||||
if (!newClientEP.Address.Equals(_relayPuncherIP.Address))
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
if (_serverProxies.TryGetByFirst(newClientEP, out SocketProxy foundProxy))
|
||||
{
|
||||
if (data.Length > 2)
|
||||
foundProxy.RelayData(data, data.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
_serverProxies.Add(newClientEP, new SocketProxy(_NATIP.Port + 1, newClientEP));
|
||||
_serverProxies.GetByFirst(newClientEP).dataReceived += ServerProcessProxyData;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isClient)
|
||||
{
|
||||
if (_clientProxy == null)
|
||||
{
|
||||
_clientProxy = new SocketProxy(_NATIP.Port - 1);
|
||||
_clientProxy.dataReceived += ClientProcessProxyData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_clientProxy.ClientRelayData(data, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerProcessProxyData(IPEndPoint remoteEndpoint, byte[] data)
|
||||
{
|
||||
_NATPuncher.Send(data, data.Length, remoteEndpoint);
|
||||
}
|
||||
|
||||
void ClientProcessProxyData(IPEndPoint _, byte[] data)
|
||||
{
|
||||
_NATPuncher.Send(data, data.Length, _directConnectEndpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3d493f36a877ab042875f198b110ebb3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
using Mirror;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
public override bool ServerActive() => _isServer;
|
||||
public override bool Available() => _connectedToRelay;
|
||||
public override void ClientConnect(Uri uri) => ClientConnect(uri.Host);
|
||||
public override int GetMaxPacketSize(int channelId = 0) => clientToServerTransport.GetMaxPacketSize(channelId);
|
||||
public override bool ClientConnected() => _isClient;
|
||||
|
||||
public override void ServerLateUpdate()
|
||||
{
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.directConnectTransport.ServerLateUpdate();
|
||||
}
|
||||
|
||||
public override string ServerGetClientAddress(int connectionId)
|
||||
{
|
||||
if (_connectedRelayClients.TryGetBySecond(connectionId, out int relayId))
|
||||
return relayId.ToString();
|
||||
|
||||
if (_connectedDirectClients.TryGetBySecond(connectionId, out int directId))
|
||||
return "DIRECT-" + directId;
|
||||
|
||||
// Shouldn't ever get here.
|
||||
return "?";
|
||||
}
|
||||
|
||||
public override void ClientEarlyUpdate()
|
||||
{
|
||||
clientToServerTransport.ClientEarlyUpdate();
|
||||
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.directConnectTransport.ClientEarlyUpdate();
|
||||
}
|
||||
|
||||
public override void ClientLateUpdate()
|
||||
{
|
||||
clientToServerTransport.ClientLateUpdate();
|
||||
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.directConnectTransport.ClientLateUpdate();
|
||||
}
|
||||
|
||||
public override void ServerEarlyUpdate()
|
||||
{
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.directConnectTransport.ServerEarlyUpdate();
|
||||
}
|
||||
|
||||
public override void ClientConnect(string address)
|
||||
{
|
||||
if (!Available())
|
||||
{
|
||||
Debug.Log("Not connected to relay!");
|
||||
OnClientDisconnected?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isClient || _isServer)
|
||||
throw new Exception("Cannot connect while hosting/already connected!");
|
||||
|
||||
_cachedHostID = address;
|
||||
|
||||
var room = GetServerForID(address);
|
||||
|
||||
if (!useLoadBalancer)
|
||||
{
|
||||
int pos = 0;
|
||||
_directConnected = false;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.JoinServer);
|
||||
_clientSendBuffer.WriteString(ref pos, address);
|
||||
_clientSendBuffer.WriteBool(ref pos, _directConnectModule != null);
|
||||
|
||||
if (_directConnectModule == null)
|
||||
{
|
||||
_clientSendBuffer.WriteString(ref pos, "0.0.0.0");
|
||||
}
|
||||
else
|
||||
{
|
||||
_clientSendBuffer.WriteString(ref pos, GetLocalIp() ?? "0.0.0.0");
|
||||
}
|
||||
|
||||
_isClient = true;
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(JoinOtherRelayAndMatch(room, address));
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClientDisconnect()
|
||||
{
|
||||
_isClient = false;
|
||||
|
||||
// make sure we are even connected to a relay
|
||||
if (Available())
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.LeaveRoom);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.ClientDisconnect();
|
||||
}
|
||||
|
||||
public override void ClientSend(ArraySegment<byte> segment, int channelId)
|
||||
{
|
||||
if (_directConnected)
|
||||
{
|
||||
_directConnectModule.ClientSend(segment, channelId);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.SendData);
|
||||
_clientSendBuffer.WriteBytes(ref pos, segment.Array.Take(segment.Count).ToArray());
|
||||
_clientSendBuffer.WriteInt(ref pos, 0);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), channelId);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ServerDisconnect(int connectionId)
|
||||
{
|
||||
if (_connectedRelayClients.TryGetBySecond(connectionId, out int relayId))
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.KickPlayer);
|
||||
_clientSendBuffer.WriteInt(ref pos, relayId);
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_connectedDirectClients.TryGetBySecond(connectionId, out int directId))
|
||||
_directConnectModule.KickClient(directId);
|
||||
}
|
||||
|
||||
public override void ServerSend(int connectionId, ArraySegment<byte> segment, int channelId)
|
||||
{
|
||||
if (_directConnectModule != null && _connectedDirectClients.TryGetBySecond(connectionId, out int directId))
|
||||
{
|
||||
_directConnectModule.ServerSend(directId, segment, channelId);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.SendData);
|
||||
_clientSendBuffer.WriteBytes(ref pos, segment.Array.Take(segment.Count).ToArray());
|
||||
_clientSendBuffer.WriteInt(ref pos, _connectedRelayClients.GetBySecond(connectionId));
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), channelId);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ServerStart()
|
||||
{
|
||||
if (!Available())
|
||||
{
|
||||
Debug.Log("Not connected to relay! Server failed to start.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isClient || _isServer)
|
||||
{
|
||||
Debug.Log("Cannot host while already hosting or connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
_isServer = true;
|
||||
_connectedRelayClients = new BiDictionary<int, int>();
|
||||
_currentMemberId = 1;
|
||||
_connectedDirectClients = new BiDictionary<int, int>();
|
||||
|
||||
var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys());
|
||||
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
_serverProxies.GetByFirst(keys[i]).Dispose();
|
||||
_serverProxies.Remove(keys[i]);
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.CreateRoom);
|
||||
|
||||
_clientSendBuffer.WriteInt(ref pos, maxServerPlayers);
|
||||
_clientSendBuffer.WriteString(ref pos, serverName);
|
||||
_clientSendBuffer.WriteBool(ref pos, isPublicServer);
|
||||
_clientSendBuffer.WriteString(ref pos, extraServerData);
|
||||
|
||||
// If we have direct connect module, and our local IP isnt null, tell server. Only time local IP is null is on cellular networks, such as IOS and Android.
|
||||
_clientSendBuffer.WriteBool(ref pos, _directConnectModule != null ? GetLocalIp() != null : false);
|
||||
|
||||
if (_directConnectModule != null && GetLocalIp() != null && useNATPunch)
|
||||
{
|
||||
_clientSendBuffer.WriteString(ref pos, GetLocalIp());
|
||||
// Transport port will be NAT port + 1 for the proxy connections.
|
||||
_directConnectModule.StartServer(useNATPunch ? _NATIP.Port + 1 : -1);
|
||||
}
|
||||
else
|
||||
_clientSendBuffer.WriteString(ref pos, "0.0.0.0");
|
||||
|
||||
if (useNATPunch)
|
||||
{
|
||||
_clientSendBuffer.WriteBool(ref pos, true);
|
||||
_clientSendBuffer.WriteInt(ref pos, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteInt(ref pos, _directConnectModule == null ? 1 : _directConnectModule.SupportsNATPunch() ? _directConnectModule.GetTransportPort() : 1);
|
||||
}
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
|
||||
public override void ServerStop()
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
_isServer = false;
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.LeaveRoom);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
|
||||
if (_directConnectModule != null)
|
||||
_directConnectModule.StopServer();
|
||||
|
||||
var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys());
|
||||
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
_serverProxies.GetByFirst(keys[i]).Dispose();
|
||||
_serverProxies.Remove(keys[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Uri ServerUri()
|
||||
{
|
||||
UriBuilder builder = new UriBuilder
|
||||
{
|
||||
Scheme = "LRM",
|
||||
Host = serverId.ToString()
|
||||
};
|
||||
|
||||
return builder.Uri;
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
_isAuthenticated = false;
|
||||
_isClient = false;
|
||||
_isServer = false;
|
||||
_connectedToRelay = false;
|
||||
clientToServerTransport.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 16602a520793b6044894096e873bc28d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
using Mirror;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
public void RequestServerList(LRMRegions searchRegion = LRMRegions.Any)
|
||||
{
|
||||
if (_isAuthenticated && _connectedToRelay)
|
||||
StartCoroutine(GetServerList(searchRegion));
|
||||
else
|
||||
Debug.Log("You must be connected to Relay to request server list!");
|
||||
}
|
||||
|
||||
IEnumerator RelayConnect()
|
||||
{
|
||||
string url = $"http://{loadBalancerAddress}:{loadBalancerPort}/api/join/";
|
||||
serverStatus = "Waiting for LLB...";
|
||||
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
|
||||
{
|
||||
// Request and wait for the desired page.
|
||||
webRequest.SetRequestHeader("x-Region", ((int)region).ToString());
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Credentials", "true");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
yield return webRequest.SendWebRequest();
|
||||
var result = webRequest.downloadHandler.text;
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
switch (webRequest.result)
|
||||
{
|
||||
case UnityWebRequest.Result.ConnectionError:
|
||||
case UnityWebRequest.Result.DataProcessingError:
|
||||
case UnityWebRequest.Result.ProtocolError:
|
||||
Debug.LogWarning("LRM | Network Error while getting a relay to join from Load Balancer.");
|
||||
break;
|
||||
case UnityWebRequest.Result.Success:
|
||||
var parsedAddress = JsonUtility.FromJson<RelayAddress>(result);
|
||||
Connect(parsedAddress.address, parsedAddress.port);
|
||||
endpointServerPort = parsedAddress.endpointPort;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (webRequest.isNetworkError || webRequest.isHttpError)
|
||||
{
|
||||
Debug.LogWarning("LRM | Network Error while getting a relay to join from Load Balancer.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// join here
|
||||
var parsedAddress = JsonUtility.FromJson<RelayAddress>(result);
|
||||
Connect(parsedAddress.address, parsedAddress.port);
|
||||
endpointServerPort = parsedAddress.endpointPort;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator JoinOtherRelayAndMatch(Room? roomValue, string ID)
|
||||
{
|
||||
var room = new Room();
|
||||
|
||||
// using load balancer, we NEED the server's relay address
|
||||
if (roomValue.HasValue)
|
||||
room = roomValue.Value;
|
||||
else
|
||||
{
|
||||
_serverListUpdated = false;
|
||||
RequestServerList();
|
||||
|
||||
yield return new WaitUntil(() => _serverListUpdated);
|
||||
|
||||
var foundRoom = GetServerForID(ID);
|
||||
|
||||
if (foundRoom.HasValue)
|
||||
{
|
||||
room = foundRoom.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("LRM | Client tried to join a server that does not exist!");
|
||||
OnClientDisconnected?.Invoke();
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for disconnection
|
||||
DisconnectFromRelay();
|
||||
|
||||
while (IsAuthenticated())
|
||||
yield return null;
|
||||
|
||||
endpointServerPort = room.relayInfo.endpointPort;
|
||||
Connect(room.relayInfo.address, room.relayInfo.port);
|
||||
|
||||
while (!IsAuthenticated())
|
||||
yield return null;
|
||||
|
||||
int pos = 0;
|
||||
_directConnected = false;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.JoinServer);
|
||||
_clientSendBuffer.WriteString(ref pos, room.serverId);
|
||||
_clientSendBuffer.WriteBool(ref pos, _directConnectModule != null);
|
||||
|
||||
string local = GetLocalIp();
|
||||
|
||||
_clientSendBuffer.WriteString(ref pos, local ?? "0.0.0.0");
|
||||
|
||||
_isClient = true;
|
||||
|
||||
clientToServerTransport.ClientSend(new System.ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
|
||||
IEnumerator GetServerList(LRMRegions region)
|
||||
{
|
||||
if (!useLoadBalancer)
|
||||
{
|
||||
string uri = $"http://{serverIP}:{endpointServerPort}/api/compressed/servers";
|
||||
|
||||
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
|
||||
{
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Credentials", "true");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
webRequest.SetRequestHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
// Request and wait for the desired page.
|
||||
yield return webRequest.SendWebRequest();
|
||||
var result = webRequest.downloadHandler.text;
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
switch (webRequest.result)
|
||||
{
|
||||
case UnityWebRequest.Result.ConnectionError:
|
||||
case UnityWebRequest.Result.DataProcessingError:
|
||||
case UnityWebRequest.Result.ProtocolError:
|
||||
Debug.LogWarning("LRM | Network Error while retreiving the server list!");
|
||||
break;
|
||||
|
||||
case UnityWebRequest.Result.Success:
|
||||
relayServerList?.Clear();
|
||||
relayServerList = JsonUtilityHelper.FromJson<Room>(result.Decompress()).ToList();
|
||||
serverListUpdated?.Invoke();
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (webRequest.isNetworkError || webRequest.isHttpError)
|
||||
{
|
||||
Debug.LogWarning("LRM | Network Error while retreiving the server list!");
|
||||
}
|
||||
else
|
||||
{
|
||||
relayServerList?.Clear();
|
||||
relayServerList = JsonUtilityHelper.FromJson<Room>(result.Decompress()).ToList();
|
||||
serverListUpdated?.Invoke();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else // get master list from load balancer
|
||||
{
|
||||
yield return StartCoroutine(RetrieveMasterServerListFromLoadBalancer(region));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets master list from the LB.
|
||||
/// This can be optimized but for now it is it's
|
||||
/// own separate method, so i can understand wtf is going on :D
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator RetrieveMasterServerListFromLoadBalancer(LRMRegions region)
|
||||
{
|
||||
string uri = $"http://{loadBalancerAddress}:{loadBalancerPort}/api/masterlist/";
|
||||
|
||||
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
|
||||
{
|
||||
webRequest.SetRequestHeader("x-Region", ((int)region).ToString());
|
||||
// Request and wait for the desired page.
|
||||
yield return webRequest.SendWebRequest();
|
||||
var result = webRequest.downloadHandler.text;
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
switch (webRequest.result)
|
||||
{
|
||||
case UnityWebRequest.Result.ConnectionError:
|
||||
case UnityWebRequest.Result.DataProcessingError:
|
||||
case UnityWebRequest.Result.ProtocolError:
|
||||
Debug.LogWarning("LRM | Network Error while retreiving the server list!");
|
||||
break;
|
||||
|
||||
case UnityWebRequest.Result.Success:
|
||||
relayServerList?.Clear();
|
||||
relayServerList = JsonUtilityHelper.FromJson<Room>(result).ToList();
|
||||
serverListUpdated?.Invoke();
|
||||
_serverListUpdated = true;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (webRequest.isNetworkError || webRequest.isHttpError)
|
||||
{
|
||||
Debug.LogWarning("LRM | Network Error while retreiving the server list!");
|
||||
}
|
||||
else
|
||||
{
|
||||
relayServerList?.Clear();
|
||||
relayServerList = JsonUtilityHelper.FromJson<Room>(result).ToList();
|
||||
serverListUpdated?.Invoke();
|
||||
_serverListUpdated = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ce47885d25567b4a8c0d6f3727de7f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
using Mirror;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
// Connection/auth variables
|
||||
public Transport clientToServerTransport;
|
||||
public string serverIP = null;
|
||||
public ushort serverPort = 7777;
|
||||
public ushort endpointServerPort = 8080;
|
||||
public float heartBeatInterval = 3;
|
||||
public bool connectOnAwake = true;
|
||||
public string authenticationKey = "Secret Auth Key";
|
||||
|
||||
public UnityEvent disconnectedFromRelay;
|
||||
public UnityEvent connectedToRelay;
|
||||
|
||||
// NAT Puncher variables
|
||||
public bool useNATPunch = false;
|
||||
public int NATPunchtroughPort = -1;
|
||||
private const int NAT_PUNCH_ATTEMPTS = 3;
|
||||
|
||||
// LLB variables (LRM Load Balancer)
|
||||
public bool useLoadBalancer = false;
|
||||
public ushort loadBalancerPort = 7070;
|
||||
public string loadBalancerAddress = null;
|
||||
|
||||
// Server hosting variables
|
||||
public string serverName = "My awesome server!";
|
||||
public string extraServerData = "Map 1";
|
||||
public int maxServerPlayers = 10;
|
||||
public bool isPublicServer = true;
|
||||
|
||||
private const string LOCALHOST = "127.0.0.1";
|
||||
|
||||
// Server list variables
|
||||
public UnityEvent serverListUpdated;
|
||||
public List<Room> relayServerList { private set; get; } = new List<Room>();
|
||||
|
||||
// Current Server Information
|
||||
public string serverStatus = "Not Started.";
|
||||
public string serverId = string.Empty;
|
||||
|
||||
private LRMDirectConnectModule _directConnectModule;
|
||||
|
||||
public LRMRegions region = LRMRegions.NorthAmerica;
|
||||
private byte[] _clientSendBuffer;
|
||||
private bool _connectedToRelay = false;
|
||||
public bool isConnectedToRelay => _connectedToRelay;
|
||||
private bool _isClient = false;
|
||||
private bool _isServer = false;
|
||||
private bool _directConnected = false;
|
||||
private bool _isAuthenticated = false;
|
||||
private int _currentMemberId;
|
||||
private bool _callbacksInitialized = false;
|
||||
private string _cachedHostID;
|
||||
private UdpClient _NATPuncher;
|
||||
private IPEndPoint _NATIP;
|
||||
private IPEndPoint _relayPuncherIP;
|
||||
private byte[] _punchData = new byte[1] { 1 };
|
||||
private IPEndPoint _directConnectEndpoint;
|
||||
private SocketProxy _clientProxy;
|
||||
private BiDictionary<IPEndPoint, SocketProxy> _serverProxies = new BiDictionary<IPEndPoint, SocketProxy>();
|
||||
private BiDictionary<int, int> _connectedRelayClients = new BiDictionary<int, int>();
|
||||
private BiDictionary<int, int> _connectedDirectClients = new BiDictionary<int, int>();
|
||||
private bool _serverListUpdated = false;
|
||||
}
|
||||
|
||||
public enum LRMRegions { Any, NorthAmerica, SouthAmerica, Europe, Asia, Africa, Oceania }
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f823917eee8f54742b6b03e520f05730
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
using kcp2k;
|
||||
using Mirror;
|
||||
using Mirror.SimpleWeb;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
[DefaultExecutionOrder(1001)]
|
||||
public partial class LightReflectiveMirrorTransport : Transport
|
||||
{
|
||||
public bool IsAuthenticated() => _isAuthenticated;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
useNATPunch = false;
|
||||
else
|
||||
_directConnectModule = GetComponent<LRMDirectConnectModule>();
|
||||
|
||||
if (clientToServerTransport is LightReflectiveMirrorTransport)
|
||||
throw new Exception("Haha real funny... Use a different transport.");
|
||||
|
||||
if (_directConnectModule != null)
|
||||
{
|
||||
if (useNATPunch && !_directConnectModule.SupportsNATPunch())
|
||||
{
|
||||
Debug.LogWarning("LRM | NATPunch is turned on but the transport used does not support it. It will be disabled.");
|
||||
useNATPunch = false;
|
||||
}
|
||||
}
|
||||
|
||||
SetupCallbacks();
|
||||
|
||||
if (connectOnAwake)
|
||||
ConnectToRelay();
|
||||
|
||||
InvokeRepeating(nameof(SendHeartbeat), heartBeatInterval, heartBeatInterval);
|
||||
}
|
||||
|
||||
private void SetupCallbacks()
|
||||
{
|
||||
if (_callbacksInitialized)
|
||||
return;
|
||||
|
||||
_callbacksInitialized = true;
|
||||
clientToServerTransport.OnClientConnected = OnConnectedToRelay;
|
||||
clientToServerTransport.OnClientDataReceived = DataReceived;
|
||||
clientToServerTransport.OnClientDisconnected = Disconnected;
|
||||
clientToServerTransport.OnClientError = (e) => Debug.LogException(e);
|
||||
}
|
||||
|
||||
private void Disconnected()
|
||||
{
|
||||
_connectedToRelay = false;
|
||||
_isAuthenticated = false;
|
||||
disconnectedFromRelay?.Invoke();
|
||||
serverStatus = "Disconnected from relay.";
|
||||
}
|
||||
|
||||
private void OnConnectedToRelay()
|
||||
{
|
||||
_connectedToRelay = true;
|
||||
connectedToRelay?.Invoke();
|
||||
}
|
||||
|
||||
public void ConnectToRelay()
|
||||
{
|
||||
if (!useLoadBalancer)
|
||||
{
|
||||
if (!_connectedToRelay)
|
||||
{
|
||||
Connect(serverIP, serverPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("LRM | Already connected to relay!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_connectedToRelay)
|
||||
{
|
||||
StartCoroutine(RelayConnect());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("LRM | Already connected to relay!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects to the desired relay
|
||||
/// </summary>
|
||||
/// <param name="serverIP"></param>
|
||||
private void Connect(string serverIP, ushort port = 7777)
|
||||
{
|
||||
// need to implement custom port
|
||||
if (clientToServerTransport is LightReflectiveMirrorTransport)
|
||||
throw new Exception("LRM | Client to Server Transport cannot be LRM.");
|
||||
|
||||
SetTransportPort(port);
|
||||
|
||||
this.serverIP = serverIP;
|
||||
serverStatus = "Connecting to relay...";
|
||||
_clientSendBuffer = new byte[clientToServerTransport.GetMaxPacketSize()];
|
||||
clientToServerTransport.ClientConnect(serverIP);
|
||||
}
|
||||
|
||||
public void DisconnectFromRelay()
|
||||
{
|
||||
if (IsAuthenticated())
|
||||
{
|
||||
clientToServerTransport.ClientDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void SendHeartbeat()
|
||||
{
|
||||
if (_connectedToRelay)
|
||||
{
|
||||
// Send a blank message with just the opcode 200, which is heartbeat
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, 200);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
|
||||
// If NAT Puncher is initialized, send heartbeat on that as well.
|
||||
try
|
||||
{
|
||||
if (_NATPuncher != null)
|
||||
_NATPuncher.Send(new byte[] { 0 }, 1, _relayPuncherIP);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
print(e);
|
||||
}
|
||||
|
||||
// Check if any server-side proxies havent been used in 10 seconds, and timeout if so.
|
||||
var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys());
|
||||
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
if (DateTime.Now.Subtract(_serverProxies.GetByFirst(keys[i]).lastInteractionTime).TotalSeconds > 10)
|
||||
{
|
||||
_serverProxies.GetByFirst(keys[i]).Dispose();
|
||||
_serverProxies.Remove(keys[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DataReceived(ArraySegment<byte> segmentData, int channel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = segmentData.Array;
|
||||
int pos = segmentData.Offset;
|
||||
// Read the opcode of the incoming data, this allows us to know what its used for.
|
||||
OpCodes opcode = (OpCodes)data.ReadByte(ref pos);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case OpCodes.Authenticated:
|
||||
// Server authenticated us! That means we are fully ready to host and join servers.
|
||||
serverStatus = "Authenticated! Good to go!";
|
||||
_isAuthenticated = true;
|
||||
RequestServerList();
|
||||
break;
|
||||
|
||||
case OpCodes.AuthenticationRequest:
|
||||
// Server requested that we send an authentication request, lets send our auth key.
|
||||
serverStatus = "Sent authentication to relay...";
|
||||
SendAuthKey();
|
||||
break;
|
||||
|
||||
case OpCodes.GetData:
|
||||
// Someone sent us a packet from their mirror over the relay
|
||||
var recvData = data.ReadBytes(ref pos);
|
||||
|
||||
// If we are the server and the client is registered, invoke the callback
|
||||
if (_isServer)
|
||||
{
|
||||
if (_connectedRelayClients.TryGetByFirst(data.ReadInt(ref pos), out int clientID))
|
||||
OnServerDataReceived?.Invoke(clientID, new ArraySegment<byte>(recvData), channel);
|
||||
}
|
||||
|
||||
// If we are the client, invoke the callback
|
||||
if (_isClient)
|
||||
OnClientDataReceived?.Invoke(new ArraySegment<byte>(recvData), channel);
|
||||
break;
|
||||
|
||||
case OpCodes.ServerLeft:
|
||||
// Called when server was closed.
|
||||
if (_isClient)
|
||||
{
|
||||
_isClient = false;
|
||||
OnClientDisconnected?.Invoke();
|
||||
}
|
||||
break;
|
||||
|
||||
case OpCodes.PlayerDisconnected:
|
||||
// Called when another player left the room.
|
||||
if (_isServer)
|
||||
{
|
||||
// Get their client ID and invoke the mirror callback
|
||||
int user = data.ReadInt(ref pos);
|
||||
if (_connectedRelayClients.TryGetByFirst(user, out int clientID))
|
||||
{
|
||||
OnServerDisconnected?.Invoke(clientID);
|
||||
_connectedRelayClients.Remove(user);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpCodes.RoomCreated:
|
||||
// We successfully created the room, the server also gave us the serverId of the room!
|
||||
serverId = data.ReadString(ref pos);
|
||||
break;
|
||||
|
||||
case OpCodes.ServerJoined:
|
||||
// Called when a player joins the room or when we joined a room.
|
||||
int clientId = data.ReadInt(ref pos);
|
||||
if (_isClient)
|
||||
{
|
||||
// We successfully joined a room, let mirror know.
|
||||
OnClientConnected?.Invoke();
|
||||
}
|
||||
if (_isServer)
|
||||
{
|
||||
// A client joined our room, let mirror know and setup their ID in the dictionary.
|
||||
_connectedRelayClients.Add(clientId, _currentMemberId);
|
||||
OnServerConnected?.Invoke(_currentMemberId);
|
||||
_currentMemberId++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OpCodes.DirectConnectIP:
|
||||
// Either a client is trying to join us via NAT Punch, or we are trying to join a host over NAT punch/Direct connect.
|
||||
var ip = data.ReadString(ref pos);
|
||||
int port = data.ReadInt(ref pos);
|
||||
bool attemptNatPunch = data.ReadBool(ref pos);
|
||||
|
||||
_directConnectEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
|
||||
|
||||
// Both client and server will send data to each other to open the hole.
|
||||
if (useNATPunch && attemptNatPunch)
|
||||
{
|
||||
StartCoroutine(NATPunch(_directConnectEndpoint));
|
||||
}
|
||||
|
||||
if (!_isServer)
|
||||
{
|
||||
// We arent the server, so lets tell the direct connect module to attempt a connection and initializing our middle man socket.
|
||||
if (_clientProxy == null && useNATPunch && attemptNatPunch)
|
||||
{
|
||||
_clientProxy = new SocketProxy(_NATIP.Port - 1);
|
||||
_clientProxy.dataReceived += ClientProcessProxyData;
|
||||
}
|
||||
|
||||
if (useNATPunch && attemptNatPunch)
|
||||
{
|
||||
if (ip == LOCALHOST)
|
||||
_directConnectModule.JoinServer(LOCALHOST, port + 1);
|
||||
else
|
||||
_directConnectModule.JoinServer(LOCALHOST, _NATIP.Port - 1);
|
||||
}
|
||||
else
|
||||
_directConnectModule.JoinServer(ip, port);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OpCodes.RequestNATConnection:
|
||||
// Called when the LRM node would like us to establish a NAT puncher connection. Its safe to ignore if NAT punch is disabled.
|
||||
if (useNATPunch && GetLocalIp() != null && _directConnectModule != null)
|
||||
{
|
||||
byte[] initalData = new byte[150];
|
||||
int sendPos = 0;
|
||||
|
||||
initalData.WriteBool(ref sendPos, true);
|
||||
initalData.WriteString(ref sendPos, data.ReadString(ref pos));
|
||||
NATPunchtroughPort = data.ReadInt(ref pos);
|
||||
|
||||
if (_NATPuncher == null)
|
||||
{
|
||||
_NATPuncher = new UdpClient { ExclusiveAddressUse = false };
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
_NATIP = new IPEndPoint(IPAddress.Parse(GetLocalIp()), UnityEngine.Random.Range(16000, 17000));
|
||||
_NATPuncher.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
_NATPuncher.Client.Bind(_NATIP);
|
||||
break;
|
||||
}
|
||||
catch { } // Binding port is in use, keep trying :P
|
||||
}
|
||||
}
|
||||
|
||||
if (!IPAddress.TryParse(serverIP, out IPAddress serverAddr))
|
||||
serverAddr = Dns.GetHostEntry(serverIP).AddressList[0];
|
||||
|
||||
_relayPuncherIP = new IPEndPoint(serverAddr, NATPunchtroughPort);
|
||||
|
||||
for (int attempts = 0; attempts < NAT_PUNCH_ATTEMPTS; attempts++)
|
||||
_NATPuncher.Send(initalData, sendPos, _relayPuncherIP);
|
||||
|
||||
_NATPuncher.BeginReceive(new AsyncCallback(RecvData), _NATPuncher);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e) { print(e); }
|
||||
}
|
||||
|
||||
public void SetTransportPort(ushort port)
|
||||
{
|
||||
if (clientToServerTransport is KcpTransport kcp)
|
||||
kcp.Port = port;
|
||||
|
||||
if (clientToServerTransport is TelepathyTransport telepathy)
|
||||
telepathy.port = port;
|
||||
|
||||
if (clientToServerTransport is SimpleWebTransport swt)
|
||||
swt.port = port;
|
||||
}
|
||||
|
||||
public void UpdateRoomName(string newServerName = "My Awesome Server!")
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
|
||||
|
||||
_clientSendBuffer.WriteBool(ref pos, true);
|
||||
_clientSendBuffer.WriteString(ref pos, newServerName);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateRoomData(string newServerData = "Extra Data!")
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
|
||||
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, true);
|
||||
_clientSendBuffer.WriteString(ref pos, newServerData);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateRoomVisibility(bool isPublic = true)
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
|
||||
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, true);
|
||||
_clientSendBuffer.WriteBool(ref pos, isPublic);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateRoomPlayerCount(int maxPlayers = 16)
|
||||
{
|
||||
if (_isServer)
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
|
||||
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, false);
|
||||
_clientSendBuffer.WriteBool(ref pos, true);
|
||||
_clientSendBuffer.WriteInt(ref pos, maxPlayers);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private Room? GetServerForID(string serverID)
|
||||
{
|
||||
for (int i = 0; i < relayServerList.Count; i++)
|
||||
{
|
||||
if (relayServerList[i].serverId == serverID)
|
||||
return relayServerList[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SendAuthKey()
|
||||
{
|
||||
int pos = 0;
|
||||
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.AuthenticationResponse);
|
||||
_clientSendBuffer.WriteString(ref pos, authenticationKey);
|
||||
|
||||
clientToServerTransport.ClientSend(new ArraySegment<byte>(_clientSendBuffer, 0, pos), 0);
|
||||
}
|
||||
|
||||
public enum OpCodes
|
||||
{
|
||||
Default = 0, RequestID = 1, JoinServer = 2, SendData = 3, GetID = 4, ServerJoined = 5, GetData = 6, CreateRoom = 7, ServerLeft = 8, PlayerDisconnected = 9, RoomCreated = 10,
|
||||
LeaveRoom = 11, KickPlayer = 12, AuthenticationRequest = 13, AuthenticationResponse = 14, Authenticated = 17, UpdateRoomData = 18, ServerConnectionData = 19, RequestNATConnection = 20,
|
||||
DirectConnectIP = 21
|
||||
}
|
||||
|
||||
private static string GetLocalIp()
|
||||
{
|
||||
var host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
foreach (var ip in host.AddressList)
|
||||
{
|
||||
if (ip.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
return ip.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct Room
|
||||
{
|
||||
public string serverName;
|
||||
public int maxPlayers;
|
||||
public string serverId;
|
||||
public string serverData;
|
||||
public int hostId;
|
||||
public List<int> clients;
|
||||
public int currentPlayers;
|
||||
public RelayAddress relayInfo;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct RelayAddress
|
||||
{
|
||||
public ushort port;
|
||||
public ushort endpointPort;
|
||||
public string address;
|
||||
public LRMRegions serverRegion;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7064b1b1d0671194baf55fa8d5f564d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: f4000c50bdad7994f8425330b81e5d87, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Mirror/Runtime/Transport/LRM/Resources.meta
Normal file
8
Assets/Mirror/Runtime/Transport/LRM/Resources.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 814f94525da21a6f6a039204f1e8deb5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Mirror/Runtime/Transport/LRM/Resources/LRM.png
Normal file
BIN
Assets/Mirror/Runtime/Transport/LRM/Resources/LRM.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
92
Assets/Mirror/Runtime/Transport/LRM/Resources/LRM.png.meta
Normal file
92
Assets/Mirror/Runtime/Transport/LRM/Resources/LRM.png.meta
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f4000c50bdad7994f8425330b81e5d87
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/Mirror/Runtime/Transport/LRM/SocketProxy.cs
Normal file
68
Assets/Mirror/Runtime/Transport/LRM/SocketProxy.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LightReflectiveMirror
|
||||
{
|
||||
|
||||
// This class handles the proxying from punched socket to transport.
|
||||
public class SocketProxy
|
||||
{
|
||||
public DateTime lastInteractionTime;
|
||||
public Action<IPEndPoint, byte[]> dataReceived;
|
||||
UdpClient _udpClient;
|
||||
IPEndPoint _recvEndpoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
IPEndPoint _remoteEndpoint;
|
||||
bool _clientInitialRecv = false;
|
||||
|
||||
public SocketProxy(int port, IPEndPoint remoteEndpoint)
|
||||
{
|
||||
_udpClient = new UdpClient();
|
||||
_udpClient.Connect(new IPEndPoint(IPAddress.Loopback, port));
|
||||
_udpClient.BeginReceive(new AsyncCallback(RecvData), _udpClient);
|
||||
lastInteractionTime = DateTime.Now;
|
||||
// Clone it so when main socket recvies new data, it wont switcheroo on us.
|
||||
_remoteEndpoint = new IPEndPoint(remoteEndpoint.Address, remoteEndpoint.Port);
|
||||
}
|
||||
|
||||
public SocketProxy(int port)
|
||||
{
|
||||
_udpClient = new UdpClient(port);
|
||||
_udpClient.BeginReceive(new AsyncCallback(RecvData), _udpClient);
|
||||
lastInteractionTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public void RelayData(byte[] data, int length)
|
||||
{
|
||||
_udpClient.Send(data, length);
|
||||
lastInteractionTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public void ClientRelayData(byte[] data, int length)
|
||||
{
|
||||
if (_clientInitialRecv)
|
||||
{
|
||||
_udpClient.Send(data, length, _recvEndpoint);
|
||||
lastInteractionTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_udpClient.Dispose();
|
||||
}
|
||||
|
||||
void RecvData(IAsyncResult result)
|
||||
{
|
||||
byte[] data = _udpClient.EndReceive(result, ref _recvEndpoint);
|
||||
_udpClient.BeginReceive(new AsyncCallback(RecvData), _udpClient);
|
||||
_clientInitialRecv = true;
|
||||
lastInteractionTime = DateTime.Now;
|
||||
dataReceived?.Invoke(_remoteEndpoint, data);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Mirror/Runtime/Transport/LRM/SocketProxy.cs.meta
Normal file
11
Assets/Mirror/Runtime/Transport/LRM/SocketProxy.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f482ce0c4da51924ba033e827aca8f28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Mirror/Runtime/Transport/LRM/package.json
Normal file
9
Assets/Mirror/Runtime/Transport/LRM/package.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "com.derek-r-s.lrm",
|
||||
"version": "0.10.120",
|
||||
"displayName": "Light-Reflective-Mirror",
|
||||
"description": "Light Reflective Mirror is a transport for Mirror Networking which relays network traffic through your own servers.",
|
||||
"unity": "2019.4",
|
||||
"dependencies": {},
|
||||
"keywords": []
|
||||
}
|
||||
7
Assets/Mirror/Runtime/Transport/LRM/package.json.meta
Normal file
7
Assets/Mirror/Runtime/Transport/LRM/package.json.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09ee2ee51265449fea67160707630572
|
||||
PackageManifestImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue
Block a user