mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-11 16:48:30 +00:00
提交
This commit is contained in:
7
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/HTTP.meta
Normal file
7
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/HTTP.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56badbd91a344cf49b819809ce60c94a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,593 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1944314068052120}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1251304880022356
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224766109861186050}
|
||||
- component: {fileID: 222007061184830686}
|
||||
- component: {fileID: 114332842110793280}
|
||||
- component: {fileID: 114741082604224458}
|
||||
- component: {fileID: 114821562994013518}
|
||||
- component: {fileID: 114970735310707698}
|
||||
- component: {fileID: 114169851664053792}
|
||||
m_Layer: 5
|
||||
m_Name: Start Download Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1298646758441480
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224796360726838160}
|
||||
- component: {fileID: 222450923967724424}
|
||||
- component: {fileID: 114756570423530596}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1548055376625982
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224222599636736864}
|
||||
- component: {fileID: 222263229427737546}
|
||||
- component: {fileID: 114864362160119752}
|
||||
- component: {fileID: 114863480533508966}
|
||||
m_Layer: 5
|
||||
m_Name: RawImage
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1549333168510042
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224641546219099906}
|
||||
- component: {fileID: 222240980090431082}
|
||||
- component: {fileID: 114444815419025578}
|
||||
m_Layer: 5
|
||||
m_Name: Header
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1928372766581374
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224044084468067872}
|
||||
- component: {fileID: 222379004667598028}
|
||||
- component: {fileID: 114378960042926580}
|
||||
m_Layer: 5
|
||||
m_Name: Status Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1944314068052120
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224637431015742208}
|
||||
- component: {fileID: 114589682599655862}
|
||||
- component: {fileID: 114248578834748736}
|
||||
m_Layer: 5
|
||||
m_Name: AssetBundle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114169851664053792
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: -1
|
||||
m_FlexibleHeight: 0
|
||||
m_LayoutPriority: 1
|
||||
--- !u!114 &114248578834748736
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1944314068052120}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 03eab9c6191c5cd4c9613084e817bd29, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Category: HTTP
|
||||
DisplayName: Asset Bundle
|
||||
Description: 'A small example that shows a possible way to download an AssetBundle
|
||||
and load a resource from it.
|
||||
|
||||
|
||||
<b>Features demoed in this example:</b>
|
||||
|
||||
-Using HTTPRequest without a callback
|
||||
|
||||
-Using HTTPRequest in a Coroutine
|
||||
|
||||
-Loading an AssetBundle from the downloaded bytes
|
||||
|
||||
-Automatic Caching'
|
||||
_path: /AssetBundles/WebGL/demobundle.assetbundle
|
||||
_assetnameInBundle: 9443182_orig
|
||||
_statusText: {fileID: 114378960042926580}
|
||||
_rawImage: {fileID: 114864362160119752}
|
||||
_downloadButton: {fileID: 114741082604224458}
|
||||
--- !u!114 &114332842110793280
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &114378960042926580
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1928372766581374}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Status
|
||||
--- !u!114 &114444815419025578
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1549333168510042}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 20
|
||||
m_FontStyle: 1
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Asset Bundle Example
|
||||
--- !u!114 &114589682599655862
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1944314068052120}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 5
|
||||
m_Right: 5
|
||||
m_Top: 5
|
||||
m_Bottom: 5
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 5
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!114 &114741082604224458
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
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_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 114332842110793280}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 114248578834748736}
|
||||
m_MethodName: OnStartDownloadButton
|
||||
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
|
||||
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!114 &114756570423530596
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1298646758441480}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Start Download
|
||||
--- !u!114 &114821562994013518
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 5
|
||||
m_Right: 5
|
||||
m_Top: 5
|
||||
m_Bottom: 5
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 1
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!114 &114863480533508966
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1548055376625982}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: -1
|
||||
m_FlexibleHeight: 1
|
||||
m_LayoutPriority: 1
|
||||
--- !u!114 &114864362160119752
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1548055376625982}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Texture: {fileID: 0}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!114 &114970735310707698
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!222 &222007061184830686
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
--- !u!222 &222240980090431082
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1549333168510042}
|
||||
--- !u!222 &222263229427737546
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1548055376625982}
|
||||
--- !u!222 &222379004667598028
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1928372766581374}
|
||||
--- !u!222 &222450923967724424
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1298646758441480}
|
||||
--- !u!224 &224044084468067872
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1928372766581374}
|
||||
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: 224637431015742208}
|
||||
m_RootOrder: 1
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224222599636736864
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1548055376625982}
|
||||
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: 224637431015742208}
|
||||
m_RootOrder: 2
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224637431015742208
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1944314068052120}
|
||||
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: 224641546219099906}
|
||||
- {fileID: 224044084468067872}
|
||||
- {fileID: 224222599636736864}
|
||||
- {fileID: 224766109861186050}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224641546219099906
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1549333168510042}
|
||||
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: 224637431015742208}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224766109861186050
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1251304880022356}
|
||||
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: 224796360726838160}
|
||||
m_Father: {fileID: 224637431015742208}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 300, y: 0}
|
||||
m_SizeDelta: {x: 590, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &224796360726838160
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1298646758441480}
|
||||
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: 224766109861186050}
|
||||
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.5, y: 0.5}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a56a1df7e0b38848bb9bf237a577478
|
||||
timeCreated: 1571226561
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BestHTTP;
|
||||
|
||||
namespace BestHTTP.Examples.HTTP
|
||||
{
|
||||
public sealed class AssetBundleSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
|
||||
[Tooltip("The url of the resource to download")]
|
||||
[SerializeField]
|
||||
private string _path = "/AssetBundles/WebGL/demobundle.assetbundle";
|
||||
|
||||
[SerializeField]
|
||||
private string _assetnameInBundle = "9443182_orig";
|
||||
|
||||
[SerializeField]
|
||||
private Text _statusText;
|
||||
|
||||
[SerializeField]
|
||||
private RawImage _rawImage;
|
||||
|
||||
[SerializeField]
|
||||
private Button _downloadButton;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the request to be able to call Abort on it.
|
||||
/// </summary>
|
||||
HTTPRequest request;
|
||||
|
||||
/// <summary>
|
||||
/// The downloaded and cached AssetBundle
|
||||
/// </summary>
|
||||
AssetBundle cachedBundle;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Events
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
this._statusText.text = "Waiting for user interaction";
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (this.request != null)
|
||||
this.request.Abort();
|
||||
this.request = null;
|
||||
|
||||
UnloadBundle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GUI button callback
|
||||
/// </summary>
|
||||
public void OnStartDownloadButton()
|
||||
{
|
||||
this._downloadButton.enabled = false;
|
||||
UnloadBundle();
|
||||
|
||||
StartCoroutine(DownloadAssetBundle());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Helper Functions
|
||||
|
||||
IEnumerator DownloadAssetBundle()
|
||||
{
|
||||
// Create and send our request
|
||||
request = new HTTPRequest(new Uri(this.sampleSelector.BaseURL + this._path)).Send();
|
||||
|
||||
this._statusText.text = "Download started";
|
||||
|
||||
// Wait while it's finishes and add some fancy dots to display something while the user waits for it.
|
||||
// A simple "yield return StartCoroutine(request);" would do the job too.
|
||||
while (request.State < HTTPRequestStates.Finished)
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
|
||||
this._statusText.text += ".";
|
||||
}
|
||||
|
||||
// Check the outcome of our request.
|
||||
switch (request.State)
|
||||
{
|
||||
// The request finished without any problem.
|
||||
case HTTPRequestStates.Finished:
|
||||
|
||||
if (request.Response.IsSuccess)
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
if (request.Response.IsFromCache)
|
||||
this._statusText.text = "Loaded from local cache!";
|
||||
else
|
||||
this._statusText.text = "Downloaded!";
|
||||
#else
|
||||
this._statusText.text = "Downloaded!";
|
||||
#endif
|
||||
|
||||
// Start creating the downloaded asset bundle
|
||||
AssetBundleCreateRequest async =
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
AssetBundle.LoadFromMemoryAsync(request.Response.Data);
|
||||
#else
|
||||
AssetBundle.CreateFromMemory(request.Response.Data);
|
||||
#endif
|
||||
|
||||
// wait for it
|
||||
yield return async;
|
||||
|
||||
BestHTTP.PlatformSupport.Memory.BufferPool.Release(request.Response.Data);
|
||||
|
||||
// And process the bundle
|
||||
yield return StartCoroutine(ProcessAssetBundle(async.assetBundle));
|
||||
}
|
||||
else
|
||||
{
|
||||
this._statusText.text = string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
|
||||
request.Response.StatusCode,
|
||||
request.Response.Message,
|
||||
request.Response.DataAsText);
|
||||
Debug.LogWarning(this._statusText.text);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
|
||||
case HTTPRequestStates.Error:
|
||||
this._statusText.text = "Request Finished with Error! " + (request.Exception != null ? (request.Exception.Message + "\n" + request.Exception.StackTrace) : "No Exception");
|
||||
Debug.LogError(this._statusText.text);
|
||||
break;
|
||||
|
||||
// The request aborted, initiated by the user.
|
||||
case HTTPRequestStates.Aborted:
|
||||
this._statusText.text = "Request Aborted!";
|
||||
Debug.LogWarning(this._statusText.text);
|
||||
break;
|
||||
|
||||
// Connecting to the server is timed out.
|
||||
case HTTPRequestStates.ConnectionTimedOut:
|
||||
this._statusText.text = "Connection Timed Out!";
|
||||
Debug.LogError(this._statusText.text);
|
||||
break;
|
||||
|
||||
// The request didn't finished in the given time.
|
||||
case HTTPRequestStates.TimedOut:
|
||||
this._statusText.text = "Processing the request Timed Out!";
|
||||
Debug.LogError(this._statusText.text);
|
||||
break;
|
||||
}
|
||||
|
||||
this.request = null;
|
||||
this._downloadButton.enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In this function we can do whatever we want with the freshly downloaded bundle.
|
||||
/// In this example we will cache it for later use, and we will load a texture from it.
|
||||
/// </summary>
|
||||
IEnumerator ProcessAssetBundle(AssetBundle bundle)
|
||||
{
|
||||
if (bundle == null)
|
||||
yield break;
|
||||
|
||||
// Save the bundle for future use
|
||||
cachedBundle = bundle;
|
||||
|
||||
// Start loading the asset from the bundle
|
||||
var asyncAsset =
|
||||
#if UNITY_5_1 || UNITY_5_2 || UNITY_5_3_OR_NEWER
|
||||
cachedBundle.LoadAssetAsync(this._assetnameInBundle, typeof(Texture2D));
|
||||
#else
|
||||
|
||||
cachedBundle.LoadAsync(this._assetnameInBundle, typeof(Texture2D));
|
||||
#endif
|
||||
|
||||
// wait til load
|
||||
yield return asyncAsset;
|
||||
|
||||
// get the texture
|
||||
this._rawImage.texture = asyncAsset.asset as Texture2D;
|
||||
}
|
||||
|
||||
void UnloadBundle()
|
||||
{
|
||||
this._rawImage.texture = null;
|
||||
|
||||
if (cachedBundle != null)
|
||||
{
|
||||
cachedBundle.Unload(true);
|
||||
cachedBundle = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03eab9c6191c5cd4c9613084e817bd29
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BestHTTP.Extensions;
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
|
||||
namespace BestHTTP
|
||||
{
|
||||
/// <summary>
|
||||
/// Stream based implementation of the multipart/form-data Content-Type. Using this class reading a whole file into memory can be avoided.
|
||||
/// This implementation expects that all streams has a final, accessible Length.
|
||||
/// </summary>
|
||||
public sealed class MultipartFormDataStream : System.IO.Stream
|
||||
{
|
||||
public override bool CanRead { get { return true; } }
|
||||
|
||||
public override bool CanSeek { get { return false; } }
|
||||
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
// multipart/form-data requires a leading boundary that we can add when all streams are added.
|
||||
// This final preparation could be user initiated, but we can do it automatically too when the HTTPRequest
|
||||
// first access the Length property.
|
||||
if (!this.prepared)
|
||||
{
|
||||
this.prepared = true;
|
||||
this.Prepare();
|
||||
}
|
||||
|
||||
return this._length;
|
||||
}
|
||||
}
|
||||
private long _length;
|
||||
|
||||
public override long Position { get; set; }
|
||||
/// <summary>
|
||||
/// A random boundary generated in the constructor.
|
||||
/// </summary>
|
||||
private string boundary;
|
||||
|
||||
private Queue<StreamList> fields = new Queue<StreamList>(1);
|
||||
private StreamList currentField;
|
||||
private bool prepared;
|
||||
|
||||
public MultipartFormDataStream(HTTPRequest request)
|
||||
{
|
||||
this.boundary = "BestHTTP_MultipartFormDataStream_" + this.GetHashCode().ToString("X2");
|
||||
|
||||
request.SetHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||
request.UploadStream = this;
|
||||
request.UseUploadStreamLength = true;
|
||||
}
|
||||
|
||||
public void AddField(string fieldName, string value)
|
||||
{
|
||||
AddField(fieldName, value, System.Text.Encoding.UTF8);
|
||||
}
|
||||
|
||||
public void AddField(string fieldName, string value, System.Text.Encoding encoding)
|
||||
{
|
||||
var enc = encoding ?? System.Text.Encoding.UTF8;
|
||||
var byteCount = enc.GetByteCount(value);
|
||||
var buffer = BufferPool.Get(byteCount, true);
|
||||
var stream = new BufferPoolMemoryStream();
|
||||
|
||||
enc.GetBytes(value, 0, value.Length, buffer, 0);
|
||||
|
||||
stream.Write(buffer, 0, byteCount);
|
||||
|
||||
stream.Position = 0;
|
||||
|
||||
string mime = encoding != null ? "text/plain; charset=" + encoding.WebName : null;
|
||||
AddStreamField(stream, fieldName, null, mime);
|
||||
}
|
||||
|
||||
public void AddStreamField(System.IO.Stream stream, string fieldName)
|
||||
{
|
||||
AddStreamField(stream, fieldName, null, null);
|
||||
}
|
||||
|
||||
public void AddStreamField(System.IO.Stream stream, string fieldName, string fileName)
|
||||
{
|
||||
AddStreamField(stream, fieldName, fileName, null);
|
||||
}
|
||||
|
||||
public void AddStreamField(System.IO.Stream stream, string fieldName, string fileName, string mimeType)
|
||||
{
|
||||
var header = new BufferPoolMemoryStream();
|
||||
header.WriteLine("--" + this.boundary);
|
||||
header.WriteLine("Content-Disposition: form-data; name=\"" + fieldName + "\"" + (!string.IsNullOrEmpty(fileName) ? "; filename=\"" + fileName + "\"" : string.Empty));
|
||||
// Set up Content-Type head for the form.
|
||||
if (!string.IsNullOrEmpty(mimeType))
|
||||
header.WriteLine("Content-Type: " + mimeType);
|
||||
//header.WriteLine("Content-Length: " + stream.Length.ToString());
|
||||
header.WriteLine();
|
||||
header.Position = 0;
|
||||
|
||||
var footer = new BufferPoolMemoryStream();
|
||||
footer.Write(HTTPRequest.EOL, 0, HTTPRequest.EOL.Length);
|
||||
footer.Position = 0;
|
||||
|
||||
// all wrapped streams going to be disposed by the StreamList wrapper.
|
||||
var wrapper = new StreamList(header, stream, footer);
|
||||
|
||||
try
|
||||
{
|
||||
if (this._length >= 0)
|
||||
this._length += wrapper.Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
this._length = -1;
|
||||
}
|
||||
|
||||
this.fields.Enqueue(wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the final boundary.
|
||||
/// </summary>
|
||||
private void Prepare()
|
||||
{
|
||||
var boundaryStream = new BufferPoolMemoryStream();
|
||||
boundaryStream.WriteLine("--" + this.boundary + "--");
|
||||
boundaryStream.Position = 0;
|
||||
|
||||
this.fields.Enqueue(new StreamList(boundaryStream));
|
||||
|
||||
if (this._length >= 0)
|
||||
this._length += boundaryStream.Length;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.currentField == null && this.fields.Count == 0)
|
||||
return -1;
|
||||
|
||||
if (this.currentField == null && this.fields.Count > 0)
|
||||
this.currentField = this.fields.Dequeue();
|
||||
|
||||
int readCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// read from the current stream
|
||||
int count = this.currentField.Read(buffer, offset + readCount, length - readCount);
|
||||
|
||||
if (count > 0)
|
||||
readCount += count;
|
||||
else
|
||||
{
|
||||
// if the current field's stream is empty, go for the next one.
|
||||
|
||||
// dispose the current one first
|
||||
try
|
||||
{
|
||||
this.currentField.Dispose();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
// no more fields/streams? exit
|
||||
if (this.fields.Count == 0)
|
||||
break;
|
||||
|
||||
// grab the next one
|
||||
this.currentField = this.fields.Dequeue();
|
||||
}
|
||||
|
||||
// exit when we reach the length goal, or there's no more streams to read from
|
||||
} while (readCount < length && this.fields.Count > 0);
|
||||
|
||||
return readCount;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Flush() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d54866f088b8c154db3325a2771b58af
|
||||
timeCreated: 1582886645
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceca5a2f4b7ce1e4fb307cc3d3e4624a
|
||||
timeCreated: 1571229570
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BestHTTP;
|
||||
|
||||
namespace BestHTTP.Examples.HTTP
|
||||
{
|
||||
public sealed class ResumableStreamingSample : StreamingSample
|
||||
{
|
||||
const string ProcessedBytesKey = "ProcessedBytes";
|
||||
const string DownloadLengthKey = "DownloadLength";
|
||||
|
||||
/// <summary>
|
||||
/// Expected content length
|
||||
/// </summary>
|
||||
protected override long DownloadLength { get { return PlayerPrefs.GetInt(this._downloadPath + DownloadLengthKey); } set { PlayerPrefs.SetInt(this._downloadPath + DownloadLengthKey, (int)value); } }
|
||||
|
||||
/// <summary>
|
||||
/// Total processed bytes
|
||||
/// </summary>
|
||||
protected override long ProcessedBytes { get { return PlayerPrefs.GetInt(this._downloadPath + ProcessedBytesKey, 0); } set { PlayerPrefs.SetInt(this._downloadPath + ProcessedBytesKey, (int)value); } }
|
||||
|
||||
private long downloadStartedAt = 0;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
// If we have a non-finished download, set the progress to the value where we left it
|
||||
float progress = GetSavedProgress();
|
||||
if (progress > 0.0f)
|
||||
{
|
||||
this._downloadProgressSlider.value = progress;
|
||||
base._statusText.text = progress.ToString("F2");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetupRequest()
|
||||
{
|
||||
base.SetupRequest();
|
||||
|
||||
// Are there any progress, that we can continue?
|
||||
this.downloadStartedAt = this.ProcessedBytes;
|
||||
|
||||
if (this.downloadStartedAt > 0)
|
||||
{
|
||||
// Set the range header
|
||||
request.SetRangeHeader(this.downloadStartedAt);
|
||||
}
|
||||
else
|
||||
// This is a new request
|
||||
DeleteKeys();
|
||||
}
|
||||
|
||||
protected override void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
|
||||
{
|
||||
base.OnRequestFinished(req, resp);
|
||||
|
||||
if (req.State == HTTPRequestStates.Finished && resp.IsSuccess)
|
||||
DeleteKeys();
|
||||
}
|
||||
|
||||
protected override void OnDownloadProgress(HTTPRequest originalRequest, long downloaded, long downloadLength)
|
||||
{
|
||||
double downloadPercent = ((this.downloadStartedAt + downloaded) / (double)this.DownloadLength) * 100;
|
||||
|
||||
this._downloadProgressSlider.value = (float)downloadPercent;
|
||||
this._downloadProgressText.text = string.Format("{0:F1}%", downloadPercent);
|
||||
}
|
||||
|
||||
protected override void ResetProcessedValues()
|
||||
{
|
||||
SetDataProcessedUI(this.ProcessedBytes, this.DownloadLength);
|
||||
}
|
||||
|
||||
private float GetSavedProgress()
|
||||
{
|
||||
long down = this.ProcessedBytes;
|
||||
long length = this.DownloadLength;
|
||||
|
||||
if (down > 0 && length > 0)
|
||||
return (down / (float)length) * 100f;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void DeleteKeys()
|
||||
{
|
||||
PlayerPrefs.DeleteKey(this._downloadPath + ProcessedBytesKey);
|
||||
PlayerPrefs.DeleteKey(this._downloadPath + DownloadLengthKey);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 972fc2301f87c9e46bfb5523f2bc5090
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3045
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/HTTP/Streaming.prefab
Normal file
3045
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/HTTP/Streaming.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cab27f13c267f9e42ab47de965b407b9
|
||||
timeCreated: 1571294301
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,272 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BestHTTP;
|
||||
|
||||
namespace BestHTTP.Examples.HTTP
|
||||
{
|
||||
public class StreamingSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
|
||||
[Tooltip("The url of the resource to download")]
|
||||
[SerializeField]
|
||||
protected string _downloadPath = "/test100mb.dat";
|
||||
|
||||
[Header("Streaming Setup")]
|
||||
|
||||
[SerializeField]
|
||||
protected RectTransform _streamingSetupRoot;
|
||||
|
||||
[SerializeField]
|
||||
protected Slider _fragmentSizeSlider;
|
||||
|
||||
[SerializeField]
|
||||
protected Text _fragmentSizeText;
|
||||
|
||||
[SerializeField]
|
||||
protected Toggle _disableCacheToggle;
|
||||
|
||||
[Header("Reporting")]
|
||||
|
||||
[SerializeField]
|
||||
protected RectTransform _reportingRoot;
|
||||
|
||||
[SerializeField]
|
||||
protected Slider _downloadProgressSlider;
|
||||
|
||||
[SerializeField]
|
||||
protected Text _downloadProgressText;
|
||||
|
||||
[SerializeField]
|
||||
protected Slider _processedDataSlider;
|
||||
|
||||
[SerializeField]
|
||||
protected Text _processedDataText;
|
||||
|
||||
[SerializeField]
|
||||
protected Text _statusText;
|
||||
|
||||
[SerializeField]
|
||||
protected Button _startDownload;
|
||||
|
||||
[SerializeField]
|
||||
protected Button _cancelDownload;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
/// <summary>
|
||||
/// Cached request to be able to abort it
|
||||
/// </summary>
|
||||
protected HTTPRequest request;
|
||||
|
||||
/// <summary>
|
||||
/// Download(processing) progress. Its range is between [0..1]
|
||||
/// </summary>
|
||||
protected float progress;
|
||||
|
||||
/// <summary>
|
||||
/// The fragment size that we will set to the request
|
||||
/// </summary>
|
||||
protected int fragmentSize = HTTPResponse.MinReadBufferSize;
|
||||
|
||||
protected virtual long DownloadLength { get; set; }
|
||||
|
||||
protected virtual long ProcessedBytes { get; set; }
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
this._streamingSetupRoot.gameObject.SetActive(true);
|
||||
this._reportingRoot.gameObject.SetActive(false);
|
||||
|
||||
this._startDownload.interactable = true;
|
||||
this._cancelDownload.interactable = false;
|
||||
|
||||
this._fragmentSizeSlider.value = (1024 * 1024 - HTTPResponse.MinReadBufferSize) / 1024;
|
||||
this._fragmentSizeText.text = GUIHelper.GetBytesStr(1024 * 1024, 1);
|
||||
}
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
// Stop the download if we are leaving this example
|
||||
if (request != null && request.State < HTTPRequestStates.Finished)
|
||||
{
|
||||
request.OnDownloadProgress = null;
|
||||
request.Callback = null;
|
||||
request.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnFragmentSizeSliderChanged(float value)
|
||||
{
|
||||
this.fragmentSize = HTTPResponse.MinReadBufferSize + (int)value * 1024;
|
||||
this._fragmentSizeText.text = GUIHelper.GetBytesStr(this.fragmentSize, 1);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (this.request != null)
|
||||
this.request.Abort();
|
||||
}
|
||||
|
||||
protected virtual void SetupRequest()
|
||||
{
|
||||
request = new HTTPRequest(new Uri(base.sampleSelector.BaseURL + this._downloadPath), OnRequestFinished);
|
||||
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
// If we are writing our own file set it to true(disable), so don't duplicate it on the file-system
|
||||
request.DisableCache = this._disableCacheToggle.isOn;
|
||||
#endif
|
||||
|
||||
request.StreamFragmentSize = fragmentSize;
|
||||
|
||||
request.Tag = DateTime.Now;
|
||||
|
||||
request.OnHeadersReceived += OnHeadersReceived;
|
||||
request.OnDownloadProgress += OnDownloadProgress;
|
||||
request.OnStreamingData += OnDataDownloaded;
|
||||
}
|
||||
|
||||
public virtual void StartStreaming()
|
||||
{
|
||||
SetupRequest();
|
||||
|
||||
// Start Processing the request
|
||||
request.Send();
|
||||
|
||||
this._statusText.text = "Download started!";
|
||||
|
||||
// UI
|
||||
this._streamingSetupRoot.gameObject.SetActive(false);
|
||||
this._reportingRoot.gameObject.SetActive(true);
|
||||
|
||||
this._startDownload.interactable = false;
|
||||
this._cancelDownload.interactable = true;
|
||||
|
||||
ResetProcessedValues();
|
||||
}
|
||||
|
||||
private void OnHeadersReceived(HTTPRequest req, HTTPResponse resp, Dictionary<string, List<string>> newHeaders)
|
||||
{
|
||||
var range = resp.GetRange();
|
||||
if (range != null)
|
||||
this.DownloadLength = range.ContentLength;
|
||||
else
|
||||
{
|
||||
var contentLength = resp.GetFirstHeaderValue("content-length");
|
||||
if (contentLength != null)
|
||||
{
|
||||
long length = 0;
|
||||
if (long.TryParse(contentLength, out length))
|
||||
this.DownloadLength = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
|
||||
{
|
||||
switch (req.State)
|
||||
{
|
||||
// The request finished without any problem.
|
||||
case HTTPRequestStates.Finished:
|
||||
if (resp.IsSuccess)
|
||||
{
|
||||
DateTime downloadStarted = (DateTime)req.Tag;
|
||||
TimeSpan diff = DateTime.Now - downloadStarted;
|
||||
|
||||
this._statusText.text = string.Format("Streaming finished in {0:N0}ms", diff.TotalMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._statusText.text = string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
|
||||
resp.StatusCode,
|
||||
resp.Message,
|
||||
resp.DataAsText);
|
||||
Debug.LogWarning(this._statusText.text);
|
||||
|
||||
request = null;
|
||||
}
|
||||
break;
|
||||
|
||||
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
|
||||
case HTTPRequestStates.Error:
|
||||
this._statusText.text = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception");
|
||||
Debug.LogError(this._statusText.text);
|
||||
|
||||
request = null;
|
||||
break;
|
||||
|
||||
// The request aborted, initiated by the user.
|
||||
case HTTPRequestStates.Aborted:
|
||||
this._statusText.text = "Request Aborted!";
|
||||
Debug.LogWarning(this._statusText.text);
|
||||
|
||||
request = null;
|
||||
break;
|
||||
|
||||
// Connecting to the server is timed out.
|
||||
case HTTPRequestStates.ConnectionTimedOut:
|
||||
this._statusText.text = "Connection Timed Out!";
|
||||
Debug.LogError(this._statusText.text);
|
||||
|
||||
request = null;
|
||||
break;
|
||||
|
||||
// The request didn't finished in the given time.
|
||||
case HTTPRequestStates.TimedOut:
|
||||
this._statusText.text = "Processing the request Timed Out!";
|
||||
Debug.LogError(this._statusText.text);
|
||||
|
||||
request = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// UI
|
||||
|
||||
this._streamingSetupRoot.gameObject.SetActive(true);
|
||||
this._reportingRoot.gameObject.SetActive(false);
|
||||
|
||||
this._startDownload.interactable = true;
|
||||
this._cancelDownload.interactable = false;
|
||||
request = null;
|
||||
}
|
||||
|
||||
protected virtual void OnDownloadProgress(HTTPRequest originalRequest, long downloaded, long downloadLength)
|
||||
{
|
||||
double downloadPercent = (downloaded / (double)downloadLength) * 100;
|
||||
this._downloadProgressSlider.value = (float)downloadPercent;
|
||||
this._downloadProgressText.text = string.Format("{0:F1}%", downloadPercent);
|
||||
}
|
||||
|
||||
protected virtual bool OnDataDownloaded(HTTPRequest request, HTTPResponse response, byte[] dataFragment, int dataFragmentLength)
|
||||
{
|
||||
this.ProcessedBytes += dataFragmentLength;
|
||||
SetDataProcessedUI(this.ProcessedBytes, this.DownloadLength);
|
||||
|
||||
// Use downloaded data
|
||||
|
||||
// Return true if dataFrament is processed so the plugin can recycle the byte[]
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void SetDataProcessedUI(long processed, long length)
|
||||
{
|
||||
float processedPercent = (processed / (float)length) * 100f;
|
||||
|
||||
this._processedDataSlider.value = processedPercent;
|
||||
this._processedDataText.text = GUIHelper.GetBytesStr(processed, 0);
|
||||
}
|
||||
|
||||
protected virtual void ResetProcessedValues()
|
||||
{
|
||||
this.ProcessedBytes = 0;
|
||||
this.DownloadLength = 0;
|
||||
|
||||
SetDataProcessedUI(this.ProcessedBytes, this.DownloadLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7608ce95dba469c42b49baa85e3c300c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b7ac2a0c58362148840c49056fa7bda
|
||||
timeCreated: 1571294809
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BestHTTP;
|
||||
|
||||
namespace BestHTTP.Examples.HTTP
|
||||
{
|
||||
public sealed class TextureDownloadSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[Header("Texture Download Example")]
|
||||
|
||||
[Tooltip("The URL of the server that will serve the image resources")]
|
||||
[SerializeField]
|
||||
private string _path = "/images/Demo/";
|
||||
|
||||
[Tooltip("The downloadable images")]
|
||||
[SerializeField]
|
||||
private string[] _imageNames = new string[9] { "One.png", "Two.png", "Three.png", "Four.png", "Five.png", "Six.png", "Seven.png", "Eight.png", "Nine.png" };
|
||||
|
||||
[SerializeField]
|
||||
private RawImage[] _images = new RawImage[0];
|
||||
|
||||
[SerializeField]
|
||||
private Text _maxConnectionPerServerLabel;
|
||||
|
||||
[SerializeField]
|
||||
private Text _cacheLabel;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
private byte savedMaxConnectionPerServer;
|
||||
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
private bool allDownloadedFromLocalCache;
|
||||
#endif
|
||||
|
||||
private List<HTTPRequest> activeRequests = new List<HTTPRequest>();
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
this.savedMaxConnectionPerServer = HTTPManager.MaxConnectionPerServer;
|
||||
|
||||
// Set a well observable value
|
||||
// This is how many concurrent requests can be made to a server
|
||||
HTTPManager.MaxConnectionPerServer = 1;
|
||||
|
||||
this._maxConnectionPerServerLabel.text = HTTPManager.MaxConnectionPerServer.ToString();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
// Set back to its defualt value.
|
||||
HTTPManager.MaxConnectionPerServer = this.savedMaxConnectionPerServer;
|
||||
foreach (var request in this.activeRequests)
|
||||
request.Abort();
|
||||
this.activeRequests.Clear();
|
||||
}
|
||||
|
||||
public void OnMaxConnectionPerServerChanged(float value)
|
||||
{
|
||||
HTTPManager.MaxConnectionPerServer = (byte)Mathf.RoundToInt(value);
|
||||
this._maxConnectionPerServerLabel.text = HTTPManager.MaxConnectionPerServer.ToString();
|
||||
}
|
||||
|
||||
public void DownloadImages()
|
||||
{
|
||||
// Set these metadatas to its initial values
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
allDownloadedFromLocalCache = true;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < _imageNames.Length; ++i)
|
||||
{
|
||||
// Set a blank placeholder texture, overriding previously downloaded texture
|
||||
this._images[i].texture = null;
|
||||
|
||||
// Construct the request
|
||||
var request = new HTTPRequest(new Uri(this.sampleSelector.BaseURL + this._path + this._imageNames[i]), ImageDownloaded);
|
||||
|
||||
// Set the Tag property, we can use it as a general storage bound to the request
|
||||
request.Tag = this._images[i];
|
||||
|
||||
// Send out the request
|
||||
request.Send();
|
||||
|
||||
this.activeRequests.Add(request);
|
||||
}
|
||||
|
||||
this._cacheLabel.text = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback function of the image download http requests
|
||||
/// </summary>
|
||||
void ImageDownloaded(HTTPRequest req, HTTPResponse resp)
|
||||
{
|
||||
switch (req.State)
|
||||
{
|
||||
// The request finished without any problem.
|
||||
case HTTPRequestStates.Finished:
|
||||
if (resp.IsSuccess)
|
||||
{
|
||||
// The target RawImage reference is stored in the Tag property
|
||||
RawImage rawImage = req.Tag as RawImage;
|
||||
rawImage.texture = resp.DataAsTexture2D;
|
||||
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
// Update the cache-info variable
|
||||
allDownloadedFromLocalCache = allDownloadedFromLocalCache && resp.IsFromCache;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
|
||||
resp.StatusCode,
|
||||
resp.Message,
|
||||
resp.DataAsText));
|
||||
}
|
||||
break;
|
||||
|
||||
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
|
||||
case HTTPRequestStates.Error:
|
||||
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
|
||||
break;
|
||||
|
||||
// The request aborted, initiated by the user.
|
||||
case HTTPRequestStates.Aborted:
|
||||
Debug.LogWarning("Request Aborted!");
|
||||
break;
|
||||
|
||||
// Connecting to the server is timed out.
|
||||
case HTTPRequestStates.ConnectionTimedOut:
|
||||
Debug.LogError("Connection Timed Out!");
|
||||
break;
|
||||
|
||||
// The request didn't finished in the given time.
|
||||
case HTTPRequestStates.TimedOut:
|
||||
Debug.LogError("Processing the request Timed Out!");
|
||||
break;
|
||||
}
|
||||
|
||||
this.activeRequests.Remove(req);
|
||||
if (this.activeRequests.Count == 0)
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
if (this.allDownloadedFromLocalCache)
|
||||
this._cacheLabel.text = "All images loaded from local cache!";
|
||||
else
|
||||
#endif
|
||||
this._cacheLabel.text = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af6ffe2bbf96d2b49ba3ef0713511d45
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,222 @@
|
||||
using BestHTTP;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace BestHTTP.Examples
|
||||
{
|
||||
public sealed class UploadStream : Stream
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Buffer for reads
|
||||
/// </summary>
|
||||
MemoryStream ReadBuffer = new MemoryStream();
|
||||
|
||||
/// <summary>
|
||||
/// Buffer for writes
|
||||
/// </summary>
|
||||
MemoryStream WriteBuffer = new MemoryStream();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that we will not write more data to this stream
|
||||
/// </summary>
|
||||
bool noMoreData;
|
||||
|
||||
/// <summary>
|
||||
/// For thread synchronization
|
||||
/// </summary>
|
||||
AutoResetEvent ARE = new AutoResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// For thread synchronization
|
||||
/// </summary>
|
||||
object locker = new object();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Name of this stream for easier debugging
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// true if we are read all data from the read buffer
|
||||
/// </summary>
|
||||
private bool IsReadBufferEmpty { get { lock (locker) return ReadBuffer.Position == ReadBuffer.Length; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public UploadStream(string name)
|
||||
: this()
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
public UploadStream()
|
||||
{
|
||||
this.ReadBuffer = new MemoryStream();
|
||||
this.WriteBuffer = new MemoryStream();
|
||||
this.Name = string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stream Implementation
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
// We will not push more data to the write buffer
|
||||
if (noMoreData)
|
||||
{
|
||||
// No data left in the read buffer
|
||||
if (ReadBuffer.Position == ReadBuffer.Length)
|
||||
{
|
||||
// Is there any data in the write buffer? If so, switch the buffers
|
||||
if (WriteBuffer.Length > 0)
|
||||
SwitchBuffers();
|
||||
else
|
||||
{
|
||||
HTTPManager.Logger.Information("UploadStream", string.Format("{0} - Read - End Of Stream", this.Name));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
return ReadBuffer.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
// There are no more data in the read buffer? Wait for it.
|
||||
if (IsReadBufferEmpty)
|
||||
{
|
||||
ARE.WaitOne();
|
||||
|
||||
lock (locker)
|
||||
if (IsReadBufferEmpty && WriteBuffer.Length > 0)
|
||||
SwitchBuffers();
|
||||
}
|
||||
|
||||
int read = -1;
|
||||
|
||||
lock (locker)
|
||||
read = ReadBuffer.Read(buffer, offset, count);
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (noMoreData)
|
||||
throw new System.ArgumentException("noMoreData already set!");
|
||||
|
||||
lock (locker)
|
||||
{
|
||||
WriteBuffer.Write(buffer, offset, count);
|
||||
|
||||
SwitchBuffers();
|
||||
}
|
||||
|
||||
ARE.Set();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dispose Implementation
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
HTTPManager.Logger.Information("UploadStream", string.Format("{0} - Dispose", this.Name));
|
||||
|
||||
ReadBuffer.Dispose();
|
||||
ReadBuffer = null;
|
||||
|
||||
WriteBuffer.Dispose();
|
||||
WriteBuffer = null;
|
||||
|
||||
#if NETFX_CORE
|
||||
ARE.Dispose();
|
||||
#else
|
||||
ARE.Close();
|
||||
#endif
|
||||
ARE = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Functions
|
||||
|
||||
public void Finish()
|
||||
{
|
||||
if (noMoreData)
|
||||
throw new System.ArgumentException("noMoreData already set!");
|
||||
|
||||
HTTPManager.Logger.Information("UploadStream", string.Format("{0} - Finish", this.Name));
|
||||
|
||||
noMoreData = true;
|
||||
|
||||
ARE.Set();
|
||||
}
|
||||
|
||||
private bool SwitchBuffers()
|
||||
{
|
||||
// Switch the buffers only when all data are consumed from our read buffer
|
||||
lock (locker)
|
||||
{
|
||||
if (ReadBuffer.Position == ReadBuffer.Length)
|
||||
{
|
||||
// This buffer will be the read buffer, we need to seek back to the beginning
|
||||
WriteBuffer.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// This will be the write buffer, set the length to zero
|
||||
ReadBuffer.SetLength(0);
|
||||
|
||||
// switch the two buffers
|
||||
MemoryStream tmp = WriteBuffer;
|
||||
WriteBuffer = ReadBuffer;
|
||||
ReadBuffer = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Not Implemented Functions and Properties
|
||||
|
||||
public override bool CanRead { get { throw new NotImplementedException(); } }
|
||||
public override bool CanSeek { get { throw new NotImplementedException(); } }
|
||||
public override bool CanWrite { get { throw new NotImplementedException(); } }
|
||||
|
||||
public override long Length { get { throw new NotImplementedException(); } }
|
||||
public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2ab021301a7baf45a80b5a46275a140
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61ccf02e2b33b974b9bc1bfd84f2610c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d4bfda5b11c65749922fce76d61bbe6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BestHTTP.Core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.Components
|
||||
{
|
||||
public class Cache : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649, 0169
|
||||
[SerializeField]
|
||||
private Text _count;
|
||||
|
||||
[SerializeField]
|
||||
private Text _size;
|
||||
|
||||
[SerializeField]
|
||||
private Button _clear;
|
||||
#pragma warning restore
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PluginEventHelper.OnEvent += OnPluginEvent;
|
||||
UpdateLabels();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
PluginEventHelper.OnEvent -= OnPluginEvent;
|
||||
}
|
||||
|
||||
private void OnPluginEvent(PluginEventInfo @event)
|
||||
{
|
||||
if (@event.Event == PluginEvents.SaveCacheLibrary)
|
||||
UpdateLabels();
|
||||
}
|
||||
|
||||
private void UpdateLabels()
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
this._count.text = BestHTTP.Caching.HTTPCacheService.GetCacheEntityCount().ToString("N0");
|
||||
this._size.text = BestHTTP.Caching.HTTPCacheService.GetCacheSize().ToString("N0");
|
||||
#else
|
||||
this._count.text = "0";
|
||||
this._size.text = "0";
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnClearButtonClicked()
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
BestHTTP.Caching.HTTPCacheService.BeginClear();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b640e13d843caef4885814c6d13d8e3d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using BestHTTP.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.Components
|
||||
{
|
||||
public class Cookies : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649, 0169
|
||||
[SerializeField]
|
||||
private Text _count;
|
||||
|
||||
[SerializeField]
|
||||
private Text _size;
|
||||
|
||||
[SerializeField]
|
||||
private Button _clear;
|
||||
#pragma warning restore
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PluginEventHelper.OnEvent += OnPluginEvent;
|
||||
UpdateLabels();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
PluginEventHelper.OnEvent -= OnPluginEvent;
|
||||
}
|
||||
|
||||
private void OnPluginEvent(PluginEventInfo @event)
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_COOKIES
|
||||
if (@event.Event == PluginEvents.SaveCookieLibrary)
|
||||
UpdateLabels();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void UpdateLabels()
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_COOKIES
|
||||
var cookies = BestHTTP.Cookies.CookieJar.GetAll();
|
||||
var size = cookies.Sum(c => c.GuessSize());
|
||||
|
||||
this._count.text = cookies.Count.ToString("N0");
|
||||
this._size.text = size.ToString("N0");
|
||||
#else
|
||||
this._count.text = "0";
|
||||
this._size.text = "0";
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnClearButtonClicked()
|
||||
{
|
||||
#if !BESTHTTP_DISABLE_COOKIES
|
||||
BestHTTP.Cookies.CookieJar.Clear();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b9db2d0fa31b054b835fb38d688f211
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using BestHTTP.Examples.Helpers;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples
|
||||
{
|
||||
public static class GUIHelper
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Binary_prefix
|
||||
private static string[] prefixes = new string[] { " B", " KiB", " MiB", " GiB", " TiB" };
|
||||
public static string GetBytesStr(double bytes, byte precision)
|
||||
{
|
||||
int prefixIdx = 0;
|
||||
while (bytes >= 1024)
|
||||
{
|
||||
bytes = bytes / 1024;
|
||||
prefixIdx++;
|
||||
}
|
||||
|
||||
return bytes.ToString("F" + precision) + prefixes[prefixIdx];
|
||||
}
|
||||
|
||||
public static void RemoveChildren(RectTransform transform, int maxChildCount)
|
||||
{
|
||||
while (transform.childCount > maxChildCount)
|
||||
{
|
||||
var child = transform.GetChild(0);
|
||||
child.SetParent(null);
|
||||
|
||||
GameObject.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static TextListItem AddText(TextListItem prefab, RectTransform contentRoot, string text, int maxEntries, ScrollRect scrollRect)
|
||||
{
|
||||
if (contentRoot == null)
|
||||
return null;
|
||||
|
||||
var listItem = GameObject.Instantiate<TextListItem>(prefab, contentRoot, false);
|
||||
listItem.SetText(text);
|
||||
|
||||
GUIHelper.RemoveChildren(contentRoot, maxEntries);
|
||||
|
||||
if (scrollRect != null && scrollRect.isActiveAndEnabled)
|
||||
scrollRect.StartCoroutine(ScrollToBottom(scrollRect));
|
||||
|
||||
return listItem;
|
||||
}
|
||||
|
||||
public static IEnumerator ScrollToBottom(ScrollRect scrollRect)
|
||||
{
|
||||
yield return null;
|
||||
|
||||
if (scrollRect != null && scrollRect.isActiveAndEnabled)
|
||||
scrollRect.normalizedPosition = new Vector2(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd560ff6f0fa60844a43a82db1ad03be
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace BestHTTP.Examples
|
||||
{
|
||||
public class Link : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler
|
||||
{
|
||||
public string url;
|
||||
public Texture2D linkSelectCursor;
|
||||
|
||||
void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
openWindow(this.url);
|
||||
#else
|
||||
Application.OpenURL(this.url);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
Cursor.SetCursor(this.linkSelectCursor, Vector2.zero, CursorMode.Auto);
|
||||
}
|
||||
|
||||
void IPointerExitHandler.OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
|
||||
}
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
[DllImport("__Internal")]
|
||||
private static extern void openWindow(string url);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab0e37de384a5b4d8320cdd8644b44c
|
||||
timeCreated: 1572211254
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcfb03f220265ea4e9fd88ae5af90176
|
||||
timeCreated: 1572242320
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
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: 1
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 7
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 115e9a87669ff8641b48c627cf3d14e2
|
||||
folderAsset: yes
|
||||
timeCreated: 1572243579
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33f2b105c6dd5f6418e70c8858a1387f
|
||||
folderAsset: yes
|
||||
timeCreated: 1572243588
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Based on:
|
||||
* https://github.com/valyard/UnityWebGLOpenLink
|
||||
*/
|
||||
|
||||
var OpenWindowPlugin = {
|
||||
openWindow: function(link)
|
||||
{
|
||||
var url = Pointer_stringify(link);
|
||||
|
||||
var func = function()
|
||||
{
|
||||
window.open(url);
|
||||
document.removeEventListener('mouseup', func);
|
||||
}
|
||||
|
||||
document.addEventListener('mouseup', func);
|
||||
}
|
||||
};
|
||||
|
||||
mergeInto(LibraryManager.library, OpenWindowPlugin);
|
||||
@@ -0,0 +1,36 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba6012acd13dbb34390ea3e1de9e8a93
|
||||
timeCreated: 1572243826
|
||||
licenseType: Store
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Facebook: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
WebGL: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers
|
||||
{
|
||||
public abstract class SampleBase : MonoBehaviour
|
||||
{
|
||||
[Header("Common Properties")]
|
||||
public string Category;
|
||||
public string DisplayName;
|
||||
|
||||
[TextArea]
|
||||
public string Description;
|
||||
|
||||
public RuntimePlatform[] BannedPlatforms = new RuntimePlatform[0];
|
||||
|
||||
protected SampleRoot sampleSelector;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
this.sampleSelector = FindObjectOfType<SampleRoot>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f8792c52d9520447a1c9d7139925f57
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 901494a9e35e283418e26dd2ae48f62c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.SelectorUI
|
||||
{
|
||||
public sealed class Category : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
|
||||
[SerializeField]
|
||||
private Text _text;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
public void SetLabel(string category)
|
||||
{
|
||||
this._text.text = category;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1101c9e1e1276414d8062a6a7ca4db45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,171 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1904131878966858}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1904131878966858
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224461754452575090}
|
||||
- component: {fileID: 114104161713339180}
|
||||
- component: {fileID: 114607162270506794}
|
||||
- component: {fileID: 114804161523563040}
|
||||
m_Layer: 5
|
||||
m_Name: Category
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1966926200078894
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224471434808036404}
|
||||
- component: {fileID: 222752501853716432}
|
||||
- component: {fileID: 114045595599197664}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114045595599197664
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1966926200078894}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 1
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Sample Name
|
||||
--- !u!114 &114104161713339180
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1904131878966858}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1101c9e1e1276414d8062a6a7ca4db45, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_text: {fileID: 114045595599197664}
|
||||
--- !u!114 &114607162270506794
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1904131878966858}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 2
|
||||
m_VerticalFit: 2
|
||||
--- !u!114 &114804161523563040
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1904131878966858}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 0
|
||||
m_Right: 0
|
||||
m_Top: 0
|
||||
m_Bottom: 0
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 1
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!222 &222752501853716432
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1966926200078894}
|
||||
--- !u!224 &224461754452575090
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1904131878966858}
|
||||
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: 224471434808036404}
|
||||
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: 400, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &224471434808036404
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1966926200078894}
|
||||
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: 224461754452575090}
|
||||
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.5, y: 0.5}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc69717198f6d93498890b7b67812172
|
||||
timeCreated: 1571212112
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.SelectorUI
|
||||
{
|
||||
public sealed class ExampleInfo : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private Text _header;
|
||||
|
||||
[SerializeField]
|
||||
private Text _description;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
private SampleSelectorUI _parentUI;
|
||||
|
||||
private SampleBase _example;
|
||||
|
||||
public void Setup(SampleSelectorUI parentUI, SampleBase example)
|
||||
{
|
||||
this._parentUI = parentUI;
|
||||
this._example = example;
|
||||
|
||||
this._header.text = this._example.name;
|
||||
this._description.text = this._example.Description;
|
||||
}
|
||||
|
||||
public void OnExecuteExample()
|
||||
{
|
||||
this._parentUI.ExecuteExample(this._example);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd424cc4259865c4ba2fb4d9d68d0272
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,507 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1844362866936956}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1164538047482000
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224919186422011706}
|
||||
- component: {fileID: 222389287056714158}
|
||||
- component: {fileID: 114764438814610556}
|
||||
- component: {fileID: 114425745104630664}
|
||||
- component: {fileID: 114698872193548206}
|
||||
- component: {fileID: 114431572224555080}
|
||||
m_Layer: 5
|
||||
m_Name: Execute Sample Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1248744110497022
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224829437101102402}
|
||||
- component: {fileID: 222702223361243722}
|
||||
- component: {fileID: 114859111753421280}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1397735183102074
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224216400874628136}
|
||||
- component: {fileID: 222516365031537928}
|
||||
- component: {fileID: 114059492809184142}
|
||||
- component: {fileID: 114493726555860862}
|
||||
m_Layer: 5
|
||||
m_Name: Description
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1531245648659982
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224368887501416132}
|
||||
- component: {fileID: 222882642833739976}
|
||||
- component: {fileID: 114666879149101946}
|
||||
m_Layer: 5
|
||||
m_Name: Header
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1844362866936956
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224811306304922960}
|
||||
- component: {fileID: 114988937263723000}
|
||||
- component: {fileID: 114645756897919032}
|
||||
- component: {fileID: 114471653971156696}
|
||||
m_Layer: 5
|
||||
m_Name: ExampleInfo
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114059492809184142
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1397735183102074}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Description
|
||||
--- !u!114 &114425745104630664
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
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_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 114764438814610556}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 114471653971156696}
|
||||
m_MethodName: OnExecuteExample
|
||||
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
|
||||
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!114 &114431572224555080
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!114 &114471653971156696
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1844362866936956}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fd424cc4259865c4ba2fb4d9d68d0272, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_header: {fileID: 114666879149101946}
|
||||
_description: {fileID: 114059492809184142}
|
||||
--- !u!114 &114493726555860862
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1397735183102074}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1679637790, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: 1
|
||||
m_FlexibleHeight: 1
|
||||
m_LayoutPriority: 1
|
||||
--- !u!114 &114645756897919032
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1844362866936956}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1679637790, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: 3
|
||||
m_FlexibleHeight: 1
|
||||
m_LayoutPriority: 1
|
||||
--- !u!114 &114666879149101946
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1531245648659982}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 24
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Header
|
||||
--- !u!114 &114698872193548206
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 5
|
||||
m_Right: 5
|
||||
m_Top: 5
|
||||
m_Bottom: 5
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!114 &114764438814610556
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &114859111753421280
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1248744110497022}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Execute
|
||||
--- !u!114 &114988937263723000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1844362866936956}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 5
|
||||
m_Right: 5
|
||||
m_Top: 5
|
||||
m_Bottom: 5
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 5
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!222 &222389287056714158
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
--- !u!222 &222516365031537928
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1397735183102074}
|
||||
--- !u!222 &222702223361243722
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1248744110497022}
|
||||
--- !u!222 &222882642833739976
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1531245648659982}
|
||||
--- !u!224 &224216400874628136
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1397735183102074}
|
||||
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: 224811306304922960}
|
||||
m_RootOrder: 1
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224368887501416132
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1531245648659982}
|
||||
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: 224811306304922960}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224811306304922960
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1844362866936956}
|
||||
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: 224368887501416132}
|
||||
- {fileID: 224216400874628136}
|
||||
- {fileID: 224919186422011706}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224829437101102402
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1248744110497022}
|
||||
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: 224919186422011706}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224919186422011706
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1164538047482000}
|
||||
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: 224829437101102402}
|
||||
m_Father: {fileID: 224811306304922960}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 300, y: 0}
|
||||
m_SizeDelta: {x: 590, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d57a4ffd57493de4f9f41009f52c658e
|
||||
timeCreated: 1571212676
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.SelectorUI
|
||||
{
|
||||
public sealed class ExampleListItem : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private Text _text;
|
||||
#pragma warning restore
|
||||
|
||||
public SampleSelectorUI ParentUI { get; private set; }
|
||||
|
||||
public SampleBase ExamplePrefab { get; private set; }
|
||||
|
||||
public void Setup(SampleSelectorUI parentUI, SampleBase prefab)
|
||||
{
|
||||
this.ParentUI = parentUI;
|
||||
this.ExamplePrefab = prefab;
|
||||
|
||||
this._text.text = prefab.DisplayName;
|
||||
}
|
||||
|
||||
public void OnButton()
|
||||
{
|
||||
this.ParentUI.SelectSample(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 376fb4eb0776e41479fb60f520aaa1f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,222 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1972462828926934}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1706707392201452
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224973040142512786}
|
||||
- component: {fileID: 222441293650573372}
|
||||
- component: {fileID: 114389340898110916}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1972462828926934
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224145737800144754}
|
||||
- component: {fileID: 222972952305363732}
|
||||
- component: {fileID: 114266276035656386}
|
||||
- component: {fileID: 114629809360314506}
|
||||
- component: {fileID: 114416681848148688}
|
||||
m_Layer: 5
|
||||
m_Name: ExampleListItem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114266276035656386
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1972462828926934}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &114389340898110916
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1706707392201452}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Button
|
||||
--- !u!114 &114416681848148688
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1972462828926934}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 376fb4eb0776e41479fb60f520aaa1f3, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_text: {fileID: 114389340898110916}
|
||||
--- !u!114 &114629809360314506
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1972462828926934}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
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_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 114266276035656386}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 114416681848148688}
|
||||
m_MethodName: OnButton
|
||||
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
|
||||
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!222 &222441293650573372
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1706707392201452}
|
||||
--- !u!222 &222972952305363732
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1972462828926934}
|
||||
--- !u!224 &224145737800144754
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1972462828926934}
|
||||
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: 224973040142512786}
|
||||
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: 160, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &224973040142512786
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1706707392201452}
|
||||
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: 224145737800144754}
|
||||
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}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 216b271b42611e447829c7e7de089ab4
|
||||
timeCreated: 1571212394
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers.SelectorUI
|
||||
{
|
||||
public class SampleSelectorUI : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649, 0169
|
||||
|
||||
[SerializeField]
|
||||
private Category _categoryListItemPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private ExampleListItem _exampleListItemPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private ExampleInfo _exampleInfoPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _listRoot;
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _dyncamicContentRoot;
|
||||
|
||||
private SampleRoot sampleSelector;
|
||||
private ExampleListItem selectedSample;
|
||||
private GameObject dynamicContent;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
private void Start()
|
||||
{
|
||||
this.sampleSelector = FindObjectOfType<SampleRoot>();
|
||||
DisplayExamples();
|
||||
}
|
||||
|
||||
private void DisplayExamples()
|
||||
{
|
||||
// Sort examples by category
|
||||
this.sampleSelector.samples.Sort((a, b) => {
|
||||
if (a == null || b == null)
|
||||
return 0;
|
||||
|
||||
int result = a.Category.CompareTo(b.Category);
|
||||
if (result == 0)
|
||||
result = a.DisplayName.CompareTo(b.DisplayName);
|
||||
return result;
|
||||
});
|
||||
|
||||
string currentCategory = null;
|
||||
|
||||
for (int i = 0; i < this.sampleSelector.samples.Count; ++i)
|
||||
{
|
||||
var examplePrefab = this.sampleSelector.samples[i];
|
||||
|
||||
if (examplePrefab == null)
|
||||
continue;
|
||||
|
||||
if (examplePrefab.BannedPlatforms.Contains(UnityEngine.Application.platform))
|
||||
continue;
|
||||
|
||||
if (currentCategory != examplePrefab.Category)
|
||||
{
|
||||
var category = Instantiate<Category>(this._categoryListItemPrefab, this._listRoot, false);
|
||||
category.SetLabel(examplePrefab.Category);
|
||||
|
||||
currentCategory = examplePrefab.Category;
|
||||
}
|
||||
|
||||
var listItem = Instantiate<ExampleListItem>(this._exampleListItemPrefab, this._listRoot, false);
|
||||
listItem.Setup(this, examplePrefab);
|
||||
|
||||
if (this.sampleSelector.selectedExamplePrefab == null)
|
||||
{
|
||||
SelectSample(listItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectSample(ExampleListItem item)
|
||||
{
|
||||
this.sampleSelector.selectedExamplePrefab = item.ExamplePrefab;
|
||||
if (this.dynamicContent != null)
|
||||
Destroy(this.dynamicContent);
|
||||
|
||||
var example = Instantiate<ExampleInfo>(this._exampleInfoPrefab, this._dyncamicContentRoot, false);
|
||||
example.Setup(this, item.ExamplePrefab);
|
||||
this.dynamicContent = example.gameObject;
|
||||
}
|
||||
|
||||
public void ExecuteExample(SampleBase example)
|
||||
{
|
||||
if (this.dynamicContent != null)
|
||||
Destroy(this.dynamicContent);
|
||||
this.dynamicContent = Instantiate(example, this._dyncamicContentRoot, false).gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd639b2a784de314984c606b7e8329e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.Helpers
|
||||
{
|
||||
public class TextListItem : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private Text _text;
|
||||
#pragma warning restore
|
||||
|
||||
public void SetText(string text)
|
||||
{
|
||||
this._text.text = text;
|
||||
}
|
||||
|
||||
public void AddLeftPadding(int padding)
|
||||
{
|
||||
this.GetComponent<LayoutGroup>().padding.left += padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05975660b0231b84f849693106b207d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,206 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1727935926237334}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1503879635514882
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224106021874867618}
|
||||
- component: {fileID: 222738347872656220}
|
||||
- component: {fileID: 114900463745114476}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1727935926237334
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224916463173798366}
|
||||
- component: {fileID: 222969618919079142}
|
||||
- component: {fileID: 114878452276715702}
|
||||
- component: {fileID: 114769119028883068}
|
||||
- component: {fileID: 114599056085522236}
|
||||
- component: {fileID: 114144824129317776}
|
||||
m_Layer: 5
|
||||
m_Name: TextListItem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114144824129317776
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 05975660b0231b84f849693106b207d1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_text: {fileID: 114900463745114476}
|
||||
--- !u!114 &114599056085522236
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!114 &114769119028883068
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1297475563, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 5
|
||||
m_Right: 2
|
||||
m_Top: 2
|
||||
m_Bottom: 2
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 2
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 1
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!114 &114878452276715702
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.39215687}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &114900463745114476
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1503879635514882}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 10
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: New Text
|
||||
--- !u!222 &222738347872656220
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1503879635514882}
|
||||
--- !u!222 &222969618919079142
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
--- !u!224 &224106021874867618
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1503879635514882}
|
||||
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: 224916463173798366}
|
||||
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.5, y: 0.5}
|
||||
--- !u!224 &224916463173798366
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1727935926237334}
|
||||
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: 224106021874867618}
|
||||
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: 400, y: 0}
|
||||
m_SizeDelta: {x: 800, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46bdaff7a8bf5d34da870d286f962c69
|
||||
timeCreated: 1571213203
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4b189b8db53fae40b63e2563cc658ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
#if CSHARP_7_OR_LATER
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BestHTTP
|
||||
{
|
||||
public static class AsyncExtensions
|
||||
{
|
||||
public static Task<T> GetFromJsonResultAsync<T>(this HTTPRequest request, CancellationToken token = default)
|
||||
{
|
||||
return HTTPRequestAsyncExtensions.CreateTask<T>(request, token, (req, resp, tcs) =>
|
||||
{
|
||||
switch (req.State)
|
||||
{
|
||||
// The request finished without any problem.
|
||||
case HTTPRequestStates.Finished:
|
||||
if (resp.IsSuccess)
|
||||
tcs.TrySetResult(BestHTTP.JSON.LitJson.JsonMapper.ToObject<T>(resp.DataAsText));
|
||||
else
|
||||
tcs.TrySetException(HTTPRequestAsyncExtensions.CreateException("Request finished Successfully, but the server sent an error.", resp));
|
||||
break;
|
||||
|
||||
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
|
||||
case HTTPRequestStates.Error:
|
||||
HTTPRequestAsyncExtensions.VerboseLogging(request, "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
|
||||
|
||||
tcs.TrySetException(HTTPRequestAsyncExtensions.CreateException("No Exception", null, req.Exception));
|
||||
break;
|
||||
|
||||
// The request aborted, initiated by the user.
|
||||
case HTTPRequestStates.Aborted:
|
||||
HTTPRequestAsyncExtensions.VerboseLogging(request, "Request Aborted!");
|
||||
|
||||
tcs.TrySetCanceled();
|
||||
break;
|
||||
|
||||
// Connecting to the server is timed out.
|
||||
case HTTPRequestStates.ConnectionTimedOut:
|
||||
HTTPRequestAsyncExtensions.VerboseLogging(request, "Connection Timed Out!");
|
||||
|
||||
tcs.TrySetException(HTTPRequestAsyncExtensions.CreateException("Connection Timed Out!"));
|
||||
break;
|
||||
|
||||
// The request didn't finished in the given time.
|
||||
case HTTPRequestStates.TimedOut:
|
||||
HTTPRequestAsyncExtensions.VerboseLogging(request, "Processing the request Timed Out!");
|
||||
|
||||
tcs.TrySetException(HTTPRequestAsyncExtensions.CreateException("Processing the request Timed Out!"));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f0aefe97b2a43844850d2d8b234e819
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
103
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/SampleRoot.cs
Normal file
103
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/SampleRoot.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using BestHTTP.Examples.Helpers;
|
||||
|
||||
namespace BestHTTP.Examples
|
||||
{
|
||||
public class SampleRoot : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649, 0169
|
||||
[Header("Common Properties")]
|
||||
public string BaseURL = "https://besthttpwebgldemo.azurewebsites.net";
|
||||
|
||||
[Header("References")]
|
||||
|
||||
[SerializeField]
|
||||
private Text _pluginVersion;
|
||||
|
||||
[SerializeField]
|
||||
private Dropdown _logLevelDropdown;
|
||||
|
||||
[SerializeField]
|
||||
private Text _proxyLabel;
|
||||
|
||||
[SerializeField]
|
||||
private InputField _proxyInputField;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
[SerializeField]
|
||||
public List<SampleBase> samples = new List<SampleBase>();
|
||||
|
||||
[HideInInspector]
|
||||
public SampleBase selectedExamplePrefab;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Application.runInBackground = true;
|
||||
|
||||
this._pluginVersion.text = "Version: " + HTTPManager.UserAgent;
|
||||
|
||||
int logLevel = PlayerPrefs.GetInt("BestHTTP.HTTPManager.Logger.Level", (int)HTTPManager.Logger.Level);
|
||||
this._logLevelDropdown.value = logLevel;
|
||||
HTTPManager.Logger.Level = (BestHTTP.Logger.Loglevels)logLevel;
|
||||
|
||||
#if (UNITY_WEBGL && !UNITY_EDITOR) || BESTHTTP_DISABLE_PROXY
|
||||
this._proxyLabel.gameObject.SetActive(false);
|
||||
this._proxyInputField.gameObject.SetActive(false);
|
||||
#else
|
||||
string proxyURL = PlayerPrefs.GetString("BestHTTP.HTTPManager.Proxy", null);
|
||||
if (!string.IsNullOrEmpty(proxyURL))
|
||||
{
|
||||
try
|
||||
{
|
||||
HTTPManager.Proxy = new HTTPProxy(new Uri(proxyURL), null, true);
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
this._proxyInputField.SetTextWithoutNotify(proxyURL);
|
||||
#else
|
||||
this._proxyInputField.onEndEdit.RemoveAllListeners();
|
||||
this._proxyInputField.text = proxyURL;
|
||||
this._proxyInputField.onEndEdit.AddListener(this.OnProxyEditEnd);
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
else
|
||||
HTTPManager.Proxy = null;
|
||||
#endif
|
||||
|
||||
#if !BESTHTTP_DISABLE_CACHING
|
||||
// Remove too old cache entries.
|
||||
BestHTTP.Caching.HTTPCacheService.BeginMaintainence(new BestHTTP.Caching.HTTPCacheMaintananceParams(TimeSpan.FromDays(30), ulong.MaxValue));
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnLogLevelChanged(int idx)
|
||||
{
|
||||
HTTPManager.Logger.Level = (BestHTTP.Logger.Loglevels)idx;
|
||||
PlayerPrefs.SetInt("BestHTTP.HTTPManager.Logger.Level", idx);
|
||||
}
|
||||
|
||||
public void OnProxyEditEnd(string proxyURL)
|
||||
{
|
||||
#if (!UNITY_WEBGL || UNITY_EDITOR) && !BESTHTTP_DISABLE_PROXY
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(this._proxyInputField.text))
|
||||
HTTPManager.Proxy = null;
|
||||
else
|
||||
HTTPManager.Proxy = new HTTPProxy(new Uri(this._proxyInputField.text), null, true);
|
||||
|
||||
PlayerPrefs.SetString("BestHTTP.HTTPManager.Proxy", this._proxyInputField.text);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0eb115c0377f90041a9ecfde21658f92
|
||||
timeCreated: 1571213708
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6086
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/SampleSelector.unity
Normal file
6086
JNFrame/Assets/Game/Plugins/Best HTTP/Examples/SampleSelector.unity
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ed13563a809f06489c3e97e4da02176
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d95d33b7692aa2c4494946f8f92a989f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 623f70cc1d86e664ca6e0128d812b8fe
|
||||
timeCreated: 1571295463
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,156 @@
|
||||
#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS
|
||||
|
||||
using System;
|
||||
using BestHTTP.Examples.Helpers;
|
||||
using BestHTTP.ServerSentEvents;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.ServerSentEvents
|
||||
{
|
||||
public class SimpleSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
|
||||
[Tooltip("The url of the resource to use.")]
|
||||
[SerializeField]
|
||||
private string _path = "/sse";
|
||||
|
||||
[SerializeField]
|
||||
private ScrollRect _scrollRect;
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _contentRoot;
|
||||
|
||||
[SerializeField]
|
||||
private TextListItem _listItemPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private int _maxListItemEntries = 100;
|
||||
|
||||
[SerializeField]
|
||||
private Button _startButton;
|
||||
|
||||
[SerializeField]
|
||||
private Button _closeButton;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
private EventSource eventSource;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
SetButtons(true, false);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (this.eventSource != null)
|
||||
{
|
||||
this.eventSource.Close();
|
||||
this.eventSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStartButton()
|
||||
{
|
||||
GUIHelper.RemoveChildren(this._contentRoot, 0);
|
||||
|
||||
// Create the EventSource instance
|
||||
this.eventSource = new EventSource(new Uri(base.sampleSelector.BaseURL + this._path));
|
||||
|
||||
// Subscribe to generic events
|
||||
this.eventSource.OnOpen += OnOpen;
|
||||
this.eventSource.OnClosed += OnClosed;
|
||||
this.eventSource.OnError += OnError;
|
||||
this.eventSource.OnStateChanged += this.OnStateChanged;
|
||||
this.eventSource.OnMessage += OnMessage;
|
||||
|
||||
// Subscribe to an application specific event
|
||||
this.eventSource.On("datetime", OnDateTime);
|
||||
|
||||
// Start to connect to the server
|
||||
this.eventSource.Open();
|
||||
|
||||
AddText("Opening Server-Sent Events...");
|
||||
|
||||
SetButtons(false, true);
|
||||
}
|
||||
|
||||
public void OnCloseButton()
|
||||
{
|
||||
SetButtons(false, false);
|
||||
this.eventSource.Close();
|
||||
}
|
||||
|
||||
private void OnOpen(EventSource eventSource)
|
||||
{
|
||||
AddText("Open");
|
||||
}
|
||||
|
||||
private void OnClosed(EventSource eventSource)
|
||||
{
|
||||
AddText("Closed");
|
||||
|
||||
this.eventSource = null;
|
||||
|
||||
SetButtons(true, false);
|
||||
}
|
||||
|
||||
private void OnError(EventSource eventSource, string error)
|
||||
{
|
||||
AddText(string.Format("Error: <color=red>{0}</color>", error));
|
||||
}
|
||||
|
||||
private void OnStateChanged(EventSource eventSource, States oldState, States newState)
|
||||
{
|
||||
AddText(string.Format("State Changed {0} => {1}", oldState, newState));
|
||||
}
|
||||
|
||||
private void OnMessage(EventSource eventSource, Message message)
|
||||
{
|
||||
AddText(string.Format("Message: <color=yellow>{0}</color>", message));
|
||||
}
|
||||
|
||||
private void OnDateTime(EventSource eventSource, Message message)
|
||||
{
|
||||
DateTimeData dtData = BestHTTP.JSON.LitJson.JsonMapper.ToObject<DateTimeData>(message.Data);
|
||||
|
||||
AddText(string.Format("OnDateTime: <color=yellow>{0}</color>", dtData.ToString()));
|
||||
}
|
||||
|
||||
private void SetButtons(bool start, bool close)
|
||||
{
|
||||
if (this._startButton != null)
|
||||
this._startButton.interactable = start;
|
||||
|
||||
if (this._closeButton != null)
|
||||
this._closeButton.interactable = close;
|
||||
}
|
||||
|
||||
private void AddText(string text)
|
||||
{
|
||||
GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
|
||||
}
|
||||
}
|
||||
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
sealed class DateTimeData
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
public int eventid;
|
||||
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
public string datetime;
|
||||
#pragma warning restore
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[DateTimeData EventId: {0}, DateTime: {1}]", this.eventid, this.datetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 730e176dfa30cb24c93efcaabb4f8688
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d69707652d0d406448aedf33b807bf6d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9286baa677f488b4bb493dd5436147c6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,135 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR
|
||||
#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
|
||||
using BestHTTP.Cookies;
|
||||
using BestHTTP.SignalR.Transports;
|
||||
|
||||
namespace BestHTTP.SignalR.Authentication
|
||||
{
|
||||
public sealed class SampleCookieAuthentication : IAuthenticationProvider
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public Uri AuthUri { get; private set; }
|
||||
public string UserName { get; private set; }
|
||||
public string Password { get; private set; }
|
||||
public string UserRoles { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAuthenticationProvider properties
|
||||
|
||||
public bool IsPreAuthRequired { get; private set; }
|
||||
|
||||
public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
|
||||
public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Privates
|
||||
|
||||
private HTTPRequest AuthRequest;
|
||||
private Cookie Cookie;
|
||||
|
||||
#endregion
|
||||
|
||||
public SampleCookieAuthentication(Uri authUri, string user, string passwd, string roles)
|
||||
{
|
||||
this.AuthUri = authUri;
|
||||
this.UserName = user;
|
||||
this.Password = passwd;
|
||||
this.UserRoles = roles;
|
||||
this.IsPreAuthRequired = true;
|
||||
}
|
||||
|
||||
#region IAuthenticationProvider Implementation
|
||||
|
||||
public void StartAuthentication()
|
||||
{
|
||||
AuthRequest = new HTTPRequest(AuthUri, HTTPMethods.Post, OnAuthRequestFinished);
|
||||
|
||||
// Setup the form
|
||||
AuthRequest.AddField("userName", UserName);
|
||||
AuthRequest.AddField("Password", Password); // not used in the sample
|
||||
AuthRequest.AddField("roles", UserRoles);
|
||||
|
||||
AuthRequest.Send();
|
||||
}
|
||||
|
||||
public void PrepareRequest(HTTPRequest request, RequestTypes type)
|
||||
{
|
||||
// Adding the cookie to the request is not required, as it's managed by the plugin automatically,
|
||||
// but for now, we want to be really sure that it's added
|
||||
request.Cookies.Add(Cookie);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Request Handler
|
||||
|
||||
void OnAuthRequestFinished(HTTPRequest req, HTTPResponse resp)
|
||||
{
|
||||
AuthRequest = null;
|
||||
string failReason = string.Empty;
|
||||
|
||||
switch (req.State)
|
||||
{
|
||||
// The request finished without any problem.
|
||||
case HTTPRequestStates.Finished:
|
||||
if (resp.IsSuccess)
|
||||
{
|
||||
Cookie = resp.Cookies != null ? resp.Cookies.Find(c => c.Name.Equals(".ASPXAUTH")) : null;
|
||||
|
||||
if (Cookie != null)
|
||||
{
|
||||
HTTPManager.Logger.Information("CookieAuthentication", "Auth. Cookie found!");
|
||||
|
||||
if (OnAuthenticationSucceded != null)
|
||||
OnAuthenticationSucceded(this);
|
||||
|
||||
// return now, all other paths are authentication failures
|
||||
return;
|
||||
}
|
||||
else
|
||||
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Auth. Cookie NOT found!");
|
||||
}
|
||||
else
|
||||
HTTPManager.Logger.Warning("CookieAuthentication", failReason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
|
||||
resp.StatusCode,
|
||||
resp.Message,
|
||||
resp.DataAsText));
|
||||
break;
|
||||
|
||||
// The request finished with an unexpected error. The request's Exception property may contain more info about the error.
|
||||
case HTTPRequestStates.Error:
|
||||
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
|
||||
break;
|
||||
|
||||
// The request aborted, initiated by the user.
|
||||
case HTTPRequestStates.Aborted:
|
||||
HTTPManager.Logger.Warning("CookieAuthentication", failReason = "Request Aborted!");
|
||||
break;
|
||||
|
||||
// Connecting to the server is timed out.
|
||||
case HTTPRequestStates.ConnectionTimedOut:
|
||||
HTTPManager.Logger.Error("CookieAuthentication", failReason = "Connection Timed Out!");
|
||||
break;
|
||||
|
||||
// The request didn't finished in the given time.
|
||||
case HTTPRequestStates.TimedOut:
|
||||
HTTPManager.Logger.Error("CookieAuthentication", failReason = "Processing the request Timed Out!");
|
||||
break;
|
||||
}
|
||||
|
||||
if (OnAuthenticationFailed != null)
|
||||
OnAuthenticationFailed(this, failReason);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48a74a50eeb07bb4ea649a902e9d487a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR
|
||||
|
||||
namespace BestHTTP.SignalR.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom http-header based authenticator.
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Server side implementation of the Header-based authenticator
|
||||
/// // Use it by adding the app.Use(typeof(HeaderBasedAuthenticationMiddleware)); line to the Startup class' Configuration function.
|
||||
/// private class HeaderBasedAuthenticationMiddleware : OwinMiddleware
|
||||
/// {
|
||||
/// public HeaderBasedAuthenticationMiddleware(OwinMiddleware next)
|
||||
/// : base(next)
|
||||
/// {
|
||||
/// }
|
||||
///
|
||||
/// public override Task Invoke(IOwinContext context)
|
||||
/// {
|
||||
/// string username = context.Request.Headers.Get("username");
|
||||
/// string roles = context.Request.Headers.Get("roles");
|
||||
///
|
||||
/// if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(roles))
|
||||
/// {
|
||||
/// var identity = new System.Security.Principal.GenericIdentity(username);
|
||||
///
|
||||
/// var principal = new System.Security.Principal.GenericPrincipal(identity, SplitString(roles));
|
||||
///
|
||||
/// context.Request.User = principal;
|
||||
/// }
|
||||
///
|
||||
/// return Next.Invoke(context);
|
||||
/// }
|
||||
///
|
||||
/// private static string[] SplitString(string original)
|
||||
/// {
|
||||
/// if (String.IsNullOrEmpty(original))
|
||||
/// return new string[0];
|
||||
///
|
||||
/// var split = from piece in original.Split(',') let trimmed = piece.Trim() where !String.IsNullOrEmpty(trimmed) select trimmed;
|
||||
///
|
||||
/// return split.ToArray();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
class HeaderAuthenticator : IAuthenticationProvider
|
||||
{
|
||||
public string User { get; private set; }
|
||||
public string Roles { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// No pre-auth step required for this type of authentication
|
||||
/// </summary>
|
||||
public bool IsPreAuthRequired { get { return false; } }
|
||||
|
||||
#pragma warning disable 0067
|
||||
/// <summary>
|
||||
/// Not used event as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
|
||||
|
||||
/// <summary>
|
||||
/// Not used event as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
|
||||
|
||||
#pragma warning restore 0067
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to initialise the authenticator with username and roles.
|
||||
/// </summary>
|
||||
public HeaderAuthenticator(string user, string roles)
|
||||
{
|
||||
this.User = user;
|
||||
this.Roles = roles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not used as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public void StartAuthentication()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the request by adding two headers to it
|
||||
/// </summary>
|
||||
public void PrepareRequest(BestHTTP.HTTPRequest request, RequestTypes type)
|
||||
{
|
||||
request.SetHeader("username", this.User);
|
||||
request.SetHeader("roles", this.Roles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ebd4ce02d369a6498f9be6bb7141ac3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c996438e0be72649b8abf5fbdee3f41
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR && BESTHTTP_SIGNALR_WITH_JSONDOTNET
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BestHTTP.SignalR.JsonEncoders
|
||||
{
|
||||
public sealed class JSonDotnetEncoder : IJsonEncoder
|
||||
{
|
||||
public string Encode(object obj)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
|
||||
public IDictionary<string, object> DecodeMessage(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 653a0f163689052438748b7beda14886
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.JSON.LitJson;
|
||||
|
||||
namespace BestHTTP.SignalR.JsonEncoders
|
||||
{
|
||||
public sealed class LitJsonEncoder : IJsonEncoder
|
||||
{
|
||||
public string Encode(object obj)
|
||||
{
|
||||
JsonWriter writer = new JsonWriter();
|
||||
JsonMapper.ToJson(obj, writer);
|
||||
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
public IDictionary<string, object> DecodeMessage(string json)
|
||||
{
|
||||
JsonReader reader = new JsonReader(json);
|
||||
|
||||
return JsonMapper.ToObject<Dictionary<string, object>>(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2870a746a601b8b439c495ff39474385
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7ff75ba203704d45bf1098536a2db5a
|
||||
folderAsset: yes
|
||||
timeCreated: 1515401610
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1561e378e33bde4a9cfca1323516c79
|
||||
timeCreated: 1571296382
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,240 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using BestHTTP.SignalRCore;
|
||||
using BestHTTP.SignalRCore.Encoders;
|
||||
using UnityEngine.UI;
|
||||
using BestHTTP.Examples.Helpers;
|
||||
#if CSHARP_7_OR_LATER
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
|
||||
namespace BestHTTP.Examples
|
||||
{
|
||||
// Server side of this example can be found here:
|
||||
// https://github.com/Benedicht/BestHTTP_DemoSite/blob/master/BestHTTP_DemoSite/Hubs/TestHub.cs
|
||||
public class AsyncTestHubSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
#pragma warning disable 0414
|
||||
[SerializeField]
|
||||
private string _path = "/TestHub";
|
||||
|
||||
[SerializeField]
|
||||
private ScrollRect _scrollRect;
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _contentRoot;
|
||||
|
||||
[SerializeField]
|
||||
private TextListItem _listItemPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private int _maxListItemEntries = 100;
|
||||
|
||||
[SerializeField]
|
||||
private Button _connectButton;
|
||||
|
||||
[SerializeField]
|
||||
private Button _closeButton;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
// Instance of the HubConnection
|
||||
HubConnection hub;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
#if !CSHARP_7_OR_LATER
|
||||
AddText("<color=red>This sample can work only when at least c# 7.3 is supported!</color>");
|
||||
SetButtons(false, false);
|
||||
#else
|
||||
SetButtons(true, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CSHARP_7_OR_LATER
|
||||
async void OnDestroy()
|
||||
{
|
||||
await hub?.CloseAsync();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// GUI button callback
|
||||
/// </summary>
|
||||
public
|
||||
#if CSHARP_7_OR_LATER
|
||||
async
|
||||
#endif
|
||||
void OnConnectButton()
|
||||
{
|
||||
#if CSHARP_7_OR_LATER
|
||||
#if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
|
||||
try
|
||||
{
|
||||
MessagePack.Resolvers.StaticCompositeResolver.Instance.Register(
|
||||
MessagePack.Resolvers.DynamicEnumAsStringResolver.Instance,
|
||||
MessagePack.Unity.UnityResolver.Instance,
|
||||
//MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
|
||||
//MessagePack.Resolvers.StandardResolver.Instance,
|
||||
MessagePack.Resolvers.ContractlessStandardResolver.Instance
|
||||
);
|
||||
|
||||
var options = MessagePack.MessagePackSerializerOptions.Standard.WithResolver(MessagePack.Resolvers.StaticCompositeResolver.Instance);
|
||||
MessagePack.MessagePackSerializer.DefaultOptions = options;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
#endif
|
||||
|
||||
IProtocol protocol = null;
|
||||
#if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
|
||||
protocol = new MessagePackCSharpProtocol();
|
||||
#elif BESTHTTP_SIGNALR_CORE_ENABLE_GAMEDEVWARE_MESSAGEPACK
|
||||
protocol = new MessagePackProtocol();
|
||||
#else
|
||||
protocol = new JsonProtocol(new LitJsonEncoder());
|
||||
#endif
|
||||
// Crete the HubConnection
|
||||
hub = new HubConnection(new Uri(this.sampleSelector.BaseURL + this._path), protocol);
|
||||
|
||||
// Subscribe to hub events
|
||||
hub.OnError += Hub_OnError;
|
||||
|
||||
hub.OnTransportEvent += (hub, transport, ev) => AddText(string.Format("Transport(<color=green>{0}</color>) event: <color=green>{1}</color>", transport.TransportType, ev));
|
||||
|
||||
// Set up server callable functions
|
||||
hub.On("Send", (string arg) => AddText(string.Format("On '<color=green>Send</color>': '<color=yellow>{0}</color>'", arg)).AddLeftPadding(20));
|
||||
hub.On<Person>("Person", (person) => AddText(string.Format("On '<color=green>Person</color>': '<color=yellow>{0}</color>'", person)).AddLeftPadding(20));
|
||||
hub.On<Person, Person>("TwoPersons", (person1, person2) => AddText(string.Format("On '<color=green>TwoPersons</color>': '<color=yellow>{0}</color>', '<color=yellow>{1}</color>'", person1, person2)).AddLeftPadding(20));
|
||||
|
||||
AddText("StartConnect called");
|
||||
|
||||
SetButtons(false, false);
|
||||
|
||||
// And finally start to connect to the server
|
||||
await hub.ConnectAsync();
|
||||
|
||||
SetButtons(false, true);
|
||||
AddText(string.Format("Hub Connected with <color=green>{0}</color> transport using the <color=green>{1}</color> encoder.", hub.Transport.TransportType.ToString(), hub.Protocol.Name));
|
||||
|
||||
// Call a server function with a string param. We expect no return value.
|
||||
await hub.SendAsync("Send", "my message");
|
||||
|
||||
// Call a parameterless function. We expect a string return value.
|
||||
try
|
||||
{
|
||||
string result = await hub.InvokeAsync<string>("NoParam");
|
||||
|
||||
AddText(string.Format("'<color=green>NoParam</color>' returned: '<color=yellow>{0}</color>'", result))
|
||||
.AddLeftPadding(20);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddText(string.Format("'<color=green>NoParam</color>' error: '<color=red>{0}</color>'", ex.Message)).AddLeftPadding(20);
|
||||
}
|
||||
|
||||
// Call a function on the server to add two numbers. OnSuccess will be called with the result and OnError if there's an error.
|
||||
var addResult = await hub.InvokeAsync<int>("Add", 10, 20);
|
||||
AddText(string.Format("'<color=green>Add(10, 20)</color>' returned: '<color=yellow>{0}</color>'", addResult)).AddLeftPadding(20);
|
||||
|
||||
var nullabelTestResult = await hub.InvokeAsync<int?>("NullableTest", 10);
|
||||
AddText(string.Format("'<color=green>NullableTest(10)</color>' returned: '<color=yellow>{0}</color>'", nullabelTestResult)).AddLeftPadding(20);
|
||||
|
||||
// Call a function that will return a Person object constructed from the function's parameters.
|
||||
var getPersonResult = await hub.InvokeAsync<Person>("GetPerson", "Mr. Smith", 26);
|
||||
AddText(string.Format("'<color=green>GetPerson(\"Mr. Smith\", 26)</color>' returned: '<color=yellow>{0}</color>'", getPersonResult)).AddLeftPadding(20);
|
||||
|
||||
// To test errors/exceptions this call always throws an exception on the server side resulting in an OnError call.
|
||||
// OnError expected here!
|
||||
|
||||
try
|
||||
{
|
||||
var singleResultFailureResult = await hub.InvokeAsync<int>("SingleResultFailure", 10, 20);
|
||||
AddText(string.Format("'<color=green>SingleResultFailure(10, 20)</color>' returned: '<color=yellow>{0}</color>'", singleResultFailureResult)).AddLeftPadding(20);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddText(string.Format("'<color=green>SingleResultFailure(10, 20)</color>' error: '<color=red>{0}</color>'", ex.Message)).AddLeftPadding(20);
|
||||
}
|
||||
|
||||
// This call demonstrates IEnumerable<> functions, result will be the yielded numbers.
|
||||
var batchedResult = await hub.InvokeAsync<int[]>("Batched", 10);
|
||||
AddText(string.Format("'<color=green>Batched(10)</color>' returned items: '<color=yellow>{0}</color>'", batchedResult.Length)).AddLeftPadding(20);
|
||||
|
||||
// OnItem is called for a streaming request for every items returned by the server. OnSuccess will still be called with all the items.
|
||||
hub.GetDownStreamController<int>("ObservableCounter", 10, 1000)
|
||||
.OnItem(result => AddText(string.Format("'<color=green>ObservableCounter(10, 1000)</color>' OnItem: '<color=yellow>{0}</color>'", result)).AddLeftPadding(20))
|
||||
.OnSuccess(result => AddText("'<color=green>ObservableCounter(10, 1000)</color>' OnSuccess.").AddLeftPadding(20))
|
||||
.OnError(error => AddText(string.Format("'<color=green>ObservableCounter(10, 1000)</color>' error: '<color=red>{0}</color>'", error)).AddLeftPadding(20));
|
||||
|
||||
// A stream request can be cancelled any time.
|
||||
var controller = hub.GetDownStreamController<int>("ChannelCounter", 10, 1000);
|
||||
|
||||
controller.OnItem(result => AddText(string.Format("'<color=green>ChannelCounter(10, 1000)</color>' OnItem: '<color=yellow>{0}</color>'", result)).AddLeftPadding(20))
|
||||
.OnSuccess(result => AddText("'<color=green>ChannelCounter(10, 1000)</color>' OnSuccess.").AddLeftPadding(20))
|
||||
.OnError(error => AddText(string.Format("'<color=green>ChannelCounter(10, 1000)</color>' error: '<color=red>{0}</color>'", error)).AddLeftPadding(20));
|
||||
|
||||
// a stream can be cancelled by calling the controller's Cancel method
|
||||
controller.Cancel();
|
||||
|
||||
// This call will stream strongly typed objects
|
||||
hub.GetDownStreamController<Person>("GetRandomPersons", 20, 2000)
|
||||
.OnItem(result => AddText(string.Format("'<color=green>GetRandomPersons(20, 1000)</color>' OnItem: '<color=yellow>{0}</color>'", result)).AddLeftPadding(20))
|
||||
.OnSuccess(result => AddText("'<color=green>GetRandomPersons(20, 1000)</color>' OnSuccess.").AddLeftPadding(20));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GUI button callback
|
||||
/// </summary>
|
||||
public
|
||||
#if CSHARP_7_OR_LATER
|
||||
async
|
||||
#endif
|
||||
void OnCloseButton()
|
||||
{
|
||||
#if CSHARP_7_OR_LATER
|
||||
if (this.hub != null)
|
||||
{
|
||||
AddText("Calling CloseAsync");
|
||||
SetButtons(false, false);
|
||||
|
||||
await this.hub.CloseAsync();
|
||||
|
||||
SetButtons(true, false);
|
||||
AddText("Hub Closed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when an unrecoverable error happen. After this event the hub will not send or receive any messages.
|
||||
/// </summary>
|
||||
private void Hub_OnError(HubConnection hub, string error)
|
||||
{
|
||||
SetButtons(true, false);
|
||||
AddText(string.Format("Hub Error: <color=red>{0}</color>", error));
|
||||
}
|
||||
|
||||
private void SetButtons(bool connect, bool close)
|
||||
{
|
||||
if (this._connectButton != null)
|
||||
this._connectButton.interactable = connect;
|
||||
|
||||
if (this._closeButton != null)
|
||||
this._closeButton.interactable = close;
|
||||
}
|
||||
|
||||
private TextListItem AddText(string text)
|
||||
{
|
||||
return GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e516808e7e284014c8b7afb3ff270943
|
||||
timeCreated: 1577715218
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e87559ef678942428f064af598c1696
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE
|
||||
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SignalRCore.Authentication
|
||||
{
|
||||
public sealed class HeaderAuthenticator : IAuthenticationProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// No pre-auth step required for this type of authentication
|
||||
/// </summary>
|
||||
public bool IsPreAuthRequired { get { return false; } }
|
||||
|
||||
#pragma warning disable 0067
|
||||
/// <summary>
|
||||
/// Not used event as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
|
||||
|
||||
/// <summary>
|
||||
/// Not used event as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
|
||||
|
||||
#pragma warning restore 0067
|
||||
|
||||
private string _credentials;
|
||||
|
||||
public HeaderAuthenticator(string credentials)
|
||||
{
|
||||
this._credentials = credentials;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not used as IsPreAuthRequired is false
|
||||
/// </summary>
|
||||
public void StartAuthentication()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the request by adding two headers to it
|
||||
/// </summary>
|
||||
public void PrepareRequest(BestHTTP.HTTPRequest request)
|
||||
{
|
||||
#if !UNITY_WEBGL || UNITY_EDITOR
|
||||
request.SetHeader("Authorization", "Bearer " + this._credentials);
|
||||
#endif
|
||||
}
|
||||
|
||||
public Uri PrepareUri(Uri uri)
|
||||
{
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
string query = string.IsNullOrEmpty(uri.Query) ? "?" : uri.Query + "&";
|
||||
UriBuilder uriBuilder = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath, query + "access_token=" + this._credentials);
|
||||
return uriBuilder.Uri;
|
||||
#else
|
||||
return uri;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80b2246c164414c468eea4f0550eb9ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35c592488a6dbbc4a96c1739cd74046c
|
||||
folderAsset: yes
|
||||
timeCreated: 1515401610
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE && BESTHTTP_SIGNALR_CORE_ENABLE_NEWTONSOFT_JSON_DOTNET_ENCODER
|
||||
using System;
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
|
||||
namespace BestHTTP.SignalRCore.Encoders
|
||||
{
|
||||
public sealed class JsonDotNetEncoder : BestHTTP.SignalRCore.IEncoder
|
||||
{
|
||||
Newtonsoft.Json.JsonSerializerSettings _settings;
|
||||
|
||||
public JsonDotNetEncoder()
|
||||
{ }
|
||||
|
||||
public JsonDotNetEncoder(Newtonsoft.Json.JsonSerializerSettings settings)
|
||||
{
|
||||
this._settings = settings;
|
||||
}
|
||||
|
||||
public object ConvertTo(Type toType, object obj)
|
||||
{
|
||||
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj, this._settings);
|
||||
|
||||
return Newtonsoft.Json.JsonConvert.DeserializeObject(json, toType, this._settings);
|
||||
}
|
||||
|
||||
public T DecodeAs<T>(BufferSegment buffer)
|
||||
{
|
||||
using (var reader = new System.IO.StreamReader(new System.IO.MemoryStream(buffer.Data, buffer.Offset, buffer.Count)))
|
||||
using (var jsonReader = new Newtonsoft.Json.JsonTextReader(reader))
|
||||
return Newtonsoft.Json.JsonSerializer.CreateDefault(this._settings).Deserialize<T>(jsonReader);
|
||||
}
|
||||
|
||||
public BufferSegment Encode<T>(T value)
|
||||
{
|
||||
var json = Newtonsoft.Json.JsonConvert.SerializeObject(value, this._settings);
|
||||
|
||||
int len = System.Text.Encoding.UTF8.GetByteCount(json);
|
||||
byte[] buffer = BufferPool.Get(len + 1, true);
|
||||
System.Text.Encoding.UTF8.GetBytes(json, 0, json.Length, buffer, 0);
|
||||
|
||||
buffer[len] = 0x1e;
|
||||
|
||||
return new BufferSegment(buffer, 0, len + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e565b09f1e97ee4c9d119735901397b
|
||||
timeCreated: 1515401618
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE
|
||||
using System;
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
using BestHTTP.JSON.LitJson;
|
||||
|
||||
namespace BestHTTP.SignalRCore.Encoders
|
||||
{
|
||||
public sealed class LitJsonEncoder : BestHTTP.SignalRCore.IEncoder
|
||||
{
|
||||
public LitJsonEncoder()
|
||||
{
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<int, long>((input) => input);
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<long, int>((input) => (int)input);
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<double, int>((input) => (int)(input + 0.5));
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<string, DateTime>((input) => Convert.ToDateTime((string)input).ToUniversalTime());
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<double, float>((input) => (float)input);
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterImporter<string, byte[]>((input) => Convert.FromBase64String(input));
|
||||
BestHTTP.JSON.LitJson.JsonMapper.RegisterExporter<float>((f, writer) => writer.Write((double)f));
|
||||
}
|
||||
|
||||
public T DecodeAs<T>(BufferSegment buffer)
|
||||
{
|
||||
using (var reader = new System.IO.StreamReader(new System.IO.MemoryStream(buffer.Data, buffer.Offset, buffer.Count)))
|
||||
{
|
||||
return JsonMapper.ToObject<T>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public PlatformSupport.Memory.BufferSegment Encode<T>(T value)
|
||||
{
|
||||
var json = JsonMapper.ToJson(value);
|
||||
int len = System.Text.Encoding.UTF8.GetByteCount(json);
|
||||
byte[] buffer = BufferPool.Get(len + 1, true);
|
||||
System.Text.Encoding.UTF8.GetBytes(json, 0, json.Length, buffer, 0);
|
||||
buffer[len] = (byte)JsonProtocol.Separator;
|
||||
return new BufferSegment(buffer, 0, len + 1);
|
||||
}
|
||||
|
||||
public object ConvertTo(Type toType, object obj)
|
||||
{
|
||||
string json = BestHTTP.JSON.LitJson.JsonMapper.ToJson(obj);
|
||||
return BestHTTP.JSON.LitJson.JsonMapper.ToObject(toType, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5784b64da7c8ad47b441a9f2f27a33b
|
||||
timeCreated: 1515401618
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,567 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE && BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.Extensions;
|
||||
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
using BestHTTP.SignalRCore.Messages;
|
||||
|
||||
using MessagePack;
|
||||
|
||||
namespace BestHTTP.SignalRCore.Encoders
|
||||
{
|
||||
class BufferPoolBufferWriter : IBufferWriter<byte>
|
||||
{
|
||||
private BufferPoolMemoryStream underlyingStream;
|
||||
private BufferSegment last;
|
||||
|
||||
public BufferPoolBufferWriter(BufferPoolMemoryStream stream)
|
||||
{
|
||||
this.underlyingStream = stream;
|
||||
this.last = BufferSegment.Empty;
|
||||
}
|
||||
|
||||
public void Advance(int count)
|
||||
{
|
||||
this.underlyingStream.Write(this.last.Data, this.last.Offset, this.last.Count + count);
|
||||
BufferPool.Release(this.last);
|
||||
this.last = BufferSegment.Empty;
|
||||
}
|
||||
|
||||
public Memory<byte> GetMemory(int sizeHint = 0)
|
||||
{
|
||||
var buffer = BufferPool.Get(Math.Max(sizeHint, BufferPool.MinBufferSize), true);
|
||||
//Array.Clear(buffer, 0, buffer.Length);
|
||||
|
||||
this.last = new BufferSegment(buffer, 0, 0);
|
||||
return new Memory<byte>(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public Span<byte> GetSpan(int sizeHint = 0)
|
||||
{
|
||||
var buffer = BufferPool.Get(Math.Max(sizeHint, BufferPool.MinBufferSize), true);
|
||||
//Array.Clear(buffer, 0, buffer.Length);
|
||||
|
||||
this.last = new BufferSegment(buffer, 0, 0);
|
||||
|
||||
return new Span<byte>(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MessagePackCSharpProtocol : BestHTTP.SignalRCore.IProtocol
|
||||
{
|
||||
public string Name { get { return "messagepack"; } }
|
||||
public TransferModes Type { get { return TransferModes.Binary; } }
|
||||
public IEncoder Encoder { get; private set; }
|
||||
public HubConnection Connection { get; set; }
|
||||
|
||||
public BufferSegment EncodeMessage(Message message)
|
||||
{
|
||||
var memBuffer = BufferPool.Get(256, true);
|
||||
var stream = new BufferPoolMemoryStream(memBuffer, 0, memBuffer.Length, true, true, false, true);
|
||||
|
||||
// Write 5 bytes for placeholder for length prefix
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
|
||||
var bufferWriter = new BufferPoolBufferWriter(stream);
|
||||
var writer = new MessagePackWriter(bufferWriter);
|
||||
|
||||
switch (message.type)
|
||||
{
|
||||
case MessageTypes.StreamItem:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streamitem-message-encoding-1
|
||||
// [2, Headers, InvocationId, Item]
|
||||
|
||||
writer.WriteArrayHeader(4);
|
||||
|
||||
writer.Write(2);
|
||||
WriteHeaders(ref writer);
|
||||
WriteString(ref writer, message.invocationId);
|
||||
WriteValue(ref writer, bufferWriter, message.item);
|
||||
|
||||
break;
|
||||
|
||||
case MessageTypes.Completion:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#completion-message-encoding-1
|
||||
// [3, Headers, InvocationId, ResultKind, Result?]
|
||||
|
||||
byte resultKind = (byte)(!string.IsNullOrEmpty(message.error) ? /*error*/ 1 : message.result != null ? /*non-void*/ 3 : /*void*/ 2);
|
||||
|
||||
writer.WriteArrayHeader(resultKind == 2 ? 4 : 5);
|
||||
|
||||
writer.Write(3);
|
||||
WriteHeaders(ref writer);
|
||||
WriteString(ref writer, message.invocationId);
|
||||
writer.Write(resultKind);
|
||||
|
||||
if (resultKind == 1) // error
|
||||
WriteString(ref writer, message.error);
|
||||
else if (resultKind == 3) // non-void
|
||||
WriteValue(ref writer, bufferWriter, message.result);
|
||||
|
||||
break;
|
||||
|
||||
case MessageTypes.Invocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#invocation-message-encoding-1
|
||||
// [1, Headers, InvocationId, NonBlocking, Target, [Arguments], [StreamIds]]
|
||||
|
||||
case MessageTypes.StreamInvocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streaminvocation-message-encoding-1
|
||||
// [4, Headers, InvocationId, Target, [Arguments], [StreamIds]]
|
||||
|
||||
writer.WriteArrayHeader(message.streamIds != null ? 6 : 5);
|
||||
|
||||
writer.Write((int)message.type);
|
||||
WriteHeaders(ref writer);
|
||||
WriteString(ref writer, message.invocationId);
|
||||
WriteString(ref writer, message.target);
|
||||
writer.WriteArrayHeader(message.arguments != null ? message.arguments.Length : 0);
|
||||
if (message.arguments != null)
|
||||
for (int i = 0; i < message.arguments.Length; ++i)
|
||||
WriteValue(ref writer, bufferWriter, message.arguments[i]);
|
||||
|
||||
if (message.streamIds != null)
|
||||
{
|
||||
writer.WriteArrayHeader(message.streamIds.Length);
|
||||
|
||||
for (int i = 0; i < message.streamIds.Length; ++i)
|
||||
WriteValue(ref writer, bufferWriter, message.streamIds[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MessageTypes.CancelInvocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#cancelinvocation-message-encoding-1
|
||||
// [5, Headers, InvocationId]
|
||||
|
||||
writer.WriteArrayHeader(3);
|
||||
|
||||
writer.Write(5);
|
||||
WriteHeaders(ref writer);
|
||||
WriteString(ref writer, message.invocationId);
|
||||
|
||||
break;
|
||||
|
||||
case MessageTypes.Ping:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#ping-message-encoding-1
|
||||
// [6]
|
||||
|
||||
writer.WriteArrayHeader(1);
|
||||
writer.Write(6);
|
||||
|
||||
break;
|
||||
|
||||
case MessageTypes.Close:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding-1
|
||||
// [7, Error, AllowReconnect?]
|
||||
|
||||
writer.WriteArrayHeader(string.IsNullOrEmpty(message.error) ? 1 : 2);
|
||||
|
||||
writer.Write(7);
|
||||
if (!string.IsNullOrEmpty(message.error))
|
||||
WriteString(ref writer, message.error);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
writer.Flush();
|
||||
|
||||
// get how much bytes got written to the buffer. This includes the 5 placeholder bytes too.
|
||||
int length = (int)stream.Position;
|
||||
|
||||
// this is the length without the 5 placeholder bytes
|
||||
int contentLength = length - 5;
|
||||
|
||||
// get the stream's internal buffer. We set the releaseBuffer flag to false, so we can use it safely.
|
||||
var buffer = stream.GetBuffer();
|
||||
|
||||
// add varint length prefix
|
||||
byte prefixBytes = GetRequiredBytesForLengthPrefix(contentLength);
|
||||
WriteLengthAsVarInt(buffer, 5 - prefixBytes, contentLength);
|
||||
|
||||
// return with the final segment
|
||||
return new BufferSegment(buffer, 5 - prefixBytes, contentLength + prefixBytes);
|
||||
}
|
||||
|
||||
private void WriteValue(ref MessagePackWriter writer, BufferPoolBufferWriter bufferWriter, object item)
|
||||
{
|
||||
if (item == null)
|
||||
writer.WriteNil();
|
||||
else
|
||||
{
|
||||
writer.Flush();
|
||||
MessagePackSerializer.Serialize(item.GetType(), bufferWriter, item);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteString(ref MessagePackWriter writer, string str)
|
||||
{
|
||||
if (str == null)
|
||||
writer.WriteNil();
|
||||
else
|
||||
{
|
||||
int count = System.Text.Encoding.UTF8.GetByteCount(str);
|
||||
var buffer = BufferPool.Get(count, true);
|
||||
System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0);
|
||||
|
||||
writer.WriteString(new ReadOnlySpan<byte>(buffer, 0, count));
|
||||
|
||||
BufferPool.Release(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteHeaders(ref MessagePackWriter writer)
|
||||
{
|
||||
writer.WriteMapHeader(0);
|
||||
}
|
||||
|
||||
public void ParseMessages(BufferSegment segment, ref List<Message> messages)
|
||||
{
|
||||
int offset = segment.Offset;
|
||||
while (offset < segment.Count)
|
||||
{
|
||||
int length = (int)ReadVarInt(segment.Data, ref offset);
|
||||
|
||||
var reader = new MessagePackReader(new ReadOnlyMemory<byte>(segment.Data, offset, length));
|
||||
|
||||
int arrayLength = reader.ReadArrayHeader();
|
||||
int messageType = reader.ReadByte();
|
||||
|
||||
switch ((MessageTypes)messageType)
|
||||
{
|
||||
case MessageTypes.Invocation: messages.Add(ReadInvocation(ref reader)); break;
|
||||
case MessageTypes.StreamItem: messages.Add(ReadStreamItem(ref reader)); break;
|
||||
case MessageTypes.Completion: messages.Add(ReadCompletion(ref reader)); break;
|
||||
case MessageTypes.StreamInvocation: messages.Add(ReadStreamInvocation(ref reader)); break;
|
||||
case MessageTypes.CancelInvocation: messages.Add(ReadCancelInvocation(ref reader)); break;
|
||||
case MessageTypes.Ping:
|
||||
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#ping-message-encoding-1
|
||||
messages.Add(new Message { type = MessageTypes.Ping });
|
||||
break;
|
||||
case MessageTypes.Close: messages.Add(ReadClose(ref reader)); break;
|
||||
}
|
||||
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
private Message ReadClose(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding-1
|
||||
|
||||
string error = reader.ReadString();
|
||||
bool allowReconnect = false;
|
||||
try
|
||||
{
|
||||
allowReconnect = reader.ReadBoolean();
|
||||
}
|
||||
catch { }
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Close,
|
||||
error = error,
|
||||
allowReconnect = allowReconnect
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadCancelInvocation(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#cancelinvocation-message-encoding-1
|
||||
|
||||
ReadHeaders(ref reader);
|
||||
string invocationId = reader.ReadString();
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.CancelInvocation,
|
||||
invocationId = invocationId
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadStreamInvocation(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streaminvocation-message-encoding-1
|
||||
|
||||
ReadHeaders(ref reader);
|
||||
string invocationId = reader.ReadString();
|
||||
string target = reader.ReadString();
|
||||
object[] arguments = ReadArguments(ref reader, target);
|
||||
string[] streamIds = ReadStreamIds(ref reader);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.StreamInvocation,
|
||||
invocationId = invocationId,
|
||||
target = target,
|
||||
arguments = arguments,
|
||||
streamIds = streamIds
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadCompletion(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#completion-message-encoding-1
|
||||
|
||||
ReadHeaders(ref reader);
|
||||
string invocationId = reader.ReadString();
|
||||
byte resultKind = reader.ReadByte();
|
||||
|
||||
switch (resultKind)
|
||||
{
|
||||
// 1 - Error result - Result contains a String with the error message
|
||||
case 1:
|
||||
string error = reader.ReadString();
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId,
|
||||
error = error
|
||||
};
|
||||
|
||||
// 2 - Void result - Result is absent
|
||||
case 2:
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId
|
||||
};
|
||||
|
||||
// 3 - Non-Void result - Result contains the value returned by the server
|
||||
case 3:
|
||||
object item = ReadItem(ref reader, invocationId);
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId,
|
||||
item = item,
|
||||
result = item
|
||||
};
|
||||
|
||||
default:
|
||||
throw new NotImplementedException("Unknown resultKind: " + resultKind);
|
||||
}
|
||||
}
|
||||
|
||||
private Message ReadStreamItem(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streamitem-message-encoding-1
|
||||
|
||||
ReadHeaders(ref reader);
|
||||
string invocationId = reader.ReadString();
|
||||
object item = ReadItem(ref reader, invocationId);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.StreamItem,
|
||||
invocationId = invocationId,
|
||||
item = item
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadInvocation(ref MessagePackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#invocation-message-encoding-1
|
||||
|
||||
ReadHeaders(ref reader);
|
||||
string invocationId = reader.ReadString();
|
||||
string target = reader.ReadString();
|
||||
object[] arguments = ReadArguments(ref reader, target);
|
||||
string[] streamIds = ReadStreamIds(ref reader);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Invocation,
|
||||
invocationId = invocationId,
|
||||
target = target,
|
||||
arguments = arguments,
|
||||
streamIds = streamIds
|
||||
};
|
||||
}
|
||||
|
||||
private object ReadItem(ref MessagePackReader reader, string invocationId)
|
||||
{
|
||||
long longId = 0;
|
||||
if (long.TryParse(invocationId, out longId))
|
||||
{
|
||||
Type itemType = this.Connection.GetItemType(longId);
|
||||
|
||||
return MessagePackSerializer.Deserialize(itemType, reader.ReadRaw());
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Skip();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string[] ReadStreamIds(ref MessagePackReader reader)
|
||||
{
|
||||
var count = reader.ReadArrayHeader();
|
||||
string[] result = null;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
result = new string[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
result[i] = reader.ReadString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private object[] ReadArguments(ref MessagePackReader reader, string target)
|
||||
{
|
||||
var subscription = this.Connection.GetSubscription(target);
|
||||
|
||||
object[] args = null;
|
||||
if (subscription == null || subscription.callbacks == null || subscription.callbacks.Count == 0)
|
||||
{
|
||||
reader.Skip();
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = reader.ReadArrayHeader();
|
||||
|
||||
if (subscription.callbacks[0].ParamTypes != null)
|
||||
{
|
||||
args = new object[subscription.callbacks[0].ParamTypes.Length];
|
||||
for (int i = 0; i < subscription.callbacks[0].ParamTypes.Length; ++i)
|
||||
args[i] = MessagePackSerializer.Deserialize(subscription.callbacks[0].ParamTypes[i], reader.ReadRaw());
|
||||
}
|
||||
else
|
||||
args = null;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> ReadHeaders(ref MessagePackReader reader)
|
||||
{
|
||||
int count = reader.ReadMapHeader();
|
||||
|
||||
Dictionary<string, string> result = null;
|
||||
if (count > 0)
|
||||
{
|
||||
result = new Dictionary<string, string>(count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = reader.ReadString();
|
||||
string value = reader.ReadString();
|
||||
|
||||
result.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte GetRequiredBytesForLengthPrefix(int length)
|
||||
{
|
||||
byte bytes = 0;
|
||||
do
|
||||
{
|
||||
length >>= 7;
|
||||
bytes++;
|
||||
}
|
||||
while (length > 0);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static int WriteLengthAsVarInt(byte[] data, int offset, int length)
|
||||
{
|
||||
do
|
||||
{
|
||||
var current = data[offset];
|
||||
current = (byte)(length & 0x7f);
|
||||
length >>= 7;
|
||||
if (length > 0)
|
||||
{
|
||||
current |= 0x80;
|
||||
}
|
||||
|
||||
data[offset++] = current;
|
||||
}
|
||||
while (length > 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static uint ReadVarInt(byte[] data, ref int offset)
|
||||
{
|
||||
var length = 0U;
|
||||
var numBytes = 0;
|
||||
|
||||
byte byteRead;
|
||||
do
|
||||
{
|
||||
byteRead = data[offset + numBytes];
|
||||
length = length | (((uint)(byteRead & 0x7f)) << (numBytes * 7));
|
||||
numBytes++;
|
||||
}
|
||||
while (offset + numBytes < data.Length && ((byteRead & 0x80) != 0));
|
||||
|
||||
offset += numBytes;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public object ConvertTo(Type toType, object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
#if NETFX_CORE
|
||||
TypeInfo typeInfo = toType.GetTypeInfo();
|
||||
#endif
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsEnum)
|
||||
#else
|
||||
if (toType.IsEnum)
|
||||
#endif
|
||||
return Enum.Parse(toType, obj.ToString(), true);
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsPrimitive)
|
||||
#else
|
||||
if (toType.IsPrimitive)
|
||||
#endif
|
||||
return Convert.ChangeType(obj, toType);
|
||||
|
||||
if (toType == typeof(string))
|
||||
return obj.ToString();
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GenericTypeArguments[0]);
|
||||
#else
|
||||
if (toType.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GetGenericArguments()[0]);
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public object[] GetRealArguments(Type[] argTypes, object[] arguments)
|
||||
{
|
||||
if (arguments == null || arguments.Length == 0)
|
||||
return null;
|
||||
|
||||
if (argTypes.Length > arguments.Length)
|
||||
throw new Exception(string.Format("argType.Length({0}) < arguments.length({1})", argTypes.Length, arguments.Length));
|
||||
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c4d3d400dd496d43a409e350143e85a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,868 @@
|
||||
#if !BESTHTTP_DISABLE_SIGNALR_CORE && BESTHTTP_SIGNALR_CORE_ENABLE_GAMEDEVWARE_MESSAGEPACK
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
using BestHTTP.SignalRCore.Messages;
|
||||
using GameDevWare.Serialization;
|
||||
using GameDevWare.Serialization.MessagePack;
|
||||
using GameDevWare.Serialization.Serializers;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace BestHTTP.SignalRCore.Encoders
|
||||
{
|
||||
public sealed class MessagePackProtocolSerializationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// A function that must return a TypeSerializer for the given Type. To serialize an enum it can return an EnumNumberSerializer (default) to serialize enums as numbers or EnumSerializer to serialize them as strings.
|
||||
/// </summary>
|
||||
public Func<Type, TypeSerializer> EnumSerializerFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IPRotocol implementation using the "Json & MessagePack Serialization" asset store package (https://assetstore.unity.com/packages/tools/network/json-messagepack-serialization-59918).
|
||||
/// </summary>
|
||||
public sealed class MessagePackProtocol : BestHTTP.SignalRCore.IProtocol
|
||||
{
|
||||
public string Name { get { return "messagepack"; } }
|
||||
|
||||
public TransferModes Type { get { return TransferModes.Binary; } }
|
||||
|
||||
public IEncoder Encoder { get; private set; }
|
||||
|
||||
public HubConnection Connection { get; set; }
|
||||
|
||||
public MessagePackProtocolSerializationOptions Options { get; set; }
|
||||
|
||||
public MessagePackProtocol()
|
||||
: this(new MessagePackProtocolSerializationOptions { EnumSerializerFactory = (enumType) => new EnumNumberSerializer(enumType) })
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MessagePackProtocol(MessagePackProtocolSerializationOptions options)
|
||||
{
|
||||
this.Options = options;
|
||||
|
||||
GameDevWare.Serialization.Json.DefaultSerializers.Clear();
|
||||
GameDevWare.Serialization.Json.DefaultSerializers.AddRange(new TypeSerializer[]
|
||||
{
|
||||
new BinarySerializer(),
|
||||
new DateTimeOffsetSerializer(),
|
||||
new DateTimeSerializer(),
|
||||
new GuidSerializer(),
|
||||
new StreamSerializer(),
|
||||
new UriSerializer(),
|
||||
new VersionSerializer(),
|
||||
new TimeSpanSerializer(),
|
||||
new DictionaryEntrySerializer(),
|
||||
|
||||
new BestHTTP.SignalRCore.Encoders.Vector2Serializer(),
|
||||
new BestHTTP.SignalRCore.Encoders.Vector3Serializer(),
|
||||
new BestHTTP.SignalRCore.Encoders.Vector4Serializer(),
|
||||
|
||||
new PrimitiveSerializer(typeof (bool)),
|
||||
new PrimitiveSerializer(typeof (byte)),
|
||||
new PrimitiveSerializer(typeof (decimal)),
|
||||
new PrimitiveSerializer(typeof (double)),
|
||||
new PrimitiveSerializer(typeof (short)),
|
||||
new PrimitiveSerializer(typeof (int)),
|
||||
new PrimitiveSerializer(typeof (long)),
|
||||
new PrimitiveSerializer(typeof (sbyte)),
|
||||
new PrimitiveSerializer(typeof (float)),
|
||||
new PrimitiveSerializer(typeof (ushort)),
|
||||
new PrimitiveSerializer(typeof (uint)),
|
||||
new PrimitiveSerializer(typeof (ulong)),
|
||||
new PrimitiveSerializer(typeof (string)),
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function must convert all element in the arguments array to the corresponding type from the argTypes array.
|
||||
/// </summary>
|
||||
public object[] GetRealArguments(Type[] argTypes, object[] arguments)
|
||||
{
|
||||
if (arguments == null || arguments.Length == 0)
|
||||
return null;
|
||||
|
||||
if (argTypes.Length > arguments.Length)
|
||||
throw new Exception(string.Format("argType.Length({0}) < arguments.length({1})", argTypes.Length, arguments.Length));
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a value to the given type.
|
||||
/// </summary>
|
||||
public object ConvertTo(Type toType, object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
#if NETFX_CORE
|
||||
TypeInfo typeInfo = toType.GetTypeInfo();
|
||||
#endif
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsEnum)
|
||||
#else
|
||||
if (toType.IsEnum)
|
||||
#endif
|
||||
return Enum.Parse(toType, obj.ToString(), true);
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsPrimitive)
|
||||
#else
|
||||
if (toType.IsPrimitive)
|
||||
#endif
|
||||
return Convert.ChangeType(obj, toType);
|
||||
|
||||
if (toType == typeof(string))
|
||||
return obj.ToString();
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GenericTypeArguments[0]);
|
||||
#else
|
||||
if (toType.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GetGenericArguments()[0]);
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function must return the encoded representation of the given message.
|
||||
/// </summary>
|
||||
public BufferSegment EncodeMessage(Message message)
|
||||
{
|
||||
var memBuffer = BufferPool.Get(256, true);
|
||||
var stream = new BestHTTP.Extensions.BufferPoolMemoryStream(memBuffer, 0, memBuffer.Length, true, true, false, true);
|
||||
|
||||
// Write 5 bytes for placeholder for length prefix
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
stream.WriteByte(0);
|
||||
|
||||
var buffer = BufferPool.Get(MsgPackWriter.DEFAULT_BUFFER_SIZE, true);
|
||||
|
||||
var context = new SerializationContext {
|
||||
Options = SerializationOptions.SuppressTypeInformation,
|
||||
EnumSerializerFactory = this.Options.EnumSerializerFactory,
|
||||
ExtensionTypeHandler = CustomMessagePackExtensionTypeHandler.Instance
|
||||
};
|
||||
|
||||
var writer = new MsgPackWriter(stream, context, buffer);
|
||||
|
||||
switch (message.type)
|
||||
{
|
||||
case MessageTypes.StreamItem:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streamitem-message-encoding-1
|
||||
// [2, Headers, InvocationId, Item]
|
||||
|
||||
writer.WriteArrayBegin(4);
|
||||
|
||||
writer.WriteNumber(2);
|
||||
WriteHeaders(writer);
|
||||
writer.WriteString(message.invocationId);
|
||||
WriteValue(writer, message.item);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
|
||||
case MessageTypes.Completion:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#completion-message-encoding-1
|
||||
// [3, Headers, InvocationId, ResultKind, Result?]
|
||||
|
||||
byte resultKind = (byte)(!string.IsNullOrEmpty(message.error) ? /*error*/ 1 : message.result != null ? /*non-void*/ 3 : /*void*/ 2);
|
||||
|
||||
writer.WriteArrayBegin(resultKind == 2 ? 4 : 5);
|
||||
|
||||
writer.WriteNumber(3);
|
||||
WriteHeaders(writer);
|
||||
writer.WriteString(message.invocationId);
|
||||
writer.WriteNumber(resultKind);
|
||||
|
||||
if (resultKind == 1) // error
|
||||
writer.WriteString(message.error);
|
||||
else if (resultKind == 3) // non-void
|
||||
WriteValue(writer, message.result);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
|
||||
case MessageTypes.Invocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#invocation-message-encoding-1
|
||||
// [1, Headers, InvocationId, NonBlocking, Target, [Arguments], [StreamIds]]
|
||||
|
||||
case MessageTypes.StreamInvocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streaminvocation-message-encoding-1
|
||||
// [4, Headers, InvocationId, Target, [Arguments], [StreamIds]]
|
||||
|
||||
writer.WriteArrayBegin(message.streamIds != null ? 6 : 5);
|
||||
|
||||
writer.WriteNumber((int)message.type);
|
||||
WriteHeaders(writer);
|
||||
writer.WriteString(message.invocationId);
|
||||
writer.WriteString(message.target);
|
||||
writer.WriteArrayBegin(message.arguments != null ? message.arguments.Length : 0);
|
||||
if (message.arguments != null)
|
||||
for (int i = 0; i < message.arguments.Length; ++i)
|
||||
WriteValue(writer, message.arguments[i]);
|
||||
writer.WriteArrayEnd();
|
||||
|
||||
if (message.streamIds != null)
|
||||
{
|
||||
writer.WriteArrayBegin(message.streamIds.Length);
|
||||
|
||||
for (int i = 0; i < message.streamIds.Length; ++i)
|
||||
WriteValue(writer, message.streamIds[i]);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
|
||||
case MessageTypes.CancelInvocation:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#cancelinvocation-message-encoding-1
|
||||
// [5, Headers, InvocationId]
|
||||
|
||||
writer.WriteArrayBegin(3);
|
||||
|
||||
writer.WriteNumber(5);
|
||||
WriteHeaders(writer);
|
||||
writer.WriteString(message.invocationId);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
|
||||
case MessageTypes.Ping:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#ping-message-encoding-1
|
||||
// [6]
|
||||
|
||||
writer.WriteArrayBegin(1);
|
||||
|
||||
writer.WriteNumber(6);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
|
||||
case MessageTypes.Close:
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding-1
|
||||
// [7, Error, AllowReconnect?]
|
||||
|
||||
writer.WriteArrayBegin(string.IsNullOrEmpty(message.error) ? 1 : 2);
|
||||
|
||||
writer.WriteNumber(7);
|
||||
if (!string.IsNullOrEmpty(message.error))
|
||||
writer.WriteString(message.error);
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
writer.Flush();
|
||||
|
||||
// release back the buffer we used for the MsgPackWriter
|
||||
BufferPool.Release(buffer);
|
||||
|
||||
// get how much bytes got written to the buffer. This includes the 5 placeholder bytes too.
|
||||
int length = (int)stream.Position;
|
||||
|
||||
// this is the length without the 5 placeholder bytes
|
||||
int contentLength = length - 5;
|
||||
|
||||
// get the stream's internal buffer. We set the releaseBuffer flag to false, so we can use it safely.
|
||||
buffer = stream.GetBuffer();
|
||||
|
||||
// add varint length prefix
|
||||
byte prefixBytes = GetRequiredBytesForLengthPrefix(contentLength);
|
||||
WriteLengthAsVarInt(buffer, 5 - prefixBytes, contentLength);
|
||||
|
||||
// return with the final segment
|
||||
return new BufferSegment(buffer, 5 - prefixBytes, contentLength + prefixBytes);
|
||||
}
|
||||
|
||||
private void WriteValue(MsgPackWriter writer, object value)
|
||||
{
|
||||
if (value == null)
|
||||
writer.WriteNull();
|
||||
else
|
||||
writer.WriteValue(value, value.GetType());
|
||||
}
|
||||
|
||||
private void WriteHeaders(MsgPackWriter writer)
|
||||
{
|
||||
writer.WriteObjectBegin(0);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function must parse binary representation of the messages into the list of Messages.
|
||||
/// </summary>
|
||||
public void ParseMessages(BufferSegment segment, ref List<Message> messages)
|
||||
{
|
||||
messages.Clear();
|
||||
|
||||
int offset = segment.Offset;
|
||||
while (offset < segment.Count)
|
||||
{
|
||||
int length = (int)ReadVarInt(segment.Data, ref offset);
|
||||
|
||||
using (var stream = new System.IO.MemoryStream(segment.Data, offset, length))
|
||||
{
|
||||
var buff = BufferPool.Get(MsgPackReader.DEFAULT_BUFFER_SIZE, true);
|
||||
try
|
||||
{
|
||||
var context = new SerializationContext {
|
||||
Options = SerializationOptions.SuppressTypeInformation,
|
||||
ExtensionTypeHandler = CustomMessagePackExtensionTypeHandler.Instance
|
||||
};
|
||||
var reader = new MsgPackReader(stream, context, Endianness.BigEndian, buff);
|
||||
|
||||
reader.NextToken();
|
||||
reader.NextToken();
|
||||
|
||||
int messageType = reader.ReadByte();
|
||||
switch ((MessageTypes)messageType)
|
||||
{
|
||||
case MessageTypes.Invocation: messages.Add(ReadInvocation(reader)); break;
|
||||
case MessageTypes.StreamItem: messages.Add(ReadStreamItem(reader)); break;
|
||||
case MessageTypes.Completion: messages.Add(ReadCompletion(reader)); break;
|
||||
case MessageTypes.StreamInvocation: messages.Add(ReadStreamInvocation(reader)); break;
|
||||
case MessageTypes.CancelInvocation: messages.Add(ReadCancelInvocation(reader)); break;
|
||||
case MessageTypes.Ping:
|
||||
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#ping-message-encoding-1
|
||||
messages.Add(new Message { type = MessageTypes.Ping });
|
||||
break;
|
||||
case MessageTypes.Close: messages.Add(ReadClose(reader)); break;
|
||||
}
|
||||
|
||||
reader.NextToken();
|
||||
}
|
||||
finally
|
||||
{
|
||||
BufferPool.Release(buff);
|
||||
}
|
||||
}
|
||||
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
private Message ReadClose(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding-1
|
||||
|
||||
string error = reader.ReadString();
|
||||
bool allowReconnect = false;
|
||||
try
|
||||
{
|
||||
allowReconnect = reader.ReadBoolean();
|
||||
}
|
||||
catch { }
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Close,
|
||||
error = error,
|
||||
allowReconnect = allowReconnect
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadCancelInvocation(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#cancelinvocation-message-encoding-1
|
||||
|
||||
ReadHeaders(reader);
|
||||
string invocationId = reader.ReadString();
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.CancelInvocation,
|
||||
invocationId = invocationId
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadStreamInvocation(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streaminvocation-message-encoding-1
|
||||
|
||||
ReadHeaders(reader);
|
||||
string invocationId = reader.ReadString();
|
||||
string target = reader.ReadString();
|
||||
object[] arguments = ReadArguments(reader, target);
|
||||
string[] streamIds = ReadStreamIds(reader);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.StreamInvocation,
|
||||
invocationId = invocationId,
|
||||
target = target,
|
||||
arguments = arguments,
|
||||
streamIds = streamIds
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadCompletion(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#completion-message-encoding-1
|
||||
|
||||
ReadHeaders(reader);
|
||||
string invocationId = reader.ReadString();
|
||||
byte resultKind = reader.ReadByte();
|
||||
|
||||
switch(resultKind)
|
||||
{
|
||||
// 1 - Error result - Result contains a String with the error message
|
||||
case 1:
|
||||
string error = reader.ReadString();
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId,
|
||||
error = error
|
||||
};
|
||||
|
||||
// 2 - Void result - Result is absent
|
||||
case 2:
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId
|
||||
};
|
||||
|
||||
// 3 - Non-Void result - Result contains the value returned by the server
|
||||
case 3:
|
||||
object item = ReadItem(reader, invocationId);
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Completion,
|
||||
invocationId = invocationId,
|
||||
item = item,
|
||||
result = item
|
||||
};
|
||||
|
||||
default:
|
||||
throw new NotImplementedException("Unknown resultKind: " + resultKind);
|
||||
}
|
||||
}
|
||||
|
||||
private Message ReadStreamItem(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streamitem-message-encoding-1
|
||||
|
||||
ReadHeaders(reader);
|
||||
string invocationId = reader.ReadString();
|
||||
object item = ReadItem(reader, invocationId);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.StreamItem,
|
||||
invocationId = invocationId,
|
||||
item = item
|
||||
};
|
||||
}
|
||||
|
||||
private Message ReadInvocation(MsgPackReader reader)
|
||||
{
|
||||
// https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#invocation-message-encoding-1
|
||||
|
||||
ReadHeaders(reader);
|
||||
string invocationId = reader.ReadString();
|
||||
string target = reader.ReadString();
|
||||
object[] arguments = ReadArguments(reader, target);
|
||||
string[] streamIds = ReadStreamIds(reader);
|
||||
|
||||
return new Message
|
||||
{
|
||||
type = MessageTypes.Invocation,
|
||||
invocationId = invocationId,
|
||||
target = target,
|
||||
arguments = arguments,
|
||||
streamIds = streamIds
|
||||
};
|
||||
}
|
||||
|
||||
private object ReadItem(MsgPackReader reader, string invocationId)
|
||||
{
|
||||
long longId = 0;
|
||||
if (long.TryParse(invocationId, out longId))
|
||||
{
|
||||
Type itemType = this.Connection.GetItemType(longId);
|
||||
return reader.ReadValue(itemType);
|
||||
}
|
||||
else
|
||||
return reader.ReadValue(typeof(object));
|
||||
}
|
||||
|
||||
private string[] ReadStreamIds(MsgPackReader reader)
|
||||
{
|
||||
return reader.ReadValue(typeof(string[])) as string[];
|
||||
}
|
||||
|
||||
private object[] ReadArguments(MsgPackReader reader, string target)
|
||||
{
|
||||
var subscription = this.Connection.GetSubscription(target);
|
||||
|
||||
object[] args;
|
||||
if (subscription == null || subscription.callbacks == null || subscription.callbacks.Count == 0)
|
||||
{
|
||||
args = reader.ReadValue(typeof(object[])) as object[];
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.NextToken();
|
||||
|
||||
if (subscription.callbacks[0].ParamTypes != null)
|
||||
{
|
||||
args = new object[subscription.callbacks[0].ParamTypes.Length];
|
||||
for (int i = 0; i < subscription.callbacks[0].ParamTypes.Length; ++i)
|
||||
args[i] = reader.ReadValue(subscription.callbacks[0].ParamTypes[i]);
|
||||
}
|
||||
else
|
||||
args = null;
|
||||
|
||||
reader.NextToken();
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> ReadHeaders(MsgPackReader reader)
|
||||
{
|
||||
return reader.ReadValue(typeof(Dictionary<string, string>)) as Dictionary<string, string>;
|
||||
}
|
||||
|
||||
public static byte GetRequiredBytesForLengthPrefix(int length)
|
||||
{
|
||||
byte bytes = 0;
|
||||
do
|
||||
{
|
||||
length >>= 7;
|
||||
bytes++;
|
||||
}
|
||||
while (length > 0);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static int WriteLengthAsVarInt(byte[] data, int offset, int length)
|
||||
{
|
||||
do
|
||||
{
|
||||
var current = data[offset];
|
||||
current = (byte)(length & 0x7f);
|
||||
length >>= 7;
|
||||
if (length > 0)
|
||||
{
|
||||
current |= 0x80;
|
||||
}
|
||||
|
||||
data[offset++] = current;
|
||||
}
|
||||
while (length > 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static uint ReadVarInt(byte[] data, ref int offset)
|
||||
{
|
||||
var length = 0U;
|
||||
var numBytes = 0;
|
||||
|
||||
byte byteRead;
|
||||
do
|
||||
{
|
||||
byteRead = data[offset + numBytes];
|
||||
length = length | (((uint)(byteRead & 0x7f)) << (numBytes * 7));
|
||||
numBytes++;
|
||||
}
|
||||
while (offset + numBytes < data.Length && ((byteRead & 0x80) != 0));
|
||||
|
||||
offset += numBytes;
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CustomMessagePackExtensionTypeHandler : MessagePackExtensionTypeHandler
|
||||
{
|
||||
public const int EXTENSION_TYPE_DATE_TIME = -1;
|
||||
public const int DATE_TIME_SIZE = 8;
|
||||
|
||||
public const long BclSecondsAtUnixEpoch = 62135596800;
|
||||
public const int NanosecondsPerTick = 100;
|
||||
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
private static readonly Type[] DefaultExtensionTypes = new[] { typeof(DateTime) };
|
||||
public static CustomMessagePackExtensionTypeHandler Instance = new CustomMessagePackExtensionTypeHandler();
|
||||
|
||||
public override IEnumerable<Type> ExtensionTypes
|
||||
{
|
||||
get { return DefaultExtensionTypes; }
|
||||
}
|
||||
|
||||
|
||||
public override bool TryRead(sbyte type, ArraySegment<byte> data, out object value)
|
||||
{
|
||||
if (data.Array == null) throw new ArgumentNullException("data");
|
||||
|
||||
value = default(object);
|
||||
switch (type)
|
||||
{
|
||||
case EXTENSION_TYPE_DATE_TIME:
|
||||
switch (data.Count)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
var intValue = unchecked((int)(FromBytes(data.Array, data.Offset, 4)));
|
||||
value = CustomMessagePackExtensionTypeHandler.UnixEpoch.AddSeconds(unchecked((uint)intValue));
|
||||
return true;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
long longValue = FromBytes(data.Array, data.Offset, 8);
|
||||
ulong ulongValue = unchecked((ulong)longValue);
|
||||
long nanoseconds = (long)(ulongValue >> 34);
|
||||
ulong seconds = ulongValue & 0x00000003ffffffffL;
|
||||
value = CustomMessagePackExtensionTypeHandler.UnixEpoch.AddSeconds(seconds).AddTicks(nanoseconds / CustomMessagePackExtensionTypeHandler.NanosecondsPerTick);
|
||||
return true;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
var intValue = unchecked((int)(FromBytes(data.Array, data.Offset, 4)));
|
||||
long longValue = FromBytes(data.Array, data.Offset, 8);
|
||||
|
||||
var nanoseconds = unchecked((uint)intValue);
|
||||
value = CustomMessagePackExtensionTypeHandler.UnixEpoch.AddSeconds(longValue).AddTicks(nanoseconds / CustomMessagePackExtensionTypeHandler.NanosecondsPerTick);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
throw new Exception($"Length of extension was {data.Count}. Either 4, 8 or 12 were expected.");
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryWrite(object value, out sbyte type, ref ArraySegment<byte> data)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
type = 0;
|
||||
return false;
|
||||
}
|
||||
else if (value is DateTime)
|
||||
{
|
||||
type = EXTENSION_TYPE_DATE_TIME;
|
||||
|
||||
var dateTime = (DateTime)(object)value;
|
||||
|
||||
// The spec requires UTC. Convert to UTC if we're sure the value was expressed as Local time.
|
||||
// If it's Unspecified, we want to leave it alone since .NET will change the value when we convert
|
||||
// and we simply don't know, so we should leave it as-is.
|
||||
if (dateTime.Kind == DateTimeKind.Local)
|
||||
{
|
||||
dateTime = dateTime.ToUniversalTime();
|
||||
}
|
||||
|
||||
var secondsSinceBclEpoch = dateTime.Ticks / TimeSpan.TicksPerSecond;
|
||||
var seconds = secondsSinceBclEpoch - CustomMessagePackExtensionTypeHandler.BclSecondsAtUnixEpoch;
|
||||
var nanoseconds = (dateTime.Ticks % TimeSpan.TicksPerSecond) * CustomMessagePackExtensionTypeHandler.NanosecondsPerTick;
|
||||
|
||||
if ((seconds >> 34) == 0)
|
||||
{
|
||||
var data64 = unchecked((ulong)((nanoseconds << 34) | seconds));
|
||||
if ((data64 & 0xffffffff00000000L) == 0)
|
||||
{
|
||||
// timestamp 32(seconds in 32-bit unsigned int)
|
||||
var data32 = (UInt32)data64;
|
||||
|
||||
const int TIMESTAMP_SIZE = 4;
|
||||
|
||||
if (data.Array == null || data.Count < TIMESTAMP_SIZE)
|
||||
data = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);
|
||||
|
||||
CopyBytesImpl(data32, 4, data.Array, data.Offset);
|
||||
|
||||
if (data.Count != DATE_TIME_SIZE)
|
||||
data = new ArraySegment<byte>(data.Array, data.Offset, DATE_TIME_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// timestamp 64(nanoseconds in 30-bit unsigned int | seconds in 34-bit unsigned int)
|
||||
const int TIMESTAMP_SIZE = 8;
|
||||
if (data.Array == null || data.Count < TIMESTAMP_SIZE)
|
||||
data = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);
|
||||
|
||||
CopyBytesImpl(unchecked((long)data64), 8, data.Array, data.Offset);
|
||||
|
||||
if (data.Count != DATE_TIME_SIZE)
|
||||
data = new ArraySegment<byte>(data.Array, data.Offset, DATE_TIME_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// timestamp 96( nanoseconds in 32-bit unsigned int | seconds in 64-bit signed int )
|
||||
|
||||
const int TIMESTAMP_SIZE = 12;
|
||||
|
||||
if (data.Array == null || data.Count < TIMESTAMP_SIZE)
|
||||
data = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);
|
||||
|
||||
CopyBytesImpl((uint)nanoseconds, 4, data.Array, data.Offset);
|
||||
CopyBytesImpl(seconds, 8, data.Array, data.Offset + 4);
|
||||
|
||||
if (data.Count != DATE_TIME_SIZE)
|
||||
data = new ArraySegment<byte>(data.Array, data.Offset, DATE_TIME_SIZE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
type = default(sbyte);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)
|
||||
{
|
||||
var endOffset = index + bytes - 1;
|
||||
for (var i = 0; i < bytes; i++)
|
||||
{
|
||||
buffer[endOffset - i] = unchecked((byte)(value & 0xff));
|
||||
value = value >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
private long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
|
||||
{
|
||||
long ret = 0;
|
||||
for (var i = 0; i < bytesToConvert; i++)
|
||||
{
|
||||
ret = unchecked((ret << 8) | buffer[startIndex + i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/neuecc/MessagePack-CSharp/blob/13c299a5172c60154bae53395612af194c02d286/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Unity/Formatters.cs#L15
|
||||
public sealed class Vector2Serializer : TypeSerializer
|
||||
{
|
||||
public override Type SerializedType { get { return typeof(Vector2); } }
|
||||
|
||||
public override object Deserialize(IJsonReader reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("reader");
|
||||
|
||||
if (reader.Token == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
var value = new Vector2();
|
||||
reader.ReadArrayBegin();
|
||||
|
||||
int idx = 0;
|
||||
while (reader.Token != JsonToken.EndOfArray)
|
||||
value[idx++] = reader.ReadSingle();
|
||||
|
||||
reader.ReadArrayEnd(nextToken: false);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override void Serialize(IJsonWriter writer, object value)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
var vector2 = (Vector2)value;
|
||||
writer.WriteArrayBegin(2);
|
||||
writer.Write(vector2.x);
|
||||
writer.Write(vector2.y);
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/neuecc/MessagePack-CSharp/blob/13c299a5172c60154bae53395612af194c02d286/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Unity/Formatters.cs#L56
|
||||
public sealed class Vector3Serializer : TypeSerializer
|
||||
{
|
||||
public override Type SerializedType { get { return typeof(Vector3); } }
|
||||
|
||||
public override object Deserialize(IJsonReader reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("reader");
|
||||
|
||||
if (reader.Token == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
var value = new Vector3();
|
||||
reader.ReadArrayBegin();
|
||||
|
||||
int idx = 0;
|
||||
while (reader.Token != JsonToken.EndOfArray)
|
||||
value[idx++] = reader.ReadSingle();
|
||||
|
||||
reader.ReadArrayEnd(nextToken: false);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override void Serialize(IJsonWriter writer, object value)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
var vector3 = (Vector3)value;
|
||||
writer.WriteArrayBegin(3);
|
||||
writer.Write(vector3.x);
|
||||
writer.Write(vector3.y);
|
||||
writer.Write(vector3.z);
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/neuecc/MessagePack-CSharp/blob/13c299a5172c60154bae53395612af194c02d286/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Unity/Formatters.cs#L102
|
||||
public sealed class Vector4Serializer : TypeSerializer
|
||||
{
|
||||
public override Type SerializedType { get { return typeof(Vector4); } }
|
||||
|
||||
public override object Deserialize(IJsonReader reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("reader");
|
||||
|
||||
if (reader.Token == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
var value = new Vector4();
|
||||
reader.ReadArrayBegin();
|
||||
|
||||
int idx = 0;
|
||||
while (reader.Token != JsonToken.EndOfArray)
|
||||
value[idx++] = reader.ReadSingle();
|
||||
|
||||
reader.ReadArrayEnd(nextToken: false);
|
||||
|
||||
return value;
|
||||
}
|
||||
public override void Serialize(IJsonWriter writer, object value)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
var vector4 = (Vector4)value;
|
||||
writer.WriteArrayBegin(4);
|
||||
writer.Write(vector4.x);
|
||||
writer.Write(vector4.y);
|
||||
writer.Write(vector4.z);
|
||||
writer.Write(vector4.z);
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fe4434eade98e547aca1e026a4dbcc3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 485378cd297e7db4bba72fd93ae1d80f
|
||||
timeCreated: 1571296078
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user