diff --git a/Assets/GWConquest/Prefabs/Battle.prefab b/Assets/GWConquest/Prefabs/Battle.prefab index 1cbfa2d..8c01253 100644 --- a/Assets/GWConquest/Prefabs/Battle.prefab +++ b/Assets/GWConquest/Prefabs/Battle.prefab @@ -41,7 +41,7 @@ MonoBehaviour: m_GameObject: {fileID: 2057280478138210166} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -55,12 +55,12 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!114 &2057280478138210153 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/BattleFlank.prefab b/Assets/GWConquest/Prefabs/BattleFlank.prefab index b168802..65ba841 100644 --- a/Assets/GWConquest/Prefabs/BattleFlank.prefab +++ b/Assets/GWConquest/Prefabs/BattleFlank.prefab @@ -41,7 +41,7 @@ MonoBehaviour: m_GameObject: {fileID: 4026633161700752889} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -55,12 +55,12 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!114 &4026633161700752888 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/District.prefab b/Assets/GWConquest/Prefabs/District.prefab index d2f0eb9..f6713d5 100644 --- a/Assets/GWConquest/Prefabs/District.prefab +++ b/Assets/GWConquest/Prefabs/District.prefab @@ -43,7 +43,7 @@ MonoBehaviour: m_GameObject: {fileID: 1519560224452675769} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -57,12 +57,12 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!114 &4941434942006963670 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/Factory.prefab b/Assets/GWConquest/Prefabs/Factory.prefab index a6bcda0..5ab6402 100644 --- a/Assets/GWConquest/Prefabs/Factory.prefab +++ b/Assets/GWConquest/Prefabs/Factory.prefab @@ -92,7 +92,7 @@ MonoBehaviour: m_GameObject: {fileID: 1355812926097278600} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -102,7 +102,7 @@ MonoBehaviour: _autoFreezeProxyFrames: 0 _clientPredicted: 1 _allowInstantiateOnClient: 1 - _persistThroughSceneLoads: 1 + _persistThroughSceneLoads: 0 _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 @@ -110,8 +110,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!114 &3375267946260043055 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/Formation.prefab b/Assets/GWConquest/Prefabs/Formation.prefab index e5901cb..229034d 100644 --- a/Assets/GWConquest/Prefabs/Formation.prefab +++ b/Assets/GWConquest/Prefabs/Formation.prefab @@ -58,7 +58,7 @@ MonoBehaviour: m_GameObject: {fileID: 8292977142823461082} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -72,9 +72,9 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 diff --git a/Assets/GWConquest/Prefabs/Planet.prefab b/Assets/GWConquest/Prefabs/Planet.prefab index 27c555c..a83b686 100644 --- a/Assets/GWConquest/Prefabs/Planet.prefab +++ b/Assets/GWConquest/Prefabs/Planet.prefab @@ -120,7 +120,7 @@ MonoBehaviour: m_GameObject: {fileID: 4678135251219452000} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -138,8 +138,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &4678135251355824058 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/Player.prefab b/Assets/GWConquest/Prefabs/Player.prefab index 5cc0a6a..16ecb32 100644 --- a/Assets/GWConquest/Prefabs/Player.prefab +++ b/Assets/GWConquest/Prefabs/Player.prefab @@ -41,7 +41,7 @@ MonoBehaviour: m_GameObject: {fileID: 3262827332414082260} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -55,12 +55,12 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!114 &-3762956886024860011 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Prefabs/Unit.prefab b/Assets/GWConquest/Prefabs/Unit.prefab index 1b78a44..f7cd43f 100644 --- a/Assets/GWConquest/Prefabs/Unit.prefab +++ b/Assets/GWConquest/Prefabs/Unit.prefab @@ -53,7 +53,7 @@ MonoBehaviour: m_GameObject: {fileID: 8890686142670377634} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: _sceneGuid: @@ -67,9 +67,9 @@ MonoBehaviour: _sceneObjectDestroyOnDetach: 1 _sceneObjectAutoAttach: 1 _alwaysProxy: 0 - _detachOnDisable: 1 + _detachOnDisable: 0 _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 diff --git a/Assets/GWConquest/Scenes/GalaxyMap.unity b/Assets/GWConquest/Scenes/GalaxyMap.unity index 6e2ba85..a42684f 100644 --- a/Assets/GWConquest/Scenes/GalaxyMap.unity +++ b/Assets/GWConquest/Scenes/GalaxyMap.unity @@ -2544,12 +2544,12 @@ MonoBehaviour: m_GameObject: {fileID: 40190437} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: d89092bc-8bff-409d-a7a8-aa2c35c26c9a + _sceneGuid: aa3ca6ea-d8ee-4f1e-851a-b7c72764ad23 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -2562,8 +2562,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &43272447 PrefabInstance: m_ObjectHideFlags: 0 @@ -5004,12 +5004,12 @@ MonoBehaviour: m_GameObject: {fileID: 86848882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: c9811208-1ed6-4a4f-86d0-dcb8e460077b + _sceneGuid: c7a25553-18c4-4924-82b5-85aa4d7ecb30 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -5022,8 +5022,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &89695237 GameObject: m_ObjectHideFlags: 0 @@ -7349,12 +7349,12 @@ MonoBehaviour: m_GameObject: {fileID: 113413688} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 67333eeb-f1dd-43d8-a444-185b7aad5635 + _sceneGuid: 71c3e256-cf29-4146-81a1-377f989cb0b5 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -7367,8 +7367,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &116792920 PrefabInstance: m_ObjectHideFlags: 0 @@ -8782,12 +8782,12 @@ MonoBehaviour: m_GameObject: {fileID: 131868898} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 82c542ed-a846-4225-b009-b28b9bd79999 + _sceneGuid: ec679b89-d756-48aa-9af6-1e2c839247ca _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -8800,8 +8800,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &138533022 GameObject: m_ObjectHideFlags: 0 @@ -12491,12 +12491,12 @@ MonoBehaviour: m_GameObject: {fileID: 214596035} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: fe6ceeff-1572-4902-a201-0b6cd14dd809 + _sceneGuid: f0b4ff7c-b490-4ae7-a8b4-c6f85798b22f _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -12509,8 +12509,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &214790439 PrefabInstance: m_ObjectHideFlags: 0 @@ -17117,12 +17117,12 @@ MonoBehaviour: m_GameObject: {fileID: 302288824} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 1eabf257-bada-4c9c-b41b-a397605fc90d + _sceneGuid: 0cba882c-c83d-4493-ac45-ba03bb1bd562 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -17135,8 +17135,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &302396706 PrefabInstance: m_ObjectHideFlags: 0 @@ -18417,12 +18417,12 @@ MonoBehaviour: m_GameObject: {fileID: 322489092} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: f3818d77-8dca-4a80-b896-3ccb62062947 + _sceneGuid: a4f05907-ff39-448d-ab5a-1c13ece913eb _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -18435,8 +18435,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &330075613 PrefabInstance: m_ObjectHideFlags: 0 @@ -19441,12 +19441,12 @@ MonoBehaviour: m_GameObject: {fileID: 353074285} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: d7262e7d-85ab-4d57-ba02-6d828874c5aa + _sceneGuid: ddf30d75-8c41-4b6e-8c54-94a11b5a04c5 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -19459,8 +19459,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &355993168 PrefabInstance: m_ObjectHideFlags: 0 @@ -40380,12 +40380,12 @@ MonoBehaviour: m_GameObject: {fileID: 755114446} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 4492a9e6-24f8-41b7-b89f-9af539b6f40a + _sceneGuid: 49d9c072-966e-47c6-9910-ce07c594ab63 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -40398,8 +40398,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &755462604 GameObject: m_ObjectHideFlags: 0 @@ -41378,12 +41378,12 @@ MonoBehaviour: m_GameObject: {fileID: 769496620} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: db6ededc-03c4-49f8-aa97-b9b61fcc6735 + _sceneGuid: a36f85fc-d395-4332-9aec-fe319c245db9 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -41396,8 +41396,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &769700106 GameObject: m_ObjectHideFlags: 0 @@ -41880,12 +41880,12 @@ MonoBehaviour: m_GameObject: {fileID: 776571278} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 1ad2ef9f-ebc8-4275-b509-72d50b10e3d4 + _sceneGuid: a638e88d-cb5c-449a-a5f3-3e6ae3ed0989 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -41898,8 +41898,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &778900677 GameObject: m_ObjectHideFlags: 0 @@ -44439,12 +44439,12 @@ MonoBehaviour: m_GameObject: {fileID: 829595062} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: fa2861ca-d1b0-4ac8-9420-3bff9ef032b8 + _sceneGuid: 3a39e4b9-6cbc-4c4e-83ec-52c277b750a6 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -44457,8 +44457,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &830094179 PrefabInstance: m_ObjectHideFlags: 0 @@ -45664,12 +45664,12 @@ MonoBehaviour: m_GameObject: {fileID: 853110020} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 574d2106-7f47-4e68-8b34-176df09b0811 + _sceneGuid: d608fc1f-a30b-4c07-afa6-3078ab7dacfa _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -45682,8 +45682,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &853420527 PrefabInstance: m_ObjectHideFlags: 0 @@ -46700,12 +46700,12 @@ MonoBehaviour: m_GameObject: {fileID: 884239765} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: b991503a-6fd8-48c7-89a3-84f6133f3ff9 + _sceneGuid: 3662a93f-f3fc-4766-93ca-8323f279517c _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -46718,8 +46718,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &884296281 GameObject: m_ObjectHideFlags: 0 @@ -58769,12 +58769,12 @@ MonoBehaviour: m_GameObject: {fileID: 1091417640} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 8d4da6cd-4cb4-4f73-b094-103b4223765a + _sceneGuid: e6b97169-e6f2-4581-bdf1-87e73a0d6aee _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -58787,8 +58787,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1095021216 GameObject: m_ObjectHideFlags: 0 @@ -62595,12 +62595,12 @@ MonoBehaviour: m_GameObject: {fileID: 1147370006} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: c06f3f3f-0fa5-4f57-9229-dab98e58006a + _sceneGuid: f3a851a6-d875-474f-868c-c97af0b1d4bb _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -62613,8 +62613,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1150859384 PrefabInstance: m_ObjectHideFlags: 0 @@ -63431,12 +63431,12 @@ MonoBehaviour: m_GameObject: {fileID: 1166148164} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 5143f105-5bc2-45a8-b0b0-f44e4d04ebc2 + _sceneGuid: 55fd93e9-e363-49f0-81d1-57a77c6fc41a _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -63449,8 +63449,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1166602516 PrefabInstance: m_ObjectHideFlags: 0 @@ -65731,12 +65731,12 @@ MonoBehaviour: m_GameObject: {fileID: 1213153679} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 277d09e9-bb41-43d6-80fc-03d157ebc4fa + _sceneGuid: 0da35cae-3728-4a46-b945-987462bf4369 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -65749,8 +65749,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1213346271 PrefabInstance: m_ObjectHideFlags: 0 @@ -66361,12 +66361,12 @@ MonoBehaviour: m_GameObject: {fileID: 1229600185} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 62acf2dc-0ab4-4ec1-b577-cf2697d090b9 + _sceneGuid: 5dbb0855-f442-4357-894a-bcd521dc665a _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -66379,8 +66379,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1230009383 PrefabInstance: m_ObjectHideFlags: 0 @@ -68118,12 +68118,12 @@ MonoBehaviour: m_GameObject: {fileID: 1267657454} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 9070f0ee-bf8e-49b8-952a-3c8fa8d3472d + _sceneGuid: d4e1457f-b7ee-40d3-b8c4-ee8e133f8f03 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -68136,8 +68136,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1270522073 GameObject: m_ObjectHideFlags: 0 @@ -78161,12 +78161,12 @@ MonoBehaviour: m_GameObject: {fileID: 1409165551} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 1e1574f4-63b5-4bab-b24b-d8183301f0ba + _sceneGuid: e2c98a79-d667-4705-a991-5b82378f9067 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -78179,8 +78179,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1411249165 PrefabInstance: m_ObjectHideFlags: 0 @@ -78378,12 +78378,12 @@ MonoBehaviour: m_GameObject: {fileID: 1412114073} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 4375c08a-8970-479a-9124-025a35440bff + _sceneGuid: 3e20a241-c55b-4404-b0da-b6c8e48d9c7d _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -78396,8 +78396,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1417547141 GameObject: m_ObjectHideFlags: 0 @@ -82854,12 +82854,12 @@ MonoBehaviour: m_GameObject: {fileID: 1497715125} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 835b7dcd-5276-455a-9811-87ac65e97e19 + _sceneGuid: b31fdf0f-7b22-47a0-98d6-cf89ecdb476d _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -82872,8 +82872,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1502869307 PrefabInstance: m_ObjectHideFlags: 0 @@ -89223,12 +89223,12 @@ MonoBehaviour: m_GameObject: {fileID: 1658452142} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 43bb803d-9069-4a35-a988-05b5413560e3 + _sceneGuid: ba70f1ca-04d0-4976-83ed-82c92c886c34 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -89241,8 +89241,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1659683065 GameObject: m_ObjectHideFlags: 0 @@ -92116,12 +92116,12 @@ MonoBehaviour: m_GameObject: {fileID: 1724478287} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: ee32ce16-ddea-4a83-8eb8-afbc7f6ef09f + _sceneGuid: 07008f2d-4860-4950-b40b-91c2c21f4e17 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -92134,8 +92134,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1725236684 GameObject: m_ObjectHideFlags: 0 @@ -93813,12 +93813,12 @@ MonoBehaviour: m_GameObject: {fileID: 1758196031} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 6e37d929-ca28-4273-a01a-4b2da1c094ae + _sceneGuid: 34849c2c-a59b-4ba3-9c0c-d0b7d8586f4d _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -93831,8 +93831,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1759634039 PrefabInstance: m_ObjectHideFlags: 0 @@ -101403,12 +101403,12 @@ MonoBehaviour: m_GameObject: {fileID: 1798405254} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: d2e88d6e-cdcc-4a5e-b8ae-e0f3cdbceddf + _sceneGuid: a37ad134-167a-4c02-8941-77d13a567fe6 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -101421,8 +101421,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1798411514 GameObject: m_ObjectHideFlags: 0 @@ -103385,12 +103385,12 @@ MonoBehaviour: m_GameObject: {fileID: 1846341749} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 942352e1-9b45-4562-9823-1922bdd1bb30 + _sceneGuid: e53f7f22-baca-439b-a171-aaaeea9e00fa _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -103403,8 +103403,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1849002053 GameObject: m_ObjectHideFlags: 0 @@ -107351,12 +107351,12 @@ MonoBehaviour: m_GameObject: {fileID: 1924742657} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 72ff476a-dd73-42dc-8351-9469ea37aca0 + _sceneGuid: aced4142-c6fb-49e3-9c2f-2cc6ec51c8b6 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -107369,8 +107369,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1 &1929296923 GameObject: m_ObjectHideFlags: 0 @@ -108150,12 +108150,12 @@ MonoBehaviour: m_GameObject: {fileID: 1947037423} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 5e03512e-d57f-4d19-b22a-8294091f6448 + _sceneGuid: c0256ca9-e985-48d8-a19a-d2167e2a4dba _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -108168,8 +108168,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1950421186 PrefabInstance: m_ObjectHideFlags: 0 @@ -108384,12 +108384,12 @@ MonoBehaviour: m_GameObject: {fileID: 1952294458} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: f8839b47-ee36-4d7b-a6d5-22330e6f6a7b + _sceneGuid: 2f03041c-5827-45f9-be32-ee99cdea0321 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -108402,8 +108402,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1955062052 PrefabInstance: m_ObjectHideFlags: 0 @@ -110557,12 +110557,12 @@ MonoBehaviour: m_GameObject: {fileID: 1976539132} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 7d9ea04a-1474-4b7b-8265-0a19d87cc48c + _sceneGuid: 69a72c91-23e6-4cdc-84d2-a0b6bb354bbe _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -110575,8 +110575,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &1976755952 PrefabInstance: m_ObjectHideFlags: 0 @@ -113840,12 +113840,12 @@ MonoBehaviour: m_GameObject: {fileID: 2042552054} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: 6558cf6a-3db9-477c-925e-1d3e19361129 + _sceneGuid: e2c8f230-88f3-47ce-b537-6bece88a2c68 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -113858,8 +113858,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!224 &2043238809 stripped RectTransform: m_CorrespondingSourceObject: {fileID: 799397620141813293, guid: 050563ffe1cf76a4ca6ad29e50cca378, @@ -117988,12 +117988,12 @@ MonoBehaviour: m_GameObject: {fileID: 2141017710} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -36112512, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 155943207, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: m_EditorClassIdentifier: - _sceneGuid: efa697b2-eebe-4e93-ad6f-b191d7c6dc1f + _sceneGuid: b6be21d7-20d2-40b3-8a2c-d82eef7672f4 _serializerGuid: 593f7749-42a7-44fa-b61f-4bec598bae21 - _prefabId: 0 + _prefabId: 3 _updateRate: 1 _autoFreezeProxyFrames: 0 _clientPredicted: 1 @@ -118006,8 +118006,8 @@ MonoBehaviour: _allowFirstReplicationWhenFrozen: 0 _autoRemoveChildEntities: 0 _entityBehaviourQueryOption: 0 - _entityPriorityCalculatorQueryOption: 0 - _entityReplicationFilterQueryOption: 0 + _entityPriorityCalculatorQueryOption: 1 + _entityReplicationFilterQueryOption: 1 --- !u!1001 &2143302936 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/GWConquest/Scripts/Battle.cs b/Assets/GWConquest/Scripts/Battle.cs index 8e65166..a1cc589 100644 --- a/Assets/GWConquest/Scripts/Battle.cs +++ b/Assets/GWConquest/Scripts/Battle.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Collections.Generic; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/BattleFlank.cs b/Assets/GWConquest/Scripts/BattleFlank.cs index 80e7ae1..d9ea8d6 100644 --- a/Assets/GWConquest/Scripts/BattleFlank.cs +++ b/Assets/GWConquest/Scripts/BattleFlank.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Photon.Bolt; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/BattleLog.cs b/Assets/GWConquest/Scripts/BattleLog.cs index 65e1d72..9cad26e 100644 --- a/Assets/GWConquest/Scripts/BattleLog.cs +++ b/Assets/GWConquest/Scripts/BattleLog.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using Bolt; +using Photon.Bolt; using System; namespace GWConquest diff --git a/Assets/GWConquest/Scripts/BoltEntityCache.cs b/Assets/GWConquest/Scripts/BoltEntityCache.cs index 4bbb121..182b07e 100644 --- a/Assets/GWConquest/Scripts/BoltEntityCache.cs +++ b/Assets/GWConquest/Scripts/BoltEntityCache.cs @@ -1,4 +1,4 @@ -using Bolt; +using Photon.Bolt; using UnityEngine; using System.Collections.Generic; diff --git a/Assets/GWConquest/Scripts/BoltList.cs b/Assets/GWConquest/Scripts/BoltList.cs index b819411..59aced6 100644 --- a/Assets/GWConquest/Scripts/BoltList.cs +++ b/Assets/GWConquest/Scripts/BoltList.cs @@ -1,4 +1,4 @@ -using Bolt; +using Photon.Bolt; using System; using System.Collections; using System.Collections.Generic; diff --git a/Assets/GWConquest/Scripts/District.cs b/Assets/GWConquest/Scripts/District.cs index 919e0d5..f2119f9 100644 --- a/Assets/GWConquest/Scripts/District.cs +++ b/Assets/GWConquest/Scripts/District.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Collections.Generic; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/DistrictFactory.cs b/Assets/GWConquest/Scripts/DistrictFactory.cs index 6d7e0fa..0a50a3f 100644 --- a/Assets/GWConquest/Scripts/DistrictFactory.cs +++ b/Assets/GWConquest/Scripts/DistrictFactory.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Collections.Generic; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/EntityList.cs b/Assets/GWConquest/Scripts/EntityList.cs index 6bb4afb..7af08b3 100644 --- a/Assets/GWConquest/Scripts/EntityList.cs +++ b/Assets/GWConquest/Scripts/EntityList.cs @@ -1,5 +1,5 @@ using UdpKit; -using Bolt; +using Photon.Bolt; using System.Collections.Generic; using System.Linq; using System.Collections; diff --git a/Assets/GWConquest/Scripts/Formation.cs b/Assets/GWConquest/Scripts/Formation.cs index aac174f..56090c0 100644 --- a/Assets/GWConquest/Scripts/Formation.cs +++ b/Assets/GWConquest/Scripts/Formation.cs @@ -3,6 +3,8 @@ using System.Linq; using System; using System.Collections.Generic; using System.Collections; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { @@ -206,7 +208,7 @@ namespace GWConquest { if (path.Count > 1 && entity.IsControlled && MovementState == FormationMovementState.Idle) { - MoveFormationEvent evnt = MoveFormationEvent.Create(Bolt.GlobalTargets.OnlyServer); + MoveFormationEvent evnt = MoveFormationEvent.Create(GlobalTargets.OnlyServer); evnt.Formation = entity; //evnt.TargetZone = Zone.GetZoneId(path[1]); if(path.Count > 1) diff --git a/Assets/GWConquest/Scripts/GWBoltBehaviour.cs b/Assets/GWConquest/Scripts/GWBoltBehaviour.cs index b12cc89..2028186 100644 --- a/Assets/GWConquest/Scripts/GWBoltBehaviour.cs +++ b/Assets/GWConquest/Scripts/GWBoltBehaviour.cs @@ -1,4 +1,4 @@ -using Bolt; +using Photon.Bolt; namespace GWConquest { public abstract class GWBoltBehaviour : EntityBehaviour where T : class, IState @@ -7,11 +7,12 @@ namespace GWConquest { public T State { get { - if(_state == null) + /*if(_state == null) { _state = state; } - return _state; + return _state;*/ + return state; } } } @@ -22,11 +23,12 @@ namespace GWConquest { public T State { get { - if(_state == null) + /*if(_state == null) { _state = state; } - return _state; + return _state;*/ + return state; } } } diff --git a/Assets/GWConquest/Scripts/GameManager.cs b/Assets/GWConquest/Scripts/GameManager.cs index 0a1a972..078410a 100644 --- a/Assets/GWConquest/Scripts/GameManager.cs +++ b/Assets/GWConquest/Scripts/GameManager.cs @@ -1,5 +1,7 @@ using UnityEngine; using System.Collections; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/GlobalCallbacks.cs b/Assets/GWConquest/Scripts/GlobalCallbacks.cs index 9742ecc..5588ead 100644 --- a/Assets/GWConquest/Scripts/GlobalCallbacks.cs +++ b/Assets/GWConquest/Scripts/GlobalCallbacks.cs @@ -1,4 +1,5 @@ -using Bolt; +using Photon.Bolt; +using Photon.Bolt.Utils; using UdpKit; using UnityEngine; using System.Linq; @@ -6,7 +7,7 @@ using System.Linq; namespace GWConquest { [BoltGlobalBehaviour] - public class GlobalCallbacks : Bolt.GlobalEventListener + public class GlobalCallbacks : GlobalEventListener { public override void BoltStartBegin() { @@ -16,7 +17,7 @@ namespace GWConquest BoltNetwork.RegisterTokenClass(); } - public override void SceneLoadLocalDone(string scene) + public override void SceneLoadLocalDone(string scene, IProtocolToken token) { //BoltLog.Info("scene load token: {0}", token); diff --git a/Assets/GWConquest/Scripts/Inventory.cs b/Assets/GWConquest/Scripts/Inventory.cs index af7bfb9..b9df833 100644 --- a/Assets/GWConquest/Scripts/Inventory.cs +++ b/Assets/GWConquest/Scripts/Inventory.cs @@ -1,5 +1,6 @@ using UdpKit; -using Bolt; +using Photon.Bolt; +using Photon.Bolt.Utils; using System; using System.Linq; using System.Collections.Generic; diff --git a/Assets/GWConquest/Scripts/Planet.cs b/Assets/GWConquest/Scripts/Planet.cs index f35444d..7fe3a66 100644 --- a/Assets/GWConquest/Scripts/Planet.cs +++ b/Assets/GWConquest/Scripts/Planet.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/PlanetConnection.cs b/Assets/GWConquest/Scripts/PlanetConnection.cs index 117c0bf..a1a29f3 100644 --- a/Assets/GWConquest/Scripts/PlanetConnection.cs +++ b/Assets/GWConquest/Scripts/PlanetConnection.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Linq; using System.Collections.Generic; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/PlanetPlacement.cs b/Assets/GWConquest/Scripts/PlanetPlacement.cs index fbdb0b8..6c0c245 100644 --- a/Assets/GWConquest/Scripts/PlanetPlacement.cs +++ b/Assets/GWConquest/Scripts/PlanetPlacement.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest diff --git a/Assets/GWConquest/Scripts/PlanetRegistry.cs b/Assets/GWConquest/Scripts/PlanetRegistry.cs index b8efa8e..3abfe18 100644 --- a/Assets/GWConquest/Scripts/PlanetRegistry.cs +++ b/Assets/GWConquest/Scripts/PlanetRegistry.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/Player.cs b/Assets/GWConquest/Scripts/Player.cs index 5eff173..8bfa2fb 100644 --- a/Assets/GWConquest/Scripts/Player.cs +++ b/Assets/GWConquest/Scripts/Player.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Collections.Generic; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/ServerCallbacks.cs b/Assets/GWConquest/Scripts/ServerCallbacks.cs index 7ad9bf2..16c58db 100644 --- a/Assets/GWConquest/Scripts/ServerCallbacks.cs +++ b/Assets/GWConquest/Scripts/ServerCallbacks.cs @@ -1,15 +1,16 @@ using System.Linq; using UnityEngine; using UdpKit; -using Bolt; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { [BoltGlobalBehaviour(BoltNetworkModes.Server)] - public class ServerCallbacks : Bolt.GlobalEventListener + public class ServerCallbacks : GlobalEventListener { - public override void SceneLoadLocalDone(string scene) + public override void SceneLoadLocalDone(string scene, IProtocolToken token) { FindObjectOfType().PlacePlanets(); @@ -53,7 +54,7 @@ namespace GWConquest BoltLog.Info("Server scene loading done."); } - public override void SceneLoadRemoteDone(BoltConnection connection) + public override void SceneLoadRemoteDone(BoltConnection connection, IProtocolToken token) { BoltEntity playerEntity = BoltNetwork.Instantiate(BoltPrefabs.Player); IPlayerState playerState = playerEntity.GetState(); diff --git a/Assets/GWConquest/Scripts/SpawnAIUnits.cs b/Assets/GWConquest/Scripts/SpawnAIUnits.cs index bca459f..bdf21d5 100644 --- a/Assets/GWConquest/Scripts/SpawnAIUnits.cs +++ b/Assets/GWConquest/Scripts/SpawnAIUnits.cs @@ -1,5 +1,7 @@ using UnityEngine; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs b/Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs index f9967d7..783c676 100644 --- a/Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs +++ b/Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs @@ -2,6 +2,8 @@ using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { public class BattleArmyPanel : MonoBehaviour { @@ -235,7 +237,7 @@ namespace GWConquest { var fui = icon.GetComponentInParent(); if(fui != null && target == fui.LeaderIcon) { - var ev = AssignLeaderEvent.Create(Bolt.GlobalTargets.OnlyServer); + var ev = AssignLeaderEvent.Create(GlobalTargets.OnlyServer); ev.Unit = icon.Unit.entity; ev.Formation = icon.Unit.Formation.entity; ev.Send(); @@ -251,7 +253,7 @@ namespace GWConquest { if(flankUI.BattleFlank.GetUnit(flankIndex) == null) { - var ev = MoveUnitToFlankEvent.Create(Bolt.GlobalTargets.OnlyServer); + var ev = MoveUnitToFlankEvent.Create(GlobalTargets.OnlyServer); ev.Unit = icon.Unit.entity; ev.Flank = flankUI.BattleFlank.entity; ev.FlankIndex = flankIndex; diff --git a/Assets/GWConquest/Scripts/UI/BattleFlankUI.cs b/Assets/GWConquest/Scripts/UI/BattleFlankUI.cs index 059a543..ac9a6b2 100644 --- a/Assets/GWConquest/Scripts/UI/BattleFlankUI.cs +++ b/Assets/GWConquest/Scripts/UI/BattleFlankUI.cs @@ -1,5 +1,7 @@ using UnityEngine; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { @@ -102,7 +104,7 @@ namespace GWConquest { { if(icon.Unit.BattleState == BattleUnitState.OnFlank) { - MoveUnitToReserveEvent ev = MoveUnitToReserveEvent.Create(Bolt.GlobalTargets.OnlyServer); + MoveUnitToReserveEvent ev = MoveUnitToReserveEvent.Create(GlobalTargets.OnlyServer); ev.Unit = icon.Unit.entity; ev.Send(); } diff --git a/Assets/GWConquest/Scripts/UI/BattleUI.cs b/Assets/GWConquest/Scripts/UI/BattleUI.cs index 614ed69..6a7609a 100644 --- a/Assets/GWConquest/Scripts/UI/BattleUI.cs +++ b/Assets/GWConquest/Scripts/UI/BattleUI.cs @@ -2,6 +2,8 @@ using UnityEngine; using UnityEngine.UI; using System.Linq; using System.Collections.Generic; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { @@ -439,7 +441,7 @@ namespace GWConquest if (hasTarget) { - var ev = StartShellingEvent.Create(Bolt.GlobalTargets.OnlyServer); + var ev = StartShellingEvent.Create(GlobalTargets.OnlyServer); ev.Unit = SelectingTargetUnit.entity; ev.BattleFlank = flank?.entity; ev.Send(); diff --git a/Assets/GWConquest/Scripts/UI/BattleUnitIcon.cs b/Assets/GWConquest/Scripts/UI/BattleUnitIcon.cs index 9d45254..fbc0bcc 100644 --- a/Assets/GWConquest/Scripts/UI/BattleUnitIcon.cs +++ b/Assets/GWConquest/Scripts/UI/BattleUnitIcon.cs @@ -1,6 +1,8 @@ using UnityEngine; using UnityEngine.UI; using System.Collections; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { public class BattleUnitIcon : DragDropElement { diff --git a/Assets/GWConquest/Scripts/UI/FormationIcon.cs b/Assets/GWConquest/Scripts/UI/FormationIcon.cs index 284e739..b9d0f1b 100644 --- a/Assets/GWConquest/Scripts/UI/FormationIcon.cs +++ b/Assets/GWConquest/Scripts/UI/FormationIcon.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { public class FormationIcon : DragDropElement, IUpdatable diff --git a/Assets/GWConquest/Scripts/UI/FormationUI.cs b/Assets/GWConquest/Scripts/UI/FormationUI.cs index 644bdf9..24ccbf0 100644 --- a/Assets/GWConquest/Scripts/UI/FormationUI.cs +++ b/Assets/GWConquest/Scripts/UI/FormationUI.cs @@ -2,6 +2,8 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/GarrisonUI.cs b/Assets/GWConquest/Scripts/UI/GarrisonUI.cs index 645b5c0..6c1d089 100644 --- a/Assets/GWConquest/Scripts/UI/GarrisonUI.cs +++ b/Assets/GWConquest/Scripts/UI/GarrisonUI.cs @@ -2,6 +2,8 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/IngameUI.cs b/Assets/GWConquest/Scripts/UI/IngameUI.cs index 57a42c5..6e3b663 100644 --- a/Assets/GWConquest/Scripts/UI/IngameUI.cs +++ b/Assets/GWConquest/Scripts/UI/IngameUI.cs @@ -2,6 +2,8 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/ItemMoveTooltip.cs b/Assets/GWConquest/Scripts/UI/ItemMoveTooltip.cs index 9555c5d..cbbd888 100644 --- a/Assets/GWConquest/Scripts/UI/ItemMoveTooltip.cs +++ b/Assets/GWConquest/Scripts/UI/ItemMoveTooltip.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { @@ -71,7 +73,7 @@ namespace GWConquest int transferable = GetMaxTransferable(); if(current <= transferable) { - var ev = MoveItemEvent.Create(Bolt.GlobalTargets.OnlyServer); + var ev = MoveItemEvent.Create(GlobalTargets.OnlyServer); ev.ItemName = MovedItem.ItemName; ev.ItemAmount = current; ev.Origin = Origin.Type == TransportUIElement.ObjectType.District ? Origin.District.entity : Origin.Formation.entity; diff --git a/Assets/GWConquest/Scripts/UI/MainMenu.cs b/Assets/GWConquest/Scripts/UI/MainMenu.cs index 4ff80aa..e3ade88 100644 --- a/Assets/GWConquest/Scripts/UI/MainMenu.cs +++ b/Assets/GWConquest/Scripts/UI/MainMenu.cs @@ -1,11 +1,13 @@ -using Bolt.Matchmaking; +using Photon.Bolt; +using Photon.Bolt.Utils; +using Photon.Bolt.Matchmaking; using System; using UdpKit; using UnityEngine; namespace GWConquest { - public class MainMenu : Bolt.GlobalEventListener + public class MainMenu : GlobalEventListener { private void Start() { @@ -64,7 +66,7 @@ namespace GWConquest { LoadingScreen.Show(); - BoltNetwork.Connect(photonSession); + BoltMatchmaking.JoinSession(photonSession); } } } diff --git a/Assets/GWConquest/Scripts/UI/PauseMenu.cs b/Assets/GWConquest/Scripts/UI/PauseMenu.cs index 9255574..c76ac86 100644 --- a/Assets/GWConquest/Scripts/UI/PauseMenu.cs +++ b/Assets/GWConquest/Scripts/UI/PauseMenu.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using Photon.Bolt; +using UnityEngine; using UnityEngine.SceneManagement; namespace GWConquest diff --git a/Assets/GWConquest/Scripts/UI/PlanetViewUI.cs b/Assets/GWConquest/Scripts/UI/PlanetViewUI.cs index 49d5580..10df27c 100644 --- a/Assets/GWConquest/Scripts/UI/PlanetViewUI.cs +++ b/Assets/GWConquest/Scripts/UI/PlanetViewUI.cs @@ -2,6 +2,7 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/ProductionMenu.cs b/Assets/GWConquest/Scripts/UI/ProductionMenu.cs index cef2772..3fd5bda 100644 --- a/Assets/GWConquest/Scripts/UI/ProductionMenu.cs +++ b/Assets/GWConquest/Scripts/UI/ProductionMenu.cs @@ -2,6 +2,7 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Photon.Bolt; namespace GWConquest { @@ -121,7 +122,7 @@ namespace GWConquest { if(factory.ProductionQueueLength < factory.MaxQueueLength) { - AddProductionEvent ev = AddProductionEvent.Create(Bolt.GlobalTargets.OnlyServer); + AddProductionEvent ev = AddProductionEvent.Create(GlobalTargets.OnlyServer); ev.Factory = factory.entity; ev.UnitClass = uc.ShortName; ev.Player = Player.CurrentPlayer.entity; diff --git a/Assets/GWConquest/Scripts/UI/SelectFactionMenu.cs b/Assets/GWConquest/Scripts/UI/SelectFactionMenu.cs index 149b0ca..7c11d46 100644 --- a/Assets/GWConquest/Scripts/UI/SelectFactionMenu.cs +++ b/Assets/GWConquest/Scripts/UI/SelectFactionMenu.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/TransportUI.cs b/Assets/GWConquest/Scripts/UI/TransportUI.cs index d308e06..995aa58 100644 --- a/Assets/GWConquest/Scripts/UI/TransportUI.cs +++ b/Assets/GWConquest/Scripts/UI/TransportUI.cs @@ -2,6 +2,7 @@ using UnityEngine; using UnityEngine.UI; using System.Linq; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/TransportUIItemIcon.cs b/Assets/GWConquest/Scripts/UI/TransportUIItemIcon.cs index 1eb2d84..a71784f 100644 --- a/Assets/GWConquest/Scripts/UI/TransportUIItemIcon.cs +++ b/Assets/GWConquest/Scripts/UI/TransportUIItemIcon.cs @@ -1,5 +1,6 @@ using UnityEngine.UI; using UnityEngine; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UI/TransportUIUnitIcon.cs b/Assets/GWConquest/Scripts/UI/TransportUIUnitIcon.cs index 2209d19..1fe119d 100644 --- a/Assets/GWConquest/Scripts/UI/TransportUIUnitIcon.cs +++ b/Assets/GWConquest/Scripts/UI/TransportUIUnitIcon.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.UI; +using Photon.Bolt; namespace GWConquest { @@ -40,7 +41,7 @@ namespace GWConquest var LeaderIcon = ParentElement.DragTransform; if (RectTransformUtility.RectangleContainsScreenPoint(LeaderIcon, Input.mousePosition)) { - AssignLeaderEvent ev = AssignLeaderEvent.Create(Bolt.GlobalTargets.OnlyServer); + AssignLeaderEvent ev = AssignLeaderEvent.Create(GlobalTargets.OnlyServer); ev.Formation = ParentElement.Formation.entity; ev.Unit = Unit.entity; ev.Send(); diff --git a/Assets/GWConquest/Scripts/Unit.cs b/Assets/GWConquest/Scripts/Unit.cs index be208b0..2157b74 100644 --- a/Assets/GWConquest/Scripts/Unit.cs +++ b/Assets/GWConquest/Scripts/Unit.cs @@ -1,5 +1,7 @@ using System.Linq; using UnityEngine; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/UnitClass.cs b/Assets/GWConquest/Scripts/UnitClass.cs index 8f9c197..8888c90 100644 --- a/Assets/GWConquest/Scripts/UnitClass.cs +++ b/Assets/GWConquest/Scripts/UnitClass.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/GWConquest/Scripts/Zone.cs b/Assets/GWConquest/Scripts/Zone.cs index 550cb55..750842f 100644 --- a/Assets/GWConquest/Scripts/Zone.cs +++ b/Assets/GWConquest/Scripts/Zone.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using UnityEngine; using System.Linq; +using Photon.Bolt; +using Photon.Bolt.Utils; namespace GWConquest { diff --git a/Assets/Gizmos/Bolt Icon.png b/Assets/Gizmos/Bolt Icon.png new file mode 100644 index 0000000..fce4e62 Binary files /dev/null and b/Assets/Gizmos/Bolt Icon.png differ diff --git a/Assets/Gizmos/Bolt Icon.png.meta b/Assets/Gizmos/Bolt Icon.png.meta new file mode 100644 index 0000000..58791cd --- /dev/null +++ b/Assets/Gizmos/Bolt Icon.png.meta @@ -0,0 +1,128 @@ +fileFormatVersion: 2 +guid: 1abf0ef6bcd6f4d33852c878c3400bc4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 5 + maxTextureSize: 256 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 256 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/README.txt b/Assets/Photon/PhotonBolt/README.txt index 0595d3f..f2527f8 100644 --- a/Assets/Photon/PhotonBolt/README.txt +++ b/Assets/Photon/PhotonBolt/README.txt @@ -7,8 +7,4 @@ SUPPORT Forum: http://forum.photonengine.com/categories/bolt-engine Discord: https://discord.gg/0ya6ZpOvnShSCtbb -Email: support@boltengine.com - -VIDEOS - -YouTube: https://www.youtube.com/channel/UC9NVIbI5rpP7zmEOiB2Cs6Q +Email: support@boltengine.com \ No newline at end of file diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.dll b/Assets/Photon/PhotonBolt/assemblies/bolt.dll index 6252d35..f7bcc90 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/bolt.dll and b/Assets/Photon/PhotonBolt/assemblies/bolt.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.dll.meta b/Assets/Photon/PhotonBolt/assemblies/bolt.dll.meta index 72f3832..027d469 100644 --- a/Assets/Photon/PhotonBolt/assemblies/bolt.dll.meta +++ b/Assets/Photon/PhotonBolt/assemblies/bolt.dll.meta @@ -1,109 +1,98 @@ fileFormatVersion: 2 guid: 5b00bf8b25851d440940a40ec23344f4 -timeCreated: 1500296595 -licenseType: Store PluginImporter: + externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: BoltEntity: -2500 BoltPoll: -10000 BoltSend: 10000 + Photon.Bolt.BoltEntity: -2500 + Photon.Bolt.Internal.BoltPoll: -10000 + Photon.Bolt.Internal.BoltSend: 10000 isPreloaded: 0 isOverridable: 0 platformData: - data: - first: - Any: - second: - enabled: 1 - settings: {} - data: - first: - Editor: Editor - second: - enabled: 0 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: AnyOS - data: - first: - Facebook: Win - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Facebook: Win64 - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: Linux - second: - enabled: 1 - settings: - CPU: x86 - data: - first: - Standalone: Linux64 - second: - enabled: 1 - settings: - CPU: x86_64 - data: - first: - Standalone: LinuxUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: OSXIntel - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: OSXIntel64 - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: Win - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Standalone: Win64 - second: - enabled: 1 - settings: - CPU: AnyCPU - data: - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 1 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: OSXIntel + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: OSXIntel64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.dll.release b/Assets/Photon/PhotonBolt/assemblies/bolt.dll.release index e5c0a95..ba091bb 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/bolt.dll.release and b/Assets/Photon/PhotonBolt/assemblies/bolt.dll.release differ diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll index 27cd788..9d83ce8 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll and b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup deleted file mode 100644 index 449718e..0000000 Binary files a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup and /dev/null differ diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb index 12b7c8f..d29880c 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb and b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb differ diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb.meta b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb.meta index fac81d8..b3b3fee 100644 --- a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb.meta +++ b/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.mdb.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: de9db0a509b364269abbfe02c7ba5923 +guid: 6d132d7481716604fa51d7715fa8afd3 DefaultImporter: externalObjects: {} userData: diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.xml b/Assets/Photon/PhotonBolt/assemblies/bolt.xml index 9b75142..b55efef 100644 --- a/Assets/Photon/PhotonBolt/assemblies/bolt.xml +++ b/Assets/Photon/PhotonBolt/assemblies/bolt.xml @@ -4,2025 +4,1665 @@ bolt - + - Interface that can be implemented to create custom event filtering rules - - - *Example:* An event filter that blocks chat events from a chat restricted player - - - public class ChatEventFilter : IEventFilter { - public bool EventReceived(Event evt) { - if(chatRestrictedPlayerList.ContainsKey(evt.RaisedBy)) { - return false; - } - else return true; - } - } - - - - - - Called when a new event is recieved - - The event data - Whether to accept or reject the event - - - - Default implementation of Bolt.IEventFilter that lets everything through - - - - - Interface that can be implemented on Bolt.GlobalEventListener, Bolt.EntityEventListener and Bolt.EntityEventListener<T> - to modify its invoke condition settings - - - *Example:* A custom server callback class that invokes events even when disabled. - - - [BoltGlobalBehaviour(BoltNetworkModes.Server)] - public class BoltServerCallbacks : Bolt.GlobalEventListener, Bolt.IEventListener { - public bool InvokeIfDisabled { return true; } - public bool InvokeIfGameObjectIsInactive { return true; } - - // event callback overrides below - } - - - - - - Describe a Protocol Token that can be used to transfer data between peers - when running certain process on Bolt. - Read more at here - Utility methods to work with IProtocolTokens can be found on . - - - - - Used to deserialize the Token reading data from the data packet. - - Data packet that contains the Token info - - - - Used to serialize the Token by writing data into the data packet. - - Data packet used to store the Token info - - - - Utility methods to manage IProtocolToken's content - - - - - Convert the IProtocolToken into a byte array + Use this function to finish any pending Control Command in the queue. + Usefull if when Bolt needs to be shutdown while a control command still running. + All command in the queue are marked as Finished. - Token to be converted - Byte array with the Token content - + - Convert a byte array into a IProtocolToken + Number of frames per second as the simulation rate + Defaults to 60 fps - Byte array to be converted - IProtocolToken of type described on the byte array - + - Writes a IProtocolToken into this UdpPacket + Runs the Bolt Shutdown procedure, cleaning and resetting all necessary values in order to get Bolt ready + for a new startup process. - Packet where the Token will be written - IProtocolToken to be written at the end of the Packet + NetworkMode when shutting down + + + + - + - Reads a IProtocolToken from the UdpPacket + Invoked when the Application is about to Quit - Packet from where the Token will be read - IProtocolToken read from the tip of the Packet - + - Handle Read and Write of a IProtocolToken based on the UdpPacket type, - if is true, this method will write the Token, - or read it otherwise. + Update all BoltGlobalBahaviours active in the scene. + This method will check accross all registered GlobalBehaviours classes which ones need to be + created or destroyed. - UdpPacket where the Token will be manupulated - IProtocolToken to be written or read + Scene index to lookup for associated GlobalBehaviours. + Passing -1 will load only behaviours with no associated scene. - + - Base class that all commands inherit from + Auto loads the predefined scene with the asigned Token - + - The value of the BoltNetwork.serverFrame property of the computer this command was created on + Temporary re-used list for holding current proxies that need to be frozen. - + - Returns true if it's the first time this command executed + This method will register the internal Protocol Tokens used by Bolt + but will also look at the BoltProtocolTokenRegistry and register any Protocol Token + previously saved on the registry - - - User assignable token that lets you pair arbitrary data with the command, this is not replicated over the network to any remote computers. - + + + Override this method and return true if you want the event listener to keep being attached to Bolt even + when Bolt shuts down and starts again. + + True/False + + *Example:* Configuring the persistence behaviour to keep this listener alive between startup and shutdown. + + + public override bool PersistBetweenStartupAndShutdown() { + return true; + } + + - - - Convert a Command into a Bool. - Useful to check if the reference to a Command is not null - - Command to be checked + + + Callback triggered when the Bolt simulation is shutting down. + + + *Example:* Logging a message in the Bolt console when the server has shut down unexpectedly. + + + public override void BoltShutdown(AddCallback registerDoneCallback, UdpConnectionDisconnectReason disconnectReason = UdpConnectionDisconnectReason.Disconnected) { + BoltLog.Warn("Bolt is shutting down"); + + registerDoneCallback(() => + { + BoltLog.Warn("Bolt is down"); + SceneManager.LoadScene(0); + }); + } + + - + - Base class for unity behaviours that want to access Bolt methods + Callback triggered before the Bolt simulation starts. - *Example:* Using Bolt.EntityBehaviour to write a simple PlayerController class. Attach to a valid bolt entity/prefab. + *Example:* Logging a message in the console when Bolt is starting. - public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { - - bool forward; - bool backward; - bool left; - bool right; - - public override void Initialized() { - MiniMap.instance.AddKnownPlayer(this.gameObject); - } - - public override void Attached() { - state.AddCallback("name", NameChanged); - state.AddCallback("team", TeamChanged); - } - - public override void ControlGained() { - GameCamera.instance.AddFollowTarget(this.transform); - MiniMap.instance.SetControlledPlayer(this.entity); - } - - public override SimulateOwner() { - if(state.health < 100) - { - state.Modify().health += state.healthRegen * BoltNetwork.frameDeltaTime; - } - } - - public override void SimulateController() { - IPlayerCommandInput input = PlayerCommand.Create(); - - PollKeys(); - - input.forward = forward; - input.backward = backward; - input.left = left; - input.right = right; - - entity.QueueInput(input); - } - - public override ExecuteCommand(Bolt.Command command, bool resetState) { - if(resetState) { - motor.SetState(cmd.Result.position); - } - else - { - cmd.Result.position = motor.Move(cmd.Input.forward, cmd.Input.backward, command.Input.left, command.Input.right); - - if (cmd.IsFirstExecution) { - AnimatePlayer(cmd); - } - } - } + public override void BoltStartBegin() { + BoltLog.Info("Warning: Bolt is Starting..."); } - + - The entity for this behaviour + Callback triggered after the Bolt simulation starts. - Use the ```entity``` property to access the internal ```BoltEntity``` of the gameObject that this script is attached to. - *Example:* Passing the ```entity``` of this gameObject to a ```MiniMap```, giving it the position, facing direction and the - entity state (such as team, alive/dead, hostile, etc). + *Example:* Logging a message in the console when Bolt is already started. - public class PlayerController : Bolt.EntityBehaviour { - public override void ControlGained() { - GameCamera.instance.AddFollowTarget(this.transform); - MiniMap.instance.SetControlledPlayer(this.entity); - } + public override void BoltStartDone() { + BoltLog.Info("Warning: Bolt started..."); } - + - Invoked when the entity has been initialized, before Attached + Callback triggered when Bolt was not able to initialize completely. - *Example:* Notifying a ```MiniMap``` class to draw this gameObject by overriding the ```Initialized()``` method. + *Example:* Logging a message in the console when Bolt failed to start. - public override void Initialized() { - MiniMap.instance.AddKnownPlayer(this.gameObject); + public override void BoltStartFailed(UdpConnectionDisconnectReason disconnectReason) { + BoltLog.Info("Warning: Bolt failed to start. Reason: {0}", disconnectReason); } - + - Invoked when Bolt is aware of this entity and all internal state has been setup + Callback triggered when a new binary stream data is being transferred. + The sender connection + Stream Channel where the data will be sent + Stream Unique ID - *Example:* Overriding the ```Attached()``` method to add state change callbacks to the newly valid state. + *Example:* Receiving data from BoltConnection. - public override void Attached() { - state.AddCallback("name", NameChanged); - state.AddCallback("team", TeamChanged); + public override void StreamDataStarted(BoltConnection connnection, UdpChannelName channel, ulong streamID) { + BoltLog.Info("Connection {0} is transfering data on channel {1}...", connection, channel); } - + - Invoked when this entity is removed from Bolt's awareness + Callback triggered when a binary stream data has been aborted. + The sender connection + Stream Channel where the data was being sent + Stream Unique ID - *Example:* Notifying the game minimap to remove the entity upon detaching from the simulation. + *Example:* Receiving data from BoltConnection. - public override void Detached() { - MiniMap.instance.RemoveKnownPlayer(this.entity); - { - + public override void StreamDataAborted(BoltConnection connnection, UdpChannelName channel, ulong streamID) { + BoltLog.Info("Stream {0} on channel {1} from connection {2} has been aborted.", streamID, channel, connection); + } + - + - Invoked each simulation step on the owner + Callback triggered when a new binary stream data is being transferred. + The sender connection + Stream Channel where the data is being sent + Stream Unique ID + Stream transfer progress from 0 to 0.99 - *Example:* Implementing an authoritative health regeneration update every 10th frame. Also fires the - DeathTrigger() on the state if health falls below zero. + *Example:* Receiving data from BoltConnection. - public override SimulateOwner() { - if(state.alive && state.Health.Current <= 0) { - using(var mod = state.Health.Modify()) { - mod.alive = false; - mod.DeathTrigger(); - } - } - else if(state.alive && (BoltNetwork.frame % 10) == 0) { - using(var mod = state.Health.Modify()) { - mod.Current = Mathf.Clamp (state.Health.Current + (state.Health.RegenPer10 * BoltNetwork.frameDeltaTime), - // clamp from 0 to max health - 0, state.Health.Max); - } - } + public override void StreamDataProgress(BoltConnection connnection, UdpChannelName channel, ulong streamID, float progress) { + BoltLog.Info("Connection {0} is transfering data on channel {1} :: Transfer {2} on {3}%...", connection, channel, streamID, progress * 100); } - + - Invoked each simulation step on the controller + Callback triggered when binary stream data is received. + The sender connection + The binary stream data - *Example:* Creating a simple WASD-style movement input command and adding it to the queue of inputs. One input command - should be added to the queue per execution and remember to create and compile a Command asset before using this method! + *Example:* Receiving a custom player icon. - bool forward; - bool backward; - bool left; - bool right; - - public override void SimulateController() { - IPlayerCommandInput input = PlayerCommand.Create(); - - PollKeys(); - - input.forward = forward; - input.backward = backward; - input.left = left; - input.right = right; + public override void StreamDataReceived(BoltConnection connnection, UdpStreamData data) { + Texture2D icon = new Texture2D(4, 4); + icon.LoadImage(data.Data); - entity.QueueInput(input); + PlayerData playerData = (PlayerData)connection.userToken; + playerData.SetIcon(icon); } - + - Invoked when you gain control of this entity + Callback triggered before the new local scene is loaded. + Name of scene being loaded + Token passed by the Server when loading the new scene. - *Example:* Using the ```ControlGained()``` callback to set up a ```GameCamera``` and ```MiniMap``` to focus on this entity. + *Example:* Showing a splash screen when clients are loading the game scene. - public override void ControlGained() { - GameCamera.instance.AddFollowTarget(this.transform); - MiniMap.instance.ControlGained(this.entity); + public override void SceneLoadLocalBegin(string scene, IProtocolToken token) { + if(BoltNetwork.isClient && map.Equals(""GameScene"") { + SplashScreen.Show(SplashScreens.GameLoad); + } } - + - + - Invoked when you lost control of this entity + Callback triggered after the new local scene has been completely loaded. + Name of scene that has loaded + Token passed by the Server when loading the new scene. - *Example:* Using the ```ControlLost()``` callback to remove the focus of a ```GameCamera``` and ```MiniMap```. + *Example:* Hiding a splash screen that was shown during loading. - public override void ControlLost() { - GameCamera.instance.RemoveFollowTarget(); - MiniMap.instance.ControlLost(this.entity); + public override void SceneLoadLocalDone(string scene, IProtocolToken token) { + if(BoltNetwork.isClient && scene.Equals(""GameScene"") { + SplashScreen.Hide(); + } } - + - + - Invoked on the owner when a remote connection is controlling this entity but we have not received any command for the current simulation frame. + Callback triggered when a remote connection has completely loaded the current scene - The last valid command received + The remote connection + Token passed by the Server when loading the new scene. - *Example:* Handling missing input commands by using the last received input command to continue moving in the same direction. + *Example:* Instantiating and configuring a player entity on the server and then assigning control to the client. - public override void MissingCommand(Bolt.Command previous) - { - WASDCommand cmd = (WASDCommand)command; + public override void SceneLoadRemoteDone(BoltConnection connection, IProtocolToken token) { + var player = BoltNetwork.Instantiate(BoltPrefabs.Player); + player.transform.position = spawnPoint.transform.position; - cmd.Result.position motor.Move(cmd.Input.forward, cmd.Input.backward, cmd.Input.left, cmd.Input.right); + var initData = prototype.GetNewPlayer(GameLogic.PlayableClass.Mercenary); + Configure(player, initData); + + player.AssignControl(connection); } - + + + Callback triggered when a client has become connected to this instance + + Endpoint of the connected client + + *Example:* Instantiating and configuring a player entity when a client connects to the server. + + + public override void Connected(BoltConnection connection) { + BoltLog.Info("Accept Token {0} using Connect Token {1}", connection.AcceptToken, connection.ConnectToken); + + var player = BoltNetwork.Instantiate(BoltPrefabs.Player); + player.transform.position = spawnPoint.transform.position; + + var initData = prototype.GetNewPlayer(GameLogic.PlayableClass.Mercenary); + Configure(player, initData); + + player.AssignControl(connection); + } + + + + - Invoked on both the owner and controller to execute a command + Callback triggered when a connection to remote server has failed - The command to execute - Indicates if we should reset the state of the local motor or not + The remote address + Connect token sent by the client when trying to connect. - *Example:* Executing a simple WASD movement command. On the client this method can be called multiple times per fixed frame, - beginning with a reset to the last confirmed state (resetState == true), and then again for each unverified input command in the queue (resetState == false); - - Use the cmd.isFirstExecution property to do any type of one-shot behaviour such as playing sound or animations. This will prevent it from being called each time - the input is replayed on the client. - - Remember to create and compile a Command asset before using this method! + *Example:* Logging an error message when the remote connection has failed. - public override ExecuteCommand(Bolt.Command command, bool resetState) { - WASDCommand cmd = (WASDCommand)command; - if(resetState) { - motor.SetState(cmd.Result.position); - } - else { - cmd.Result.position = motor.Move(cmd.Input.forward, cmd.Input.backward, cmd.Input.left, cmd.Input.right); - - if (cmd.IsFirstExecution) { - AnimatePlayer(cmd); - } - } + public override void ConnectFailed(UdpEndPoint endpoint, IProtocolToken token) { + BoltLog.Info(string.Format("Connection To ({0}:{1}) has failed", endpoint.Address.ToString(), endpoint.ToString())); } - + - Base class for unity behaviours that want to access Bolt methods with the state available also + Callback triggered when this instance receives an incoming client connection - The type of state on this BoltEntity + The incoming client endpoint + A data token sent from the incoming client - *Example:* Using the IPlayerState type as a parameter and using its property state.team in code. + *Example:* Accepting an incoming connection with user credentials in the data token. - public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { - public override void ControlGained() { - state.AddCallback("team", TeamChanged); - } - - void TeamChanged() { - var nameplate = GetComponent<PlayerNameplate>(); - if (state.team == 0) nameplate.color = Color.Blue; - else nameplate.color = Color.Red; + public override void ConnectRequest(UdpEndPoint endpoint, IProtocolToken token) { + UserCredentials creds = (UserCredentials)token); + if(Authenticate(creds.username, creds.password)) { + BoltNetwork.Accept(connection.remoteEndPoint); } } - + - The state for this behaviours entity + Callback triggered when the connection to a remote server has been refused. + The remote server endpoint + Data token sent by the refusing server - *Example:* Using the ```state``` property to set up state callbacks. + *Example:* Logging an error message when the remote connection has been refused using an error message token from the server. - public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { - public override void ControlGained() { - state.AddCallback("team", TeamChanged); - } - - void TeamChanged() { - var nameplate = GetComponent<PlayerNameplate>(); - if (state.team == 0) nameplate.color = Color.Blue; - else nameplate.color = Color.Red; - } + public override void ConnectRefused(UdpEndPoint endpoint, IProtocolToken token) { + ServerMessage.message = (ServerMessage)token; + BoltLog.Info(string.Format("Connection To ({0}:{1}) has been refused. Reason was {3}", + endpoint.Address.ToString(), endpoint.ToString(), serverMessage.errorDescription)); } - - - Not really sure why these aren't just pulled from UnityObject when needed? - - - - - Interface for unity behaviours that want to access Bolt methods - - - - - Interface for unity behaviours that want to access Bolt methods - - Bolt state of the entity - - - - Interface which can be implemented on a behaviour attached to an entity which lets you provide - custom priority calculations for state and events. - - - - - Called for calculating the priority of this entity for the connection passed in - - The connection we are calculating priority for - How many packets since we sent an update for this entity - The priority of the entity - - - - Called for calculating the priority of an event sent to this entity for the connection passed in - - The connection we are calculating priority for - The event we are calculating priority for - The priority of the event - - + - Base class that all events inherit from + Callback triggered when trying to connect to a remote endpoint + The remote server address + Token passed by the client when trying to connect to a server. - *Example:* Using a LogEvent object to send a message. + *Example:* Logging a message when initializing a connection to server. - void LogMessage(string message) { - var logEvt = new LogEvent(); - logEvt.message = message; - logEvt.Send(); + public override void ConnectAttempt((UdpEndPoint endpoint) { + BoltLog.Info(string.Format("To Remote Server At ({0}:{1})", endpoint.Address, endpoint.Port); } - + - Returns true if this event was sent from own connection + Callback triggered when disconnected from remote server + The remote server endpoint - *Example:* Showing chat messages from other players. + *Example:* Logging a disconnect message and returning to the main menu scene. - public override void OnEvent(ChatEvent chatEvt) { - if(chatEvt.FromSelf) { - return; - } - - ChatWindow.instance.ShowMessage(chatEvt.message, chatEvt.timestamp); + public override void Disconnected(BoltConnection connection) { + BoltLog.Info("Disconnected with Token {0}", connection.DisconnectToken); + BoltLog.Info("Returning to main menu..."); + Application.LoadLevel("MainMenu"); } - + - + - The connection which raised this event + Callback triggered when this instance of Bolt loses control of a Bolt entity + The controlled entity - *Example:* Blocking messages from players on a chat restricted list. + *Example:* Setting up game components to no longer control an entity. - public override void OnEvent(ChatEvent chatEvt) { - if(chatRestrictedPlayerList.ContainsKey(chatEvt.RaisedBy)) { - return; - } - - ChatWindow.instance.ShowMessage(chatEvt.message, chatEvt.timestamp); + public override void ControlOfEntityLost(BoltEntity entity) { + BoltLog.Info("Control lost with Token {0}", entity.ControlLostToken); + GameInput.instance.RemoveControlledEntity(entity); + MiniMap.instance.RemoveControlledEntity(entity); } - + - Returns true if this is a global event / not an entity event + Callback triggered when this instance of bolt receieves control of a bolt entity + The controlled entity - *Example:* Using the isGlobal property to determine whether to send local or whole-zone chat. + *Example:* Setting up the game minimap and other components to use a specific entity as the player's controlled entity. - public override void OnEvent(ChatEvent chatEvt) { - if(chatEvt.isGlobalEvent) { - BroadcastZoneChat(chatEvt.message, chatEvt.timestamp); - } - else { - SendLocalChat(chatEvt.message, chatEvt.timestamp); - } + public override void ControlOfEntityGained(BoltEntity entity) { + GameInput.instance.SetControlledEntity(entity); + MiniMap.instance.SetControlledEntity(entity); } - + - The raw bytes of the event data + Callback triggered when a new entity is attached to the bolt simulation + The attached entity - *Example:* Removing repeated chat messages by doing sequence comparison on the raw byte data and filtering out - any repeated messages after a certain limit. + *Example:* Setting up the game minimap to show a newly attached entity. - public override void OnEvent(ChatEvent chatEvt) { - bool repeated = true; - - for(int i = 0; i < CHAT_REPEAT_LIMIT; i++) { - if(!chatEvt.BinaryData.SequenceEqual(previousChatEvts.GoBack(i).BinaryData) { - repeated = false; - break; - } - } + public override void EntityAttached(BoltEntity entity) { + MiniMap.instance.SetKnownEntity(entity); } - + - Enqueue this object for sending across the network + Callback triggered when a new entity is detached from the bolt simulation + The detached entity - *Example:* Sending a log message. + *Example:* Removing the newly detached entity from the game minimap. - void LogMessage(string message) { - var logEvt = new LogEvent(); - logEvt.message = message; - logEvt.Send(); + public override void EntityDetached(BoltEntity entity) { + MiniMap.instance.RemoveKnownEntity(entity); } - - - The reliability mode of an event - - - + - The target of an entity event - - - - - The target of a global event + Callback triggered when a bolt entity is recieved from the network + The recieved bolt entity + + *Example:* Loggging connections from remote players in the client bolt console + + + public override void EntityReceived(BoltEntity entity) { + string name = entity.GetState<PlayerState>().Name; + BoltLog.Info(string.Format("{0} Has Connected", name)); + } + + - + - Called by Bolt to inspect a prefab before instantiating it. The object - returned from this method can be the prefab itself, it does not have - to be a unique instance. + Callback triggered when a bolt entity is frozen. - The id of the prefab we are looking for - A game object representing the prefab or an instance of the prefab + The recieved bolt entity + + *Example:* Loggging connections from remote players in the client bolt console + + + public override void EntityFrozen(BoltEntity entity) { + string name = entity.GetState<PlayerState>().Name; + BoltLog.Info(string.Format("{0} Has been frozen", name)); + } + + - + - This is called when bolt wants to create a new instance of an entity prefab. + Callback triggered when a bolt entity is thawed. - The id of this prefab - The position we want the instance instantiated at - The rotation we want the instance to take - The newly instantiate object, or null if a prefab with was not found + The recieved bolt entity + + *Example:* Loggging connections from remote players in the client bolt console + + + public override void EntityThawed(BoltEntity entity) { + string name = entity.GetState<PlayerState>().Name; + BoltLog.Info(string.Format("{0} Has been thawed", name)); + } + + - - - This is called when Bolt wants to destroy the instance of an entity prefab. - - The instance to destroy + + + Callback triggered when the session list is updated. + + The updated session list + + *Example:* Loggging all sessions from the list. + + + public override void SessionListUpdated(Map<System.Guid, UdpSession> sessionList) { + BoltLog.Info("Session list updated: {0} total sessions", sessionList.Count); + + foreach (var session in sessionList) + { + UdpSession udpSession = session.Value as UdpSession; + BoltLog.Info("UdpSession {0} Source: {1}", udpSession.HostName, udpSession.Source); + } + } + + - + - Deault implementation of Bolt.IPrefabPool which uses GameObject.Instantiate and GameObject.Destroy + Callback triggered when connecting to a session has successful. + The session the client was trying to connect to + Connection token + + *Example:* Loggging + + + public override void SessionConnected(UdpSession session, IProtocolToken token) + { + BoltLog.Error("Success to connect to session {0} with token {1}", session, token); + } + + - + - Base interface for all states + Callback triggered when connecting to a session has failed. + The session the client was trying to connect to + Connection token + Reason the operation has failed + + *Example:* Loggging + + + public override void SessionConnectFailed(UdpSession session, IProtocolToken token, UdpSessionError errorReason) + { + BoltLog.Error("Failed to connect to session {0} with token {1}", session, token); + } + + - + - The Animator component associated with this entity state + Callback triggered when the requested session creation was successful. + The created session + + *Example:* Loggging + + + public override void SessionCreatedOrUpdated(UdpSession session) + { + BoltLog.Info("UdpSession {0} of type {1} was created", session.HostName, session.Source); + } + + - + - A collection of all Animator components associated with this entity state + Callback triggered when the requested session creation has failed. + The failed session + Reason the operation has failed + + *Example:* Loggging + + + public override void SessionCreationFailed(UdpSession session, UdpSessionError errorReason) + { + BoltLog.Info("UdpSession {0} of type {1} has failed to create", session.HostName, session.Source); + } + + - - - Set the animator object this state should use for reading/writing mecanim parameters - - The animator object to use + + + Bolt behaviour to poll the network and step entities in the simulation + + + *Example:* if bolt is missing the ```BoltPoll`` behaviour then the simulation is broken and we should shut down. + + + void CheckBoltHealth() { + if(BoltNetwork.globalObject.GetComponent<BoltPoll>() == null) { + Debug.Log("BoltPoll is missing!); + GameApplication.Shutdown(ErrorCode.Bolt); + } + } + + - - - Allows you to hook up a callback to a specific property - - The path of the property - The callback delegate + + + + + + *Example:* if bolt is missing the ```BoltSend`` behaviour then the simulation is broken and we should shut down. + + + void CheckBoltHealth() { + if(BoltNetwork.globalObject.GetComponent<BoltSend>() == null) { + Debug.Log("BoltSend is missing!); + GameApplication.Shutdown(ErrorCode.Bolt); + } + } + + - + - Allows you to hook up a callback to a specific property + Defines where the entity prefab can be instantiated - The path of the property - The callback delegate - + - Removes a callback from a property + Defines how the Unity Editor instance will be started, + If as server, client or none - The path of the property - The callback delegate to remove - - - Removes a callback from a property - - The path of the property - The callback delegate to remove + + + Provides logging capabilities to a variety of outputs + + + *Example:* Logging with different status levels. + + + void OwnerOnAttack(BoltEntity player, BoltEntity target) { + if(!target.IsAttached) { + BoltLog.Error("Attempting to target an entity that is not attached: {0}", target.NetworkId); + } + else { + BoltLog.Info("{0} attack on {1}", player.NetworkId, target.NetworkId); + + var playerState = player.GetState<PlayerState>(); + var targetState = target.GetState<PlayerState>(); + + targetState.HP = -= playerState.BaseDamage * playerState.DamageModMultiplier; + } + } + + - + - Clears all callbacks currently set. This is useful when pooling entities and you wish to clear out the current callbacks before returning the entity to the pool. + The interface providing log writing capabilities to an output - + - Set a property dynamically by string name + IWriter implementation that outputs to a file - The property name to set - The property value to set - + - Gets a property dynamically by string name + IWriter implementation that outputs to the Bolt console - The property name to get - - + - Double buffer class represents a buffer with only 2 values, - swapped when you call @ + IWriter implementation that outputs to the system console out - + - Shift the specified value into the buffer, while - saving the current value as the previous one + IWriter implementation that outputs to Unity console - The shift. - Value. - + - Inits the buffer. + Sequence Generator creates a sequence of numbers - The buffer itself. - Value to set on the both spots on the buffer. - + - Contains the indices for all arrays that contain a specific property, in order + The in-game console window + + *Example:* Writing a custom message to the console. + + + void Start() { + BoltConsole.Write("[Start:" + this.gameObject.name + "]); + } + + - + - The amount of indices + Write one line to the console + Text to write + Color of the text + + *Example:* Writing a custom message to the console in color. + + + void OnDeath() { + BoltConsole.Write("[Death:" + this.gameObject.name + "], Color.Red); + } + + - + - Network object. + Write one line to the console + Text to write + + *Example:* Writing a custom message to the console. + + + void OnSpawn() { + BoltConsole.Write("[Spawn:" + this.gameObject.name + "]); + } + + - + - Network property describes one property of a State + Interface that can be implemented to create custom event filtering rules - - - - What type of shape to use in a bolt hitbox - - - *Example:* Sorting the hitboxes in a body based on shape. - - - void ConfigureHitboxes(BoltHitboxBody body) { - foreach(BoltHitbox hitbox in body.hitboxes) { - switch(hitbox.hitboxShape) { - case BoltHitboxShape.Sphere: ConfigureSphere(hitbox); break; - case BoltHitboxShape.Box: ConfigureBox(hitbox); break; - } - } - } - - - - - - The body area represented by a bolt hitbox - - - *Example:* Modifying a base damage value depending on the area of the hit. - - - float CalculateDamage(BoltHitbox hit, float baseDamage) { - switch(hit.hitboxType) { - case BoltHitboxType.Head: return 2.0f * baseDamage; - - case BoltHitboxType.Leg: - case BoltHitboxType.UpperArm: return 0.7f * baseDamage; - - default: return baseDamage; - } - } - - - - - - Container for a group of BoltPhysicsHits - - - *Example:* Using ```BoltNetwork.RaycastAll()``` to detect hit events and processing the BoltPhysicsHits object that is returned. - - - void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { - if(entity.IsOwner) { - using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), - cmd.ServerFrame)) { - var hit = hits.GetHit(0); - var targetEntity = hit.body.GetComponent<BoltEntity>(); + + *Example:* An event filter that blocks chat events from a chat restricted player - if(targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; - } - } - } - } - - + + public class ChatEventFilter : IEventFilter { + public bool EventReceived(Event evt) { + if(chatRestrictedPlayerList.ContainsKey(evt.RaisedBy)) { + return false; + } + else return true; + } + } + + - - - How many hits we have in the collection - - - *Example:* Using the hit count to iterate through all hits - - void OnOwner(PlayerCommand cmd, BoltEntity entity) - { - if (entity.IsOwner) - { - using (BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), cmd.ServerFrame)) - { - for (int i = 0; i < hits.count; ++i) - { - var hit = hits.GetHit(i); - var targetEntity = hit.body.GetComponent<BoltEntity>(); - - if (targetEntity.StateIs<ILivingEntity>()) - { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; - } - } - } - } - } - - + + + Called when a new event is recieved + + The event data + Whether to accept or reject the event - - - Array indexing of the hits in this object - - Index position - The BoltPhysicsHit at the given index - - *Example:* Using the array indexing to get the first object hit by a weapon firing raycast. - - - void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { - if(entity.IsOwner) { - using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), - cmd.ServerFrame))0 { - - if(hit.count > 0) { - var hit = hits[0]; - var targetEntity = hit.body.GetComponent<BoltEntity>(); - - if(targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; - } - } - } - } - } - - + + + Default implementation of Bolt.IEventFilter that lets everything through + - - - Get the hit at a specific index - - Index position - The BoltPhysicsHit at the given index - - *Example:* Using the GetHit method to find the first object hit by a weapon firing raycast. - - - void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { - if(entity.IsOwner) { - using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), - cmd.ServerFrame))0 { - - if(hit.count > 0) { - var hit = hits.GetHit(0); - var targetEntity = hit.body.GetComponent<BoltEntity>(); + + + Interface that can be implemented on Bolt.GlobalEventListener, Bolt.EntityEventListener and Bolt.EntityEventListener<T> + to modify its invoke condition settings + + + *Example:* A custom server callback class that invokes events even when disabled. - if(targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; - } - } - } - } - } - - - - - - Implementing the IDisposable interface to allow "using" syntax. - - - *Example:* Implementing the Disponse() method allows BoltPhysicsHits to be in a "using" block. + + [BoltGlobalBehaviour(BoltNetworkModes.Server)] + public class BoltServerCallbacks : Bolt.GlobalEventListener, Bolt.IEventListener { + public bool InvokeIfDisabled { return true; } + public bool InvokeIfGameObjectIsInactive { return true; } - - void DoRaycast(Ray ray) { - using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(ray)) { - // the hits variable will be automatically disposed at the end of this block - } - } - - + // event callback overrides below + } + + - - - Describes a hit to a BoltHitbox on a BoltHitboxBody - - - *Example:* Logging the details of a BoltPhysicsHit object. - - - void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { - if(entity.IsOwner) { - using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), - cmd.ServerFrame))0 { - - if(hit.count > 0) { - BoltPhysicsHit hit = hits.GetHit(0); - Debug.Log(string.Format("[HIT] Target={0}, Distance={1}, HitArea={2}", hit.body.gameObject.name, hit.distance, hit.hitbox.hitboxType); - } - } - } - } - - + + + Signal to Bolt if this EventListener must receive events even if it's disabled. + Return true to receive events. + - + - The distance away from the origin of the ray + Signal to Bolt if this EventListener must receive events even if the GameObject is disabled. + Return true to receive events. - + - Which hitbox was hit + Represents a simple Object Pool manager + - + - The body which was hit + Internal Object Pool - + - Don't query anything. + Check if the Pool has any Pooled Object + True if there is any object to be reused on the pool - + - Query for a single component + Object Pool Constructor - + - Query for all components on this entity + Returns an instance to the Object Pool + Object to the returned to Pool - + - Query for all components on this entity and children. + Returns a valid reference from the Pool. + If there is a old object on the Pool, returns it, if not, create a new one. + Reference from the Object Pool - + - Use global options + Describe a Protocol Token that can be used to transfer data between peers + when running certain process on Bolt. + Read more at here + Utility methods to work with IProtocolTokens can be found on . - + - Dont query anything + Used to deserialize the Token reading data from the data packet. + Data packet that contains the Token info - + - Query for a single component + Used to serialize the Token by writing data into the data packet. + Data packet used to store the Token info - + - Query for all components on this entity + Used to deserialize the Token reading data from the data packet. + Data packet that contains the Token info - + - Query for all components on this entity and children. + Used to serialize the Token by writing data into the data packet. + Data packet used to store the Token info - + - Utility struct for caching a unity component globally as a field on a class + Used to reset all fields from a IProtocolToken in order to return it to the Pool - The component type - + - Returns false if the component is currently null + Utility methods to manage IProtocolToken's content - + - Returns the cached component + Convert the IProtocolToken into a byte array + Token to be converted + Byte array with the Token content - + - Utility struct for caching a unity component on the same object (or children) field on a class + Convert a byte array into a IProtocolToken - The component type + Byte array to be converted + IProtocolToken of type described on the byte array - + - Returns false if the component is currently null + Writes a IProtocolToken into this UdpPacket + Packet where the Token will be written + IProtocolToken to be written at the end of the Packet - + - Returns the cached component + Reads a IProtocolToken from the UdpPacket + Packet from where the Token will be read + IProtocolToken read from the tip of the Packet - + - Whether a NAT port mapping is open or closed + Handle Read and Write of a IProtocolToken based on the UdpPacket type, + if is true, this method will write the Token, + or read it otherwise. + UdpPacket where the Token will be manupulated + IProtocolToken to be written or read - + - This class is responsible to initialize the Photon Cloud system - in order to always mantain the player connected to the cloud services - and take care of the CCU count. + Releases a PooledProtocolToken back to the Pool + A IProtocolToken candidate that can be PooledProtocolToken instance - + - Adds the room property. + Creates a new Protocol Token instance from a PooledProtocolToken type that can be reused by the pooling system - true, if room property was added, false otherwise. - Propety Key. - Property Value. - If set to true show this property on the Lobby too, - so the client can see the properties before entering the room. + Protocol Type that represents a PooledProtocolToken type + A new instance of a PooledProtocolToken - + - Removes the room property. + Check if the Prefab Database contains a reference to a Bolt Entity - true, if room property was removed, false otherwise. - Property Key. - - - - Service ID of this instance (server only) - - - - - IP address on which this game server should listen - - - - - Port on which this game server should listen - - - - - Server Group ID of this instance - - - - - Game Profile ID of this instance - - - - - Override settings for game server - - IP address of the server - Port on which the server listen - Port for A2S queries - Zeuz Server Group ID - Zeuz Game Profile ID - - - - Initialize zeuz - loads properties from command line arguments, setup query port and unreserve service (optional). We recommend to call this in Awake. - - Set if you want to call Unreserve on zeuz API (with Service ID received as command line argument) - - - - Deinitialize zeuz and unreserve service (optional). We recommend to call this when the game is over and all clients already left the server. - - Set if you want to call Unreserve on zeuz API (with Service ID received as command line argument) - - - - Called when the game server instance is successfully reserved and returns IP address and port - - - - - Called when the game server instance reservation failed - - - - - Get room options with Server Group ID and Game Profile ID properties. Both properties set as visible for lobby. - - Zeuz Server Group ID - Zeuz Game Profile ID - New instance of RoomOptions, filled with Server Group ID and Game Profile ID - - - - Get room options with Server Group ID, Game Profile ID and minimum players needed for server reservation. Server Group ID and Game Profile ID set as visible for lobby. - - Zeuz Server Group ID - Zeuz Game Profile ID - Minimum players needed for server reservation - New instance of RoomOptions, filled with Server Group ID, Game Profile ID and minimum players needed for server reservation - - - - Get room options with Server Group ID, Game Profile ID, custom server IP and Port properties. Server Group ID and Game Profile ID set as visible for lobby. - Use this if you want to bypass zeuz.io Reserve API call and send all clients in the room to a specific server instance. - - Zeuz Server Group ID - Zeuz Game Profile ID - IP address of custom server - Port on which custom server listen - New instance of RoomOptions, filled with Server Group ID, Game Profile ID, custom server IP address and Port properties - - - - Get room options with Server Group ID, Game Profile ID, custom server IP, Port and minimum players needed for server reservation. Server Group ID and Game Profile ID set as visible for lobby. - Use this if you want to bypass zeuz.io Reserve API call and send all clients in the room to a specific server instance. - - Zeuz Server Group ID - Zeuz Game Profile ID - Minimum players needed for server reservation - IP address of custom server - Port on which custom server listen - New instance of RoomOptions, filled with Server Group ID, Game Profile ID, custom server IP address and Port properties - - - - Get room properties with Server Group ID, Game Profile ID - - Zeuz Server Group ID - Zeuz Game Profile ID - Hashtable filled with Server Group ID and Game Profile ID - - - - Get room properties with Server Group ID, Game Profile ID and minimum players needed for server reservation. - - Zeuz Server Group ID - Zeuz Game Profile ID - Minimum players needed for server reservation - Hashtable filled with Server Group ID and Game Profile ID - - - - Get room properties with Server Group ID, Game Profile ID, custom server IP and Port. - Use this if you want to bypass zeuz.io Reserve API call and send all clients in the room to a specific server instance. - - Zeuz Server Group ID - Zeuz Game Profile ID - IP address of custom server - Port on which custom server listen - Hashtable filled with Server Group ID, Game Profile ID, custom server IP address and Port - - - - Get room properties with Server Group ID, Game Profile ID, custom server IP, Port and minimum players needed for server reservation. - Use this if you want to bypass zeuz.io Reserve API call and send all clients in the room to a specific server instance. - - Zeuz Server Group ID - Zeuz Game Profile ID - Minimum players needed for server reservation - IP address of custom server - Port on which custom server listen - Hashtable filled with Server Group ID, Game Profile ID, custom server IP address and Port - - - - Get room property names related to zeuz to expose them in lobby. - - Array of property names for zeuz Server Group ID and Game Profile ID - - - - Generic Bolt exception. - - - - - Thrown if a debug assert fails somewhere in the code - - - - - Bolt package overflow exception. - - - - - Fail automatically with the specified message. - - Message. + BoltEntity to heck + True, if the BoltEntity is registred on the Prefabs Database - + - Test if both A and B are not null and are the same, or raise a exception otherwise. - - The A component. - The B component. - Error message. - - - - Raises the Generic Exception Type if the condition is not False, passing the extraInfo object. - - Condition to test as False. - Extra info passed to the BoltException instance. - A derivative type. - - - - Raises the Generic Exception Type if the condition is not True, passing the extraInfo object. - - Condition to test as True. - Extra info passed to the BoltException instance. - A derivative type. - - - - NetworkValue describes one set of values that can be networked - - - - - Interval between publish count information - - - - - Remote Server + Base class that all commands inherit from - + - Sends the report count to the Server + The value of the BoltNetwork.serverFrame property of the computer this command was created on - - + - Create the HTTP request and send JSON data to remote server + Returns true if it's the first time this command executed - Server URL. - App identifier. - License key. - Total players in the Game. - + - Gets the current session this peer is connected. + User assignable token that lets you pair arbitrary data with the command, this is not replicated over the network to any remote computers. - The current session. - + - Expose custom metadata information about the current platform and connection if a remove server. - The information retrieved by this call depends on the current active platform and the current - internal status of it. + Convert a Command into a Bool. + Useful to check if the reference to a Command is not null + Command to be checked - - - Creates a Session using the current running Platform. - - Session identifier. This value will be public available and - can be used by other players to join this specific session. - User custom data. This Token can be used to pass custom data to other players - and/or to configure custom properties of the session. More information look at . - - Target Scene to be loaded after the session creation procedure starts. - - *Example:* Creating a session with some custom properties. - - - void SetupSession(string map, int gameType) - { - if (BoltNetwork.IsServer) - { - string matchName = Guid.NewGuid().ToString(); - - PhotonRoomProperties props = new PhotonRoomProperties(); - props["m"] = map; - props["t"] = gameType; - - BoltMatchmaking.CreateSession( - sessionID: matchName, - sceneToLoad: map, - token: props - ); - } - } - - - - + - Updates the current session configuration. The local peer need to be the Server in order to call this method. + Base class for unity behaviours that want to access Bolt methods - Settings Token. This can be any or - a to setup a Photon Session. - - - - Joins a Session by name. - - Session name that you want to enter - Connection Token - - *Example*: Joining a session using the Session identifier. - - - void Join(string sessionID) - { - if (BoltNetwork.IsClient) - { - var token = new TokenTest(); - BoltMatchmaking.JoinSession(sessionID, token); - } - } - - - - - - Joins a Session using a UdpSession as reference. - - UdpSession that you want to enter - Connection Token - - *Example*: Joining a session using a UdpSession. - - - public override void SessionListUpdated(Map<Guid, UdpSession> sessionList) - { - foreach (var session in sessionList) - { - UdpSession udpSession = session.Value as UdpSession; - var token = new TestToken(); - BoltMatchmaking.JoinSession(udpSession, token); - } - } - - - - - - Joins a Session in a random fashion. When not using the , the client - will try to enter in any available room. - - - - *Example*: Joining a Random Session when Bolt is ready. + + *Example:* Using Bolt.EntityBehaviour to write a simple PlayerController class. Attach to a valid bolt entity/prefab. - - public override void BoltStartDone() - { - if (BoltNetwork.IsClient) - { - var token = new TestToken(); - BoltMatchmaking.JoinRandomSession(token); - } - } - - - - - - Joins a Session in a random fashion. In order to filter the rooms the player can join, - you can make use of the class and pass custom parameters. - - Session filter parameters - Join Token - - *Example*: + + public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { - - public void Join(string map, int gameType) - { - if (BoltNetwork.IsClient) - { - var token = new TestToken(); + bool forward; + bool backward; + bool left; + bool right; - UdpSessionFilter filter = new UdpSessionFilter(); + public override void Initialized() { + MiniMap.instance.AddKnownPlayer(this.gameObject); + } - filter.FillMode = UdpSessionFillMode.Random; - filter["m"] = map; - filter["t"] = gameType; + public override void Attached() { + state.AddCallback("name", NameChanged); + state.AddCallback("team", TeamChanged); + } - BoltMatchmaking.JoinRandomSession(filter, token); - } - } - - - - - - Temporary re-used list for holding current proxies that need to be frozen. - - - - - Override this method and return true if you want the event listener to keep being attached to Bolt even - when Bolt shuts down and starts again. - - True/False - - *Example:* Configuring the persistence behaviour to keep this listener alive between startup and shutdown. + public override void ControlGained() { + GameCamera.instance.AddFollowTarget(this.transform); + MiniMap.instance.SetControlledPlayer(this.entity); + } - - public override bool PersistBetweenStartupAndShutdown() { - return true; - } - - - - - - Callback triggered before the Bolt simulation starts. - - - *Example:* Logging a message in the console when Bolt is starting. + public override SimulateOwner() { + if(state.health < 100) + { + state.health += state.healthRegen * BoltNetwork.frameDeltaTime; + } + } - - public override void BoltStartBegin() { - BoltLog.Debug("Warning: Bolt is Starting..."); - } - - - - - - Callback triggered after the Bolt simulation starts. - - - *Example:* Logging a message in the console when Bolt is already started. + public override void SimulateController() { + IPlayerCommandInput input = PlayerCommand.Create(); - - public override void BoltStartDone() { - BoltLog.Debug("Warning: Bolt started..."); - } - - - - - - Callback triggered when Bolt was not able to initialize completely. - - - *Example:* Logging a message in the console when Bolt failed to start. + PollKeys(); - - public override void BoltStartFailed() { - BoltLog.Debug("Warning: Bolt failed to start."); - } - - - - - - Callback triggered when the Bolt simulation is shutting down. - - - *Example:* Logging a message in the Bolt console when the server has shut down unexpectedly. - - - public override void BoltShutdown(Bolt.AddCallback registerDoneCallback) { - BoltLog.Warn("Bolt is shutting down"); + input.forward = forward; + input.backward = backward; + input.left = left; + input.right = right; - registerDoneCallback(() => - { - BoltLog.Warn("Bolt is down"); - SceneManager.LoadScene(0); - }); - } - - - - - - Callback triggered when the Bolt simulation is shutting down. - - - *Example:* Logging a message in the Bolt console when the server has shut down unexpectedly. - - - public override void BoltShutdown(Bolt.AddCallback registerDoneCallback, UdpConnectionDisconnectReason disconnectReason = UdpConnectionDisconnectReason.Disconnected) { - BoltLog.Warn("Bolt is shutting down"); + entity.QueueInput(input); + } - registerDoneCallback(() => - { - BoltLog.Warn("Bolt is down"); - SceneManager.LoadScene(0); - }); - } - - - - - - Callback triggered when a client has become connected to this instance - - Endpoint of the connected client - - *Example:* Instantiating and configuring a player entity when a client connects to the server. - - - public override void Connected(BoltConnection connection) { - BoltLog.Info("Accept Token {0} using Connect Token {1}", connection.AcceptToken, connection.ConnectToken); + public override ExecuteCommand(Bolt.Command command, bool resetState) { + if(resetState) { + motor.SetState(cmd.Result.position); + } + else + { + cmd.Result.position = motor.Move(cmd.Input.forward, cmd.Input.backward, command.Input.left, command.Input.right); - var player = BoltNetwork.Instantiate(BoltPrefabs.Player); - player.transform.position = spawnPoint.transform.position; - - var initData = prototype.GetNewPlayer(GameLogic.PlayableClass.Mercenary); - Configure(player, initData); - - player.AssignControl(connection); - } - - + if (cmd.IsFirstExecution) { + AnimatePlayer(cmd); + } + } + } + } + + - + - Callback triggered when a connection to remote server has failed + The entity for this behaviour - The remote address - Connect token sent by the client when trying to connect. + Use the ```entity``` property to access the internal ```BoltEntity``` of the gameObject that this script is attached to. - *Example:* Logging an error message when the remote connection has failed. + *Example:* Passing the ```entity``` of this gameObject to a ```MiniMap```, giving it the position, facing direction and the + entity state (such as team, alive/dead, hostile, etc). - public override void ConnectFailed(UdpEndPoint endpoint, Bolt.IProtocolToken token) { - BoltLog.Info(string.Format("Connection To ({0}:{1}) has failed", endpoint.Address.ToString(), endpoint.ToString())); + public class PlayerController : Bolt.EntityBehaviour { + public override void ControlGained() { + GameCamera.instance.AddFollowTarget(this.transform); + MiniMap.instance.SetControlledPlayer(this.entity); + } } - + - Callback triggered when this instance receives an incoming client connection + Invoked when the entity has been initialized, before Attached - The incoming client endpoint - A data token sent from the incoming client - *Example:* Accepting an incoming connection with user credentials in the data token. + *Example:* Notifying a ```MiniMap``` class to draw this gameObject by overriding the ```Initialized()``` method. - public override void ConnectRequest(UdpEndPoint endpoint, Bolt.IProtocolToken token) { - UserCredentials creds = (UserCredentials)token); - if(Authenticate(creds.username, creds.password)) { - BoltNetwork.Accept(connection.remoteEndPoint); - } + public override void Initialized() { + MiniMap.instance.AddKnownPlayer(this.gameObject); } - + - Callback triggered when the connection to a remote server has been refused. + Invoked when Bolt is aware of this entity and all internal state has been setup - The remote server endpoint - Data token sent by the refusing server - *Example:* Logging an error message when the remote connection has been refused using an error message token from the server. + *Example:* Overriding the ```Attached()``` method to add state change callbacks to the newly valid state. - public override void ConnectRefused(UdpEndPoint endpoint, Bolt.IProtocolToken token) { - ServerMessage.message = (ServerMessage)token; - BoltLog.Info(string.Format("Connection To ({0}:{1}) has been refused. Reason was {3}", - endpoint.Address.ToString(), endpoint.ToString(), serverMessage.errorDescription)); + public override void Attached() { + state.AddCallback("name", NameChanged); + state.AddCallback("team", TeamChanged); } - + - Callback triggered when trying to connect to a remote endpoint + Invoked when this entity is removed from Bolt's awareness - The remote server address - Token passed by the client when trying to connect to a server. - *Example:* Logging a message when initializing a connection to server. + *Example:* Notifying the game minimap to remove the entity upon detaching from the simulation. - public override void ConnectAttempt((UdpEndPoint endpoint) { - BoltLog.Info(string.Format("To Remote Server At ({0}:{1})", endpoint.Address, endpoint.Port); + public override void Detached() { + MiniMap.instance.RemoveKnownPlayer(this.entity); + { + + + + + + Invoked each simulation step on the owner + + + *Example:* Implementing an authoritative health regeneration update every 10th frame. Also fires the + DeathTrigger() on the state if health falls below zero. + + + public override SimulateOwner() { + if(state.alive && state.Health.Current <= 0) { + state.Health.alive = false; + state.DeathTrigger(); + } + else if(state.alive && (BoltNetwork.frame % 10) == 0) + { + state.Health.Current = Mathf.Clamp (state.Health.Current + (state.Health.RegenPer10 * BoltNetwork.frameDeltaTime), + // clamp from 0 to max health + 0, state.Health.Max); + } } - + - Callback triggered when this instance of Bolt loses control of a Bolt entity + Invoked each simulation step on the controller - The controlled entity - *Example:* Setting up game components to no longer control an entity. + *Example:* Creating a simple WASD-style movement input command and adding it to the queue of inputs. One input command + should be added to the queue per execution and remember to create and compile a Command asset before using this method! - public override void ControlOfEntityLost(BoltEntity entity) { - BoltLog.Info("Control lost with Token {0}", entity.ControlLostToken); - GameInput.instance.RemoveControlledEntity(entity); - MiniMap.instance.RemoveControlledEntity(entity); + bool forward; + bool backward; + bool left; + bool right; + + public override void SimulateController() { + IPlayerCommandInput input = PlayerCommand.Create(); + + PollKeys(); + + input.forward = forward; + input.backward = backward; + input.left = left; + input.right = right; + + entity.QueueInput(input); } - + - Callback triggered when this instance of bolt receieves control of a bolt entity + Invoked when you gain control of this entity - The controlled entity - *Example:* Setting up the game minimap and other components to use a specific entity as the player's controlled entity. + *Example:* Using the ```ControlGained()``` callback to set up a ```GameCamera``` and ```MiniMap``` to focus on this entity. - public override void ControlOfEntityGained(BoltEntity entity) { - GameInput.instance.SetControlledEntity(entity); - MiniMap.instance.SetControlledEntity(entity); + public override void ControlGained() { + GameCamera.instance.AddFollowTarget(this.transform); + MiniMap.instance.ControlGained(this.entity); } - + - + - Callback triggered when disconnected from remote server + Invoked when you lost control of this entity - The remote server endpoint - *Example:* Logging a disconnect message and returning to the main menu scene. + *Example:* Using the ```ControlLost()``` callback to remove the focus of a ```GameCamera``` and ```MiniMap```. - public override void Disconnected(BoltConnection connection) { - BoltLog.Info("Disconnected with Token {0}", connection.DisconnectToken); - BoltLog.Info("Returning to main menu..."); - Application.LoadLevel("MainMenu"); + public override void ControlLost() { + GameCamera.instance.RemoveFollowTarget(); + MiniMap.instance.ControlLost(this.entity); } - + - + - Callback triggered when a new entity is attached to the bolt simulation + Invoked on the owner when a remote connection is controlling this entity but we have not received any command for the current simulation frame. - The attached entity + The last valid command received - *Example:* Setting up the game minimap to show a newly attached entity. + *Example:* Handling missing input commands by using the last received input command to continue moving in the same direction. - public override void EntityAttached(BoltEntity entity) { - MiniMap.instance.SetKnownEntity(entity); + public override void MissingCommand(Bolt.Command previous) + { + WASDCommand cmd = (WASDCommand)command; + + cmd.Result.position motor.Move(cmd.Input.forward, cmd.Input.backward, cmd.Input.left, cmd.Input.right); } - + - Callback triggered when a new entity is detached from the bolt simulation + Invoked on both the owner and controller to execute a command - The detached entity + The command to execute + Indicates if we should reset the state of the local motor or not - *Example:* Removing the newly detached entity from the game minimap. + *Example:* Executing a simple WASD movement command. On the client this method can be called multiple times per fixed frame, + beginning with a reset to the last confirmed state (resetState == true), and then again for each unverified input command in the queue (resetState == false); + + Use the cmd.isFirstExecution property to do any type of one-shot behaviour such as playing sound or animations. This will prevent it from being called each time + the input is replayed on the client. + + Remember to create and compile a Command asset before using this method! - public override void EntityDetached(BoltEntity entity) { - MiniMap.instance.RemoveKnownEntity(entity); + public override ExecuteCommand(Bolt.Command command, bool resetState) { + WASDCommand cmd = (WASDCommand)command; + if(resetState) { + motor.SetState(cmd.Result.position); + } + else { + cmd.Result.position = motor.Move(cmd.Input.forward, cmd.Input.backward, cmd.Input.left, cmd.Input.right); + + if (cmd.IsFirstExecution) { + AnimatePlayer(cmd); + } + } } - + - Callback triggered when a bolt entity is recieved from the network + Utility callback used to signal to the user that this entity is about to be reset by a Command Result. + Using this method, you are able to signal Bolt that the Result of the Command is equaled the current state of your + entity, skipping all the recomputation needed when a Reset command arrives. - The recieved bolt entity + The Command with ResetState flag as true for ExecuteCommand callback + True if you want to not recompute everything when local and remote Result match. False otherwise (default always recompute) + + + + Base class for unity behaviours that want to access Bolt methods with the state available also + + The type of state on this BoltEntity - *Example:* Loggging connections from remote players in the client bolt console + *Example:* Using the IPlayerState type as a parameter and using its property state.team in code. - public override void EntityReceived(BoltEntity entity) { - string name = entity.GetState<PlayerState>().Name; - BoltLog.Info(string.Format("{0} Has Connected", name)); + public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { + public override void ControlGained() { + state.AddCallback("team", TeamChanged); + } + + void TeamChanged() { + var nameplate = GetComponent<PlayerNameplate>(); + if (state.team == 0) nameplate.color = Color.Blue; + else nameplate.color = Color.Red; + } } - + - Callback triggered when a bolt entity is frozen. + The state for this behaviours entity - The recieved bolt entity - *Example:* Loggging connections from remote players in the client bolt console + *Example:* Using the ```state``` property to set up state callbacks. - public override void EntityFrozen(BoltEntity entity) { - string name = entity.GetState<PlayerState>().Name; - BoltLog.Info(string.Format("{0} Has been frozen", name)); + public class PlayerController : Bolt.EntityBehaviour<IPlayerState> { + public override void ControlGained() { + state.AddCallback("team", TeamChanged); + } + + void TeamChanged() { + var nameplate = GetComponent<PlayerNameplate>(); + if (state.team == 0) nameplate.color = Color.Blue; + else nameplate.color = Color.Red; + } } - + + + Not really sure why these aren't just pulled from UnityObject when needed? + + + + + This runs the commands received from the Controller of this entity. + + The number of executed commands + + + + Interface for unity behaviours that want to access Bolt methods + + + + + Interface for unity behaviours that want to access Bolt methods + + Bolt state of the entity + + + + Interface for unity behaviours that want to control for each connection an Entity can be replicated to. + + + + + Based on the BoltConnection, signal if this particular Entity must be replicated to it or not. + By default, all entities are replicated to all connections. + + Target BoltConnection to where the entity will be replicated + True to replicate the Entity for this connection, false otherwise + + + + Interface which can be implemented on a behaviour attached to an entity which lets you provide + custom priority calculations for state and events. + + + + + Called for calculating the priority of this entity for the connection passed in + + The connection we are calculating priority for + How many packets since we sent an update for this entity + The priority of the entity + + - Callback triggered when a bolt entity is thawed. + Called for calculating the priority of an event sent to this entity for the connection passed in + + The connection we are calculating priority for + The event we are calculating priority for + The priority of the event + + + + Base class that all events inherit from - The recieved bolt entity - *Example:* Loggging connections from remote players in the client bolt console + *Example:* Using a LogEvent object to send a message. - public override void EntityThawed(BoltEntity entity) { - string name = entity.GetState<PlayerState>().Name; - BoltLog.Info(string.Format("{0} Has been thawed", name)); + void LogMessage(string message) { + var logEvt = new LogEvent(); + logEvt.message = message; + logEvt.Send(); } - + - Callback triggered before the new local scene is loaded. + Returns true if this event was sent from own connection - Name of scene being loaded - *Example:* Showing a splash screen when clients are loading the game scene. + *Example:* Showing chat messages from other players. - public override void SceneLoadLocalBegin(string scene) { - if(BoltNetwork.isClient && scene.Equals(""GameScene"") { - SplashScreen.Show(SplashScreens.GameLoad); + public override void OnEvent(ChatEvent chatEvt) { + if(chatEvt.FromSelf) { + return; } + + ChatWindow.instance.ShowMessage(chatEvt.message, chatEvt.timestamp); } - + - + - Callback triggered before the new local scene is loaded. + The connection which raised this event - Name of scene being loaded - Token passed by the Server when loading the new scene. - *Example:* Showing a splash screen when clients are loading the game scene. + *Example:* Blocking messages from players on a chat restricted list. - public override void SceneLoadLocalBegin(string scene, Bolt.IProtocolToken token) { - if(BoltNetwork.isClient && map.Equals(""GameScene"") { - SplashScreen.Show(SplashScreens.GameLoad); + public override void OnEvent(ChatEvent chatEvt) { + if(chatRestrictedPlayerList.ContainsKey(chatEvt.RaisedBy)) { + return; } + + ChatWindow.instance.ShowMessage(chatEvt.message, chatEvt.timestamp); } - + - Callback triggered after the new local scene has been completely loaded. + Returns true if this is a global event / not an entity event - Name of scene that has loaded - *Example:* Hiding a splash screen that was shown during loading. + *Example:* Using the isGlobal property to determine whether to send local or whole-zone chat. - public override void SceneLoadLocalDone(string scene) { - if(BoltNetwork.isClient && scene.Equals(""GameScene"") { - SplashScreen.Hide(); + public override void OnEvent(ChatEvent chatEvt) { + if(chatEvt.isGlobalEvent) { + BroadcastZoneChat(chatEvt.message, chatEvt.timestamp); } + else { + SendLocalChat(chatEvt.message, chatEvt.timestamp); + } } - + - Callback triggered after the new local scene has been completely loaded. + The raw bytes of the event data - Name of scene that has loaded - Token passed by the Server when loading the new scene. - *Example:* Hiding a splash screen that was shown during loading. + *Example:* Removing repeated chat messages by doing sequence comparison on the raw byte data and filtering out + any repeated messages after a certain limit. - public override void SceneLoadLocalDone(string scene, Bolt.IProtocolToken token) { - if(BoltNetwork.isClient && scene.Equals(""GameScene"") { - SplashScreen.Hide(); + public override void OnEvent(ChatEvent chatEvt) { + bool repeated = true; + + for(int i = 0; i < CHAT_REPEAT_LIMIT; i++) { + if(!chatEvt.BinaryData.SequenceEqual(previousChatEvts.GoBack(i).BinaryData) { + repeated = false; + break; + } } } - + - Callback triggered when a remote connection has completely loaded the current scene + Enqueue this object for sending across the network - The remote connection - *Example:* Instantiating and configuring a player entity on the server and then assigning control to the client. + *Example:* Sending a log message. - public override void SceneLoadRemoteDone(BoltConnection connection) { - var player = BoltNetwork.Instantiate(BoltPrefabs.Player); - player.transform.position = spawnPoint.transform.position; - - var initData = prototype.GetNewPlayer(GameLogic.PlayableClass.Mercenary); - Configure(player, initData); - - player.AssignControl(connection); + void LogMessage(string message) { + var logEvt = new LogEvent(); + logEvt.message = message; + logEvt.Send(); } - + - Callback triggered when a remote connection has completely loaded the current scene + The Event implementation overrides this method to release any pending data that can be pooled, + like IProtocolToken references - The remote connection - Token passed by the Server when loading the new scene. - - *Example:* Instantiating and configuring a player entity on the server and then assigning control to the client. - - - public override void SceneLoadRemoteDone(BoltConnection connection, Bolt.IProtocolToken token) { - var player = BoltNetwork.Instantiate(BoltPrefabs.Player); - player.transform.position = spawnPoint.transform.position; - - var initData = prototype.GetNewPlayer(GameLogic.PlayableClass.Mercenary); - Configure(player, initData); - - player.AssignControl(connection); - } - - - - - Callback triggered when the session list is updated. - - The updated session list - - *Example:* Loggging all sessions from the list. - - - public override void SessionListUpdated(Map<System.Guid, UdpSession> sessionList) { - BoltLog.Info("Session list updated: {0} total sessions", sessionList.Count); - - foreach (var session in sessionList) - { - UdpSession udpSession = session.Value as UdpSession; - BoltLog.Info("UdpSession {0} Source: {1}", udpSession.HostName, udpSession.Source); - } - } - - + + + The reliability mode of an event + - + - Callback triggered when the requested session creation was successful. + The target of an entity event + + + + + The target of a global event + + + + + Called by Bolt to inspect a prefab before instantiating it. The object + returned from this method can be the prefab itself, it does not have + to be a unique instance. + + The id of the prefab we are looking for + A game object representing the prefab or an instance of the prefab + + + + This is called when bolt wants to create a new instance of an entity prefab. + + The id of this prefab + The position we want the instance instantiated at + The rotation we want the instance to take + The newly instantiate object, or null if a prefab with was not found + + + + This is called when Bolt wants to destroy the instance of an entity prefab. + + The instance to destroy + + + + Deault implementation of Bolt.IPrefabPool which uses GameObject.Instantiate and GameObject.Destroy + + + + + Base interface for all states + + + + + The Animator component associated with this entity state + + + + + A collection of all Animator components associated with this entity state + + + + + Set the animator object this state should use for reading/writing mecanim parameters + + The animator object to use + + + + Allows you to hook up a callback to a specific property + + The path of the property + The callback delegate + + + + Allows you to hook up a callback to a specific property + + The path of the property + The callback delegate + + + + Removes a callback from a property + + The path of the property + The callback delegate to remove + + + + Removes a callback from a property + + The path of the property + The callback delegate to remove + + + + Clears all callbacks currently set. This is useful when pooling entities and you wish to clear out the current callbacks before returning the entity to the pool. + + + + + Set a property dynamically by string name + + The property name to set + The property value to set + + + + Gets a property dynamically by string name + + The property name to get + + + + + Enum for Axis Selection + + + + All Axis + + + XY Axis + + + ZX Axis + + + YZ Axis + + + X Axis + + + Y Axis + + + Z Axis + + + Disabled for all Axis + + + + Enum for the Replication Mode + + + + + Enum to select which velocity used to extrapolate the position of the transform + + + + + Enum to select the Smoothing Algorithm + + + + + Enum to select the Transform Space of positioning + + + + + Enum to select the Rotation mode of Quaternions inside a Transform - The created session - - *Example:* Loggging - - - public override void SessionCreated(UdpSession session) - { - BoltLog.Info("UdpSession {0} of type {1} was created", session.HostName, session.Source); - } - - - + - Callback triggered when the requested session creation has failed. + Enum to select the Property Mecanim mode when synchonizing properties - The failed session - - *Example:* Loggging - - - public override void SessionCreationFailed(UdpSession session) - { - BoltLog.Info("UdpSession {0} of type {1} has failed to create", session.HostName, session.Source); - } - - - + - Callback triggered when connecting to a session has successful. + Enum to select the mode where the Animation properties would be read and written - The session the client was trying to connect to - Connection token - - *Example:* Loggging - - - public override void SessionConnected(UdpSession session, IProtocolToken token) - { - BoltLog.Error("Success to connect to session {0} with token {1}", session, token); - } - - - + - Callback triggered when connecting to a session has failed. + Uses the Animator methods to read and write values from the Animator controller - The session the client was trying to connect to - Connection token - - *Example:* Loggging - - - public override void SessionConnectFailed(UdpSession session, IProtocolToken token) - { - BoltLog.Error("Failed to connect to session {0} with token {1}", session, token); - } - - - + - Callback triggered when binary stream data is received. + Uses Bolt property values from state to update the Mecanim properties - The sender connection - The binary stream data - - *Example:* Receiving a custom player icon. - - - public override void StreamDataReceived(BoltConnection connnection, UdpStreamData data) { - Texture2D icon = new Texture2D(4, 4); - icon.LoadImage(data.Data); - - PlayerData playerData = (PlayerData)connection.userToken; - playerData.SetIcon(icon); - } - - - - - Provides logging capabilities to a variety of outputs - - - *Example:* Logging with different status levels. - - - void OwnerOnAttack(BoltEntity player, BoltEntity target) { - if(!target.IsAttached) { - BoltLog.Error("Attempting to target an entity that is not attached: {0}", target.NetworkId); - } - else { - BoltLog.Info("{0} attack on {1}", player.NetworkId, target.NetworkId); - - var playerState = player.GetState<PlayerState>(); - var targetState = target.GetState<PlayerState>(); - - using (var mod = targetState.Modify()) { - mod.HP -= playerState.BaseDamage * playerState.DamageModMultiplier; - } - } - } - - + + + Enum to select the String encoding + - + - The interface providing log writing capabilities to an output + Double buffer class represents a buffer with only 2 values, + swapped when you call @ - + - IWriter implementation that outputs to a file + Shift the specified value into the buffer, while + saving the current value as the previous one + The shift. + Value. - + - IWriter implementation that outputs to the Bolt console + Inits the buffer. + The buffer itself. + Value to set on the both spots on the buffer. - + - IWriter implementation that outputs to the system console out + Contains the indices for all arrays that contain a specific property, in order - + - IWriter implementation that outputs to Unity console + The amount of indices + + + + + Network object. + + + + + Network property describes one property of a State - + The type of random function to use for network latency simulation @@ -2044,7 +1684,7 @@ - + Whether to accept connnections automatically or use the manual process @@ -2065,7 +1705,7 @@ - + The target output of bolt logging @@ -2083,7 +1723,7 @@ - + Bolt configuration settings object @@ -2095,97 +1735,181 @@ - + The number of fixed updates to the simulation per second - + The UDP packet size in bytes - + The max data payload size of a packet - + + + The Stream UDP Packet Size in Byte + + + The max priority value for updating an entity - + The max priority value for updating a property - + Whether to scope connections manually or automatically - + The output targets to write log messages - + Whether dejitter delay buffering is disabled or not - + + + Client Update Send Rate. + Default is every 3 frames + + + + + Interpolation delay on client + + + + + Min interpolation delay on client + + + + + Max interpolation delay on client + + + + + Server Update Send Rate. + + + + + Interpolation delay on server + + + + + Min interpolation delay on server + + + + + Max interpolation delay on server + + + The max number of server connections - + Whether to use automatic or manual mode for accepting incoming client connection requests - + + + Minimum number of command left in the internal buffer in order to dejitter command base behavior + + + + + The max number of input commands that can be queued at once. + + + + + The number of times to redundantly send input commands to the server. + + + + + Whether to use network latency simulation. + + + + + The packet loss rate to use in latency simulation. + + + + + The mean ping in milliseconds to use in latency simulation. + + + - The max number of input commands that can be queued at once + The deviation to use in ping simulation. - + - The number of times to redundantly send input commands to the server + Whether to use Perlin Noise or System.Random function to create ping deviations. - + - Whether to use network latency simulation + Amount of time in milliseconds that the connection will be maintained before being closed by lack of response. - + - The packet loss rate to use in latency simulation + The timeout until a new connect request will be performed. - + - The mean ping in milliseconds to use in latency simulation + The max number of allowed connection attempts by a single client. This value is used to limit the number of + direct connection tries before the connection fails. - + - The deviation to use in ping simulation + The max number of allowed connection attempts by a single client to LAN EndPoint of a Server. + This value is used to limit the number of direct connection tries before the connection fails. - + - Whether to use Perlin Noise or System.Random function to create ping deviations + Override the Local Request Attempts calculation - + - The max number of allowed connection attempts by a single client + Disables the automatic scene loading controlled by Bolt. By setting this value to True, you need to manage + the scene synchronization between server and clients manually. - + + + Enable IPv6 Support. Bolt will use IPv6 addresses on the client and server. + + + Sets the network mode and scenes that a Bolt.GlobalEventListener should be run on @@ -2207,49 +1931,48 @@ - + Sets this behaviour to run only in server or client network mode. - for more info. + for more info. - + A list of scenes for this behaviour to run on. You can use a string with the name of the Scene or use BoltScenes. - + GlobalBehaviour will run both on Server and Client and on all scenes. - + GlobalBehaviour will run on the specified mode and on all scenes. - Select the in which + Select the in which this GlobalBehaviour will execute. - + GlobalBehaviour will run on both Server and Client but only on the specified scenes. You can use BoltScenes to select the available scenes. List of scene names - + GlobalBehaviour will run on the specified mode and only on the specified scenes. - Select the in which + Select the in which this GlobalBehaviour will execute. List of scene names - + - Holds global methods and properties for starting and - stopping bolt, instantiating prefabs and other utils + Global methods and properties to control Photon Bolt. *Example:* How to load a map on the server and instantiate a server controlled player. @@ -2282,7 +2005,7 @@ - + All the connections connected to this host @@ -2298,7 +2021,7 @@ - + All clients connected to this host @@ -2314,22 +2037,22 @@ - + Gets the current async operation. The current async operation. - + - The current server simulation frame number + Returns an IEnumerable list of all Bolt Entities currently loaded into the scene *Example:* A post-game method to destroy all minions/npcs in the server simulation. void PostGameCleanup() { - foreach(var entity in BoltNetwork.entities) { + foreach(var entity in BoltNetwork.Entities) { if(entity.IsOwner && entity.StateIs<MinionState>) { BoltNetwork.Destroy(entity); } @@ -2338,7 +2061,7 @@ - + The current local simulation frame number @@ -2354,17 +2077,17 @@ - + Normalized value of how much time have passed since the last FixedUpdate - + The time the last fixed update begain, same as Time.fixedTime - + The fixed frame delta, same as Time.fixedDeltaTime @@ -2376,12 +2099,12 @@ protected override void SimulateOwner() { float hpRegen = BoltNetwork.frameDeltaTime * state.HealthRegen; - state.Modify().HP = Mathf.Clamp(state.HP + hpRegen, 0, 100); + state.HP = Mathf.Clamp(state.HP + hpRegen, 0, 100); } - + How many FixedUpdate frames per second bolt is configured to run @@ -2395,7 +2118,7 @@ - + The global object that all global behaviours will be attached to @@ -2412,7 +2135,7 @@ - + Returns true if this instance is a server or a client with at least one valid connection. @@ -2429,7 +2152,7 @@ - + Returns true if this host is a client @@ -2445,7 +2168,7 @@ - + Returns true if Bolt was compiled in debug mode @@ -2462,9 +2185,9 @@ - + - If bolt is running + Signal if Bolt is running. *Example:* How to use the ```isRunning``` property to detect a downtime and restart the server. @@ -2479,7 +2202,7 @@ - + Returns true if this host is a server @@ -2499,13 +2222,13 @@ - + Returns true if this host is running in single player mode. true if is single player; otherwise, false. - + The max number of client connections to the server @@ -2524,7 +2247,7 @@ - + A list of all BoltEntities in the server simulation @@ -2546,12 +2269,12 @@ - + The scoping mode active - + The server connection @@ -2566,7 +2289,7 @@ - + On the server this returns the local frame, on a client this returns the currently estimated frame of all server objects we have received @@ -2577,14 +2300,14 @@ void ClientFireWeapon(PlayerCommand cmd) { if(weapon.nextFireFrame <= BoltNEtwork.serverFrame) { - state.Modify().FireTrigger(); + state.FireTrigger(); weapon.nextFireFrame = BoltNetwork.serverFrame + weapon.refireRate; } } - + The current server simulation time @@ -2601,13 +2324,13 @@ - + Gets the list of UdpSession received by the system. The session list. - + The local time, same as Time.time @@ -2624,51 +2347,56 @@ - + Gets the current UDP socket. The UDP socket. - + The current Photon Bolt assembly version number. - + Gets the current Bolt version as string. - + + + Extra info of the Current Bolt version. + + + Gets the Bolt Version description. The Bolt Version description. - + Manually add a global event listener The monobehaviour to invoke events on - + Manually add a global event callback - + Manually remove a global event listener The monobehaviour to be removed - + Manually remove a global event callback - + Enable LAN broadcasting @@ -2685,7 +2413,7 @@ - + Disable LAN broadcasting @@ -2702,7 +2430,7 @@ - + Registers a type as a potential protocol token @@ -2718,7 +2446,7 @@ - + Sets bolt to use a filter to accept or reject certain events based on custom filtering @@ -2744,7 +2472,7 @@ - + Sets the simulated network loss/ping settings for this peer. @@ -2752,18 +2480,26 @@ Simulated minimum ping Simulated max ping - + Updates the session list from an external source New sessions list. - + Updates the scene objects for fast lookup. - + + + Looks at the BoltConnection list for a specific connection reference based on its ID. + + Connection ID to check + Reference to a BoltConnection if the ID is valid + True if a BoltConnection was found + + Signal bolt to accept an incoming client connection request @@ -2778,7 +2514,7 @@ - + Signal bolt to accept an incoming client connection request @@ -2797,29 +2533,12 @@ - - - Connect to a server using a session description - - Session description sent by the server - Optional Token used when connecting to server, this can be the client credentials - - *Example:* A method to connect to any server ip and port as a client. - - - void Connect(UdpSession session) { - Credentials cred = new Credentials("DevUser01", "DevPassword"); - - BoltNetwork.Connect(session, cred); - } - - - - + - Connect to a server using a session description + Connect to a server running on a specific port. This game server must be running on the local machine. Connect to a local server using its port + Optional Token used when connecting to server, this can be the client credentials *Example:* A method to connect to any server using only its port as a client. @@ -2830,7 +2549,7 @@ - + Creating a new binary streaming channel @@ -2852,7 +2571,7 @@ - + Load a scene based on name, only possible on the Server @@ -2867,7 +2586,7 @@ - + Load a scene based on name, only possible on the Server @@ -2884,7 +2603,15 @@ - + + + Updates the internal loaded scene information. + This is useful if Bolt is *not* used to manage Scenes and this is done externally by the developer. + If the active Scene was changed, this must be invoked in order to signal that the internal data must + be updated. + + + Use this method to sync the local scene on the Client with the remote scene from the Server. This method can only be invoked on the Client and it's only useful if you have the Auto Scene Load disabled. @@ -2911,7 +2638,7 @@ - + Signal bolt to refuse an incoming connection request @@ -2926,7 +2653,7 @@ - + Signal bolt to refuse an incoming connection request @@ -2944,42 +2671,17 @@ - - - Set Session information - - Name of the server - User definable data - - *Example:* Setting the server info to contain the max number of connections allowed by this server. - - - void SetSessionData(string serverName, string description, int maxPlayers) { - SessionData sessionData = new SessionData(description, BoltNetwork.maxConnections); - - BoltNetwork.SetServerInfo(serverName, sessionData); - } - - - - - - Set Session information on a dedicated server. - - Server name. - Token. - - + Shutdown this instance. - + Shutdowns Bolt Immediately. - + Perform a hitbox rewind to get transform position at a given frame. @@ -3000,7 +2702,7 @@ - + Perform a raycast against Bolt hitboxes @@ -3017,7 +2719,7 @@ var targetEntity = hit.body.GetComponent<BoltEntity>(); if(targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; } } } @@ -3025,7 +2727,7 @@ - + Perform a raycast against Bolt hitboxes @@ -3044,7 +2746,7 @@ var targetEntity = hit.body.GetComponent<BoltEntity>(); if(targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= activeWeapon.damage; + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; } } } @@ -3052,7 +2754,7 @@ - + Perform a sphere overlap against Bolt hitboxes @@ -3071,7 +2773,7 @@ var targetEntity = hit.body.GetComponent<BoltEntity>(); if (targetEntity != entity && targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= grenade.damage; + targetEntity.GetState<ILivingEntity>().HP -= grenade.damage; } } } @@ -3080,7 +2782,7 @@ - + Perform a sphere overlap against Bolt hitboxes @@ -3100,7 +2802,7 @@ var targetEntity = hit.body.GetComponent<BoltEntity>(); if (targetEntity != entity && targetEntity.StateIs<ILivingEntity>()) { - targetEntity.GetState<ILivingEntity>().Modify().HP -= grenade.damage; + targetEntity.GetState<ILivingEntity>().HP -= grenade.damage; } } } @@ -3109,14 +2811,14 @@ - + Manually attach an Entity. Game object. The Entity to attach. - + Manually attach an Entity. @@ -3124,20 +2826,20 @@ Token. The attach. - + Manually detach an Entity. Game object. - + Manually detach an Entity. Game object. Token. - + Remove a gameObject from the bolt simulation. @@ -3156,7 +2858,7 @@ - + Remove a gameObject from the bolt simulation. @@ -3178,7 +2880,7 @@ - + Find an entity based on unique id @@ -3198,7 +2900,7 @@ - + Create a new entity in the simuation from a prefab @@ -3223,7 +2925,7 @@ - + Create a new entity in the simuation from a prefab @@ -3244,7 +2946,7 @@ - + Create a new entity in the simuation from a prefab @@ -3270,7 +2972,7 @@ - + Create a new entity in the simuation from a prefab @@ -3294,7 +2996,7 @@ - + Create a new entity in the simuation from a prefab @@ -3313,7 +3015,7 @@ - + Create a new entity in the simuation from a prefab @@ -3333,7 +3035,7 @@ - + Create a new entity in the simuation from a prefab @@ -3356,7 +3058,7 @@ - + Create a new entity in the simuation from a prefab @@ -3379,7 +3081,7 @@ - + Async load Bolt Entity prefabs @@ -3394,7 +3096,7 @@ - + Sets a custom implementation for pooling prefabs @@ -3409,7 +3111,7 @@ - + Whether the local simulation can receive entities instantiated from other connections @@ -3425,58 +3127,113 @@ - + - Base class for monobehaviours that can be accessed as a singleton. The singleton is instantiated from the resources folder and should have the same name as the class type. + Responsible by registering snapshots of the world hitboxes and perform lag compensated physics checks + like Raycasts and Sphere Overlap - The name of the type and name of the prefab inside resources folder - - *Example:* Using as a base class for PlayerCamera script. - - - public class PlayerCamera : BoltSingletonPrefab<PlayerCamera> { - Transform _target; - - public new Camera camera { - get { return _camera; } - } - } - - - + - Returns the singleton instance of this type + Max number of past snapshots to store - - *Example:* Using the player camera singleton - - - public override void ControlOfEntityGained(BoltEntity entity { - PlayerCamera.instance.SetTarget(entity); - } - - - + - Create an instance of the singleton prefab + List of all active in the scene - - *Example:* Instantiate a player camera and game hud instance when the local scene is loaded. These will be cloned from - from prefabs inside a Resources folder that have the same name as the type ("PlayerCamera" and "GameHUD"). - - - public override void SceneLoadLocalDone(string map) { - if(map.Equals("Game")) { - GameHUD.Instantiate(); - PlayerCamera.Instantiate(); - } - } - - - + + + List of all world snapshots stored on the memory, used to run the physics checks + + + + + Register a new in the list of active hitboxes + + BoltHitBoxBody to be registered + + + + Removes a from the list of active hitboxes + + BoltHitBoxBody to be removed + + + + Creates and store a new snapshot of all active + + + + + Draws all stored snapshots for debugging purpose + + + + + Return the position of a at a certain frame in the past + + BoltHitboxBody to check the position + Frame when you want to check the position + Vetor3 with the position of the hitbox at the specified frame + + + + Return the position of a at a certain World Snapshot + + BoltHitboxBody to check the position + World snapshot when you want to check the position + Vetor3 with the position of the hitbox at the specified snapshot + + + + Perform a Raycast check against all stored in a certain frame in the past + If any of the hitboxes are hit by the raycast, it's returned as a . + + Raycast to perform the collision check + Frame from where to run the check + with all the hit information + + + + Perform a Raycast check against all stored in a certain World Snapshot + If any of the hitboxes are hit by the raycast, it's returned as a . + + Raycast to perform the collision check + World snapshot when you want to check the position + with all the hit information + + + + Perform a Sphere Overlap agains all in a certain frame in the past. + If any of the hitboxes are hit by the sphere, it's returned as a . + + Sphere origin + Sphere radius + Frame from where to run the check + with all the hit information + + + + Perform a Sphere Overlap agains all in a certain World Snapshot. + If any of the hitboxes are hit by the sphere, it's returned as a . + + Sphere origin + Sphere radius + World snapshot when you want to check the position + with all the hit information + + + + Search for a World Snapshot for a specific frame + If not found, return the last one if there is one + + Frame to look for a snapshot + World Snapshot found + True if a Snapshot was found, false otherwise + + Defines one hitbox on a BoltHitboxBody @@ -3495,7 +3252,32 @@ - + + + BoltHitBox Shape + + + + + BoltHitBox Type + + + + + BoltHitBox center position + + + + + BoltHitBox box size + + + + + BoltHitBox sphere radius + + + Shape of the hitbox (box or sphere) @@ -3514,7 +3296,7 @@ /// - + Type of the hitbox @@ -3535,7 +3317,7 @@ - + Center of the hitbox in local coordinates @@ -3558,7 +3340,7 @@ - + Size of the hitbox if this shape is a box @@ -3576,7 +3358,7 @@ - + Type of the hitbox @@ -3594,46 +3376,456 @@ - + + + Check overlap between Sphere and this HitBox + + Transformation matrix of HitBox from World to Local frame + + + True if sphere overlaps this HitBox + + + + Check Ray against HitBox + + Transformation matrix of HitBox from World to Local frame + HitBox scale + Ray origin + Ray direction + Hit distance + True if ray hits this HitBox + + + + Check overlap of sphere against sphere HitBox + + Sphere center + Sphere radius + True if overlap + + + + Check overlap of sphere against box HitBox + + Sphere center + Sphere radius + True if overlap + + + + Check Hit of Ray agains Sphere + + Ray origin + Ray direction + Sphere scale + Hit distance + True if ray hits the sphere, false otherwise + + + + Clamp the input vector values based on min and max vectors + + Vector to be campled + Min vector value + Max vector value + Clamped vector result + + + + Draw the Hit Box prepresentation as a gizmo to help visualize it + + + + + + Create a new Snapshot of the BoltHitboxBody + + BoltHitboxBody used to create the new Snapshot + New BoltHitboxBodySnapshot of the BoltHitboxBody + + + + Save a snapshot of the BoltHitboxBody + + BoltHitboxBody used as reference to store the snapshot + + + + Dispose this BoltHitboxBodySnapshot and return to Pool + + + + + Get the position of the HitBoxBody + + Position of the internal HitBoxBody + + + + Executes an Sphere Overlap agaist this HitBoxBody + + Sphere center + Sphere raius + List of hits + + + + Check Hit against HitBoxBody + + Ray origin + Ray direction + List of hits + + + + Create a Transformation Matrix based on the Transform from Local to World Position + + Base Transform used to create the Transformation Matrix + Transformation Matrix + + + + Create a Transformation Matrix based on the Transform from World to Local Position + + Base Transform used to create the Transformation Matrix + Transformation Matrix + + + + Draw the Snapshot on the screen using Gizmos for debbuging purposes. + + + + + What type of shape to use in a bolt hitbox + + + *Example:* Sorting the hitboxes in a body based on shape. + + + void ConfigureHitboxes(BoltHitboxBody body) { + foreach(BoltHitbox hitbox in body.hitboxes) { + switch(hitbox.hitboxShape) { + case BoltHitboxShape.Sphere: ConfigureSphere(hitbox); break; + case BoltHitboxShape.Box: ConfigureBox(hitbox); break; + } + } + } + + + + + + Defines a body of hitboxes to be tracked + + + *Example:* Adding a hitbox body to a character pre-configured with BoltHitbox components + + + void AddHitboxBody(BoltEntity entity) { + BoltHitbox[] hitboxes = entity.GetComponentsInChildren<BoltHitbox>(); + + BoltHitboxBody body = entity.AddComponent<BoltHitboxBody>(); + body.hitboxes = hitboxes; + } + + + + + + Signal if the Snapshot history of this HitboxBody must be shown + + + + + BoltHitbox used for Proximity checks + + + + + List of BoltHitbox from this Body + + + + + A hitbox which should contain all other hitboxes on this entity + + + + + An array of hitbox components that compose this body + + + *Example:* Finding all hitbox components on an entity and adding them to a hitbox body + + + void AddHitboxBody(BoltEntity entity) { + BoltHitbox[] hitboxes = entity.gameObject.GetComponentsInChildren<BoltHitbox>(); + + BoltHitboxBody body = entity.AddComponent<BoltHitboxBody>(); + body.hitboxes = hitboxes; + } + + + + + + The body area represented by a bolt hitbox + + + *Example:* Modifying a base damage value depending on the area of the hit. + + + float CalculateDamage(BoltHitbox hit, float baseDamage) { + switch(hit.hitboxType) { + case BoltHitboxType.Head: return 2.0f * baseDamage; + + case BoltHitboxType.Leg: + case BoltHitboxType.UpperArm: return 0.7f * baseDamage; + + default: return baseDamage; + } + } + + + + + + Create a new snapshot of the BoltHitboxBody and store internally + + BoltHitboxBody reference + + + + Dispose this Snapshot and return to Pool + + + + + Container for a group of BoltPhysicsHits + + + *Example:* Using ```BoltNetwork.RaycastAll()``` to detect hit events and processing the BoltPhysicsHits object that is returned. + + + void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { + if(entity.IsOwner) { + using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), + cmd.ServerFrame)) { + var hit = hits.GetHit(0); + var targetEntity = hit.body.GetComponent<BoltEntity>(); + + if(targetEntity.StateIs<ILivingEntity>()) { + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; + } + } + } + } + + + + + + How many hits we have in the collection + + + *Example:* Using the hit count to iterate through all hits + + void OnOwner(PlayerCommand cmd, BoltEntity entity) + { + if (entity.IsOwner) + { + using (BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), cmd.ServerFrame)) + { + for (int i = 0; i < hits.count; ++i) + { + var hit = hits.GetHit(i); + var targetEntity = hit.body.GetComponent<BoltEntity>(); + + if (targetEntity.StateIs<ILivingEntity>()) + { + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; + } + } + } + } + } + + + + + + Array indexing of the hits in this object + + Index position + The BoltPhysicsHit at the given index + + *Example:* Using the array indexing to get the first object hit by a weapon firing raycast. + + + void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { + if(entity.IsOwner) { + using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), + cmd.ServerFrame))0 { + + if(hit.count > 0) { + var hit = hits[0]; + var targetEntity = hit.body.GetComponent<BoltEntity>(); + + if(targetEntity.StateIs<ILivingEntity>()) { + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; + } + } + } + } + } + + + + + + Get the hit at a specific index + + Index position + The BoltPhysicsHit at the given index + + *Example:* Using the GetHit method to find the first object hit by a weapon firing raycast. + + + void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { + if(entity.IsOwner) { + using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), + cmd.ServerFrame))0 { + + if(hit.count > 0) { + var hit = hits.GetHit(0); + var targetEntity = hit.body.GetComponent<BoltEntity>(); + + if(targetEntity.StateIs<ILivingEntity>()) { + targetEntity.GetState<ILivingEntity>().HP -= activeWeapon.damage; + } + } + } + } + } + + + + - Defines a body of hitboxes to be tracked + Implementing the IDisposable interface to allow "using" syntax. - *Example:* Adding a hitbox body to a character pre-configured with BoltHitbox components + *Example:* Implementing the Disponse() method allows BoltPhysicsHits to be in a "using" block. - void AddHitboxBody(BoltEntity entity) { - BoltHitbox[] hitboxes = entity.GetComponentsInChildren<BoltHitbox>(); - - BoltHitboxBody body = entity.AddComponent<BoltHitboxBody>(); - body.hitboxes = hitboxes; + void DoRaycast(Ray ray) { + using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(ray)) { + // the hits variable will be automatically disposed at the end of this block + } } - + - A hitbox which should contain all other hitboxes on this entity + Includes a new hit information in the list of Hits. + BoltHitboxBody of the entity that received the hit + BoltHitbox where the entity received the hit + Hit distance - + - An array of hitbox components that compose this body + Describes a hit to a BoltHitbox on a BoltHitboxBody - *Example:* Finding all hitbox components on an entity and adding them to a hitbox body + *Example:* Logging the details of a BoltPhysicsHit object. - void AddHitboxBody(BoltEntity entity) { - BoltHitbox[] hitboxes = entity.gameObject.GetComponentsInChildren<BoltHitbox>(); + void FireWeaponOwner(PlayerCommand cmd, BoltEntity entity) { + if(entity.IsOwner) { + using(BoltPhysicsHits hits = BoltNetwork.RaycastAll(new Ray(entity.transform.position, cmd.Input.targetPos), + cmd.ServerFrame))0 { - BoltHitboxBody body = entity.AddComponent<BoltHitboxBody>(); - body.hitboxes = hitboxes; + if(hit.count > 0) { + BoltPhysicsHit hit = hits.GetHit(0); + Debug.Log(string.Format("[HIT] Target={0}, Distance={1}, HitArea={2}", hit.body.gameObject.name, hit.distance, hit.hitbox.hitboxType); + } + } + } } - + + + The distance away from the origin of the ray + + + + + Which hitbox was hit + + + + + The body which was hit + + + + + Base class for monobehaviours that can be accessed as a singleton. The singleton is instantiated from the resources folder and should have the same name as the class type. + + The name of the type and name of the prefab inside resources folder + + *Example:* Using as a base class for PlayerCamera script. + + + public class PlayerCamera : BoltSingletonPrefab<PlayerCamera> { + Transform _target; + + public new Camera camera { + get { return _camera; } + } + } + + + + + + Returns the singleton instance of this type + + + *Example:* Using the player camera singleton + + + public override void ControlOfEntityGained(BoltEntity entity { + PlayerCamera.instance.SetTarget(entity); + } + + + + + + Create an instance of the singleton prefab + + + *Example:* Instantiate a player camera and game hud instance when the local scene is loaded. These will be cloned from + from prefabs inside a Resources folder that have the same name as the type ("PlayerCamera" and "GameHUD"). + + + public override void SceneLoadLocalDone(string map) { + if(map.Equals("Game")) { + GameHUD.Instantiate(); + PlayerCamera.Instantiate(); + } + } + + + + The connection to a remote endpoint @@ -3647,7 +3839,7 @@ - + Returns true if the remote computer on the other end of this connection is loading a map currently, otherwise false @@ -3663,7 +3855,7 @@ - + The estimated frame of the simulation running at the other end of this connection @@ -3685,7 +3877,21 @@ - + + + The ConnectToken contains the token sent by the client when connecting to a game server. + When you call BoltNetwork.Connect, BoltMatchmaking.JoinSession or BoltMatchmaking.JoinRandomSession with a Token, + it can be accessed via this property + + + + + The DisconnectToken contains the token used when a Connection is shutdown, either by the remote client or by the + game server. + When calling BoltConnection.Disconnect with a Token, it can be accessed via this property. + + + A data token that was passed by the server when accepting the connection @@ -3701,7 +3907,7 @@ - + The round-trip time on the network @@ -3717,7 +3923,7 @@ - + The dejitter delay in number of frames @@ -3734,7 +3940,7 @@ - + The round-trip time across the network, including processing delays and acks @@ -3751,7 +3957,7 @@ - + How many bits per second we are receiving in @@ -3769,7 +3975,7 @@ - + How many bits per second we are sending out @@ -3787,22 +3993,22 @@ - + How many packets were received by this connection - + How many packets were sent to this connection - + How many packets were registered as lost packets - + For the host this will be the ID of the client, an on the client it will show the ID of the client @@ -3826,7 +4032,7 @@ - + Remote end point of this connection @@ -3840,7 +4046,7 @@ - + User assignable object which lets you pair arbitrary data with the connection @@ -3854,7 +4060,7 @@ - + Send a binary stream of data to this connection @@ -3873,7 +4079,7 @@ - + Set the max amount of data allowed per second @@ -3888,20 +4094,20 @@ - + Sends the data. Data. - + Receives the data. true, if data was received, false otherwise. Data. - + Disconnect this connection @@ -3917,7 +4123,7 @@ - + Disconnect this connection with custom data @@ -3937,7 +4143,7 @@ - + Reference comparison between two connections @@ -3948,12 +4154,12 @@ } - + A hash code for this connection - + The string representation of this connection @@ -3967,59 +4173,9 @@ - - - The in-game console window - - - *Example:* Writing a custom message to the console. - - - void Start() { - BoltConsole.Write("[Start:" + this.gameObject.name + "]); - } - - - - - - Write one line to the console - - Text to write - Color of the text - - *Example:* Writing a custom message to the console in color. - - - void OnDeath() { - BoltConsole.Write("[Death:" + this.gameObject.name + "], Color.Red); - } - - - - - - Write one line to the console - - Text to write - - *Example:* Writing a custom message to the console. - - - void OnSpawn() { - BoltConsole.Write("[Spawn:" + this.gameObject.name + "]); - } - - - - - - Base class for all bolt specific exceptions - - - + - The runtime settings and confugration for the current bolt simulation + The Runtime Settings and Confugration for the current Bolt simulation *Example:* Using the settings instance to get a copy of the server config. @@ -4029,7 +4185,7 @@ } - + A singleton static instance of the runtime settings @@ -4043,55 +4199,153 @@ } - + The number of clients to start when launching a debug mode server - + The default debug start port - + + + Describe how the Debug Start will build the Standalone instances + + + The scene to load after initializing bolt - + Whether to play as a server or not - + Whether to show debug info or not - + Whether to show debug info or not - + - Whether to log uncaught exceptions + Editor mode when running using Debug Start - + The keycode that will toggle visibility of the bolt console - + Whether the bolt console is initially visible or not - - Photon stuff + + + Warning Level when building the Debug Start standalone clients + + + + + Flag to signal if Warning of Manual Scoping should be hidden + + + + + Show Help Hints on Bolt Entities + + + + + Serialize project as Text or Binary + + @deprecated + + + + Photon Application ID + + + + + Enable NAT Punchthrough + + + + + Photon Region List + + + + + Photon Region Code List + + + + + Current Selected Photon Region + + + + + Bolt Entity Prefabs Instantiation Mode + + + + + Entity Behaviour Query Option + + + + + Entity PriorityCalculator Query Option + + + + + Entity ReplicationFilter Query Option + + + + + A2S Server Port + + + + + Enable A2S Server + + + + + Timeout for Photon Sessions Creation + + + + + Timeout to Join a Photon Session + + + + + Enable the Client Connection metrics + + + + + Enable Bolt integration with Source Providers, such as Perforce + - + Get a memberwise copy of the current bolt config @@ -4110,41 +4364,57 @@ - - - Bolt behaviour to poll the network and step entities in the simulation - - - *Example:* if bolt is missing the ```BoltPoll`` behaviour then the simulation is broken and we should shut down. - - - void CheckBoltHealth() { - if(BoltNetwork.globalObject.GetComponent<BoltPoll>() == null) { - Debug.Log("BoltPoll is missing!); - GameApplication.Shutdown(ErrorCode.Bolt); - } - } - - + + + Utility base class for some common functionality inside of Bolt + - - - - - - *Example:* if bolt is missing the ```BoltSend`` behaviour then the simulation is broken and we should shut down. - - - void CheckBoltHealth() { - if(BoltNetwork.globalObject.GetComponent<BoltSend>() == null) { - Debug.Log("BoltSend is missing!); - GameApplication.Shutdown(ErrorCode.Bolt); - } - } - - + + + Don't query anything. + + + + + Query for a single component + + + + + Query for all components on this entity + + + + + Query for all components on this entity and children. + + + + + Use global options + + + + + Dont query anything + + + + + Query for a single component + + + + + Query for all components on this entity + + + + + Query for all components on this entity and children. + - + Modifier for bolt entity settings before it's attached @@ -4161,7 +4431,7 @@ mod.clientPredicted = false; mod.prefabId = prefabId; mod.updateRate = 1; - mod.sceneId = Bolt.UniqueId.None; + mod.sceneId = Photon.Bolt.UniqueId.None; mod.serializerId = state; } @@ -4170,59 +4440,59 @@ - + The prefab identifier - + A unique identifier present on scene entities - + A unique identifier of this entity state serializer - + The network update rate for this entity - + The network update rate for this entity - + Enable or disable client prediction on the entity - + Enable or disable instantiation of the entity by clients - + Whether the entity is persistence between scenes - + True if bolt should automatically attach the entity during instantiation - + True if this entity is always owned by the server - + - A game entity within the bolt simulation + A Game Entity within the Bolt simulation. *Example:* Instantiating and taking control of a new BoltEntity that will replicate to all connected clients. @@ -4236,7 +4506,7 @@ - + The prefabId used to instantiate this entity @@ -4250,7 +4520,7 @@ - + If this entity was created on another computer, contains the connection we received this entity from, otherwise null @@ -4264,12 +4534,12 @@ - + The unique id of this entity - + Whether the entity can be paused / frozen @@ -4287,7 +4557,7 @@ - + If this entity is controlled by a remote connection it contains that connection, otherwise null @@ -4303,7 +4573,7 @@ - + If this entity is attached to Bolt or not @@ -4313,12 +4583,12 @@ void DealDamage(BoltEntity entity, AttackData atkData) { if(entity.IsAttached) { - entity.GetState<ILivingEntity>().Modify().hp -= atkData.damage; + entity.GetState<ILivingEntity>().hp -= atkData.damage; } } - + If this entity is currently paused @@ -4336,7 +4606,7 @@ - + This is a scene object placed in the scene in the Unity editor @@ -4359,7 +4629,7 @@ - + Did the local computer create this entity or not? @@ -4381,7 +4651,7 @@ - + Do we have control of this entity? @@ -4399,12 +4669,12 @@ - + Do we have control of this entity and are we using client side prediction - + Should this entity persist between scene loads @@ -4422,25 +4692,25 @@ - + Gets a value indicating whether this has parent. true if has parent; otherwise, false. - + Gets a value indicating whether this has its input queue full. true if is input queue full; otherwise, false. - + Creates an object which lets you modify the internal settings of an entity before it is attached to Bolt. The object used to modify entity settings - + Sets the scope of all currently active connections for this entity. Only usable if Scope Mode has been set to Manual. @@ -4456,7 +4726,7 @@ - + Sets the scope for the connection passed in for this entity. Only usable if Scope Mode has been set to Manual. @@ -4489,7 +4759,7 @@ - + Sets the parent of this entity @@ -4508,7 +4778,7 @@ - + Takes local control of this entity @@ -4524,7 +4794,7 @@ - + Takes local control of this entity @@ -4543,7 +4813,7 @@ - + Releases local control of this entity @@ -4560,7 +4830,7 @@ - + Releases local control of this entity @@ -4581,7 +4851,7 @@ - + Assigns control of this entity to a connection @@ -4598,7 +4868,7 @@ - + Assigns control of this entity to a connection @@ -4624,7 +4894,7 @@ - + Revokes control of this entity from a connection @@ -4635,17 +4905,17 @@ IEnumerator Stun(BoltEntity entity, float stunInterval) { var controller = entity.Controller; entity.RevokeControl(); - entity.GetState<ILivingEntity>().Modify().stunned = true; + entity.GetState<ILivingEntity>().stunned = true; return new WaitForSeconds(stunInterval); entity.AssignControl(controller); - entity.GetState<ILivingEntity>().Modify().stunned = false; + entity.GetState<ILivingEntity>().stunned = false; } - + Revokes control of this entity from a connection @@ -4660,23 +4930,23 @@ evtData.stunInterval = stunInterval; entity.RevokeControl(evtData); - entity.GetState<ILivingEntity>().Modify().stunned = true; + entity.GetState<ILivingEntity>().stunned = true; return new WaitForSeconds(stunInterval); entity.AssignControl(controller); - entity.GetState<ILivingEntity>().Modify().stunned = false; + entity.GetState<ILivingEntity>().stunned = false; } - + Checks if this entity is being controlled by the connection The connection to check - + Queue an input data on this entity for execution. This is called on a client which is controlling a proxied entity. The data will be sent to the server for authoritative execution @@ -4707,7 +4977,7 @@ - + Set this entity as idle on the supplied connection, this means that the connection will not receive update state for this entity as long as it's idle. @@ -4715,7 +4985,7 @@ The connection to idle the entity on If this should be idle or not - + Freeze or unfreeze an entity @@ -4734,29 +5004,29 @@ - + Add an event listener to this entity. The behaviour to invoke event callbacks on - + Add a event callback to this entity. - + Remove an event listern from this entity The behaviour to remove - + Remove a event callback to this entity. - + Get the state if this entity @@ -4767,12 +5037,12 @@ public void RenameEntity(BoltEntity entity, string name) { - entity.GetState<IPlayerState>().Modify().name = name; + entity.GetState<IPlayerState>().name = name; } - + A null safe way to look for a specific type of state on an entity @@ -4788,14 +5058,14 @@ if(entity.TryGetState<IPlayerState>(out state)) { entity.Freeze(true); - state.Modify().pausedByServer = true; + state.pausedByServer = true; } } } - + Checks which type of state this entity has @@ -4811,13 +5081,13 @@ return; } - target.GetState<ILivingEntity>().Modify().health -= attack.damage; + target.GetState<ILivingEntity>().health -= attack.damage; } } - + Checks which type of state this entity has @@ -4833,13 +5103,13 @@ return; } - target.GetState<ILivingEntity>().Modify().health -= attack.damage; + target.GetState<ILivingEntity>().health -= attack.damage; } } - + String representation of the entity @@ -4853,7 +5123,7 @@ - + Destroy this entity after a given delay @@ -4865,46 +5135,185 @@ void OnDeath(BoltEntity entity) { var state = entity.GetState<ILivingEntity>(); - state.Modify().alive = false; - state.Modify().DeathTrigger(); + state.alive = false; + state.DeathTrigger(); entity.DestroyDelayed(ServerConfig.DESTRUCT_DELAY); } - + + + Whether a NAT port mapping is open or closed + + + + + This class is responsible to initialize the Photon Cloud system + in order to always mantain the player connected to the cloud services + and take care of the CCU count. + + + + + Adds the room property. + + true, if room property was added, false otherwise. + Propety Key. + Property Value. + If set to true show this property on the Lobby too, + so the client can see the properties before entering the room. + + + + Removes the room property. + + true, if room property was removed, false otherwise. + Property Key. + + + + Generic Bolt exception. + + + + + Thrown if a debug assert fails somewhere in the code + + + + + Bolt package overflow exception. + + + + + Fail automatically with the specified message. + + Message. + + + + Test if both A and B are not null and are the same, or raise a exception otherwise. + + The A component. + The B component. + Error message. + + + + Raises the Generic Exception Type if the condition is not False, passing the extraInfo object. + + Condition to test as False. + Extra info passed to the BoltException instance. + A derivative type. + + + + Raises the Generic Exception Type if the condition is not True, passing the extraInfo object. + + Condition to test as True. + Extra info passed to the BoltException instance. + A derivative type. + + + + Use this Attribute on classes that implmement IProtocolToken in order to ignore them + on the Prototol Token Registry + + + + + Protocol Token Registry contains a list of all IProtocolTokens in the project + and it's consulted to register all Tokens when Bolt is starting up. + This can be used to grant that tokens will be properly registered, in the same order, on all peers + + + + + Stores the information about the IProtocolTokens types + Both a simple name, to be shown at the listing and logs + and a full assembly name, used to load the type from the Assemblies. + + + + + Returns the instance for the current BoltProtocolTokenRegistry + + + + + Internal reference to the BoltProtocolTokenRegistry + + + + + List of IProtocolToken types based on the TokenRegistry struct + + + + + NetworkValue describes one set of values that can be networked + + + + + Interval between publish count information + + + + + Remote Server + + + + + Sends the report count to the Server + + + + + + Create the HTTP request and send JSON data to remote server + + Server URL. + App identifier. + License key. + Total players in the Game. + + Utility class used to start Bolt as Server or Client. - + Starts Bolt as a Single Player game Custom Bolt configuration - + Starts Bolt as Server. Port where the Server will try to bind - + Starts Bolt as Server. Custom Bolt configuration Default Scene loaded by Bolt when the initialization is complete - + Starts Bolt as Server. Custom EndPoint where Bolt will try to bind Default Scene loaded by Bolt when the initialization is complete - + Starts Bolt as Server. @@ -4912,40 +5321,40 @@ Custom Bolt configuration Default Scene loaded by Bolt when the initialization is complete - + Starts Bolt as Client. Port where the Server will try to bind - + Starts Bolt as Client. Custom Bolt configuration - + Starts Bolt as Client. Custom EndPoint where Bolt will try to bind Custom Bolt configuration - + Utility function to initialize Bolt with the specified modes, endpoint, config and scene. - Bolt mode. + Bolt mode. Custom EndPoint where Bolt will try to bind Custom Bolt configuration Default Scene loaded by Bolt when the initialization is complete - + Shutdown this Bolt instance. - + Set a custom UDP platform. Use this method only to set custom properties to your desired platform. By default, there is no need to change @@ -4965,5 +5374,163 @@ + + + Gets the current session this peer is connected. + + The current session. + + + + Expose custom metadata information about the current platform and connection if a remove server. + The information retrieved by this call depends on the current active platform and the current + internal status of it. + + + + + Creates a Session using the current running Platform. + + Session identifier. This value will be public available and + can be used by other players to join this specific session. + User custom data. This Token can be used to pass custom data to other players + and/or to configure custom properties of the session. More information look at . + + Target Scene to be loaded after the session creation procedure starts. + IProtocolToken that is passed on the SceneLoad callbacks. + + *Example:* Creating a session with some custom properties. + + + void SetupSession(string map, int gameType) + { + if (BoltNetwork.IsServer) + { + string matchName = Guid.NewGuid().ToString(); + + PhotonRoomProperties props = new PhotonRoomProperties(); + props["m"] = map; + props["t"] = gameType; + + BoltMatchmaking.CreateSession( + sessionID: matchName, + sceneToLoad: map, + token: props + ); + } + } + + + + + + Updates the current session configuration. The local peer need to be the Server in order to call this method. + + Settings Token. This can be any or + a to setup a Photon Session. + + + + Joins a Session by name. + + Session name that you want to enter + Connection Token + + *Example*: Joining a session using the Session identifier. + + + void Join(string sessionID) + { + if (BoltNetwork.IsClient) + { + var token = new TokenTest(); + BoltMatchmaking.JoinSession(sessionID, token); + } + } + + + + + + Joins a Session using a UdpSession as reference. + + UdpSession that you want to enter + Connection Token + + *Example*: Joining a session using a UdpSession. + + + public override void SessionListUpdated(Map<Guid, UdpSession> sessionList) + { + foreach (var session in sessionList) + { + UdpSession udpSession = session.Value as UdpSession; + var token = new TestToken(); + BoltMatchmaking.JoinSession(udpSession, token); + } + } + + + + + + Joins a Session in a random fashion. When not using the , the client + will try to enter in any available room. + + + + *Example*: Joining a Random Session when Bolt is ready. + + + public override void BoltStartDone() + { + if (BoltNetwork.IsClient) + { + var token = new TestToken(); + BoltMatchmaking.JoinRandomSession(token); + } + } + + + + + + Joins a Session in a random fashion. In order to filter the rooms the player can join, + you can make use of the class and pass custom parameters. + + Session filter parameters + Join Token + + *Example*: + + + public void Join(string map, int gameType) + { + if (BoltNetwork.IsClient) + { + var token = new TestToken(); + + UdpSessionFilter filter = new UdpSessionFilter(); + + filter.FillMode = UdpSessionFillMode.Random; + filter["m"] = map; + filter["t"] = gameType; + + BoltMatchmaking.JoinRandomSession(filter, token); + } + } + + + + + + Internal method to configure a new game session. + This will follow to the UdpPlatform the necessary information to create a session + + Session Unique ID + Protocol Token used to create the Session + Scene to be loaded when the Session is ready + Protocol Token sent with the Scene as meta data + diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll index 93b6960..cff1082 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll and b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll.release b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll.release index 3d84fb1..88781bc 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll.release and b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.dll.release differ diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.xml b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.xml index 0681af3..1c7f23b 100644 --- a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.xml +++ b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.compiler.xml @@ -4,17 +4,933 @@ bolt.compiler - + + + Enum for Axis Selection + + + + All Axis + + + XY Axis + + + ZX Axis + + + YZ Axis + + + X Axis + + + Y Axis + + + Z Axis + + + Disabled for all Axis + + + + Enum for the Replication Mode + + + + + Enum to select which velocity used to extrapolate the position of the transform + + + + + Enum to select the Smoothing Algorithm + + + + + Enum to select the Transform Space of positioning + + + + + Enum to select the Rotation mode of Quaternions inside a Transform + + + + + Enum to select the Property Mecanim mode when synchonizing properties + + + + + Enum to select the mode where the Animation properties would be read and written + + + + + Uses the Animator methods to read and write values from the Animator controller + + + + + Uses Bolt property values from state to update the Mecanim properties + + + + + Enum to select the String encoding + + + Asset Folder - + + + Mark this Asset Folder as Deleted + + + + + Name of Folder + + + + + If it's expanded or not + + + + + List of Folders + + + + + List of Assets + + + + + GUID of Folder + + + + + List of Children objects into this Folder + + + + + All assets inside this folder, including on subfolders + + + + + Class responsible by generating code when Bolt is compiled + + + + + List of states + + + + + List of Objects + + + + + List of Events + + + + + List of Commands + + + + + Run the Code Compiler in order to generate custom types based on the project definition + + Project definition + Output file where the project will be created + + + + Search in the Filters list for a Filter with the argument index + + Index to search + FilterDefinition reference + + + + Find a State based on the GUID + + GUID used to search the State + StateDecorator reference + + + + Find a Object Struct based on the GUID + + GUID used to search the Object + ObjectDecorator reference + + + + Check if the current project contains the State with the GUID + + GUID used to search for the State + True if there is State witht his GUID, false otherwise + + + + Declare a new Interface inside the main Namespace used for the Bolt compilation + + Interface Name + List of inherit interfaces + CodeTypeDeclaration reference of the new Interface + + + + Declare a new Struct inside the main Namespace used for the Bolt compilation + + Struct name + CodeTypeDeclaration reference of the new Object Struct + + + + Declare a new Class Type inside the main Namespace used for the Bolt compilation + + Class name + CodeTypeDeclaration reference of the new Class + + + + Decorator for a Object on the Command Definition + + + + + Create a new Command Object Decorator based on the Object Definition + + Object Definition reference + + + + Signal if should Emit as an Interface + + + + + Name of Base interface for this Asset Decorator + + + + + Defines the base class for an Asset Meta class + + + + + Defines the base class for an Asset + + + + + Decorator for Commands + + + + + Base Command Factory Interface + + + + + Base Class for all Commands + + + + + Define if a change on the property should be signaled + + + + + List of properties for this Command + + + + + Create a new Command Decorator based on the Command Definition + + Command Definition reference + + + + Defines a Event Decorator of a Event Definition + + + + + Factory Interface Name + + + + + Defines the base class for an Asset + + + + + Signal if changed property should be notified + + + + + List of properties for this Asset + + + + + Listener Interface Name + + + + + Create a new Event Decorator based on a Event Definition + + Event Definition reference + + + + Defines a Property Decorator, base for all property generators + + + + + Offset in Storage + + + + + Offset in the Objects + + + + + Offset in the Properties + + + + + Reference to Property Decorator + + + + + Reference to the Asset Decorator + + + + + Reference to the Property Definition + + + + + Member Atributes + + + + + C# Type that represents this property + + + + + How many objects are required for this Property + + + + + How many storage spaces are required for this Property + + + + + How many properties are required for this Property + + + + + Return the full Property Type name used to construct the code + + + + + Creates an code Emitter for a particular property type + + PropertyCodeEmitter reference + + + + Fill the PropertyDefinition with information from the Decorators + + PropertyDefinition list to be filled + Asset decorator that will contain the new PropertyDecorator + PropertyDecorator list already filled with custom data from the AssetDecorator + + + + Fill a PropertyDecorator with custom references from a PropertyDefinition and AssetDecorator + + PropertyDefinition used as base for to create the new PropertyDecorator + AssetDecorator that will hold the new PropertyDecorator + PropertyDecorator reference setup for use + + + + Base type for especilized PropertyDecorators + + PropertyType used for the particular PropertyDecorator + + + + Reference to the Type that this PropertyDecorator holds + + + + + Defines an State decorator, used to build State classes + + + + + Signal if this state has a parent State + + + + + Return the Factory Interface Type + + + + + Return the State base class + + + + + Signal if should emit as an interface + + + + + Signal if the Modified code should be emitted + + + + + Name of Base interface for this Asset Decorator + + + + + List of Parent Interfaces for this State + + + + + List of Properties from this State + + + + + Parent State reference + + + + + List of Parents for this State + + + + + Creates a new State Decorator based on a State Definition + + State Definition to crete the State Decorator + + + + Base class to define all Asset Types on Bolt + + + + + ID of the TYpe + + + + + Total number of Storage space used by the Asset + + + + + Total number of Objects on the Asset + + + + + Total number of Properties on the Asset + + + + + Reference to Code Generator + + + + + Reference to the Asset Definition + + + + + GUID for the Asset Decorator + + + + + Name of the Asset Decorator + + + + + Name of the base Meta Class for this Asset Decorator + + + + + Name of Base interface for this Asset Decorator + + + + + List of Parent interfaces + + + + + Defines the base class for an Asset + + + + + Defines the base class for an Asset Meta class + + + + + Defines the name of the Interface of this Asset + + + + + Signal if the Modified code should be emitted + + + + + Signal if should Emit code as Interface + + + + + Signal if changed property should be notified + + + + + Factory Interface Name + + + + + List of properties for this Asset + + + + + Asset Decorator designed for a particular Asset Definition + + + + + + Asset Definition Reference + + + + + Defines a Object Decorator for a Object Definition + + + + + Factory Interface Name + + + + + List of properties for this Asset + + + + + Signal if the Modified code should be emitted + + + + + List of Object Decorator dependencies + + + + + Create a new Object Decorator based on an Object Definition + + + + + + Represents a block o code generated by the Bolt compiler + + + + + Gets all the statements of this block + + The stmts. + + + + Add the specified expression to the statements + + Expression. + + + + Add the specified expression to the statements + + Statement. + + + + Initializes a new instance of the class. + + Collection of statements. + Prefix. + + + + Initializes a new instance of the class + without a prefix + + Collection of statements. + + + + Creates a temporary var name + + The variable. + + + + Create All the Post methods on the Events implmementations + You can use them to send and eventy more easily + + Event Type Declaration + + + + + Base class for the Propery Emitters, that are used to build code for each Property type + on the final generated code. + + + + + Define the offsets of this property on the Storage + + + + + Offset in Storage + + + + + Offset in the Objects + + + + + Offset in the Properties + + + + + Reference to Property Decorator + + + + + Referenece to Decorator Generator + + + + + Build the Storage Field Name + + + + + Defines the Class Serialzer Name + + + + + Enable Setter for the Property + + + + + Enable if the modification should be verified + + + + + Add specific settings to the property code based on the property type + This can be the compression settings or similar, for example + + + + + + + Defines as Named Asset + + + + + Retrieve the Asset Name + + String with the Asset Name + + + + Base class for all Property definition + + + + + Mark property as nudged + + + + + Mark property as deleted + + + + + If this property is element of an array + + + + + Adjust property in the list + + + + + Reference the root Project + + + + + Name of the Property + + + + + Mark if property is enabled + + + + + Makr if property should be replicated + + + + + Mark if property is expanded or not + + + + + Mark if property should be replicated to everyone + + + + + Signal the replication mode of this property + + + + + Some comments of the property + + + + + Set the property priority + + + + + Set the Property Type + + + + + Reference to Property Settings + + + + + Flag mask of the filters used on this property + + + + + Retrieve the Property Settings as a PropertyStateSettings + + + + + Retrieve the Property Settings as a EventAssetSettings + + + + + Retrieve the Property Settings as a CommandAssetSettings + + + + + Setup the Property when created + + + + + Axis definition Offset + + + + + Axis offset for X axis + + + + + Axis offset for Y axis + + + + + Axis offset for Z axis + + + + + Asset Definition Sort Order + + + + + Manual Mode + + + + + Sort by Name + + + + + Sort by priority + + + Asset definition describes all properties of an Bolt Asset - + + + Mark this Definition as Deleted + + + + + Reference to Project where this Asset is defined + + + + + Name of the Asset + + + + + GUID of Asset + + + + + Custom comment for the Asset + + + + + Flag to enable the Asset + + + + + List of Groups this Asset belongs to + + + + + Sort Order of this Asset + + + + + List of Type this Asset allows + + + Serializes BoltProject to file. @@ -22,7 +938,7 @@ BoltProject reference. Path to destination file. - + Deserializes a BoltProject from a file. @@ -31,124 +947,99 @@ Path to JSON file. Thrown when the JSON file was not found at path - + Represents the Asset collection of all networked data on the current game project - + Collection of Assets on this particular project - + Current active group - + List of filters applied to the assets - + List of Defined groups - + List of State Assets - + List of Structs (Object) Assets - + List of Event Assets - + List of Command Assets - + List of enabled Filters - + If this Project is using Filters - + Initializes the internal Asset list - + Finds a state asset by its guid. The state or null if not found. GUID of the State. - + Gets the inheritance tree of a State The inheritance tree. State to check the inheritance tree - + Gets the inheritance tree of a State and save to the list State to check the inheritance tree Result list of states. - - - Gets all the statements of this block - - The stmts. - - - - Add the specified expression to the statements - - Expression. - - + - Add the specified expression to the statements - - Statement. - - - - Initializes a new instance of the class. - - Collection of statements. - Prefix. - - - - Initializes a new instance of the class - without a prefix + Convert a Project into a reference of BoltProject - Collection of statements. + Base project used for the conversion + A reference a new BoltProject - + - Creates a temporary var name + Run a deep copy on the fields of the BoltProject - The variable. + A new reference of the BoltProject with all fields cloned diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll index c48d95c..cf23d8c 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll and b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll.release b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll.release index f5a8eb2..704cc79 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll.release and b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.dll.release differ diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.xml b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.xml index ccbaf62..e79c12d 100644 --- a/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.xml +++ b/Assets/Photon/PhotonBolt/assemblies/editor/bolt.editor.xml @@ -4,29 +4,121 @@ bolt.editor - + + + Search and update the list of Protocol Tokens in the ProtocolTokenRegistry + + + + + Loads all Assemblies on the project a search for Protocol Token implementations + that fulfill the requirements described on the method + + List of BoltProtocolTokenRegistry.TokenRegistry with all found tokens + + + + Returns a reference for a Assembly based on it's name + + Assembly Name + Reference to an Assembly or null if not found + + + + Remove all Temporary files from the Bolt Compilation + + + + + Custom inspector for BoltEntity component + + + + + Draw the basic information about the Bolt Entity + + Target Bolt Entity + + + + Draw the dropdown box to select the Entity state + + Target Entity to change the state type + + + + Draw Entity properties at runtime + + Target Entity + + + + Save the current Entity + + Entity to be saved + + + + Show a extra text alongside the property drawer + + Message to be shown + + + + Custom editor for BoltProtocolTokenRegistry + It shows a list of all IProtocolTokens found on the project + and show a button to update the list of Tokens + + + + + Update the Protocol Token list + + + + + This class will setup the BoltLog class using the current configuration + on the Bolt Settings. This will keep the logs appearing in Editor Mode, + but will totally disabled if the user prefers. + + + + + Used to checkout files from a Source Code Provider, like Perforce when enabled + (link) + The main behavior is enabled only if it's enabled in the Bolt Settings () + + + + + Checkout all files specified on the paths list + If the Source Provider was properly configured, this method will checkout the file and set it as writable + + List of file paths to checkout + + Update the internal prefab database - + Run the Bolt Compiler to generate the Dynamic data - + List all Bolt Entities from the Scene and assing new Scene IDs for each one - + Invoke the action in the main Thread by Enqueuing it for execution on the Editor Update method - + Utility to Move Files @@ -34,51 +126,30 @@ Destination file path If the destination will be deleted before the move - + Setup "BOLT_CLOUD" constant as a Compiler flag on the current Build Target - + Assing a new Scene ID to a Bolt Entity component Entity to assing a new Scene ID - + Enable a Compiler constant on the Player Settings Build target where to enable the flag Flag to enable - + Disable a Compiler constant on the Player Settings Build target where to disable the flag Flag to disable - - - This class will setup the BoltLog class using the current configuration - on the Bolt Settings. This will keep the logs appearing in Editor Mode, - but will totally disabled if the user prefers. - - - - - Used to checkout files from a Source Code Provider, like Perforce when enabled - - The main behavior is enabled only if it's enabled in the Bolt Settings () - - - - - Checkout all files specified on the paths list - If the Source Provider was properly configured, this method will checkout the file and set it as writable - - List of file paths to checkout - diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt deleted file mode 100644 index 692cf3b..0000000 --- a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -The core Protocol Buffers technology is provided courtesy of Google. -At the time of writing, this is released under the BSD license. -Full details can be found here: - -http://code.google.com/p/protobuf/ - - -This .NET implementation is Copyright 2008 Marc Gravell - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll index 3d24cd0..a50bb36 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll and b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll.meta b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll.meta index b3209fb..5973771 100644 --- a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll.meta +++ b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.dll.meta @@ -1,34 +1,33 @@ fileFormatVersion: 2 guid: 06714bfac45eb04499b97307938f1ff6 -timeCreated: 1500292913 -licenseType: Store PluginImporter: + externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} + defineConstraints: [] isPreloaded: 0 isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 platformData: - data: - first: - Any: - second: - enabled: 0 - settings: {} - data: - first: - Editor: Editor - second: - enabled: 1 - settings: - DefaultValueInitialized: true - data: - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml new file mode 100644 index 0000000..a3478c4 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml @@ -0,0 +1,3657 @@ + + + + protobuf-net + + + + + Provides support for common .NET types that do not have a direct representation + in protobuf, using the definitions from bcl.proto + + + + + Creates a new instance of the specified type, bypassing the constructor. + + The type to create + The new instance + If the platform does not support constructor-skipping + + + + The default value for dates that are following google.protobuf.Timestamp semantics + + + + + Writes a TimeSpan to a protobuf stream using protobuf-net's own representation, bcl.TimeSpan + + + + + Parses a TimeSpan from a protobuf stream using protobuf-net's own representation, bcl.TimeSpan + + + + + Parses a TimeSpan from a protobuf stream using the standardized format, google.protobuf.Duration + + + + + Writes a TimeSpan to a protobuf stream using the standardized format, google.protobuf.Duration + + + + + Parses a DateTime from a protobuf stream using the standardized format, google.protobuf.Timestamp + + + + + Writes a DateTime to a protobuf stream using the standardized format, google.protobuf.Timestamp + + + + + Parses a DateTime from a protobuf stream + + + + + Writes a DateTime to a protobuf stream, excluding the Kind + + + + + Writes a DateTime to a protobuf stream, including the Kind + + + + + Parses a decimal from a protobuf stream + + + + + Writes a decimal to a protobuf stream + + + + + Writes a Guid to a protobuf stream + + + + + Parses a Guid from a protobuf stream + + + + + Optional behaviours that introduce .NET-specific functionality + + + + + No special behaviour + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + If false, the constructor for the type is bypassed during deserialization, meaning any field initializers + or other initialization code is skipped. + + + + + Should the object index be reserved, rather than creating an object promptly + + + + + Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. + + + + + Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. + + + + + Provides a simple buffer-based implementation of an extension object. + + + + + https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element + + + + Specifies a method on the root-contract in an hierarchy to be invoked before serialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked after serialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked before deserialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked after deserialization. + + + + Pushes a null reference onto the stack. Note that this should only + be used to return a null (or set a variable to null); for null-tests + use BranchIfTrue / BranchIfFalse. + + + + + Creates a new "using" block (equivalent) around a variable; + the variable must exist, and note that (unlike in C#) it is + the variables *final* value that gets disposed. If you need + *original* disposal, copy your variable first. + + It is the callers responsibility to ensure that the variable's + scope fully-encapsulates the "using"; if not, the variable + may be re-used (and thus re-assigned) unexpectedly. + + + + + Sub-format to use when serializing/deserializing data + + + + + Uses the default encoding for the data-type. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that zigzag variant encoding will be used. This means that values + with small magnitude (regardless of sign) take a small amount + of space to encode. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that two's-complement variant encoding will be used. + This means that any -ve number will take 10 bytes (even for 32-bit), + so should only be used for compatibility. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that a fixed amount of space will be used. + + + + + When applied to a sub-message, indicates that the value should be treated + as group-delimited. + + + + + When applied to members of types such as DateTime or TimeSpan, specifies + that the "well known" standardized representation should be use; DateTime uses Timestamp, + + + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Guid + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Guid + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + + Simple base class for supporting unexpected fields allowing + for loss-less round-tips/merge, even if the data is not understod. + The additional fields are (by default) stored in-memory in a buffer. + + As an example of an alternative implementation, you might + choose to use the file system (temporary files) as the back-end, tracking + only the paths [such an object would ideally be IDisposable and use + a finalizer to ensure that the files are removed]. + + + + + Retrieves the extension object for the current + instance, optionally creating it if it does not already exist. + + Should a new extension object be + created if it does not already exist? + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Provides a simple, default implementation for extension support, + optionally creating it if it does not already exist. Designed to be called by + classes implementing . + + Should a new extension object be + created if it does not already exist? + The extension field to check (and possibly update). + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The type of the value to append. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The data-type of the field. + The data-format to use when encoding the value. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned is the composed value after merging any duplicated content; if the + value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The effective value of the field, or the default value if not found. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned is the composed value after merging any duplicated content; if the + value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + The effective value of the field, or the default value if not found. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + Allow tags that are present as part of the definition; for example, to query unknown enum values. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + An enumerator that yields each occurrence of the field. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + An enumerator that yields each occurrence of the field. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The model to use for configuration. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + Allow tags that are present as part of the definition; for example, to query unknown enum values. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The model to use for configuration. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + An enumerator that yields each occurrence of the field. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The model to use for configuration. + The data-format to use when encoding the value. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + This class acts as an internal wrapper allowing us to do a dynamic + methodinfo invoke; an't put into Serializer as don't want on public + API; can't put into Serializer<T> since we need to invoke + across classes + + + + + All this does is call GetExtendedValuesTyped with the correct type for "instance"; + this ensures that we don't get issues with subclasses declaring conflicting types - + the caller must respect the fields defined for the type they pass in. + + + + + All this does is call GetExtendedValuesTyped with the correct type for "instance"; + this ensures that we don't get issues with subclasses declaring conflicting types - + the caller must respect the fields defined for the type they pass in. + + + + + Not all frameworks are created equal (fx1.1 vs fx2.0, + micro-framework, compact-framework, + silverlight, etc). This class simply wraps up a few things that would + otherwise make the real code unnecessarily messy, providing fallback + implementations if necessary. + + + + + Intended to be a direct map to regular TypeCode, but: + - with missing types + - existing on WinRT + + + + + Indicates that the implementing type has support for protocol-buffer + extensions. + + Can be implemented by deriving from Extensible. + + + + Retrieves the extension object for the current + instance, optionally creating it if it does not already exist. + + Should a new extension object be + created if it does not already exist? + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Provides addition capability for supporting unexpected fields during + protocol-buffer serialization/deserialization. This allows for loss-less + round-trip/merge, even when the data is not fully understood. + + + + + Requests a stream into which any unexpected fields can be persisted. + + A new stream suitable for storing data. + + + + Indicates that all unexpected fields have now been stored. The + implementing class is responsible for closing the stream. If + "commit" is not true the data may be discarded. + + The stream originally obtained by BeginAppend. + True if the append operation completed successfully. + + + + Requests a stream of the unexpected fields previously stored. + + A prepared stream of the unexpected fields. + + + + Indicates that all unexpected fields have now been read. The + implementing class is responsible for closing the stream. + + The stream originally obtained by BeginQuery. + + + + Requests the length of the raw binary stream; this is used + when serializing sub-entities to indicate the expected size. + + The length of the binary stream representing unexpected data. + + + + Provides the ability to remove all existing extension data + + + + + Remove all existing extension data + + + + + Specifies the method used to infer field tags for members of the type + under consideration. Tags are deduced using the invariant alphabetic + sequence of the members' names; this makes implicit field tags very brittle, + and susceptible to changes such as field names (normally an isolated + change). + + + + + No members are serialized implicitly; all members require a suitable + attribute such as [ProtoMember]. This is the recmomended mode for + most scenarios. + + + + + Public properties and fields are eligible for implicit serialization; + this treats the public API as a contract. Ordering beings from ImplicitFirstTag. + + + + + Public and non-public fields are eligible for implicit serialization; + this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag. + + + + + Represents the ability to deserialize values from an input of type + + + + + Deserialize a value from the input + + + + + Represents the ability to serialize values to an output of type + + + + + Serialize the provided value + + + + + Represents the ability to serialize values to an output of type + with pre-computation of the length + + + + + Measure the length of a value in advance of serialization + + + + + Serialize the previously measured value + + + + + Represents the outcome of computing the length of an object; since this may have required computing lengths + for multiple objects, some metadata is retained so that a subsequent serialize operation using + this instance can re-use the previously calculated lengths. If the object state changes between the + measure and serialize operations, the behavior is undefined. + + + + + Releases all resources associated with this value + + + + + Gets the calculated length of this serialize operation, in bytes + + + + + Represents the set of serialization callbacks to be used when serializing/deserializing a type. + + + + Called before serializing an instance + + + Called before deserializing an instance + + + Called after serializing an instance + + + Called after deserializing an instance + + + + True if any callback is set, else False + + + + + Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined + + + + + Get the name of the type being represented + + + + + Gets the base-type for this type + + + + + When used to compile a model, should public serialization/deserialzation methods + be included for this type? + + + + + Should this type be treated as a reference by default? + + + + + Adds a known sub-type to the inheritance model + + + + + Adds a known sub-type to the inheritance model + + + + + Indicates whether the current type has defined callbacks + + + + + Indicates whether the current type has defined subtypes + + + + + Returns the set of callbacks defined for this type + + + + + Assigns the callbacks to use during serialiation/deserialization. + + The method (or null) called before serialization begins. + The method (or null) called when serialization is complete. + The method (or null) called before deserialization begins (or when a new instance is created during deserialization). + The method (or null) called when deserialization is complete. + The set of callbacks. + + + + Assigns the callbacks to use during serialiation/deserialization. + + The name of the method (or null) called before serialization begins. + The name of the method (or null) called when serialization is complete. + The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization). + The name of the method (or null) called when deserialization is complete. + The set of callbacks. + + + + Gets or sets the name of this contract. + + + + + Designate a factory-method to use to create instances of this type + + + + + Designate a factory-method to use to create instances of this type + + + + + Throws an exception if the type has been made immutable + + + + + The runtime type that the meta-type represents + + + + + Adds a member (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API. + This is otherwise identical to Add. + + + + + Gets or sets whether the type should use a parameterless constructor (the default), + or whether the type should skip the constructor completely. This option is not supported + on compact-framework. + + + + + The concrete type to create when a new instance of this type is needed; this may be useful when dealing + with dynamic proxies, or with interface-based APIs + + + + + Adds a member (by name) to the MetaType + + + + + Performs serialization of this type via a surrogate; all + other serialization options are ignored and handled + by the surrogate's configuration. + + + + + Adds a set of members (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists + + + + + Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API. + This is otherwise identical to Add. + + + + + Returns the ValueMember that matchs a given field number, or null if not found + + + + + Returns the ValueMember that matchs a given member (property/field), or null if not found + + + + + Returns the ValueMember instances associated with this type + + + + + Returns the SubType instances associated with this type + + + + + Compiles the serializer for this type; this is *not* a full + standalone compile, but can significantly boost performance + while allowing additional types to be added. + + An in-place compile can access non-public types / members + + + + Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather + than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. + + + + + Gets or sets a value indicating that this type should NOT be treated as a list, even if it has + familiar list-like characteristics (enumerable, add, etc) + + + + + Indicates whether this type should always be treated as a "group" (rather than a string-prefixed sub-message) + + + + + Apply a shift to all fields (and sub-types) on this type + + The change in field number to apply + The resultant field numbers must still all be considered valid + + + + Indiate the variant of the protobuf .proto DSL syntax to use + + + + + https://developers.google.com/protocol-buffers/docs/proto + + + + + https://developers.google.com/protocol-buffers/docs/proto3 + + + + + Provides protobuf serialization support for a number of types that can be defined at runtime + + + + + Global default that + enables/disables automatic tag generation based on the existing name / order + of the defined members. See + for usage and important warning / explanation. + You must set the global default before attempting to serialize/deserialize any + impacted type. + + + + + Global default that determines whether types are considered serializable + if they have [DataContract] / [XmlType]. With this enabled, ONLY + types marked as [ProtoContract] are added automatically. + + + + + Global switch that enables or disables the implicit + handling of "zero defaults"; meanning: if no other default is specified, + it assumes bools always default to false, integers to zero, etc. + + If this is disabled, no such assumptions are made and only *explicit* + default values are processed. This is enabled by default to + preserve similar logic to v1. + + + + + Global switch that determines whether types with a .ToString() and a Parse(string) + should be serialized as strings. + + + + + Global switch that determines whether DateTime serialization should include the Kind of the date/time. + + + + + Global switch that determines whether a single instance of the same string should be used during deserialization. + + Note this does not use the global .NET string interner + + + + Should the Kind be included on date/time values? + + + + + The default model, used to support ProtoBuf.Serializer + + + + + Returns a sequence of the Type instances that can be + processed by this model. + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + The .proto syntax to use + + + + Creates a new runtime model, to which the caller + can add support for a range of types. A model + can be used "as is", or can be compiled for + optimal performance. + + not used currently; this is for compatibility with v3 + + + + Obtains the MetaType associated with a given Type for the current model, + allowing additional configuration. + + + + + Adds support for an additional type in this model, optionally + applying inbuilt patterns. If the type is already known to the + model, the existing type is returned **without** applying + any additional behaviour. + + Inbuilt patterns include: + [ProtoContract]/[ProtoMember(n)] + [DataContract]/[DataMember(Order=n)] + [XmlType]/[XmlElement(Order=n)] + [On{Des|S}erializ{ing|ed}] + ShouldSerialize*/*Specified + + The type to be supported + Whether to apply the inbuilt configuration patterns (via attributes etc), or + just add the type with no additional configuration (the type must then be manually configured). + The MetaType representing this type, allowing + further configuration. + + + + Should serializers be compiled on demand? It may be useful + to disable this for debugging purposes. + + + + + Should support for unexpected types be added automatically? + If false, an exception is thrown when unexpected types + are encountered. + + + + + Verifies that the model is still open to changes; if not, an exception is thrown + + + + + Prevents further changes to this model + + + + + Provides the key that represents a given type in the current model. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + Represents the type (including inheritance) to consider. + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + Represents the type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Compiles the serializers individually; this is *not* a full + standalone compile, but can significantly boost performance + while allowing additional types to be added. + + An in-place compile can access non-public types / members + + + + Fully compiles the current model into a static-compiled model instance + + A full compilation is restricted to accessing public types / members + An instance of the newly created compiled type-model + + + + Represents configuration options for compiling a model to + a standalone assembly. + + + + + Import framework options from an existing type + + + + + The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly + + + + + The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly + + + + + The name of the TypeModel class to create + + + + + The path for the new dll + + + + + The runtime version for the generated assembly + + + + + The runtime version for the generated assembly + + + + + The acecssibility of the generated serializer + + + + + Type accessibility + + + + + Available to all callers + + + + + Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)] + + + + + Fully compiles the current model into a static-compiled serialization dll + (the serialization dll still requires protobuf-net for support services). + + A full compilation is restricted to accessing public types / members + The name of the TypeModel class to create + The path for the new dll + An instance of the newly created compiled type-model + + + + Fully compiles the current model into a static-compiled serialization dll + (the serialization dll still requires protobuf-net for support services). + + A full compilation is restricted to accessing public types / members + An instance of the newly created compiled type-model + + + + The amount of time to wait if there are concurrent metadata access operations + + + + + If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating + what caused the problem; this is only raised if the lock-owning code successfully completes. + + + + + Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory. + + + + + Raised before a type is auto-configured; this allows the auto-configuration to be electively suppressed + + This callback should be fast and not involve complex external calls, as it may block the model + + + + Raised after a type is auto-configured; this allows additional external customizations + + This callback should be fast and not involve complex external calls, as it may block the model + + + + Contains the stack-trace of the owning code when a lock-contention scenario is detected + + + + + The stack-trace of the code that owned the lock when a lock-contention scenario occurred + + + + + Event-type that is raised when a lock-contention scenario is detected + + + + + Represents an inherited type in a type hierarchy. + + + + + The field-number that is used to encapsulate the data (as a nested + message) for the derived dype. + + + + + The sub-type to be considered. + + + + + Creates a new SubType instance. + + The field-number that is used to encapsulate the data (as a nested + message) for the derived dype. + The sub-type to be considered. + Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default. + + + + Event data associated with new types being added to a model + + + + + Whether or not to apply the default mapping behavior + + + + + The configuration of the type being added + + + + + The type that was added to the model + + + + + The model that is being changed + + + + + Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could + be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names). + + + + + The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName. + + + + + The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type. + + + + + Delegate type used to perform type-formatting functions; the sender originates as the type-model. + + + + + Provides protobuf serialization support for a number of types + + + + + Should the Kind be included on date/time values? + + + + + Resolve a System.Type to the compiler-specific type + + + + + Resolve a System.Type to the compiler-specific type + + + + + This is the more "complete" version of Serialize, which handles single instances of mapped types. + The value is written as a complete field, including field-header and (for sub-objects) a + length-prefix + In addition to that, this provides support for: + - basic values; individual int / string / Guid / etc + - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType + + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied writer. + + The existing instance to be serialized (cannot be null). + The destination writer to write to. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). + The type of object to deserialize (can be null if "resolver" is specified). + The sequence of deserialized objects. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). + The type of object to deserialize (can be null if "resolver" is specified). + The sequence of deserialized objects. + Additional information about this serialization operation. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume (or -1 to read to the end of the stream). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume (or -1 to read to the end of the stream). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer reader to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The reader to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + This is the more "complete" version of Deserialize, which handles single instances of mapped types. + The value is read as a complete field, including field-header and (for sub-objects) a + length-prefix..kmc + + In addition to that, this provides support for: + - basic values; individual int / string / Guid / etc + - IList sets of any type handled by TryDeserializeAuxiliaryType + + + + + Creates a new runtime model, to which the caller + can add support for a range of types. A model + can be used "as is", or can be compiled for + optimal performance. + + + + + Applies common proxy scenarios, resolving the actual type to consider + + + + + Indicates whether the supplied type is explicitly modelled by the model + + + + + Provides the key that represents a given type in the current model. + The type is also normalized for proxies at the same time. + + + + + Advertise that a type's key can have changed + + + + + Provides the key that represents a given type in the current model. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + Represents the type (including inheritance) to consider. + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + Represents the type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Indicates the type of callback to be used + + + + + Invoked before an object is serialized + + + + + Invoked after an object is serialized + + + + + Invoked before an object is deserialized (or when a new instance is created) + + + + + Invoked after an object is deserialized + + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Indicates that while an inheritance tree exists, the exact type encountered was not + specified in that hierarchy and cannot be processed. + + + + + Indicates that the given type was not expected, and cannot be processed. + + + + + Indicates that the given type cannot be constructed; it may still be possible to + deserialize into existing instances. + + + + + Returns true if the type supplied is either a recognised contract type, + or a *list* of a recognised contract type. + + Note that primitives always return false, even though the engine + will, if forced, try to serialize such + True if this type is recognised as a serializable entity, else false + + + + Returns true if the type supplied is a basic type with inbuilt handling, + a recognised contract type, or a *list* of a basic / contract type. + + + + + Returns true if the type supplied is a basic type with inbuilt handling, + or a *list* of a basic type with inbuilt handling + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + The .proto syntax to use for the operation + + + + Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting + are provided on a single API as it is essential that both are mapped identically at all times. + + + + + Creates a new IFormatter that uses protocol-buffer [de]serialization. + + A new IFormatter to be used during [de]serialization. + The type of object to be [de]deserialized by the formatter. + + + + Represents a member (property/field) that is mapped to a protobuf field + + + + + The number that identifies this member in a protobuf stream + + + + + Gets the member (field/property) which this member relates to. + + + + + Gets the backing member (field/property) which this member relates to + + + + + Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList) + + + + + The underlying type of the member + + + + + For abstract types (IList etc), the type of concrete object to create (if required) + + + + + The type the defines the member + + + + + The default value of the item (members with this value will not be serialized) + + + + + Creates a new ValueMember instance + + + + + Creates a new ValueMember instance + + + + + Specifies the rules used to process the field; this is used to determine the most appropriate + wite-type, but also to describe subtypes within that wire-type (such as SignedVariant) + + + + + Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32" + is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that + when serializing the defined type is always used. + + + + + Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values). + This option only applies to list/array data of primitive types (int, double, etc). + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Indicates whether this field is mandatory. + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + Indicates that the member should be treated as a protobuf Map + + + + + Specifies the data-format that should be used for the key, when IsMap is enabled + + + + + Specifies the data-format that should be used for the value, when IsMap is enabled + + + + + Specifies methods for working with optional data members. + + Provides a method (null for none) to query whether this member should + be serialized; it must be of the form "bool {Method}()". The member is only serialized if the + method returns true. + Provides a method (null for none) to indicate that a member was + deserialized; it must be of the form "void {Method}(bool)", and will be called with "true" + when data is found. + + + + Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used + when inferring a schema). + + + + + Should lists have extended support for null values? Note this makes the serialization less efficient. + + + + + Specifies the type of prefix that should be applied to messages. + + + + + No length prefix is applied to the data; the data is terminated only be the end of the stream. + + + + + A base-128 ("varint", the default prefix format in protobuf) length prefix is applied to the data (efficient for short messages). + + + + + A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility). + + + + + A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility). + + + + + Indicates that a type is defined for protocol-buffer serialization. + + + + + Gets or sets the defined name of the type. + + + + + Gets or sets the fist offset to use with implicit field tags; + only uesd if ImplicitFields is set. + + + + + If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored. + + + + + If specified, do NOT treat this type as a list, even if it looks like one. + + + + + Gets or sets the mechanism used to automatically infer field tags + for members. This option should be used in advanced scenarios only. + Please review the important notes against the ImplicitFields enumeration. + + + + + Enables/disables automatic tag generation based on the existing name / order + of the defined members. This option is not used for members marked + with ProtoMemberAttribute, as intended to provide compatibility with + WCF serialization. WARNING: when adding new fields you must take + care to increase the Order for new elements, otherwise data corruption + may occur. + + If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName. + + + + Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed. + + + + + Specifies an offset to apply to [DataMember(Order=...)] markers; + this is useful when working with mex-generated classes that have + a different origin (usually 1 vs 0) than the original data-contract. + + This value is added to the Order of each member. + + + + + If true, the constructor for the type is bypassed during deserialization, meaning any field initializers + or other initialization code is skipped. + + + + + Should this type be treated as a reference by default? Please also see the implications of this, + as recorded on ProtoMemberAttribute.AsReference + + + + + Indicates whether this type should always be treated as a "group" (rather than a string-prefixed sub-message) + + + + + Applies only to enums (not to DTO classes themselves); gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather + than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. + + + + + Allows to define a surrogate type used for serialization/deserialization purpose. + + + + + Has a EnumPassthru value been explicitly set? + + + + + Indicates that a static member should be considered the same as though + were an implicit / explicit conversion operator; in particular, this + is useful for conversions that operator syntax does not allow, such as + to/from interface types. + + + + + Used to define protocol-buffer specific behavior for + enumerated values. + + + + + Gets or sets the specific value to use for this enum during serialization. + + + + + Indicates whether this instance has a customised value mapping + + true if a specific value is set + + + + Gets or sets the defined name of the enum, as used in .proto + (this name is not used during serialization). + + + + + Indicates an error during serialization/deserialization of a proto stream. + + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + + Indicates that a member should be excluded from serialization; this + is only normally used when using implict fields. + + + + + Indicates that a member should be excluded from serialization; this + is only normally used when using implict fields. This allows + ProtoIgnoreAttribute usage + even for partial classes where the individual members are not + under direct control. + + + + + Creates a new ProtoPartialIgnoreAttribute instance. + + Specifies the member to be ignored. + + + + The name of the member to be ignored. + + + + + Indicates the known-types to support for an individual + message. This serializes each level in the hierarchy as + a nested message to retain wire-compatibility with + other protocol-buffer implementations. + + + + + Creates a new instance of the ProtoIncludeAttribute. + + The unique index (within the type) that will identify this data. + The additional type to serialize/deserialize. + + + + Creates a new instance of the ProtoIncludeAttribute. + + The unique index (within the type) that will identify this data. + The additional type to serialize/deserialize. + + + + Gets the unique index (within the type) that will identify this data. + + + + + Gets the additional type to serialize/deserialize. + + + + + Gets the additional type to serialize/deserialize. + + + + + Specifies whether the inherited sype's sub-message should be + written with a length-prefix (default), or with group markers. + + + + + Controls the formatting of elements in a dictionary, and indicates that + "map" rules should be used: duplicates *replace* earlier values, rather + than throwing an exception + + + + + Describes the data-format used to store the key + + + + + Describes the data-format used to store the value + + + + + Disables "map" handling; dictionaries will use ".Add(key,value)" instead of "[key] = value", + which means duplicate keys will cause an exception (instead of retaining the final value); if + a proto schema is emitted, it will be produced using "repeated" instead of "map" + + + + + Declares a member to be used in protocol-buffer serialization, using + the given Tag. A DataFormat may be used to optimise the serialization + format (for instance, using zigzag encoding for negative numbers, or + fixed-length encoding for large values. + + + + + Compare with another ProtoMemberAttribute for sorting purposes + + + + + Compare with another ProtoMemberAttribute for sorting purposes + + + + + Creates a new ProtoMemberAttribute instance. + + Specifies the unique tag used to identify this member within the type. + + + + Gets or sets the original name defined in the .proto; not used + during serialization. + + + + + Gets or sets the data-format to be used when encoding this value. + + + + + Gets the unique tag used to identify this member within the type. + + + + + Gets or sets a value indicating whether this member is mandatory. + + + + + Gets a value indicating whether this member is packed. + This option only applies to list/array data of primitive types (int, double, etc). + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + Gets or sets a value indicating whether this member is packed (lists/arrays). + + + + + Additional (optional) settings that control serialization of members + + + + + Default; no additional options + + + + + Indicates that repeated elements should use packed (length-prefixed) encoding + + + + + Indicates that the given item is required + + + + + Enables full object-tracking/full-graph support + + + + + Embeds the type information into the stream, allowing usage with types not known in advance + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used + + + + + Declares a member to be used in protocol-buffer serialization, using + the given Tag and MemberName. This allows ProtoMemberAttribute usage + even for partial classes where the individual members are not + under direct control. + A DataFormat may be used to optimise the serialization + format (for instance, using zigzag encoding for negative numbers, or + fixed-length encoding for large values. + + + + + Creates a new ProtoMemberAttribute instance. + + Specifies the unique tag used to identify this member within the type. + Specifies the member to be serialized. + + + + The name of the member to be serialized. + + + + + A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call + ReadFieldHeader and (after matching the field) an appropriate Read* method. + + + + + Gets the number of the field being processed. + + + + + Indicates the underlying proto serialization format on the wire. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + + + + Gets / sets a flag indicating whether strings should be checked for repetition; if + true, any repeated UTF-8 byte sequence will result in the same String instance, rather + than a second instance of the same string. Enabled by default. Note that this uses + a custom interner - the system-wide string interner is not used. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Addition information about this deserialization operation. + + + + + Releases resources used by the reader, but importantly does not Dispose the + underlying stream; in many typical use-cases the stream is used for different + processes, so it is assumed that the consumer will Dispose their stream separately. + + + + + Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Returns the position of the current reader (note that this is not necessarily the same as the position + in the underlying stream, if multiple readers are used on the same stream) + + + + + Returns the position of the current reader (note that this is not necessarily the same as the position + in the underlying stream, if multiple readers are used on the same stream) + + + + + Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a string from the stream (using UTF8); supported wire-types: String + + + + + Throws an exception indication that the given value cannot be mapped to an enum. + + + + + Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64 + + + + + Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between) + parsing the message in accordance with the model associated with the reader + + + + + Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup + marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader + should return zero) + + + + + Begins consuming a nested message in the stream; supported wire-types: StartGroup, String + + The token returned must be help and used when callining EndSubItem + + + + Reads a field header from the stream, setting the wire-type and retuning the field number. If no + more fields are available, then 0 is returned. This methods respects sub-messages. + + + + + Looks ahead to see whether the next field in the stream is what we expect + (typically; what we've just finished reading - for example ot read successive list items) + + + + + Get the TypeModel associated with this reader + + + + + Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example, + a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made. + + + + + Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example, + SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown. + + + + + Discards the data for the current field. + + + + + Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64 + + + + + Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + + Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + + Reads a little-endian encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a big-endian encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a varint encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available. + + + + + Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available. + + + + + Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available. + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + The number of bytes consumed; 0 if no data available + + + + Copies the current field into the instance as extension data + + + + + Indicates whether the reader still has data remaining in the current sub-item, + additionally setting the wire-type for the next field if there is more data. + This is used when decoding packed data. + + + + + Utility method, not intended for public use; this helps maintain the root object is complex scenarios + + + + + Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String + + + + + Merge two objects using the details from the current reader; this is used to change the type + of objects when an inheritance relationship is discovered later than usual during deserilazation. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Represents an output stream for writing protobuf data. + + Why is the API backwards (static methods with writer arguments)? + See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html + + + + + Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). + + The object to write. + The key that uniquely identifies the type within the model. + The destination. + + + + Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the + caller is asserting that this relationship is non-recursive; no recursion check will be + performed. + + The object to write. + The key that uniquely identifies the type within the model. + The destination. + + + + Writes a field-header, indicating the format of the next data we plan to write. + + + + + Writes a byte-array to the stream; supported wire-types: String + + + + + Writes a byte-array to the stream; supported wire-types: String + + + + + Indicates the start of a nested record. + + The instance to write. + The destination. + A token representing the state of the stream; this token is given to EndSubItem. + + + + Indicates the end of a nested record. + + The token obtained from StartubItem. + The destination. + + + + Creates a new writer against a stream + + The destination stream + The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects + Additional context about this serialization operation + + + + Creates a new writer against a stream + + The destination stream + The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects + Additional context about this serialization operation + + + + Addition information about this serialization operation. + + + + + Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed + by this operation. + + + + + Get the TypeModel associated with this writer + + + + + Writes any buffered data (if possible) to the underlying stream. + + The writer to flush + It is not always possible to fully flush, since some sequences + may require values to be back-filled into the byte-stream. + + + + Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a string to the stream; supported wire-types: String + + + + + Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 + + + + + Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 + + + + + Throws an exception indicating that the given enum cannot be mapped to a serialized value. + + + + + Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Copies any extension data stored for the instance to the underlying stream + + + + + Used for packed encoding; indicates that the next field should be skipped rather than + a field header written. Note that the field number must match, else an exception is thrown + when the attempt is made to write the (incorrect) field. The wire-type is taken from the + subsequent call to WriteFieldHeader. Only primitive types can be packed. + + + + + Used for packed encoding; explicitly reset the packed field marker; this is not required + if using StartSubItem/EndSubItem + + + + + Used for packed encoding; writes the length prefix using fixed sizes rather than using + buffering. Only valid for fixed-32 and fixed-64 encoding. + + + + + Specifies a known root object to use during reference-tracked serialization + + + + + Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String + + + + + Additional information about a serialization operation + + + + + Gets or sets a user-defined object containing additional information about this serialization/deserialization operation. + + + + + A default SerializationContext, with minimal information. + + + + + Gets or sets the source or destination of the transmitted data. + + + + + Convert a SerializationContext to a StreamingContext + + + + + Convert a StreamingContext to a SerializationContext + + + + + Provides protocol-buffer serialization capability for concrete, attributed types. This + is a *default* model, but custom serializer models are also supported. + + + Protocol-buffer serialization is a compact binary format, designed to take + advantage of sparse data and knowledge of specific data types; it is also + extensible, allowing a type to be deserialized / merged even if some data is + not recognised. + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for + The .proto definition as a string + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for + The .proto definition as a string + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Applies a protocol-buffer stream to an existing instance. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Serializes a given instance and deserializes it as a different type; + this can be used to translate between wire-compatible objects (where + two .NET types represent the same data), or to promote/demote a type + through an inheritance hierarchy. + + No assumption of compatibility is made between the types. + The type of the object being copied. + The type of the new object to be created. + The existing instance to use as a template. + A new instane of type TNewType, with the data from TOldType. + + + + Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination SerializationInfo to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination SerializationInfo to write to. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied XmlWriter. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination XmlWriter to write to. + + + + Applies a protocol-buffer from an XmlReader to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The XmlReader containing the data to apply to the instance (cannot be null). + + + + Applies a protocol-buffer from a SerializationInfo to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The SerializationInfo containing the data to apply to the instance (cannot be null). + + + + Applies a protocol-buffer from a SerializationInfo to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The SerializationInfo containing the data to apply to the instance (cannot be null). + Additional information about this serialization operation. + + + + Precompiles the serializer for a given type. + + + + + Creates a new IFormatter that uses protocol-buffer [de]serialization. + + The type of object to be [de]deserialized by the formatter. + A new IFormatter to be used during [de]serialization. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignored for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + + + + Creates a new instance from a protocol-buffer stream that has a length-prefix + on data (to assist with network IO). + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + How to encode the length prefix. + A new, initialized instance. + + + + Creates a new instance from a protocol-buffer stream that has a length-prefix + on data (to assist with network IO). + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + How to encode the length prefix. + The expected tag of the item (only used with base-128 prefix style). + A new, initialized instance. + + + + Applies a protocol-buffer stream to an existing instance, using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + Indicates the number of bytes expected for the next message. + The stream containing the data to investigate for a length. + The algorithm used to encode the length. + The length of the message, if it could be identified. + True if a length could be obtained, false otherwise. + + + Indicates the number of bytes expected for the next message. + The buffer containing the data to investigate for a length. + The offset of the first byte to read from the buffer. + The number of bytes to read from the buffer. + The algorithm used to encode the length. + The length of the message, if it could be identified. + True if a length could be obtained, false otherwise. + + + + The field number that is used as a default when serializing/deserializing a list of objects. + The data is treated as repeated message with field number 1. + + + + + Provides non-generic access to the default serializer. + + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + Applies a protocol-buffer stream to an existing instance. + The existing instance to be modified (cannot be null). + The binary stream to apply to the instance (cannot be null). + The updated instance + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + Used to resolve types on a per-field basis. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Indicates whether the supplied type is explicitly modelled by the model + + + + + Precompiles the serializer for a given type. + + + + + Global switches that change the behavior of protobuf-net + + + + + + + + + + Maps a field-number to a type + + + + + Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization + operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense + of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers). + + + + + The type that this serializer is intended to work for. + + + + + Perform the steps necessary to serialize this data. + + The value to be serialized. + The writer entity that is accumulating the output data. + + + + Perform the steps necessary to deserialize this data. + + The current value, if appropriate. + The reader providing the input data. + The updated / replacement value. + + + + Indicates whether a Read operation replaces the existing value, or + extends the value. If false, the "value" parameter to Read is + discarded, and should be passed in as null. + + + + + Now all Read operations return a value (although most do); if false no + value should be expected. + + + + Emit the IL necessary to perform the given actions + to serialize this data. + + Details and utilities for the method being generated. + The source of the data to work against; + If the value is only needed once, then LoadValue is sufficient. If + the value is needed multiple times, then note that a "null" + means "the top of the stack", in which case you should create your + own copy - GetLocalWithValue. + + + + Emit the IL necessary to perform the given actions to deserialize this data. + + Details and utilities for the method being generated. + For nested values, the instance holding the values; note + that this is not always provided - a null means not supplied. Since this is always + a variable or argument, it is not necessary to consume this value. + + + + Uses protocol buffer serialization on the specified operation; note that this + must be enabled on both the client and server. + + + + + Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. + + + + + + Creates a new ProtoBehaviorExtension instance. + + + + + Gets the type of behavior. + + + + + Creates a behavior extension based on the current configuration settings. + + The behavior extension. + + + + Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. + + Add the following to the server and client app.config in the system.serviceModel section: + + + + + + + + + + + + + + Configure your endpoints to have a behaviorConfiguration as follows: + + + + + + + + + + + + + Describes a WCF operation behaviour that can perform protobuf serialization + + + + + Create a new ProtoOperationBehavior instance + + + + + The type-model that should be used with this behaviour + + + + + Creates a protobuf serializer if possible (falling back to the default WCF serializer) + + + + + An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[]) + + + + + Attempt to create a new serializer for the given model and type + + A new serializer instance if the type is recognised by the model; null otherwise + + + + Creates a new serializer for the given model and type + + + + + Ends an object in the output + + + + + Begins an object in the output + + + + + Writes the body of an object in the output + + + + + Indicates whether this is the start of an object we are prepared to handle + + + + + Reads the body of an object + + + + + Used to hold particulars relating to nested objects. This is opaque to the caller - simply + give back the token you are given at the end of an object. + + + + + Indicates the encoding used to represent an individual value in a protobuf stream + + + + + Represents an error condition + + + + + Base-128 variant-length encoding + + + + + Fixed-length 8-byte encoding + + + + + Length-variant-prefixed encoding + + + + + Indicates the start of a group + + + + + Indicates the end of a group + + + + + Fixed-length 4-byte encoding + 10 + + + + This is not a formal wire-type in the "protocol buffers" spec, but + denotes a variant integer that should be interpreted using + zig-zag semantics (so -ve numbers aren't a significant overhead) + + + + diff --git a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt.meta b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml.meta similarity index 75% rename from Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt.meta rename to Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml.meta index 97f2abd..a593ed9 100644 --- a/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.LICENSE.txt.meta +++ b/Assets/Photon/PhotonBolt/assemblies/editor/protobuf-net.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e8e508caad5f38141b5a85c4e737ea22 +guid: 0f7d08dded2c86f43afac5c3c1752f98 TextScriptImporter: externalObjects: {} userData: diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.dll b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.dll index 656e6d8..926cad2 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.dll and b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml new file mode 100644 index 0000000..9cca0b4 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml @@ -0,0 +1,1169 @@ + + + + udpkit.common + + + + + Blit manages byte arrays, to read and write data. + + + + + Pack the bool. + + true, if bool was packed, false otherwise. + Bytes array to write to. + Offset inside the byte array. + Bool value to set. + + + + Read bool from the byte array. + + Byte array. + Offset inside the byte array. + The bool + + + + Pack a Byte. + + Bytes array to write to. + Offset inside the byte array. + Byte value to set + + + + Read byte from the byte array + + Byte array. + Offset inside the byte array. + The byte + + + + Get the byte array prefix size + + Byte array + Prefix size + + + + Pack the prefix to the byte array + + Byte array to write + Offset inside the byte array. + Prefix byte array + + + + Read the prefix from the byte array + + Byte array. + Offset inside the byte array. + The prefix data array + + + + Pack byte array + + Byte array. + Offset inside the byte array. + Byte array to pack + Byte array size + + + + Read byte array + + Byte array. + Offset inside the byte array. + Target byte array to be filled. + Target byte array size. + + + + Pack byte array + + Byte array. + Offset inside the byte array. + Byte array to pack + Offset inside the from byte array + From byte array size + + + + Read byte array + + Byte array. + Offset inside the byte array. + Target byte array to insert the data + Offset in the target byte array + Target byte array size + + + + Pack a ushort value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a ushort from the byte array + + Byte array to read the data + Offset on the byte array + ushort value + + + + Pack a int32 value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a int32 from the byte array + + Byte array to read the data + Offset on the byte array + int32 value + + + + Pack a uint32 value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Pack a uint32 value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + Total number of bytes from the uint32 value to insert into the byte array + + + + Read a uint32 from the byte array + + Byte array to read the data + Offset on the byte array + uint32 value + + + + Read a int32 from the byte array + + Byte array to read the data + Offset on the byte array + Total number of bytes from the uint32 value to read from the byte array + uint32 value + + + + Pack a float value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a float from the byte array + + Byte array to read the data + Offset on the byte array + float value + + + + Pack a uint64 value into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a uint64 from the byte array + + Byte array to read the data + Offset on the byte array + uint64 value + + + + Return the total number of bytes needed to encode a string + + Target string + Total number of bytes + + + + Pack string into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a string from the byte array + + Byte array to read the data + Offset on the byte array + string value or null if not found + + + + Read a EndPoint from the byte array + + Byte array to read the data + Offset on the byte array + EndPoint object + + + + Pack EndPoint into the byte array + + Byte array to insert the data + Offset on the byte array + EndPoint object to insert into the byte array + + + + Pack GUID into the byte array + + Byte array to insert the data + Offset on the byte array + Value to be inserted + + + + Read a GUID from the byte array + + Byte array to read the data + Offset on the byte array + GUID object + + + + UPD EndPoint represents an network endpoint + + + + + Native representation of a UdpEndPoint + Used when it's necessary to exchange data between managed and unmanaged code + + + + + Native representation of the IPV4 + + + + + EndPoint Port + + + + + Convert the internal properties into a Managed version of UdpEndPoint + + + + + UdpEndPoint comparer + + + + + Represents Any IPv4 Address + + + + + Represents Any IPv6 Address + + + + + EndPoint Port + + + + + EndPoint ID + + + + + Flag signaling if this EndPoint represents a IPv6 + + + + + EndPoint IPv4 Address + + + + + EndPoint IPv6 Address + + + + + Flag signaling if this EndPoint is a WAN Address + + + + + Flag signaling if this EndPoint is a LAN Address + + + + + Convert this EndPoint from managed to unmanaged + + + + + Build a new UdpEndPoint using a IPv4 Address and Port + + IPv4 Address + Port + + + + Build a new UdpEndPoint using a IPv6 Address and Port + + IPv6 Address + Port + + + + Build a new UdpEndPoint using a ID + + EndPoint ID + + + + Build a new UdpEndPoint using a ID + + EndPoint ID + + + + Compare UdpEndPoints + + Other EndPoint to compare + Order between EndPoints + + + + Test if the other EndPoint is Equals to this one + + Other EndPoint + True if equals, false otherwise + + + + Generates a HashCode based on the EndPoint data + + HashCode for the EndPoint + + + + Test if the other object is equals to this one + + Other object to compare + True if equals, false otherwise + + + + Convert the EndPoint to a string format + + Formatted string + + + + Try to parse Address:Port information to a UdpEndPoint instance + + EndPoint description, accepts IPv4 and IPv6 values + New instance of UdpEndPoint built using the parameter + + + + Test if EndPoints are Equals + + First EndPoint + Second EndPoint + True if equal, false otherwise + + + + Test if EndPoints are NOT Equals + + First EndPoint + Second EndPoint + True if NOT equal, false otherwise + + + + AND Operator between EndPoints + + First EndPoint + Second EndPoint + Result of AND Operator + + + + Represents a custom UdpException + + + + + Represents a IPv4 Address + + + + + UdpIPv4Address comparer + + + + + Static instance of the Comparer + + + + + Represent a IPv4 Any Address 0.0.0.0 + + + + + Represents the localhost IPv4 127.0.0.1 + + + + + Represents the broadcast IPv4 255.255.255.255 + + + + + Stores that 32bit representation address of this IPv4 + + + + const string ip = "82.39.106.191"; // original IP + var ipBytes = IPAddress.Parse(ip).GetAddressBytes(); // get byte array + var ipLong = BitConverter.ToUInt32(ipBytes, 0); // convert to 32bit representation + + + + + + Stores the 1th 8bit of this address + + + + + Stores the 2th 8bit of this address + + + + + Stores the 3th 8bit of this address + + + + + Stores the 4th 8bit of this address + + + + + Build a UdpIPv4Address based on the 32bit address representation + + IPv4 into a 32bit format + + + + Build a UdpIPv4Address based on the 64bit long address in network order + + Address to be used build the UdpIPv4Address + + + + Build a UdpIPv4Address based on each byte that represents a part of the full IP + + 1th part of the IP + 2th part of the IP + 3th part of the IP + 4th part of the IP + + + + Signal if this IP represents a Any IP + + + + + Signal if this IP represents a Localhost IP + + + + + Signal if this IP represents a Broadcast IP + + + + + Signal if this IP represents a Private IP + + + + + Signal if this IP presents a WAN IP + + + + + Parse a string into a UdpIPv4Address + + String address to be parsed + UdpIPv4Address reference based on the IP + It will throw FormatException if the address in the string is not propertly formatted + + + + Represents a IPv6 Address + + + + + UdpIPv6Address Comparer + + + + + Comparer instance + + + + + Represents the IPv6 Any address + + + + + Stores the IPv6 Mask with 16 bytes + + + + + Represents the IPv6 Localhost address + + + + + Represents the 1th 64bits of the IPv6 Address in long format + + + + + Represents the 2th 64bits of the IPv6 Address in long format + + + + + Signal if this is Any address, with all address positions as 0 + + + + + Signal if this is a Localhost address + + + + + Signal if this is a broadcast address, always false + + + + + Signal if this is a WAN address + + + + + Signal if this is a private IPv6 + + + + + Get the full bytes that makes this IPv6 address + + + + + Build a new UdpIPv6Addressbased on the byte array passed as argument + + Byte array with values to build the IPv6 address + + + + Build a UdpIPv6Address based on the packet values representation + + 1th part of the address + 2th part of the address + + + + Check if two UdpIPv6Address are equal + + Other UdpIPv6Address to check + True if equal, false otherwise + + + + Compare two UdpIPv6Address + + Other UdpIPv6Address to compare + 1 if this IPv6 is greater, -1 otherwise, 0 if equal + + + + Build the hash code of this UdpIPv6Address + + int that represents the Hash code for this address + + + + Check if a object is equals to this UdpIPv6Address + + Object to compare + True if equal, false otherwise + + + + Check if this UdpIPv6Address is equal to another UdpIPv6Address + + UdpIPv6Address to compare + the UdpIPv6Address counterpart to compare + True if equal, false otherwise + + + + Check if this UdpIPv6Address is NOT equal to another UdpIPv6Address + + UdpIPv6Address to compare + the UdpIPv6Address counterpart to compare + True if not equal, false otherwise + + + + Parse a String IP into a UdpIPv6Address + + String formatted IP address to be parsed + UdpIPv6Address built based on the IP string + Will throw ArgumentException if it's not a valid IP address + + + + Apply a AND operator between all bits for both UdpIPv6Address + + UdpIPv6Address 1 to merge + UdpIPv6Address 2 to merge + A new UdpIPv6Address that results of the AND operation between the pair of UdpIPv6Address + + + + Clone this instance. + + The clone. + + + + Returns a that represents the current . + + A that represents the current . + + + + UDP session source. + + + + + LAN Source + + + + + Photon Service Source + + + + + None of the other source + + + + + Udp Session Error Enum + + + + + OK + + + + + A game with same ID already exists + + + + + The game server is full + + + + + The game server is closed + + + + + The game with the ID was not found + + + + + Generic error + + + + + Base class for a UDPKit session. + This class represents a session that can be used as starting point for a connection when Direct IP + connection is not available. + + + + + Gets the session identifier. + + + + + Gets the session source. + + + + + Gets the WAN end point of this Session. + + + + + Gets the LAN end point of this Session. + + + + + Arbitrary Object that can be set on the session. It's used to save the Session Token. + Same as , but in byte array form. + + + + + Arbitrary Object that can be set on the session. It's used to save the Session Token. + + + + + Gets the max connections allowed on this session. + + + + + Gets the current total of connections. + + The connections current. + + + + Gets the host name that is publishing this session. + + + + + Gets a value indicating whether this is dedicated server. + + true if is dedicated server; otherwise, false. + + + + Gets a value indicating whether this has WAN Address. + + true if has wan; otherwise, false. + + + + Gets a value indicating whether this has lan. + + true if has lan; otherwise, false. + + + + Clone this instance. + + The clone. + + + + UDPKit session Implementation. + This class represents a session that can be used as starting point for a connection when Direct IP + connection is not available. + + + + + Build a new UdpSession based on the Host ID string + + Host ID, just an string that identify the source of the session + UdpSession reference + + + + Gets the session identifier. + + + + + Gets the session source. + + + + + Gets the WAN end point of this Session. + + + + + Gets the LAN end point of this Session. + + + + + Gets the max connections allowed on this session. + + + + + Gets the current total of connections. + + The connections current. + + + + Gets the host name that is publishing this session. + + + + + Gets a value indicating whether this is dedicated server. + + true if is dedicated server; otherwise, false. + + + + Gets a value indicating whether this has WAN Address. + + true if has wan; otherwise, false. + + + + Gets a value indicating whether this has lan. + + true if has lan; otherwise, false. + + + + Arbitrary Object that can be set on the session. It's used to save the Session Token. + Same as , but in byte array form. + + + + + Arbitrary Object that can be set on the session. It's used to save the Session Token. + + + + + Clone this instance using + + The clone. + + + + UDP steam identifier. + + + + + The Steam identifier. + + + + + Initializes a new instance of the struct. + + Identifier. + + + + Represents a Singleton instance, just for Utility + + + + + + Instance lock + + + + + Public instance reference + + + + + Determines how the Sessions are filled with new players + when the peer joins the session in a random fashion + + + + + Fills up rooms (oldest first) to get players together as fast as possible. Default. + + + + + Distributes players across available rooms sequentially but takes filter into account. Without filter, rooms get players evenly distributed. + + + + + Joins a (fully) random room. Expected properties must match but aside from this, any available room might be selected. + + + + + Used to filter only specific sessions that agree with the desired parameters when joining a session in a random fashion. + + + + + Configure the fill mode used to join a session. + Default is . + + + + + UdpSession filter constructor + + + + + Adds a filter parameter. + + true, if the parameter was added, false otherwise. + Parameter Key. + Parameter Value. + + + + Removes a filter parameter. + + true, if the parameter was removed, false otherwise. + Parameter Key. + + + + Index operator to read and write values. + + Parameter Key + Parameter Value, if exists + + + + Get a Enumerator reference based on the internal Filter dictionary + + Dictionary.Enumerator reference + + + + String representation of the SessionFilter + + String representation + + + + Test if the object passed as argument is a valid Type to be used as filter parameter + + Value to be tested + true if is a valid Type, false otherwise + + + + Set of IPAddress extension methods + + + + + Extract the Broadcast address from an IP based on the sub-net mask + + Base Address + Subnet Mark + Broadcast address of the network + + + + Get the base IP address based on the Subnet mask + + IP address to verify + Subnet mask + Base IP + + + + Check if two IP seems to be on the same subnet based on the sub-net mask + + Base address to check + Target address to check + Subnet mask used for the check + True if both IPs seems to be on the same subnet + + + + Check if two IP seems to be on the same subnet based on all major classes of Submask + + Base address to check + Target address to check + True if both IPs seems to be on the same subnet in at least one case + + + + Check if a IPAdress describes a private IP + + IPAdress to check + True if it is private, false otherwise + + + + Converts a IPAddress into the long representation of the internal IP + + IPAddress to be converted + long representation of the IPAddress + + + + Convert a Long value into a IPAddress + + Value to convert + IPAddres Result + + + + Class to store and represents IP Submasks + + + + + Represents a Class A subnet + + + + + Represents a Class B subnet + + + + + Represents a Class C subnet + + + + + Create a Submask based on the number of bits for the HOST + + Number of bit of the host part + IPAddress that represents the network mask + + + + Create a Subnet mask based on the number of bits for the MASK + + Number of bit of the sub net mask + IPAddress that represents the network mask + + + + Create a subnet mask based on the number of hosts that need to be available + + Number of host in the subnet + IPAddress that represents the network mask + + + + UdpEndPoint conversion methods + + Using those methods you can convert UdpEndPoint between and classes + + + + + Convert to + + EndPoint to be converted + UdpEndPoint + + + + Convert to + + IPEndPoint to be converted + UdpEndPoint + + + + Convert to + + UdpEndPoint to be converted + IPEndPoint + + + + Convert to + + IPAddress to be converted + UdpIPv4Address + + + diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml.meta b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml.meta new file mode 100644 index 0000000..ca72306 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.common.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 977268033c4bb4371b7729b87f50e59e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.dll b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.dll index febd70a..7e79dec 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.dll and b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.dll b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.dll index 33a5717..c0749d8 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.dll and b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml new file mode 100644 index 0000000..b765629 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml @@ -0,0 +1,18 @@ + + + + udpkit.platform.dotnet + + + + + DotNetPlatform responsible for connecting peers directly based on the public IP + + + + + DotNetPlatform constructor + + + + diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml.meta b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml.meta new file mode 100644 index 0000000..abdbac0 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.dotnet.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cdeeb9e5429884839b1294297a769b67 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.null.dll b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.null.dll index bc2add9..9fc3bba 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.null.dll and b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.null.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.dll b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.dll index e99e4cc..09de436 100644 Binary files a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.dll and b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.dll differ diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml new file mode 100644 index 0000000..8d9990f --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml @@ -0,0 +1,362 @@ + + + + udpkit.platform.photon + + + + + Platform used to connect with the Photon Cloud + + + + + Reference to a Configuration struct used to setup the PhotonPlatform + + + + + Constructor for PhotonPlatform based on a PhotonPlatformConfig + + PhotonPlatformConfig reference used to configure the instance + + + + This class will act as a controller and bridge to the underlayng layer of Photon Realtime, + receiving/sending/treating messages using the Photon services. + + + + + Creates the Photon Poller instance. This will populate the internal instance with one of: + (i) If there is no instances of PhotonPoller in the scene, it will create a new one. + (ii) If there is only 1 instance of PhotonPoller in the scene, it will use this as the main instance. + (iii) If there is more then 1 instance in the scene, it will destroy copies but one, and use it as the main instance. + + + + void CreatePollerExample() + { + PhotonPoller.CreatePoller(new PhotonPlatformConfig().InitDefaults(), true); + } + + + Configuration used to setup the PhotonPoller instance. + If set to true will destroy the current main instance, in order to create a new one. + + + + Starts the LoadBalancingClient. + + End point. + Callback that will be invoked at the end of the operation + + + + Register a Type that fully implements PhotonPoller to be used as the main instance. + + An External Type that extends PhotonPoller. + + + + Creates a new PhotonPoller instance based on the External Type. + + Photon poller variable to be populated. + + + + Pushes out all queued messages on the list and send through Photon services + using as Event code. + + + + + Setup host info based on a + + true, if host info was set, false otherwise. + Session information. + Callback result that will be invoked at the end of the operation + + + + This is a wrapper around the Photon Rooms used to expose the same API as the UdpSession + + + + + Builds a Photon Session with only it's identifier name. This can be useful if you want to connect + to a specific session using the name of the room. + + An session with only it's name. + Room name. + + + + Dictionary like structure that stores all properties of the room + + + + + Signal if this session is open or not + + + + + Signal if this session is visible or not + + + + + Signal if this session is hosted by a dedicated server + + + + + Signal the source of this Session, in this case always + + + + + Signal if this game session is published by a Server with NAT Punch enabled + + + + + The current connection status + + + + + Represents a Photon Region on the Cloud Service + + + + + List of available regions + + + + + Map of the Regions Enum and the PhotonRegion struct, that holds meta data from the Regions + + + + + Region CODE + + + + + Region Full Name + + + + + City where the data center os located + + + + + Region ENUM value + + + + + Get a Region info based on the region code as string + + Region Code + PhotonRegion reference if exists + It will throw an Exception if no Region was found with the Code + + + + Get a Region metadata based on the Region enum + + Region enum to look for + PhotonRegion reference + + + + Build a string representation of the Region + + String describing the Region + + + + This class will act as the Corroutine manager from Unity and will run and control corroutines. + + + + + Gets the current Master client of the current Room. + + The master client ID if the client in inside a Room, -1 otherwise. + + + + Retry Join lobby ? + true = yes + false = no + null = wait to leave the room + + + + + A thread which runs independent from the Update() calls. + Keeps connections online while loading or in background. + + + + + + Internal class to encapsulate the network i/o functionality for the realtime libary. + + + + + Build a new custom Socket UDP + + Base Peer used for communication + + + + Dispose the UDP Socket + + + + + Dispose implementation + + + + + Start the connection with the Cloud service + + + + + + Disconnect from the Cloud service + + True if all went fine when disconnecting + + + used by PhotonPeer* + + + + Receive data + + + + Endless loop, run in Receive Thread. + + + + Photon Platform configuration class. + It holds the main configuration settings to setup the PhotonPlatform + + + + + Photon Application ID + + + + + Custom Authentication Credentials + + + + + Region to Connect to. See + + + + + Set to true, to enable the Punch Through behavior. + + + + + Selects the Connection Protocol used by the internal LoadBalancingClient when exchanging data with Photon Cloud + + + + + Selects the Serializaion Protocol used by the internal LoadBalancingClient when exchanging data with Photon Cloud + + + + + This suppresses the STUN process and forces the usage of the configured IPEndPoint as the external endpoint + used to punch to this peer. This is mainly focused when you are running a GameServer on a dedicated cloud service + + + + + Gets or sets the room creation timeout in seconds. + Min 10 sec, max 60 sec. + + The room creation timeout. + + + + Gets or sets the room join timeout in seconds. + Min 10 sec, max 60 sec. + + The room join timeout. + + + + Gets the max number of connections acceptable in the room. + + + + + Amount of time the background connection with the Photon Servers will be maintained until + timeout and stop sending acknowledge messages. + + + + + Current Running platform + + + + + Total Connection Request Attempts + + + + + Total Connection LAN Request Attempts + + + + + PhotonPlatformConfig constructor. + It will also initilize the configuration using the default settings + + + + + Initialize the Photon Configuration with the values from Bolt Settings + + The defaults. + + + + Save a Region as the Best Region on the Bolt Settings + + Region to save. + + + + Valids an String as containing a AppID + + true, if app identifier was valid, false otherwise. + Value. + + + diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml.meta b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml.meta new file mode 100644 index 0000000..e123fd9 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.platform.photon.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 466b35d91223b459f8cc968917525534 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml new file mode 100644 index 0000000..ac9640c --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml @@ -0,0 +1,1751 @@ + + + + udpkit + + + + + Represents a simple Object Pool manager + + + + + + Internal Object Pool + + + + + Check if the Pool has any Pooled Object + + True if there is any object to be reused on the pool + + + + Object Pool Constructor + + + + + Returns an instance to the Object Pool + + Object to the returned to Pool + + + + Returns a valid reference from the Pool. + If there is a old object on the Pool, returns it, if not, create a new one. + + Reference from the Object Pool + + + + Responsible to create and validate Hashs + + + + + Size of SHA256 Key in bytes + + + + + Hasher reference + + + + + Temporary array used to check the hash + + + + + Hash Secret + + + + + Return the hasher reference or create one if not created yet + + + + + Create a new Hash Packet Validator based on a Secret string + + Base64 encoded secret + + + + Create and append a Hash based on the data passed as argument + + Data array to create the hash + Length of the data array + Length of data array after append hash + + + + Validate the included hash on the data array passed as argument + + Data array to verify hash + Length of the data array + True if the data was not tempered and the hash match, false otherwise + + + + Get the length of the data without the hash data + + Data array to check + Length of the data array + Length of data array without the hash part + + + + Check if the buffer contains the same verified hash + + Data array to test the hash + Verified hash used to check + True if the buffer contains the same hash and is valid, false otherwise + + + + Generates a 32 bytes random key that can be used as Hash secret + + Byte Array with 32 random bytes + + + + Responsible for keep track of unique IDs for each UdpEndPoint connection + + + + + Registry of UdpEndPoint and ID of received data + + + + + Registry of UdpEndPoint and ID of sent data + + + + + Byte Converter reference + + + + + Size in Bytes of the Unique ID + + + + + Construct a new PacketIdValidator + + + + + Prefix an unique ID based on the into a data array + + UdpEndPoint used to keep the unique ID + Data array to include the ID + Length of the data array + Length of data array after include the unique ID + + + + Validate an packet based on the included unique ID and + + UdpEndPoint used to check the unique ID + Data array to check ID + Length of data array with ID + Length of data array without the unique ID + + + + Prefix the passed ID into the buffer + + ID to be prefixed + Buffer array to prefix the array + Length of the buffer data array + + + + Clear all registered IDs + + + + + Remove the registry from one specific UdpEndPoint + + EndPoint to remove the info + + + + Responsible for encrypting and decrypting data buffers + + TODO Implement the usage of a new IV and Salt for each encrypted package + + + + Internal decryptor created based on the Key and IV received as argument + + + + + Internal encryptor created based on the Key and IV received as argument + + + + + Internal AES Implementation reference + + + + + Internal encryptor reference + + + + + Internal decryptor reference + + + + + AES Key + + + + + AES Initialization Vector (IV) + + + + + Builds the SocketDataEncryption instance + + Initialization Vector + AES Key + + + + Encrypt data in place and return it's length. Doing this to avoid allocating unnecessary data. + + The data to encrypt + Length of the data to encrypt + Length after encryption + + + + Encrypt data and return a new byte array. + + The data to encrypt + Length of the data to encrypt + Byte array with data encrypted + + + + Decrypt the data and copy it in the data array passed. + + Data to decrypt + Length of the data to decrypt + Length of the data decrypted + + + + Decrypt the data and return a new buffer array. + + Data to decrypt + Length of the data to decrypt + Byte array with data decrypted + + + + Transform the data array based on the received + as argument. The resulting data is set on the same received buffer. + + Data array to be processed + Data array length + Crypto transform reference + Buffer used as temporary memory for to process + Length of data array after the transformation + + + + Transform the data array based on the received + as argument. The resulting data is returned as a new buffer. + + Data array to be processed + Data array length + Crypto transform reference + New buffer with the result of the transformation + + + + Build a new AES Implementation + + Concrete implementation of an AES Algorithm + + + + Generate a Random KEY to be used with an AES Algorithm + + Byte array with a Random Key + + + + Generate a Random IV to be used with an AES Algorithm + + Byte array with a Random IV + + + + Interface for classes that manage the encryption/decryption of byte arrays + + + + + Decrypt the data and copy it in the data array passed. + + Data to decrypt + Length of the data to decrypt + Length of the data decrypted + + + + Decrypt the data and return a new buffer array. + + Data to decrypt + Length of the data to decrypt + Byte array with data decrypted + + + + Encrypt data in place and return it's length. Doing this to avoid allocating unnecessary data. + + The data to encrypt + Length of the data to encrypt + Length after encryption + + + + Encrypt data and return a new byte array. + + The data to encrypt + Length of the data to encrypt + Byte array with data encrypted + + + + Interface for classes that manage the hashing of byte arrays + + + + + Create and append a Hash based on the data passed as argument + + Data array to create the hash + Length of the data array + Length of data array after append hash + + + + Validate the included hash on the data array passed as argument + + Data array to verify hash + Length of the data array + True if the data was not tempered and the hash match, false otherwise + + + + Get the length of the data without the hash data + + Data array to check + Length of the data array + Length of data array without the hash part + + + + Interface for classes to validate a package via an unique ID + + + + + Prefix an unique ID based on the into a data array + + UdpEndPoint used to keep the unique ID + Data array to include the ID + Length of the data array + Length of data array after include the unique ID + + + + Validate an packet based on the included unique ID and + + UdpEndPoint used to check the unique ID + Data array to check ID + Length of data array with ID + Length of data array without the unique ID + + + + Removes any reference of a particular UdpEndPoint + This can be useful when the remote endpoint disconnects + + UdpEndPoint to remove the internal references + + + + Responsible for managing all Encryption steps used on UdpKit + + + + + Signals that the Encryption system was properly setup + + + + + AES IV + + + + + AES Key + + + + + Hash Secret + + + + + Buffer encryption reference + + + + + Hasher reference + + + + + ID Validator reference + + + + + Initialize the Encryption system generating all necessary keys + + You can later access the keys, in order to exchange with a remote connection, by looking at the right members: + , and + + + + + Initialize the Encryption system with all necessary keys + + AES Initilization Vector + AES Key + Hash Key + + + + Reset all encryption variables + + + + + Encrypt a packet for a specific EndPoint + + Target EndPoint for this packet + Data buffer array + Length of the buffer array + Total length of byte array after encryption + + + + Decrypt a packet from an specific EndPoint + + Remote EndPoint + Data buffer array + Length of the buffer array + Total length of byte array after decryption + + + + Clears any references for a particular UdpEndPoint + + Target UdpEndPoint to + + + + Convert Plain String into a Base64 encoded string + + Plain Text to encode + Custom Encoding + Base64 encoded string + + + + Convert a Base64 encoded string into a Plain String + + Base64 string to decode + Custom Encoding + Plain String + + + + Generates a new Random AES Key + + Random AES Key + + + + Generates a new Random AES Initialization Vector + + Random AES Initialization Vector + + + + Generates a new Random Hash Secret key + + Random Hash Secret key + + + + LAN endpoint of this socket + + + + + WAN endpoint of this socket + + + + + The current state of the socket + + + + + The current mode of the socket + + + + + PeerId of this socket + + + + + The precision time (in ms) of the underlying socket platform + + + + + Current packet pool for this socket + + + + + A user-assignable object + + + + + Start this socket + + The endpoint to bind to + + + + + + Close this socket + + + + + Invoked when the application is about the Quit + + + + + Connect to remote endpoint + + The endpoint to connect to + + + + + Cancel ongoing attempt to connect to endpoint + + The endpoint to cancel connect attempt to + Signal if the cancel should be + + + + Accept a connection + + Accept the connection signaled by this UdpEndPoint + Arbitrary object that can store data on the Connection + Accept Token + + + + Refuse a connection request from a remote endpoint + + Refuse the connection signaled by this UdpEndPoint + Refuse Token + + + + A list of all currently available sessions + + + + + Poll socket for any events + + The current event on this socket + True if a new event is available, False otherwise + + + + This method runs asynchonously in order to update the network state. + It process any pending data on the internal socket and build the event streams + + + + + Represents the block of data received from a StreamChannel + + + + + Data received + + + + + Channel from where the peer received the data + + + + + Creates a new UdpChannelStreammer + + Connection to where this streammer will send data + Stream Channel used to send data to the connection + + + + Enqueue a new block of data to be sent on the Reliable Stream Pipe + + Byte array to be sent + + + + Remove incomming and outgoing streams + + + + + Mark a block of data as lost on the Stream Operation + + Stream Operation to perform the change + Block ID to mark as lost + + + + Mark a block of data as delivered on the Stream Operation + + Stream Operation to perform the change + Block ID to mark as delivered + + + + Try to send data from any pending Stream Channel + + True if it was able to send ONE block of data, false otherwise + + + + Treats a data buffer array with content for a Stream Operation + + Data buffer + Number of bytes received + Offset from where to start the data + + + + Initialize the Stream Operation with the CRC value + + Stream Operation to be initialized + CRC value + + + + Sends a block of data from the Stream Operation to the target Connection + + Stream Operation to get the block of data + Block identification to be sent + True if the block was sent, false otherwise + + + + Treats an incomming buffer in order to be aggregated into the local Stream Operation + + Stream Operation to where the data should be inserted + Data received + Number of bytes received + Current offset from where to start to read the data + + + + Signal that a new Stream has started + + Stream Operation used to extract data + + + + Signal that a Stream has been received + + Stream Operation used to extract data + + + + Signal that a Stream has been aborted + + Stream Operation used to extract data + + + + Signal that a Stream had some progress + + Stream Operation used to extract data + + + + A user-assignable object + + + + + The round-trip time of the network layer, excluding processing delays and ack time + + + + + The total round-trip time, including processing delays and ack + + + + + If this connection is a client + + + + + IF this connections a server + + + + + If we are connected + + + + + The remote end point + + + + + How much of the current outgoing packet window is waiting for acks + + + + + Send an object on this connection + + The object to send + + + + Disconnect this connection forcefully with the specified token and disconnectReason. + + Arbitrary Token sent within the disconnect event. + Disconnect reason. By default it just points to + + + + Event to change the Stream Bandwidth + + Byte rate to send data + + + + Enqueue a new block of data to be sent on the desired streaming channel + + Channel identifier to where send the data + Data array to send + + + + Changes the Stream Bandwidth + + Calculates the interval in which data will be sent: + + The interval is calculated into interval of milliseconds + 1000ms = 1s + byteRate is the desired bandwidth, 20kbp/s (1024 * 20) for example + The max package size from the configs, 4096 for example + + ex: 20 kb/s + 1000 / ((1024 * 20) / 4096) = 200ms + send data every 200ms + + Byte rate to send data. The rate in bytes / sec + + + + Clear all existent streams + + + + + Progress any pending outgoing data stream based on the the Data Rate previously configured + + Current timestamp + + + + Enqueue a new Stream Operation for transmission. + How the data will be sent depends on which channel it is been sent. + If it's on an Unreliable channel, this will be a one-try send, if it's on a Reliable stream, the operation will + be queued on a Channel Streamer to be sent properly. + + Channel identifier to where send the data + Stream Operation that contains the data to be sent + + + + Treats a new block of data that was received on the Unreliable Stream Pipe + + Data buffer received + Total number of bytes received + + + + Treats a new block of data that was received on the Reliable Stream Pipe + The byte array will be processed to find the responsible channel to receive and store the data + + Data buffer received on the stream pipe + Total number of bytes received + + + + Signal to a Stream Channel that a block was lost + + Data block that was lost + + + + Signal to a Stream Channel that a block was delivered + + Data block delivered + + + + Try to send any pending outgoing stream of data + The streams are sorted by priority before being sent + + + + + Describes Stream channel + + + + + Channel Name + + + + + Stream channel configuration + + + + + Signal if this Channel is Unreliable + + + + + Singal if this Channel is Reliable + + + + + Enable IPv6 Support, default: false + + + + + The default network ping for new connections, default: 0.1f (seconds) + + + + + The default aliased ping for new connections, default: 0.15f (seconds) + + + + + If we allow serialization to overflow MTU of the connection, default: false + + + + + The timeout until we should make a new connect request, default: 1000 (milliseconds) + + + + + How many attempts we should make to connect before failing, default: 5 + + + + + How many attempts we should make to connect before failing, default: 5 + + + + + How long before we time-out a connection we have not heard anything from, default: 5000 (ms) + + + + + How long we should wait to send a ping packet to the remote end if we + have not sent anything recently, default: 100 (ms) + + + + + How many packets we can receive before we force an ack packet to be sent, default: 8 + + + + + How many connections we allow, default: 64 + + + + + If we allow incomming connections, default: true + + + + + IF we automatically accept incomming connections if we have slots free, default: true + + + + + If we allow clients which are connecting to a server to implicitly accept the connection + if we get a non-rejected and non-accepted packet from the server, meaning the accept packet + was lost, default: true + + + + + How many % of the packets we should drop to simulate packet loss, default: 0. Only used in DEBUG builds. + + + + + Min ping we should simulate, default: 0 (ms). Only used in DEBUG builds. + + + + + Max ping we should simulate, default: 0 (ms). Only used in DEBUG builds. + + + + + Custom noise function for use in packet loss simulation, default: null + + + + + Reason why a connection got disconnected + + + + + Unknown reason (should never happen) + + + + + Remote end timed out (connection was lost) + + + + + Internal socket error (corrupted sequence numbers, send window overflowed, etc.) + + + + + Normal disconnect triggered by user code + + + + + The peer failed to authenticate on any step + + + + + The max connection limit with the cloud service was reached + + + + + Unkown connection type, represents an invalid connection (should never happen) + + + + + Represents a connection that has direct connectivity with the other end + + + + + Represents a connection that makes use of a relay to maintain the connectivity with the other end + + + + + TheadManager class acts as a Thread Pool implementation. + It manages an internal list of Workers responsible for running of the main thread any Action passed to them + The threads are created at request and only when necessary. + + + + + Collection of available Workers of the ThreadManager. + All Tasks are created at runtime and reused if possible + + + + + ThreadManager constructor. + + Initializes the private list of Workers (Threads) + + + + + Invoke the Abort method on all registered Tasks and clear them from the internal list. + + + + + Return a summary of the current state of the internal Tasks, how many were created and the total number of running tasks. + + + + + + Runs the Action on an available Task. + + The action that should run on a separate Thread + + + + Searches in the internal Task list for an available worker that was initialized but it is not running any action + at the moment. If the list is empty or all Tasks are busy, a new Task is created and added to the list of workers. + + An initialized and free Task that can be used to run an Action + + + + Task is a wrapper class around a Thread and acts as a Worker manager. + It's possible to initialize the Task and give works (Action) using the run method to be executed + by the internal Thread. + This wrapper will keep the Thread running until aborted (gracefully using Abort, or abruptly using ForceAbort) + + + + + Returns if there is an action being executed by the Task + + + + + Unique identifier of this Task + + + + + Private managed Thread + + + + + Private semaphore to coordinate the execution of the internal Thread + + + + + Action being executed by the Thread + + + + + Thread locker used to sync the access to the internal Action + + + + + Flag to signal to the Thread if it should continue to work or should Abort gracefully. + + + + + Task constructor. + + Initializes all main fields, including the managed Thread as a background thread. + This implies that the Task will not block the main thread of exiting the application. + + + + + Updates the action the must be executed by the Thread. + + Action to be executed + + + + Aborts gracefully the internal Thread. + This signals the thread that it should stop working, but the shutdown is not immediate. + + + + + Force Abort the internal Thread. + This causes the Thread to be aborted using + + + + + Private action manager. + This is the main body of the internal Thread, and it waits until an action need to be executed. + + + + + Signal if this package is writable + + + + + A user-assignable object + + + + + Total length in bits of the internal buffer + + + + + Current position within the internal buffer + + + + + Signal if this Packet is full. If its current is equals + to its total + + + + + Signal if the packet is overflowing. If its current is greater than + its total + + + + + Buffer that will contain all Packet data + + + + + Signal if this Packet is Pooled or not + + + + + Buffer that will contain all Packet data + + + + + UdpPacket Pool reference, used when disposing of it's usage, returning it to the pool + + + + + Current position within the internal buffer + + + + + Total length in bits of the internal buffer + + + + + Check if the Packet has 1 bit available for write + + True if you can write 1 bit, false otherwise + + + + Check if the Packet has 1 bit available for read + + True if you can read 1 bit, false otherwise + + + + Check if the Packet has N bit available for write + + Number of bits available to write + True if you can write N bit, false otherwise + + + + Check if the Packet has N bit available for read + + Number of bits available to read + True if you can read N bit, false otherwise + + + + Get a copy of the internal buffer + + Copy of data buffer + + + + Write a bool to the buffer + + Bool to be written + The bool value written + + + + Read a bool from the buffer + + Bool value from the buffer + + + + Write a byte into the buffer + + Byte value to write + Number of bits to use when writing + + + + Read a byte from the buffer + + Number of bits to use when reading + Byte value + + + + Write a byte into the buffer + + Byte to be written + + + + Read a byte from the buffer + + Byte read + + + + Write a ushort into the buffer + + UShort to be written + Number of bits to use when writing + + + + Read a ushort from the buffer + + Number of bits to use when reading + UShort value + + + + Write a ushort into the buffer + + UShort to be written + + + + Read a ushort from the buffer + + UShort value + + + + Write a short into the buffer + + Short value to be written + Number of bits to use when writing + + + + Read a short from the buffer + + Number of bits to use when reading + Short value + + + + Write a short into the buffer + + Short value to be written + + + + Read a short from the buffer + + Short value + + + + Serialize a uint into the buffer if the Packet is in Write mode, or read from the buffer otherwise + + UInt value to be written or read + Number of bits to use when writing or reading + + + + Serialize a int into the buffer if the Packet is in Write mode, or read from the buffer otherwise + + Int value to be written or read + Number of bits to use when writing or reading + + + + Write a uint into the buffer + + UInt value to be written + Number of bits to use when writing + + + + Read a uint from the buffer + + Number of bits to use when reading + UInt value + + + + Write a uint into the buffer + + UInt value to be written + + + + Read a uint from the buffer + + UInt value + + + + Write an int value + + Value to be written + Number of bits to write + Number of bits to shift + + + + Read an int value + + Number of bits to read + Number of bits to shift + Int value + + + + Write a int into the buffer + + Int value to be written + Number of bits to use when writing + + + + Read a int from the buffer + + Number of bits to use when reading + Int value + + + + Write a int into the buffer + + UInt value to be written + + + + Read a int from the buffer + + Int value + + + + Write a ulong into the buffer + + ULong value to be written + Number of bits to use when writing + + + + Read a ulong from the buffer + + Number of bits to use when reading + ULong value + + + + Write a ulong into the buffer + + ULong value to be written + + + + Read a ulong from the buffer + + ULong value + + + + Write a long into the buffer + + Long value to be written + Number of bits to use when writing + + + + Read a long from the buffer + + Number of bits to use when reading + Long value + + + + Write a long into the buffer + + Long value to be written + + + + Read a long from the buffer + + Long value + + + + Write a float into the buffer + + Float value to be written + + + + Read a float from the buffer + + Float value + + + + Write a double into the buffer + + Double value to be written + + + + Read a double from the buffer + + Double value + + + + Write a byte array into the buffer + + Byte array to be written + + + + Write a byte array into the buffer + + Byte array to be written + Number of elements to be written + + + + Write a byte array into the buffer + + Byte array to be written + Offset from the beginning of the array + Number of elements to be written + + + + Read byte array from the buffer + + Number of elements to read + Byte array extracted from the buffer + + + + Populate byte array with data from the internal buffer + + Byte array to be filled with data + + + + Populate byte array with data from the internal buffer + + Byte array to be filled with data + Number of element to be read + + + + Populate byte array with data from the internal buffer + + Byte array to be filled with data + Offset from the beginning of the array + Number of element to be read + + + + Write a byte array into the buffer with a prefix to delimit its size + + Byte array to be written + + + + Write a byte array into the buffer with a prefix to delimit its size + + Byte array to be written + Max length of the array + + + + Read a byte array with prefix + + Byte array extracted from the buffer + + + + Write a string into the buffer + + String value to be written + String encoding + + + + Write a string into the buffer + + String value to be written + String encoding + Max length of the string to be written + + + + Write a string into the buffer using UTF8 as Encoding + + String value to be written + + + + Read string from the buffer + + String encoding + String value + + + + Read string from the buffer + + String value + + + + Write a GUID into the buffer + + GUID to be written + + + + Read a GUID from the buffer + + GUID value + + + + Serialize an UdpEndPoint into the buffer + + EndPoint to be written + + + + Read an UdpEndPoint from the buffer + + UdpEndPoint value + + + + Write value into the buffer using the position and number of bits to be written + + Buffer where the value will be written + Position where to write the byte value + Number of bits used to write the byte + Byte value to be written + + + + Dispose this UdpPacket and return it to the Pool + + + + + String version of UdpPacket + + String value + + + + Write a byte value into internal buffer + + Byte value to be written + Number of bits used to write the byte + + + + Read a byte value from the internal buffer + + Number of bits used to read the byte + Byte value + + + + Number of Bytes to define the Message type + + + + + Number of Bytes to define the Ping value on the Messages + + + + + ID of the UdpPipe + + + + + Signal if the Pipe should update the calculated Ping of the connection + + + + + Timeout of the Pipe + + + + + Size of the buffer for sending and receiving data on the Pipe + + + + + Max size of the packet sent by the Pipe + + + + + Number of bytes used to acknowledge packet + + + + + Number of bytes used to store the sequence number + + + + + Number of bits to store the sequence number + + + + + Number of bits to store the acknowledge number + + + + + Total number of bytes of the Packet header + + + + + Total number of bits of the Packet header + + + + + Calculates the next sequence number based on the previous one + + Base sequence number + Next valid sequence number + + + + Calculates the distance between two sequence numbers + + Starting sequence number + Ending sequence number + Distance between sequence numbers + + + + Implements a 32-bit CRC hash algorithm compatible with Zip etc. + + + Crc32 should only be used for backward compatibility with older file formats + and algorithms. It is not secure enough for new applications. + If you need to call multiple times for the same data either use the HashAlgorithm + interface or remember that the result of one Compute call needs to be ~ (XOR) before + being passed in as the seed for the next Compute call. + + + + diff --git a/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml.meta b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml.meta new file mode 100644 index 0000000..8b9a7b7 --- /dev/null +++ b/Assets/Photon/PhotonBolt/assemblies/udpkit/udpkit.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 734bc4dbb6fac4f6a812df0a21d514e3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png new file mode 100644 index 0000000..6414e06 Binary files /dev/null and b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png differ diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png.meta new file mode 100644 index 0000000..f94dea8 --- /dev/null +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_application_lightning.png.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: fbdd77e23c6e7491290cf1ceff99d323 +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: 0 + 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} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_down.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_down.png.meta index 69af087..e6a2e17 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_down.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_down.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 3c4b4acee515bb3479c96f509fe1f6cc -timeCreated: 1490777304 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_right.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_right.png.meta index 6c82e64..1f5e506 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_right.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_right.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 161b4d230ed08564daad7d09083c6538 -timeCreated: 1490777304 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_up.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_up.png.meta index 9b2b974..3b96b89 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_up.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_arrow_up.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: d87dd3beca62fcf458ce65158ad8fec2 -timeCreated: 1490777304 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png new file mode 100644 index 0000000..a14b00a Binary files /dev/null and b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png differ diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png.meta new file mode 100644 index 0000000..9a86c04 --- /dev/null +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_brick_edit.png.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: 7e35d582a6767485091d8b4d5db34c5e +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: 0 + 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} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_bubble.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_bubble.png.meta index 89946a7..d340ea6 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_bubble.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_bubble.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 0c7f28a242364f0458ed5114aa541b97 -timeCreated: 1490777309 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_command.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_command.png.meta index 7bb2608..0a3a96b 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_command.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_command.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 166a2e10025e17146bffafa20205c077 -timeCreated: 1490777304 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile.png.meta index 89ddaed..f4446c0 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: eb980f3940e89714a8af3748ec3e4a5c -timeCreated: 1490777304 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly.png.meta index e1149c9..8f1dede 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 6c44b77a81ec33f449ed6289a925dc47 -timeCreated: 1490777305 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png new file mode 100644 index 0000000..9df0939 Binary files /dev/null and b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png differ diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png.meta new file mode 100644 index 0000000..d1a0b37 --- /dev/null +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_compile_assembly_run.png.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: 92d411b293fba42c5b52ac617d9d5a70 +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: 0 + 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} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png new file mode 100644 index 0000000..d07d5fd Binary files /dev/null and b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png differ diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png.meta new file mode 100644 index 0000000..9d4af5a --- /dev/null +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_computer.png.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: 8b2e40ca92b9e45bd8ab38e43c05969f +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: 0 + 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} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_connection.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_connection.png.meta index 79fd05d..edc31b6 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_connection.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_connection.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 6ca70d8abcc781f488c54a0ed9455a45 -timeCreated: 1490777305 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller.png.meta index 3edb2f9..ae4ccbd 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: c2694bc8bf2e64b45b8de294bf91ba76 -timeCreated: 1490777305 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_only.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_only.png.meta index 2e85a81..b4c2b0a 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_only.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_only.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: b86659b819360f944acb165f0464ac3c -timeCreated: 1490777309 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_plus.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_plus.png.meta index 5da3c81..08a3c9d 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_plus.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_plus.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: bc805cfca89b5954f8003c58ad90f963 -timeCreated: 1490777310 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png new file mode 100644 index 0000000..fd281bb Binary files /dev/null and b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png differ diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png.meta new file mode 100644 index 0000000..3a51547 --- /dev/null +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_controller_single.png.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: 3fc8ffe214eaa4c06b41c61d68cc6c50 +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: 0 + 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} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_debugplay.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_debugplay.png.meta index 16a0d71..bbf5728 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_debugplay.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_debugplay.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 0fa46567be031894893605b4f46eba47 -timeCreated: 1490777305 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_devicetype.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_devicetype.png.meta index 4ac244b..2950888 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_devicetype.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_devicetype.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: cd3b01487a4edd34ba27f159cf498292 -timeCreated: 1490777305 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_download.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_download.png.meta index 46a1f1d..8f22ecb 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_download.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_download.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 5e005d7ea84015f42998262a01f6033d -timeCreated: 1490777306 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_event.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_event.png.meta index 061a392..7aebd25 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_event.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_event.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 0d430e2b64f276a4e8b92ba115a40230 -timeCreated: 1490777306 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_group.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_group.png.meta index 45f515a..6fc1c25 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_group.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_group.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: e49db1c5d167eb141b526e5a425ce4b4 -timeCreated: 1490777306 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_input.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_input.png.meta index 54f3011..b92f445 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_input.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_input.png.meta @@ -2,32 +2,39 @@ fileFormatVersion: 2 guid: db441fcbd1a095b45b51e77fca15dadd TextureImporter: fileIDToRecycleName: {} - serializedVersion: 2 + externalObjects: {} + serializedVersion: 4 mipmaps: mipMapMode: 0 enableMipMap: 0 + sRGBTexture: 0 linearTexture: 1 - correctGamma: 0 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 - heightScale: .25 + heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 - generateCubemap: 0 + generateCubemap: 6 + cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: - filterMode: 0 + serializedVersion: 2 + filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -35,13 +42,65 @@ TextureImporter: spriteExtrude: 1 spriteMeshType: 1 alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 alphaIsTransparency: 1 + spriteTessellationDetail: -1 textureType: 2 - buildTargetSettings: [] + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: + serializedVersion: 2 sprites: [] + outline: [] + physicsShape: [] spritePackingTag: userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ipaddress.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ipaddress.png.meta index f36eb45..bd22de4 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ipaddress.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ipaddress.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 53bf4912ae5d86841bf021b7c4b8fb7b -timeCreated: 1490777306 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_masterserver.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_masterserver.png.meta index d8c867b..50762bf 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_masterserver.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_masterserver.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: c15ab68cd7d4d5a4c84d0991a44b616f -timeCreated: 1490777311 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus.png.meta index d572b9a..abfe4ea 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 84354f1dab644fe4a8296aeaa957499f -timeCreated: 1490777306 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus_small.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus_small.png.meta index a3f31e8..5089dec 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus_small.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_minus_small.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: ccf4fd28342f7f84faa90b11020a3ef6 -timeCreated: 1490777309 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_name.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_name.png.meta index acd1ca9..086bc18 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_name.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_name.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 44e09c2b23445cc4faa9cb3643a98912 -timeCreated: 1490777307 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_nat.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_nat.png.meta index 0522fcd..db9d6fb 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_nat.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_nat.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 3004fdfd7b380d24ea1d41e6b0cd824f -timeCreated: 1490777307 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_owner_only.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_owner_only.png.meta index d1902ac..551fd90 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_owner_only.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_owner_only.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 185e3c8a9b7b092409f4719a9eda9d4a -timeCreated: 1490777310 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping.png.meta index 93e767c..5c943e7 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 3ab8af6f28d8c354fbf8be402705b50b -timeCreated: 1490777309 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping_sim.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping_sim.png.meta index 1a436e8..b203fcd 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping_sim.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_ping_sim.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 44f6709a886a87b44aaefe962240eb4d -timeCreated: 1490777310 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_plus.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_plus.png.meta index 4a0ca99..9807d7d 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_plus.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_plus.png.meta @@ -2,32 +2,39 @@ fileFormatVersion: 2 guid: 9a01ab0f45d13264da6ca9c9ec720d99 TextureImporter: fileIDToRecycleName: {} - serializedVersion: 2 + externalObjects: {} + serializedVersion: 4 mipmaps: mipMapMode: 0 enableMipMap: 0 + sRGBTexture: 0 linearTexture: 1 - correctGamma: 0 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 - heightScale: .25 + heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 - generateCubemap: 0 + generateCubemap: 6 + cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: -3 maxTextureSize: 32 textureSettings: - filterMode: 0 + serializedVersion: 2 + filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -35,13 +42,65 @@ TextureImporter: spriteExtrude: 1 spriteMeshType: 1 alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 alphaIsTransparency: 1 + spriteTessellationDetail: -1 textureType: 2 - buildTargetSettings: [] + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: + serializedVersion: 2 sprites: [] + outline: [] + physicsShape: [] spritePackingTag: userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_position.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_position.png.meta index 1e66d56..4450c72 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_position.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_position.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: d74f9d3d83e3eab41a4e148e1c0e525f -timeCreated: 1490777310 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_refresh.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_refresh.png.meta index 3d7f648..9b7bac7 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_refresh.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_refresh.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 4bc574f7937c4d34ba73aaf859020176 -timeCreated: 1490777307 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_replication.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_replication.png.meta index d62f9ce..3fcd963 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_replication.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_replication.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: d6bf1d8b84458174b908acc15ee69ad5 -timeCreated: 1490777307 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_rotation.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_rotation.png.meta index deb4c92..ac21815 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_rotation.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_rotation.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 358a845f37ebf5e4898647c7c6db4d71 -timeCreated: 1490777310 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_save.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_save.png.meta index 7eaad4a..a227fe9 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_save.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_save.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 836117d75f888d84f86879d363179ac2 -timeCreated: 1490777307 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_scenes.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_scenes.png.meta index 0cf10f5..dac82ac 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_scenes.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_scenes.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: da39664b00aaba94f9d072486a6b98a1 -timeCreated: 1490777308 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_server.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_server.png.meta index b68a5fe..1613a6e 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_server.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_server.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: a8eae4b01de4e904ebc6882bfe97d89e -timeCreated: 1490777308 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_settings.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_settings.png.meta index c4111e0..3637fce 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_settings.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_settings.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: ee400fcaeb078e74690829590e541fee -timeCreated: 1490777308 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state.png.meta index b9ae6ef..600112c 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 79a653d17c0339c4ebe7ee2cc59dd7d5 -timeCreated: 1490777308 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state2.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state2.png.meta index e969876..19c24de 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state2.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_state2.png.meta @@ -2,32 +2,39 @@ fileFormatVersion: 2 guid: d8d4d9a81f468a94081f2bb98a61d8e5 TextureImporter: fileIDToRecycleName: {} - serializedVersion: 2 + externalObjects: {} + serializedVersion: 4 mipmaps: mipMapMode: 0 enableMipMap: 0 + sRGBTexture: 0 linearTexture: 1 - correctGamma: 0 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 - heightScale: .25 + heightScale: 0.25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 - generateCubemap: 0 + generateCubemap: 6 + cubemapConvolution: 0 seamlessCubemap: 0 textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -35,13 +42,65 @@ TextureImporter: spriteExtrude: 1 spriteMeshType: 1 alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePivot: {x: 0.5, y: 0.5} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 alphaIsTransparency: 1 + spriteTessellationDetail: -1 textureType: 2 - buildTargetSettings: [] + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: + serializedVersion: 2 sprites: [] + outline: [] + physicsShape: [] spritePackingTag: userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_struct.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_struct.png.meta index 146c35b..2ff4167 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_struct.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_struct.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 0795a0ae526a57e4abaa2b329245f85d -timeCreated: 1490777308 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_upload.png.meta b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_upload.png.meta index 4cd1aba..d4b2540 100644 --- a/Assets/Photon/PhotonBolt/editor/resources/icons/mc_upload.png.meta +++ b/Assets/Photon/PhotonBolt/editor/resources/icons/mc_upload.png.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 guid: 469247da248c92b4385668e611ea2ebc -timeCreated: 1490777309 -licenseType: Store TextureImporter: fileIDToRecycleName: {} + externalObjects: {} serializedVersion: 4 mipmaps: mipMapMode: 0 @@ -12,6 +11,8 @@ TextureImporter: linearTexture: 1 fadeOut: 0 borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: @@ -27,10 +28,13 @@ TextureImporter: textureFormat: 5 maxTextureSize: 32 textureSettings: + serializedVersion: 2 filterMode: 1 aniso: 1 mipBias: -1 - wrapMode: 1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 0 lightmap: 0 compressionQuality: 50 @@ -39,8 +43,9 @@ TextureImporter: spriteMeshType: 1 alignment: 0 spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 alphaIsTransparency: 1 spriteTessellationDetail: -1 @@ -52,16 +57,49 @@ TextureImporter: platformSettings: - buildTarget: DefaultTexturePlatform maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: iPhone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 textureFormat: -1 textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + androidETC2FallbackOverride: 0 spriteSheet: serializedVersion: 2 sprites: [] outline: [] + physicsShape: [] spritePackingTag: userData: assetBundleName: diff --git a/Assets/Photon/PhotonBolt/editor/scripts/AccountService.cs b/Assets/Photon/PhotonBolt/editor/scripts/AccountService.cs index baaa681..639e432 100644 --- a/Assets/Photon/PhotonBolt/editor/scripts/AccountService.cs +++ b/Assets/Photon/PhotonBolt/editor/scripts/AccountService.cs @@ -6,315 +6,315 @@ using System; using UnityEngine; using System.Collections.Generic; -namespace Bolt.Utils +namespace Photon.Bolt.Utils { - /// - /// Creates a instance of the Account Service to register Photon Cloud accounts. - /// - public class AccountService - { - private const string ServiceUrl = "https://partner.photonengine.com/api/Unity/User/RegisterEx"; - - private readonly Dictionary requestHeaders = new Dictionary - { - {"Content-Type", "application/json"}, - {"x-functions-key", "VQ920wVUieLHT9c3v1ZCbytaLXpXbktUztKb3iYLCdiRKjUagcl6eg=="} - }; - - /// - /// Attempts to create a Photon Cloud Account asynchronously. - /// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt. - /// - /// Email of the account. - /// Defines which type of Photon-service is being requested. - /// Called when the result is available. - public bool RegisterByEmail(string email, string serviceTypes, Action callback = null, - Action errorCallback = null) - { - if (IsValidEmail(email) == false) - { - Debug.LogErrorFormat("Email \"{0}\" is not valid", email); - return false; - } - - if (string.IsNullOrEmpty(serviceTypes)) - { - Debug.LogError("serviceTypes string is null or empty"); - return false; - } - - AccountServiceRequest req = new AccountServiceRequest(); - req.Email = email; - req.ServiceTypes = serviceTypes; - return this.RegisterByEmail(req, callback, errorCallback); - } - - public bool RegisterByEmail(string email, List serviceTypes, - Action callback = null, Action errorCallback = null) - { - if (serviceTypes == null || serviceTypes.Count == 0) - { - Debug.LogError("serviceTypes list is null or empty"); - return false; - } - - return this.RegisterByEmail(email, GetServiceTypesFromList(serviceTypes), callback, errorCallback); - } - - public bool RegisterByEmail(AccountServiceRequest request, Action callback = null, - Action errorCallback = null) - { - if (request == null) - { - Debug.LogError("Registration request is null"); - return false; - } - - StartCoroutine( - HttpPost(GetUrlWithQueryStringEscaped(request), - requestHeaders, - null, - s => - { - if (string.IsNullOrEmpty(s)) - { - if (errorCallback != null) - { - errorCallback( - "Server's response was empty. Please register through account website during this service interruption."); - } - } - else - { - AccountServiceResponse ase = this.ParseResult(s); - if (ase == null) - { - if (errorCallback != null) - { - errorCallback( - "Error parsing registration response. Please try registering from account website"); - } - } - else if (callback != null) - { - callback(ase); - } - } - }, - e => - { - if (errorCallback != null) - { - errorCallback(e); - } - }) - ); - return true; - } - - private static string GetUrlWithQueryStringEscaped(AccountServiceRequest request) - { - string email = UnityEngine.Networking.UnityWebRequest.EscapeURL(request.Email); - string st = UnityEngine.Networking.UnityWebRequest.EscapeURL(request.ServiceTypes); - return string.Format("{0}?email={1}&st={2}", ServiceUrl, email, st); - } - - /// - /// Reads the Json response and applies it to local properties. - /// - /// - private AccountServiceResponse ParseResult(string result) - { - try - { - AccountServiceResponse res = JsonUtility.FromJson(result); - // Unity's JsonUtility does not support deserializing Dictionary, we manually parse it, dirty & ugly af, better then using a 3rd party lib - if (res.ReturnCode == AccountServiceReturnCodes.Success) - { - string[] parts = result.Split(new[] {"\"ApplicationIds\":{"}, - StringSplitOptions.RemoveEmptyEntries); - parts = parts[1].Split('}'); - string applicationIds = parts[0]; - if (!string.IsNullOrEmpty(applicationIds)) - { - parts = applicationIds.Split(new[] {',', '"', ':'}, StringSplitOptions.RemoveEmptyEntries); - res.ApplicationIds = new Dictionary(parts.Length / 2); - for (int i = 0; i < parts.Length; i = i + 2) - { - res.ApplicationIds.Add(parts[i], parts[i + 1]); - } - } - else - { - Debug.LogError( - "The server did not return any AppId, ApplicationIds was empty in the response."); - return null; - } - } - - return res; - } - catch (Exception ex) // probably JSON parsing exception, check if returned string is valid JSON - { - Debug.LogException(ex); - return null; - } - } - - private static string GetServiceTypesFromList(List appTypes) - { - if (appTypes != null) - { - string serviceTypes = string.Empty; - if (appTypes.Count > 0) - { - serviceTypes = ((int) appTypes[0]).ToString(); - for (int i = 1; i < appTypes.Count; i++) - { - int appType = (int) appTypes[i]; - serviceTypes = string.Format("{0},{1}", serviceTypes, appType); - } - } - - return serviceTypes; - } - - return null; - } - - // RFC2822 compliant matching 99.9% of all email addresses in actual use today - // according to http://www.regular-expressions.info/email.html [22.02.2012] - private static Regex reg = new Regex( - "^((?>[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+\\x20*|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\"\\x20*)*(?<))?((?!\\.)(?>\\.?[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+)+|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\")@(((?!-)[a-zA-Z\\d\\-]+(?)$", - RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); - - public static bool IsValidEmail(string mailAddress) - { - if (string.IsNullOrEmpty(mailAddress)) - { - return false; - } - - var result = reg.Match(mailAddress); - return result.Success; - } - - //https://forum.unity.com/threads/using-unitywebrequest-in-editor-tools.397466/#post-4485181 - private static void StartCoroutine(System.Collections.IEnumerator update) - { - EditorApplication.CallbackFunction closureCallback = null; - - closureCallback = () => - { - try - { - if (update.MoveNext() == false) - { - EditorApplication.update -= closureCallback; - } - } - catch (Exception ex) - { - Debug.LogException(ex); - EditorApplication.update -= closureCallback; - } - }; - - EditorApplication.update += closureCallback; - } - - private static System.Collections.IEnumerator HttpPost(string url, Dictionary headers, - byte[] payload, Action successCallback, Action errorCallback) - { - using (UnityWebRequest w = new UnityWebRequest(url, "POST")) - { - if (payload != null) - { - w.uploadHandler = new UploadHandlerRaw(payload); - } - - w.downloadHandler = new DownloadHandlerBuffer(); - if (headers != null) - { - foreach (var header in headers) - { - w.SetRequestHeader(header.Key, header.Value); - } - } + /// + /// Creates a instance of the Account Service to register Photon Cloud accounts. + /// + public class AccountService + { + private const string ServiceUrl = "https://partner.photonengine.com/api/Unity/User/RegisterEx"; + + private readonly Dictionary requestHeaders = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-functions-key", "VQ920wVUieLHT9c3v1ZCbytaLXpXbktUztKb3iYLCdiRKjUagcl6eg=="} + }; + + /// + /// Attempts to create a Photon Cloud Account asynchronously. + /// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt. + /// + /// Email of the account. + /// Defines which type of Photon-service is being requested. + /// Called when the result is available. + public bool RegisterByEmail(string email, string serviceTypes, Action callback = null, + Action errorCallback = null) + { + if (IsValidEmail(email) == false) + { + Debug.LogErrorFormat("Email \"{0}\" is not valid", email); + return false; + } + + if (string.IsNullOrEmpty(serviceTypes)) + { + Debug.LogError("serviceTypes string is null or empty"); + return false; + } + + var req = new AccountServiceRequest(); + req.Email = email; + req.ServiceTypes = serviceTypes; + return RegisterByEmail(req, callback, errorCallback); + } + + public bool RegisterByEmail(string email, List serviceTypes, + Action callback = null, Action errorCallback = null) + { + if (serviceTypes == null || serviceTypes.Count == 0) + { + Debug.LogError("serviceTypes list is null or empty"); + return false; + } + + return RegisterByEmail(email, GetServiceTypesFromList(serviceTypes), callback, errorCallback); + } + + public bool RegisterByEmail(AccountServiceRequest request, Action callback = null, + Action errorCallback = null) + { + if (request == null) + { + Debug.LogError("Registration request is null"); + return false; + } + + StartCoroutine( + HttpPost(GetUrlWithQueryStringEscaped(request), + requestHeaders, + null, + s => + { + if (string.IsNullOrEmpty(s)) + { + if (errorCallback != null) + { + errorCallback( + "Server's response was empty. Please register through account website during this service interruption."); + } + } + else + { + var ase = ParseResult(s); + if (ase == null) + { + if (errorCallback != null) + { + errorCallback( + "Error parsing registration response. Please try registering from account website"); + } + } + else if (callback != null) + { + callback(ase); + } + } + }, + e => + { + if (errorCallback != null) + { + errorCallback(e); + } + }) + ); + return true; + } + + private static string GetUrlWithQueryStringEscaped(AccountServiceRequest request) + { + var email = UnityWebRequest.EscapeURL(request.Email); + var st = UnityWebRequest.EscapeURL(request.ServiceTypes); + return string.Format("{0}?email={1}&st={2}", ServiceUrl, email, st); + } + + /// + /// Reads the Json response and applies it to local properties. + /// + /// + private AccountServiceResponse ParseResult(string result) + { + try + { + var res = JsonUtility.FromJson(result); + // Unity's JsonUtility does not support deserializing Dictionary, we manually parse it, dirty & ugly af, better then using a 3rd party lib + if (res.ReturnCode == AccountServiceReturnCodes.Success) + { + var parts = result.Split(new[] { "\"ApplicationIds\":{" }, + StringSplitOptions.RemoveEmptyEntries); + parts = parts[1].Split('}'); + var applicationIds = parts[0]; + if (!string.IsNullOrEmpty(applicationIds)) + { + parts = applicationIds.Split(new[] { ',', '"', ':' }, StringSplitOptions.RemoveEmptyEntries); + res.ApplicationIds = new Dictionary(parts.Length / 2); + for (var i = 0; i < parts.Length; i = i + 2) + { + res.ApplicationIds.Add(parts[i], parts[i + 1]); + } + } + else + { + Debug.LogError( + "The server did not return any AppId, ApplicationIds was empty in the response."); + return null; + } + } + + return res; + } + catch (Exception ex) // probably JSON parsing exception, check if returned string is valid JSON + { + Debug.LogException(ex); + return null; + } + } + + private static string GetServiceTypesFromList(List appTypes) + { + if (appTypes != null) + { + var serviceTypes = string.Empty; + if (appTypes.Count > 0) + { + serviceTypes = ((int)appTypes[0]).ToString(); + for (var i = 1; i < appTypes.Count; i++) + { + var appType = (int)appTypes[i]; + serviceTypes = string.Format("{0},{1}", serviceTypes, appType); + } + } + + return serviceTypes; + } + + return null; + } + + // RFC2822 compliant matching 99.9% of all email addresses in actual use today + // according to http://www.regular-expressions.info/email.html [22.02.2012] + private static Regex reg = new Regex( + "^((?>[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+\\x20*|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\"\\x20*)*(?<))?((?!\\.)(?>\\.?[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+)+|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\")@(((?!-)[a-zA-Z\\d\\-]+(?)$", + RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); + + public static bool IsValidEmail(string mailAddress) + { + if (string.IsNullOrEmpty(mailAddress)) + { + return false; + } + + var result = reg.Match(mailAddress); + return result.Success; + } + + //https://forum.unity.com/threads/using-unitywebrequest-in-editor-tools.397466/#post-4485181 + private static void StartCoroutine(System.Collections.IEnumerator update) + { + EditorApplication.CallbackFunction closureCallback = null; + + closureCallback = () => + { + try + { + if (update.MoveNext() == false) + { + EditorApplication.update -= closureCallback; + } + } + catch (Exception ex) + { + Debug.LogException(ex); + EditorApplication.update -= closureCallback; + } + }; + + EditorApplication.update += closureCallback; + } + + private static System.Collections.IEnumerator HttpPost(string url, Dictionary headers, + byte[] payload, Action successCallback, Action errorCallback) + { + using (var w = new UnityWebRequest(url, "POST")) + { + if (payload != null) + { + w.uploadHandler = new UploadHandlerRaw(payload); + } + + w.downloadHandler = new DownloadHandlerBuffer(); + if (headers != null) + { + foreach (var header in headers) + { + w.SetRequestHeader(header.Key, header.Value); + } + } #if UNITY_2017_2_OR_NEWER - yield return w.SendWebRequest(); + yield return w.SendWebRequest(); #else yield return w.Send(); #endif - while (w.isDone == false) - yield return null; + while (w.isDone == false) + yield return null; #if UNITY_2017_1_OR_NEWER - if (w.isNetworkError || w.isHttpError) + if (w.isNetworkError || w.isHttpError) #else if (w.isError) #endif - { - if (errorCallback != null) - { - errorCallback(w.error); - } - } - else - { - if (successCallback != null) - { - successCallback(w.downloadHandler.text); - } - } - } - } - } - - [Serializable] - public class AccountServiceResponse - { - public int ReturnCode; - public string Message; - - public Dictionary - ApplicationIds; // Unity's JsonUtility does not support deserializing Dictionary - } - - [Serializable] - public class AccountServiceRequest - { - public string Email; - public string ServiceTypes; - } - - public class AccountServiceReturnCodes - { - public static int Success = 0; - public static int EmailAlreadyRegistered = 8; - public static int InvalidParameters = 12; - - public static readonly Dictionary ReturnCodes = new Dictionary() - { - {Success, "Success"}, - {EmailAlreadyRegistered, "Email Already Registered"}, - {InvalidParameters, "Invalid Parameters"} - }; - } - - public enum ServiceTypes - { - Realtime = 0, - Turnbased = 1, - Chat = 2, - Voice = 3, - TrueSync = 4, - Pun = 5, - Thunder = 6, - Bolt = 20 - } + { + if (errorCallback != null) + { + errorCallback(w.error); + } + } + else + { + if (successCallback != null) + { + successCallback(w.downloadHandler.text); + } + } + } + } + } + + [Serializable] + public class AccountServiceResponse + { + public int ReturnCode; + public string Message; + + public Dictionary + ApplicationIds; // Unity's JsonUtility does not support deserializing Dictionary + } + + [Serializable] + public class AccountServiceRequest + { + public string Email; + public string ServiceTypes; + } + + public class AccountServiceReturnCodes + { + public static int Success = 0; + public static int EmailAlreadyRegistered = 8; + public static int InvalidParameters = 12; + + public static readonly Dictionary ReturnCodes = new Dictionary() + { + {Success, "Success"}, + {EmailAlreadyRegistered, "Email Already Registered"}, + {InvalidParameters, "Invalid Parameters"} + }; + } + + public enum ServiceTypes + { + Realtime = 0, + Turnbased = 1, + Chat = 2, + Voice = 3, + TrueSync = 4, + Pun = 5, + Thunder = 6, + Bolt = 20 + } } -#endif \ No newline at end of file +#endif diff --git a/Assets/Photon/PhotonBolt/editor/scripts/BoltExecutionOrderManager.cs b/Assets/Photon/PhotonBolt/editor/scripts/BoltExecutionOrderManager.cs index d166de4..4b48e9e 100644 --- a/Assets/Photon/PhotonBolt/editor/scripts/BoltExecutionOrderManager.cs +++ b/Assets/Photon/PhotonBolt/editor/scripts/BoltExecutionOrderManager.cs @@ -1,75 +1,84 @@ -using System; +using System; using System.Collections.Generic; +using Photon.Bolt.Utils; using UnityEditor; -using UnityEngine; -[InitializeOnLoad] -public static class BoltExecutionOrderManager +namespace Photon.Bolt.Editor { - static BoltExecutionOrderManager() + [InitializeOnLoad] + public static class BoltExecutionOrderManager { - Dictionary monoScripts = new Dictionary(); - - foreach (MonoScript monoScript in MonoImporter.GetAllRuntimeMonoScripts()) + static BoltExecutionOrderManager() { - try + Dictionary monoScripts = new Dictionary(); + + foreach (MonoScript monoScript in MonoImporter.GetAllRuntimeMonoScripts()) { - switch (monoScript.name) + try { - case "BoltPoll": - SetExecutionOrder(monoScript, -10000); - break; + switch (monoScript.name) + { + case "BoltPoll": + SetExecutionOrder(monoScript, -10000); + break; - case "BoltSend": - SetExecutionOrder(monoScript, +10000); - break; + case "BoltSend": + SetExecutionOrder(monoScript, +10000); + break; - case "BoltEntity": - SetExecutionOrder(monoScript, -2500); - break; + case "BoltEntity": + SetExecutionOrder(monoScript, -2500); + break; - default: - if (monoScripts.ContainsKey(monoScript.name)) - { - monoScripts[monoScript.name] = monoScript; - } - else - { - monoScripts.Add(monoScript.name, monoScript); - } - break; + default: + if (monoScripts.ContainsKey(monoScript.name)) + { + monoScripts[monoScript.name] = monoScript; + } + else + { + monoScripts.Add(monoScript.name, monoScript); + } + break; + } } + catch { } } - catch { } - } - foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) - { - foreach (var type in asm.GetTypes()) + try { - if (monoScripts.ContainsKey(type.Name)) + foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { - try + foreach (var type in asm.GetTypes()) { - foreach (BoltExecutionOrderAttribute attribute in type.GetCustomAttributes(typeof(BoltExecutionOrderAttribute), false)) + if (monoScripts.ContainsKey(type.Name)) { - SetExecutionOrder(monoScripts[type.Name], attribute.executionOrder); + try + { + foreach (BoltExecutionOrderAttribute attribute in type.GetCustomAttributes(typeof(BoltExecutionOrderAttribute), false)) + { + SetExecutionOrder(monoScripts[type.Name], attribute.executionOrder); + } + } + catch (Exception exn) + { + BoltLog.Exception(exn); + } } } - catch (Exception exn) - { - BoltLog.Exception(exn); - } } } + catch (Exception) + { + } } - } - static void SetExecutionOrder(MonoScript script, Int32 executionOrder) - { - if (MonoImporter.GetExecutionOrder(script) != executionOrder) + static void SetExecutionOrder(MonoScript script, Int32 executionOrder) { - MonoImporter.SetExecutionOrder(script, executionOrder); + if (MonoImporter.GetExecutionOrder(script) != executionOrder) + { + MonoImporter.SetExecutionOrder(script, executionOrder); + } } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonBolt/editor/scripts/BoltUtils.cs b/Assets/Photon/PhotonBolt/editor/scripts/BoltUtils.cs index 7d44ce1..38bef78 100644 --- a/Assets/Photon/PhotonBolt/editor/scripts/BoltUtils.cs +++ b/Assets/Photon/PhotonBolt/editor/scripts/BoltUtils.cs @@ -1,19 +1,20 @@ -using System; -using System.Collections; +using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using Bolt.Editor; +using Photon.Bolt.Editor.Utils; using UnityEditor; using UnityEngine; -namespace Bolt.Utils +namespace Photon.Bolt.Utils { public static class MenuUtililies { + private const string DLL_SUFIX_DEBUG = ".debug"; + private const string DLL_SUFIX_RELEASE = ".release"; + // ======= PUBLIC METHODS ===================================================================================== - [MenuItem("Bolt/Utils/Find Missing Scripts", priority = 25)] + [MenuItem("Photon Bolt/Utils/Find Missing Scripts", priority = 125)] public static void FindMissingScriptsMenu() { BoltLog.Info("Searching for Missing Scripts"); @@ -23,7 +24,15 @@ namespace Bolt.Utils } } - [MenuItem("Bolt/Utils/Change DLL Mode", priority = 26)] + [MenuItem("Photon Bolt/Utils/Remove Missing Scripts", priority = 126)] + public static void RemoveMissingScriptMenu() + { + BoltLog.Info("Removing Missing Scripts"); + + RemoveMissingScripts(); + } + + [MenuItem("Photon Bolt/Utils/Change DLL Mode", priority = 127)] public static void ChangeDllModeMenu() { var current = BoltNetwork.IsDebugMode ? "Debug" : "Release"; @@ -35,11 +44,11 @@ namespace Bolt.Utils { if (ChangeDllMode()) { - UnityEngine.Debug.LogFormat("Bolt Mode swiched to {0}.", target); + Debug.LogFormat("Bolt Mode swiched to {0}.", target); } else { - UnityEngine.Debug.LogError("Error while swithing Bolt Mode, changes were reverted."); + Debug.LogError("Error while swithing Bolt Mode, changes were reverted."); } } } @@ -48,25 +57,25 @@ namespace Bolt.Utils { return SwitchDebugReleaseMode(BoltNetwork.IsDebugMode); } - + // ======= PRIVATE METHODS ===================================================================================== public static int FindMissingComponents() { - int missingScriptsCount = 0; - List components = new List(); + var missingScriptsCount = 0; + var components = new List(); - var folders = new string[] { "Assets" }; + var folders = new string[] { "Assets" }; var iter = AssetDatabase.FindAssets("t:Prefab", folders).GetEnumerator(); while (iter.MoveNext()) { - var guid = (string) iter.Current; + var guid = (string)iter.Current; var path = AssetDatabase.GUIDToAssetPath(guid); var go = AssetDatabase.LoadAssetAtPath(path); go.GetComponentsInChildren(true, components); - for (int j = 0; j < components.Count; ++j) + for (var j = 0; j < components.Count; ++j) { if (components[j] == null) { @@ -85,16 +94,49 @@ namespace Bolt.Utils return missingScriptsCount; } + public static void RemoveMissingScripts() + { + var folders = new string[] { "Assets" }; + var iter = AssetDatabase.FindAssets("t:Prefab", folders).GetEnumerator(); + + while (iter.MoveNext()) + { + var guid = (string)iter.Current; + var path = AssetDatabase.GUIDToAssetPath(guid); + var go = AssetDatabase.LoadAssetAtPath(path); + + var result = RemoveFromGO(go); + + if (result > 0) + { + BoltLog.Info("Removed scripts from {0}", path); + } + } + } + + private static int RemoveFromGO(GameObject go) + { + var result = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(go); + + for (int i = 0; i < go.transform.childCount; i++) + { + var child = go.transform.GetChild(i); + result += RemoveFromGO(child.gameObject); + } + + return result; + } + private static bool SwitchDebugReleaseMode(bool debug) { - var from = debug ? ".debug" : ".release"; - var to = debug ? ".release" : ".debug"; + var from = debug ? DLL_SUFIX_DEBUG : DLL_SUFIX_RELEASE; + var to = debug ? DLL_SUFIX_RELEASE : DLL_SUFIX_DEBUG; var paths = new string[] { - BoltPathUtility.BoltDllPath, - BoltPathUtility.BoltCompilerDLLPath, - BoltPathUtility.BoltEditorDLLPath + BoltPathUtility.BoltDllPath, + BoltPathUtility.BoltCompilerDLLPath, + BoltPathUtility.BoltEditorDLLPath }; var abort = false; @@ -109,14 +151,33 @@ namespace Bolt.Utils backup = FileUtils.BackupFile(path); FileUtils.ExchangeFile(path, from, to); } - catch (IOException) + catch (IOException ex) { - FileUtils.BackupFile(path, true); + Debug.LogError("Aborting..."); + Debug.LogException(ex); abort = true; + + try + { + FileUtils.BackupFile(path, true); + } + catch (Exception ex2) + { + Debug.LogException(ex2); + } } finally { - FileUtils.DeleteFile(backup); + try + { + FileUtils.DeleteFile(backup); + } + catch (Exception ex) + { + Debug.LogException(ex); + } + + backup = ""; } } @@ -140,20 +201,27 @@ namespace Bolt.Utils { if (File.Exists(to)) { return; } - UnityEngine.Debug.LogFormat("Moving file from {0} to {1}", from, to); + if (from.EndsWith(DLL_SUFIX_DEBUG) || from.EndsWith(DLL_SUFIX_RELEASE)) + { + DeleteFile(string.Format("{0}.meta", from)); + } + + Debug.LogFormat("Moving file from {0} to {1}", from, to); File.Move(from, to); } public static string BackupFile(string path, bool restore = false) { - var backup = path + ".backup"; + var backup = string.Format("{0}.backup", path); if (restore) { + Debug.LogFormat("Restore backup from file {0}", backup); File.Copy(backup, path, true); } else { + Debug.LogFormat("Creating backup from file {0}", path); File.Copy(path, backup, true); } @@ -163,8 +231,9 @@ namespace Bolt.Utils public static void DeleteFile(string path) { if (string.IsNullOrEmpty(path) || File.Exists(path) == false) { return; } + Debug.LogFormat("Removing file {0}", path); File.Delete(path); } } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindow.cs b/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindow.cs index 022a2aa..6b8922c 100644 --- a/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindow.cs +++ b/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindow.cs @@ -1,775 +1,778 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Text.RegularExpressions; -using System.Threading; -using Bolt.Utils; +using Photon.Bolt.Editor.Utils; +using Photon.Bolt.Utils; using UnityEditor; using UnityEngine; -using Debug = UnityEngine.Debug; +using EditorUtility = UnityEditor.EditorUtility; -[InitializeOnLoad] -public partial class BoltWizardWindow : EditorWindow +namespace Photon.Bolt.Editor { - BoltSetupStage currentStage = BoltSetupStage.Intro; - static Stopwatch watch = new Stopwatch(); + using Event = UnityEngine.Event; - static Boolean? Ready; - static Single? FirstCall; - private static volatile bool requestingAppId = false; + [InitializeOnLoad] + public partial class BoltWizardWindow : EditorWindow + { + BoltSetupStage currentStage = BoltSetupStage.Intro; + static Stopwatch watch = new Stopwatch(); - static bool RunCompiler; + static Boolean? Ready; + static Single? FirstCall; + private static volatile bool requestingAppId = false; - static String FirstStartupKey - { - get { return "$Bolt$First$Startup$Wizard/" + BoltNetwork.Version; } - } + static bool RunCompiler; - static Vector2 WindowSize; - static Vector2 WindowPosition; + static String FirstStartupKey + { + get { return "$Bolt$First$Startup$Wizard/" + BoltNetwork.Version; } + } + + static Vector2 WindowSize; + static Vector2 WindowPosition; + + static string AppIdOrEmail = ""; + + [NonSerialized] Func beforeNextCallback; + + [NonSerialized] Dictionary packageInfo; + + [NonSerialized] int ButtonWidth; + + [NonSerialized] int NavMenuWidth; + + [NonSerialized] string ReleaseHistoryHeader; + [NonSerialized] List ReleaseHistoryTextAdded; + [NonSerialized] List ReleaseHistoryTextChanged; + [NonSerialized] List ReleaseHistoryTextFixed; + [NonSerialized] List ReleaseHistoryTextRemoved; + + // GUI + + [NonSerialized] Texture2D introIcon; + + [NonSerialized] Texture2D releaseIcon; + + [NonSerialized] Texture2D photonCloudIcon; + + [NonSerialized] Texture2D boltIcon; + + [NonSerialized] Texture2D activeIcon; + + [NonSerialized] Texture2D inactiveIcon; + + [NonSerialized] Texture2D bugtrackerIcon; + + [NonSerialized] GUIContent bugtrackerHeader; + + [NonSerialized] GUIContent bugtrackerText; + + [NonSerialized] Texture2D discordIcon; + + [NonSerialized] GUIContent discordHeader; + + [NonSerialized] GUIContent discordText; + + [NonSerialized] Texture2D documentationIcon; + + [NonSerialized] GUIContent documentationHeader; + + [NonSerialized] GUIContent documentationText; + + [NonSerialized] Texture2D reviewIcon; + + [NonSerialized] GUIContent reviewHeader; + + [NonSerialized] GUIContent reviewText; + + [NonSerialized] Texture2D samplesIcon; + + [NonSerialized] GUIStyle iconSection; + + [NonSerialized] GUIStyle stepStyle; + + [NonSerialized] GUIStyle headerStyle; + + [NonSerialized] GUIStyle headerLabel; + + [NonSerialized] GUIStyle headerLargeLabel; + + [NonSerialized] GUIStyle textLabel; + + [NonSerialized] GUIStyle centerInputText; + + [NonSerialized] GUIStyle minimalButton; + + [NonSerialized] GUIStyle simpleButton; + + [NonSerialized] GUIStyle introStyle; + + [NonSerialized] Vector2 scrollPosition; + + static BoltWizardWindow() + { + EditorApplication.update -= ShowWizardWindow; + EditorApplication.update += ShowWizardWindow; + + WindowPosition = new Vector2(100, 100); + } + + static void ShowWizardWindow() + { + if (FirstCall.HasValue == false) + { + FirstCall = Time.realtimeSinceStartup; + return; + } + + if ((Time.realtimeSinceStartup - FirstCall.Value) > 1) + { + if (!EditorPrefs.GetBool(FirstStartupKey, false)) + { + Open(); + } + + EditorApplication.update -= ShowWizardWindow; + } + } + + [MenuItem("Photon Bolt/Wizard", priority = 100)] + public static void Open() + { + if (Application.isPlaying) + { + return; + } + + BoltWizardWindow window = GetWindow(true, BoltWizardText.WINDOW_TITLE, true); + window.position = new Rect(WindowPosition, WindowSize); + window.Show(); + + watch.Start(); + } + + static void ReOpen() + { + if (Ready.HasValue && Ready.Value == false) + { + Open(); + } + + EditorApplication.update -= ReOpen; + } - static string AppIdOrEmail = ""; + void OnEnable() + { + WindowSize = new Vector2(600, 600); - [NonSerialized] Func beforeNextCallback; + minSize = WindowSize; - [NonSerialized] Dictionary packageInfo; + NavMenuWidth = 210; + ButtonWidth = 120; - [NonSerialized] int ButtonWidth; + Ready = false; - [NonSerialized] int NavMenuWidth; + beforeNextCallback = null; - [NonSerialized] string ReleaseHistoryHeader; - [NonSerialized] List ReleaseHistoryTextAdded; - [NonSerialized] List ReleaseHistoryTextChanged; - [NonSerialized] List ReleaseHistoryTextFixed; - [NonSerialized] List ReleaseHistoryTextRemoved; + // Pre-load Release History + PrepareReleaseHistoryText(); + } - // GUI + void OnDestroy() + { + if (!EditorPrefs.GetBool(FirstStartupKey, false)) + { + if (!EditorUtility.DisplayDialog(BoltWizardText.CLOSE_MSG_TITLE, + BoltWizardText.CLOSE_MSG_QUESTION, "Yes", "Back")) + { + EditorApplication.update += ReOpen; + } + } - [NonSerialized] Texture2D introIcon; + Ready = false; + } - [NonSerialized] Texture2D releaseIcon; + void InitContent() + { + if (Ready.HasValue && Ready.Value) + { + return; + } + + introIcon = Resources.Load("icons_welcome/information"); + releaseIcon = Resources.Load("icons_welcome/documentation"); + photonCloudIcon = Resources.Load("PhotonCloudIcon"); + + boltIcon = Resources.Load("BoltIcon"); + + activeIcon = Resources.Load("icons_welcome/bullet_green"); + inactiveIcon = Resources.Load("icons_welcome/bullet_black"); + + Texture2D texture = new Texture2D(1, 1); + texture.SetPixel(0, 0, Color.gray); + texture.Apply(); + + Color headerTextColor = EditorGUIUtility.isProSkin + ? new Color(0xf2 / 255f, 0xad / 255f, 0f) + : new Color(30 / 255f, 99 / 255f, 183 / 255f); + Color commonTextColor = EditorGUIUtility.isProSkin ? Color.white : Color.black; + + introStyle = new GUIStyle(EditorStyles.helpBox) + { + fontSize = 15, + padding = new RectOffset(10, 10, 10, 10), + normal = + { + textColor = commonTextColor + } + }; + + stepStyle = new GUIStyle(EditorStyles.helpBox) + { + padding = new RectOffset(10, 10, 10, 10), + margin = new RectOffset(0, 0, 5, 0), + normal = + { + textColor = commonTextColor + } + }; + + headerLabel = new GUIStyle(EditorStyles.boldLabel) + { + padding = new RectOffset(10, 0, 0, 0), + margin = new RectOffset(), + normal = + { + textColor = commonTextColor + } + }; + + headerStyle = new GUIStyle(EditorStyles.boldLabel) + { + fontSize = 14, + margin = new RectOffset(), + padding = new RectOffset(10, 0, 0, 0), + normal = + { + textColor = commonTextColor + } + }; + + headerLargeLabel = new GUIStyle(EditorStyles.boldLabel) + { + padding = new RectOffset(10, 0, 0, 0), + margin = new RectOffset(), + fontSize = 18, + normal = + { + textColor = headerTextColor + } + }; + + textLabel = new GUIStyle() + { + wordWrap = true, + margin = new RectOffset(), + padding = new RectOffset(10, 0, 0, 0), + normal = + { + textColor = commonTextColor + } + }; + + centerInputText = new GUIStyle(GUI.skin.textField) + { + alignment = TextAnchor.MiddleCenter, + fontSize = 12, + fixedHeight = 26 + }; + + minimalButton = new GUIStyle(EditorStyles.miniButton) + { + fixedWidth = 130 + }; + + simpleButton = new GUIStyle(GUI.skin.button) + { + fontSize = 12, + padding = new RectOffset(10, 10, 10, 10) + }; + + iconSection = new GUIStyle + { + margin = new RectOffset(0, 0, 0, 0) + }; + + discordIcon = Resources.Load("icons_welcome/community"); + discordText = new GUIContent(BoltWizardText.DISCORD_TEXT); + discordHeader = new GUIContent(BoltWizardText.DISCORD_HEADER); + + bugtrackerIcon = Resources.Load("icons_welcome/bugtracker"); + bugtrackerText = new GUIContent(BoltWizardText.BUGTRACKER_TEXT); + bugtrackerHeader = new GUIContent(BoltWizardText.BUGTRACKER_HEADER); + + documentationIcon = Resources.Load("icons_welcome/documentation"); + documentationText = new GUIContent(BoltWizardText.DOCUMENTATION_TEXT); + documentationHeader = new GUIContent(BoltWizardText.DOCUMENTATION_HEADER); + + reviewIcon = Resources.Load("icons_welcome/comments"); + reviewText = new GUIContent(BoltWizardText.REVIEW_TEXT); + reviewHeader = new GUIContent(BoltWizardText.REVIEW_HEADER); + + samplesIcon = Resources.Load("icons_welcome/samples"); + + // Package List + + packageInfo = new Dictionary + { + { + BoltInstalls.Core, + new BoltPackage() + { + name = "bolt_install", + title = "Core Package", + description = "Install core bolt package", + installTest = MainPackageInstalled, + packageFlags = PackageFlags.RunInitialSetup + } + }, + + // { + // BoltInstalls.Mobile, + // new BoltPackage() + // { + // name = "bolt_mobile_plugins", + // title = "Mobile Plugins", + // installTest = MobilePackageInstalled, + // description = "Install iOS / Android socket plugins" + // } + // }, + + { + BoltInstalls.XB1, + new BoltPackage() + { + name = "bolt_xb1", + title = "XBox One", + installTest = XB1PackageInstalled, + description = "Install XB1 support" + } + }, + + { + BoltInstalls.PS4, + new BoltPackage() + { + name = "bolt_ps4", + title = "Playstation 4", + installTest = PS4PackageInstalled, + description = "Install PS4 support" + } + }, + + { + BoltInstalls.Samples, + new BoltPackage() + { + name = "bolt_samples", + title = "Samples", + description = "Install bolt samples", + installTest = SamplesPackageInstalled, + packageFlags = PackageFlags.WarnForProjectOverwrite + } + } + }; + + // App ID + if (string.IsNullOrEmpty(BoltRuntimeSettings.instance.photonAppId)) + { + AppIdOrEmail = ""; + } + else if (IsAppId(BoltRuntimeSettings.instance.photonAppId)) + { + AppIdOrEmail = BoltRuntimeSettings.instance.photonAppId; + } - [NonSerialized] Texture2D photonCloudIcon; + Ready = true; + RunCompiler = false; + } + + void OnGUI() + { + try + { + InitContent(); + + WindowPosition = position.position; + + EditorGUILayout.BeginVertical(); + DrawHeader(); + + // Content + EditorGUILayout.BeginHorizontal(); + + // Nav menu + EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.MaxWidth(NavMenuWidth), + GUILayout.MinWidth(NavMenuWidth)); + DrawNavMenu(); + EditorGUILayout.EndVertical(); + + // Main Content + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + DrawContent(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.EndVertical(); + + if (GUI.changed) + { + Save(); + } + } + catch (Exception) + { + // ignored + } + } + + private void DrawContent() + { + switch (currentStage) + { + case BoltSetupStage.Intro: + DrawIntro(); + break; + case BoltSetupStage.ReleaseHistory: + DrawReleaseHistory(); + break; + case BoltSetupStage.Photon: + DrawSetupPhoton(); + break; + case BoltSetupStage.Bolt: + DrawSetupBolt(); + break; + case BoltSetupStage.Support: + DrawSupport(); + break; + } + + GUILayout.FlexibleSpace(); + DrawFooter(); + } + + private void DrawIntro() + { + GUILayout.BeginVertical(); + GUILayout.Label(BoltWizardText.WIZARD_INTRO, introStyle); + + if (GUILayout.Button("Visit Getting Started Documentation", simpleButton)) + { + OpenURL("https://doc.photonengine.com/en-us/bolt/")(); + } + + if (GUILayout.Button("Leave a review", simpleButton)) + { + OpenURL("https://assetstore.unity.com/packages/tools/network/photon-bolt-free-127156")(); + } + + GUILayout.EndVertical(); + } - [NonSerialized] Texture2D boltIcon; + private void DrawSetupBolt() + { + DrawInputWithLabel("Bolt Setup", () => + { + GUILayout.BeginVertical(); + GUILayout.Space(5); + GUILayout.Label(BoltWizardText.PACKAGES, textLabel); + GUILayout.EndVertical(); + }, false); + GUILayout.Space(15); - [NonSerialized] Texture2D activeIcon; + DrawInstallOption(BoltInstalls.Core); - [NonSerialized] Texture2D inactiveIcon; + EditorGUI.BeginDisabledGroup(!IsInstalled(BoltInstalls.Core)); - [NonSerialized] Texture2D bugtrackerIcon; + // SAMPLES + DrawInstallOption(BoltInstalls.Samples); - [NonSerialized] GUIContent bugtrackerHeader; + scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); - [NonSerialized] GUIContent bugtrackerText; + // // MOBILE + // DrawInstallOption(BoltInstalls.Mobile); - [NonSerialized] Texture2D discordIcon; + // XB1 + DrawInstallOption(BoltInstalls.XB1); - [NonSerialized] GUIContent discordHeader; + // PS4 + DrawInstallOption(BoltInstalls.PS4); - [NonSerialized] GUIContent discordText; + EditorGUILayout.EndScrollView(); - [NonSerialized] Texture2D documentationIcon; + EditorGUI.EndDisabledGroup(); - [NonSerialized] GUIContent documentationHeader; + // Action - [NonSerialized] GUIContent documentationText; + if (beforeNextCallback == null) + { + beforeNextCallback = () => + { + if (!IsInstalled(BoltInstalls.Core)) + { + ShowNotification(new GUIContent("You must install at least the Bolt Core package.")); + return false; + } + + return true; + }; + } + } - [NonSerialized] Texture2D reviewIcon; + private void DrawReleaseHistory() + { + DrawInputWithLabel(string.Format("Version Changelog: {0}", ReleaseHistoryHeader), () => + { + GUILayout.BeginVertical(); + GUILayout.Space(5); - [NonSerialized] GUIContent reviewHeader; + scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUIStyle.none, GUILayout.ExpandHeight(true), + GUILayout.ExpandWidth(true)); - [NonSerialized] GUIContent reviewText; + DrawReleaseHistoryItem("Added:", ReleaseHistoryTextAdded); + DrawReleaseHistoryItem("Changed:", ReleaseHistoryTextChanged); + DrawReleaseHistoryItem("Fixed:", ReleaseHistoryTextFixed); + DrawReleaseHistoryItem("Removed:", ReleaseHistoryTextRemoved); - [NonSerialized] Texture2D samplesIcon; + GUILayout.EndScrollView(); - [NonSerialized] GUIStyle iconSection; + GUILayout.EndVertical(); + }, false, labelSize: 300); + } - [NonSerialized] GUIStyle stepStyle; + private void DrawReleaseHistoryItem(string label, List items) + { + if (items != null && items.Count > 0) + { + DrawInputWithLabel(label, () => + { + GUILayout.BeginVertical(); + GUILayout.Space(5); + + foreach (var text in items) + { + GUILayout.Label(string.Format("- {0}.", text), textLabel); + } + + GUILayout.EndVertical(); + }, false, true, 200); + } + } - [NonSerialized] GUIStyle headerStyle; + private void DrawSetupPhoton() + { + DrawInputWithLabel("Photon Cloud Setup", () => + { + GUILayout.BeginVertical(); + GUILayout.Space(5); + GUILayout.Label(BoltWizardText.PHOTON, textLabel); + GUILayout.EndVertical(); - [NonSerialized] GUIStyle headerLabel; + GUILayout.BeginHorizontal(); + GUILayout.Label(BoltWizardText.PHOTON_DASH, textLabel); + if (GUILayout.Button("Visit Dashboard", minimalButton)) + { + OpenURL("https://dashboard.photonengine.com/")(); + } - [NonSerialized] GUIStyle headerLargeLabel; + GUILayout.EndHorizontal(); + }, false); + GUILayout.Space(15); - [NonSerialized] GUIStyle textLabel; + BoltRuntimeSettings settings = BoltRuntimeSettings.instance; - [NonSerialized] GUIStyle centerInputText; + DrawInputWithLabel("Photon Bolt App ID or Email", () => + { + GUILayout.BeginVertical(); - [NonSerialized] GUIStyle minimalButton; + AppIdOrEmail = EditorGUILayout.TextField(AppIdOrEmail, centerInputText); - [NonSerialized] GUIStyle simpleButton; + GUILayout.EndVertical(); + }, false, true, 300); - [NonSerialized] GUIStyle introStyle; + DrawInputWithLabel("Region", + () => + { + settings.photonCloudRegionIndex = EditorGUILayout.Popup(settings.photonCloudRegionIndex, + BoltRuntimeSettings.photonCloudRegions); + }, true, true); - [NonSerialized] Vector2 scrollPosition; + DrawInputWithLabel("NAT Punchthrough Enabled", + () => { settings.photonUsePunch = Toggle(settings.photonUsePunch); }, true, true); - static BoltWizardWindow() - { - EditorApplication.update -= ShowWizardWindow; - EditorApplication.update += ShowWizardWindow; + // Action - WindowPosition = new Vector2(100, 100); - } + if (beforeNextCallback == null) + { + beforeNextCallback = () => + { + if (requestingAppId) + { + BoltLog.Info("Please, wait until your request for a new AppID finishes."); + return false; + } + + if (AccountService.IsValidEmail(AppIdOrEmail)) + { + try + { + EditorUtility.DisplayProgressBar(BoltWizardText.CONNECTION_TITLE, + BoltWizardText.CONNECTION_INFO, 0.5f); + BoltLog.Info("Starting request"); + + requestingAppId = new AccountService().RegisterByEmail( + AppIdOrEmail, + new List() { ServiceTypes.Bolt }, + (response) => + { + if (response.ReturnCode == AccountServiceReturnCodes.Success) + { + var appKey = response.ApplicationIds[((int)ServiceTypes.Bolt).ToString()]; + + settings.photonAppId = appKey; + AppIdOrEmail = appKey; + + BoltLog.Info("You new App ID: {0}", AppIdOrEmail); + } + else + { + BoltLog.Warn( + "It was not possible to process your request, please go to the Photon Cloud Dashboard."); + BoltLog.Warn("Return Code: {0}", + AccountServiceReturnCodes.ReturnCodes[response.ReturnCode]); + } + + requestingAppId = false; + EditorUtility.ClearProgressBar(); + }, (err) => + { + BoltLog.Error(err); + + requestingAppId = false; + EditorUtility.ClearProgressBar(); + }); + + if (requestingAppId) + { + BoltLog.Info("Requesting your new App ID"); + } + else + { + BoltLog.Warn( + "It was not possible to process your request, please go to the Photon Cloud Dashboard."); + EditorUtility.ClearProgressBar(); + } + } + catch (Exception ex) + { + EditorUtility.DisplayDialog("Error", ex.Message, "ok"); + } + } + else if (IsAppId(AppIdOrEmail)) + { + settings.photonAppId = AppIdOrEmail; + return true; + } + else + { + ShowNotification(new GUIContent("Please specify a valid Photon Bolt App ID or Email.")); + } + + return false; + }; + } + } - static void ShowWizardWindow() - { - if (FirstCall.HasValue == false) - { - FirstCall = Time.realtimeSinceStartup; - return; - } + private void DrawSupport() + { + DrawInputWithLabel("Bolt Support", () => + { + GUILayout.BeginVertical(); + GUILayout.Space(5); + GUILayout.Label(BoltWizardText.SUPPORT, textLabel); + GUILayout.EndVertical(); + }, false); + GUILayout.Space(15); + + DrawStepOption(discordIcon, discordHeader, discordText, + callback: OpenURL("https://discord.gg/0ya6ZpOvnShSCtbb")); + DrawStepOption(bugtrackerIcon, bugtrackerHeader, bugtrackerText, + callback: OpenURL("https://github.com/BoltEngine/Bolt-Tracker")); + DrawStepOption(documentationIcon, documentationHeader, documentationText, + callback: OpenURL("https://doc.photonengine.com/en-us/bolt/current/setup/overview")); + DrawStepOption(reviewIcon, reviewHeader, reviewText, + callback: OpenURL("https://assetstore.unity.com/packages/tools/network/photon-bolt-free-127156")); + + // Action + + if (beforeNextCallback == null) + { + beforeNextCallback = () => + { + RunCompiler = EditorUtility.DisplayDialog(BoltWizardText.FINISH_TITLE, BoltWizardText.FINISH_QUESTION, + "Yes", "No"); + return true; + }; + } + } - if ((Time.realtimeSinceStartup - FirstCall.Value) > 1) - { - if (!EditorPrefs.GetBool(FirstStartupKey, false)) - { - Open(); - } + private void DrawNavMenu() + { + GUILayout.Space(5); + DrawMenuHeader("Installation Steps"); + GUILayout.Space(10); - EditorApplication.update -= ShowWizardWindow; - } - } + DrawStepOption(introIcon, new GUIContent("Bolt Wizard Intro"), + active: currentStage == + BoltSetupStage.Intro); - [MenuItem("Bolt/Wizard", priority = 100)] - public static void Open() - { - if (Application.isPlaying) - { - return; - } + DrawStepOption(releaseIcon, new GUIContent("Release History"), + active: currentStage == + BoltSetupStage.ReleaseHistory); - BoltWizardWindow window = GetWindow(true, BoltWizardText.WINDOW_TITLE, true); - window.position = new Rect(WindowPosition, WindowSize); - window.Show(); + DrawStepOption(photonCloudIcon, new GUIContent("Photon Cloud"), + active: currentStage == + BoltSetupStage.Photon); - watch.Start(); - } + DrawStepOption(boltIcon, new GUIContent("Bolt"), + active: currentStage == + BoltSetupStage.Bolt); - static void ReOpen() - { - if (Ready.HasValue && Ready.Value == false) - { - Open(); - } + DrawStepOption(discordIcon, new GUIContent("Support"), + active: currentStage == + BoltSetupStage.Support); - EditorApplication.update -= ReOpen; - } + GUILayout.FlexibleSpace(); + GUILayout.Label(BoltNetwork.CurrentVersion, textLabel); + GUILayout.Space(5); + } - void OnEnable() - { - WindowSize = new Vector2(600, 600); + void DrawHeader() + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUILayout.Label(Resources.Load("BoltLogo"), GUILayout.Width(200), GUILayout.Height(109)); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } - minSize = WindowSize; + void DrawFooter() + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); - NavMenuWidth = 210; - ButtonWidth = 120; - - Ready = false; - - beforeNextCallback = null; - - // Pre-load Release History - PrepareReleaseHistoryText(); - } - - void OnDestroy() - { - if (!EditorPrefs.GetBool(FirstStartupKey, false)) - { - if (!EditorUtility.DisplayDialog(BoltWizardText.CLOSE_MSG_TITLE, - BoltWizardText.CLOSE_MSG_QUESTION, "Yes", "Back")) - { - EditorApplication.update += ReOpen; - } - } - - Ready = false; - } - - void InitContent() - { - if (Ready.HasValue && Ready.Value) - { - return; - } - - introIcon = Resources.Load("icons_welcome/information"); - releaseIcon = Resources.Load("icons_welcome/documentation"); - photonCloudIcon = Resources.Load("PhotonCloudIcon"); - - boltIcon = Resources.Load("BoltIcon"); - - activeIcon = Resources.Load("icons_welcome/bullet_green"); - inactiveIcon = Resources.Load("icons_welcome/bullet_black"); - - Texture2D texture = new Texture2D(1, 1); - texture.SetPixel(0, 0, Color.gray); - texture.Apply(); - - Color headerTextColor = EditorGUIUtility.isProSkin - ? new Color(0xf2 / 255f, 0xad / 255f, 0f) - : new Color(30 / 255f, 99 / 255f, 183 / 255f); - Color commonTextColor = EditorGUIUtility.isProSkin ? Color.white : Color.black; - - introStyle = new GUIStyle(EditorStyles.helpBox) - { - fontSize = 15, - padding = new RectOffset(10, 10, 10, 10), - normal = - { - textColor = commonTextColor - } - }; - - stepStyle = new GUIStyle(EditorStyles.helpBox) - { - padding = new RectOffset(10, 10, 10, 10), - margin = new RectOffset(0, 0, 5, 0), - normal = - { - textColor = commonTextColor - } - }; - - headerLabel = new GUIStyle(EditorStyles.boldLabel) - { - padding = new RectOffset(10, 0, 0, 0), - margin = new RectOffset(), - normal = - { - textColor = commonTextColor - } - }; - - headerStyle = new GUIStyle(EditorStyles.boldLabel) - { - fontSize = 14, - margin = new RectOffset(), - padding = new RectOffset(10, 0, 0, 0), - normal = - { - textColor = commonTextColor - } - }; - - headerLargeLabel = new GUIStyle(EditorStyles.boldLabel) - { - padding = new RectOffset(10, 0, 0, 0), - margin = new RectOffset(), - fontSize = 18, - normal = - { - textColor = headerTextColor - } - }; - - textLabel = new GUIStyle() - { - wordWrap = true, - margin = new RectOffset(), - padding = new RectOffset(10, 0, 0, 0), - normal = - { - textColor = commonTextColor - } - }; - - centerInputText = new GUIStyle(GUI.skin.textField) - { - alignment = TextAnchor.MiddleCenter, - fontSize = 12, - fixedHeight = 26 - }; - - minimalButton = new GUIStyle(EditorStyles.miniButton) - { - fixedWidth = 130 - }; - - simpleButton = new GUIStyle(GUI.skin.button) - { - fontSize = 12, - padding = new RectOffset(10, 10, 10, 10) - }; - - iconSection = new GUIStyle - { - margin = new RectOffset(0, 0, 0, 0) - }; - - discordIcon = Resources.Load("icons_welcome/community"); - discordText = new GUIContent(BoltWizardText.DISCORD_TEXT); - discordHeader = new GUIContent(BoltWizardText.DISCORD_HEADER); - - bugtrackerIcon = Resources.Load("icons_welcome/bugtracker"); - bugtrackerText = new GUIContent(BoltWizardText.BUGTRACKER_TEXT); - bugtrackerHeader = new GUIContent(BoltWizardText.BUGTRACKER_HEADER); - - documentationIcon = Resources.Load("icons_welcome/documentation"); - documentationText = new GUIContent(BoltWizardText.DOCUMENTATION_TEXT); - documentationHeader = new GUIContent(BoltWizardText.DOCUMENTATION_HEADER); - - reviewIcon = Resources.Load("icons_welcome/comments"); - reviewText = new GUIContent(BoltWizardText.REVIEW_TEXT); - reviewHeader = new GUIContent(BoltWizardText.REVIEW_HEADER); - - samplesIcon = Resources.Load("icons_welcome/samples"); - - // Package List - - packageInfo = new Dictionary - { - { - BoltInstalls.Core, - new BoltPackage() - { - name = "bolt_install", - title = "Core Package", - description = "Install core bolt package", - installTest = MainPackageInstalled, - packageFlags = PackageFlags.RunInitialSetup - } - }, - - // { - // BoltInstalls.Mobile, - // new BoltPackage() - // { - // name = "bolt_mobile_plugins", - // title = "Mobile Plugins", - // installTest = MobilePackageInstalled, - // description = "Install iOS / Android socket plugins" - // } - // }, - - { - BoltInstalls.XB1, - new BoltPackage() - { - name = "bolt_xb1", - title = "XBox One", - installTest = XB1PackageInstalled, - description = "Install XB1 support" - } - }, - - { - BoltInstalls.PS4, - new BoltPackage() - { - name = "bolt_ps4", - title = "Playstation 4", - installTest = PS4PackageInstalled, - description = "Install PS4 support" - } - }, - - { - BoltInstalls.Samples, - new BoltPackage() - { - name = "bolt_samples", - title = "Samples", - description = "Install bolt samples", - installTest = SamplesPackageInstalled, - packageFlags = PackageFlags.WarnForProjectOverwrite - } - } - }; - - // App ID - if (string.IsNullOrEmpty(BoltRuntimeSettings.instance.photonAppId)) - { - AppIdOrEmail = ""; - } - else if (IsAppId(BoltRuntimeSettings.instance.photonAppId)) - { - AppIdOrEmail = BoltRuntimeSettings.instance.photonAppId; - } - - Ready = true; - RunCompiler = false; - } - - void OnGUI() - { - try - { - InitContent(); - - WindowPosition = position.position; - - EditorGUILayout.BeginVertical(); - DrawHeader(); - - // Content - EditorGUILayout.BeginHorizontal(); - - // Nav menu - EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.MaxWidth(NavMenuWidth), - GUILayout.MinWidth(NavMenuWidth)); - DrawNavMenu(); - EditorGUILayout.EndVertical(); - - // Main Content - EditorGUILayout.BeginVertical(EditorStyles.helpBox); - DrawContent(); - EditorGUILayout.EndVertical(); - - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.EndVertical(); - - if (GUI.changed) - { - Save(); - } - } - catch (Exception) - { - // ignored - } - } - - private void DrawContent() - { - switch (currentStage) - { - case BoltSetupStage.Intro: - DrawIntro(); - break; - case BoltSetupStage.ReleaseHistory: - DrawReleaseHistory(); - break; - case BoltSetupStage.Photon: - DrawSetupPhoton(); - break; - case BoltSetupStage.Bolt: - DrawSetupBolt(); - break; - case BoltSetupStage.Support: - DrawSupport(); - break; - } - - GUILayout.FlexibleSpace(); - DrawFooter(); - } - - private void DrawIntro() - { - GUILayout.BeginVertical(); - GUILayout.Label(BoltWizardText.WIZARD_INTRO, introStyle); - - if (GUILayout.Button("Visit Getting Started Documentation", simpleButton)) - { - OpenURL("https://doc.photonengine.com/en-us/bolt/")(); - } - - if (GUILayout.Button("Leave a review", simpleButton)) - { - OpenURL("https://assetstore.unity.com/packages/tools/network/photon-bolt-free-127156")(); - } - - GUILayout.EndVertical(); - } - - private void DrawSetupBolt() - { - DrawInputWithLabel("Bolt Setup", () => - { - GUILayout.BeginVertical(); - GUILayout.Space(5); - GUILayout.Label(BoltWizardText.PACKAGES, textLabel); - GUILayout.EndVertical(); - }, false); - GUILayout.Space(15); - - DrawInstallOption(BoltInstalls.Core); - - EditorGUI.BeginDisabledGroup(!IsInstalled(BoltInstalls.Core)); - - // SAMPLES - DrawInstallOption(BoltInstalls.Samples); - - scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); - - // // MOBILE - // DrawInstallOption(BoltInstalls.Mobile); - - // XB1 - DrawInstallOption(BoltInstalls.XB1); - - // PS4 - DrawInstallOption(BoltInstalls.PS4); - - EditorGUILayout.EndScrollView(); - - EditorGUI.EndDisabledGroup(); - - // Action - - if (beforeNextCallback == null) - { - beforeNextCallback = () => - { - if (!IsInstalled(BoltInstalls.Core)) - { - ShowNotification(new GUIContent("You must install at least the Bolt Core package.")); - return false; - } - - return true; - }; - } - } - - private void DrawReleaseHistory() - { - DrawInputWithLabel(string.Format("Version Changelog: {0}", ReleaseHistoryHeader), () => - { - GUILayout.BeginVertical(); - GUILayout.Space(5); - - scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUIStyle.none, GUILayout.ExpandHeight(true), - GUILayout.ExpandWidth(true)); - - DrawReleaseHistoryItem("Added:", ReleaseHistoryTextAdded); - DrawReleaseHistoryItem("Changed:", ReleaseHistoryTextChanged); - DrawReleaseHistoryItem("Fixed:", ReleaseHistoryTextFixed); - DrawReleaseHistoryItem("Removed:", ReleaseHistoryTextRemoved); - - GUILayout.EndScrollView(); - - GUILayout.EndVertical(); - }, false, labelSize: 300); - } - - private void DrawReleaseHistoryItem(string label, List items) - { - if (items != null && items.Count > 0) - { - DrawInputWithLabel(label, () => - { - GUILayout.BeginVertical(); - GUILayout.Space(5); - - foreach (var text in items) - { - GUILayout.Label(string.Format("- {0}.", text), textLabel); - } - - GUILayout.EndVertical(); - }, false, true, 200); - } - } - - private void DrawSetupPhoton() - { - DrawInputWithLabel("Photon Cloud Setup", () => - { - GUILayout.BeginVertical(); - GUILayout.Space(5); - GUILayout.Label(BoltWizardText.PHOTON, textLabel); - GUILayout.EndVertical(); - - GUILayout.BeginHorizontal(); - GUILayout.Label(BoltWizardText.PHOTON_DASH, textLabel); - if (GUILayout.Button("Visit Dashboard", minimalButton)) - { - OpenURL("https://dashboard.photonengine.com/")(); - } - - GUILayout.EndHorizontal(); - }, false); - GUILayout.Space(15); - - BoltRuntimeSettings settings = BoltRuntimeSettings.instance; - - DrawInputWithLabel("Photon Bolt App ID or Email", () => - { - GUILayout.BeginVertical(); - - AppIdOrEmail = EditorGUILayout.TextField(AppIdOrEmail, centerInputText); - - GUILayout.EndVertical(); - }, false, true, 300); - - DrawInputWithLabel("Region", - () => - { - settings.photonCloudRegionIndex = EditorGUILayout.Popup(settings.photonCloudRegionIndex, - BoltRuntimeSettings.photonCloudRegions); - }, true, true); - - DrawInputWithLabel("NAT Punchthrough Enabled", - () => { settings.photonUsePunch = BoltEditorGUI.Toggle(settings.photonUsePunch); }, true, true); - - // Action - - if (beforeNextCallback == null) - { - beforeNextCallback = () => - { - if (requestingAppId) - { - BoltLog.Info("Please, wait until your request for a new AppID finishes."); - return false; - } - - if (AccountService.IsValidEmail(AppIdOrEmail)) - { - try - { - EditorUtility.DisplayProgressBar(BoltWizardText.CONNECTION_TITLE, - BoltWizardText.CONNECTION_INFO, 0.5f); - BoltLog.Info("Starting request"); - - requestingAppId = new AccountService().RegisterByEmail( - AppIdOrEmail, - new List() {ServiceTypes.Bolt}, - (response) => - { - if (response.ReturnCode == AccountServiceReturnCodes.Success) - { - var appKey = response.ApplicationIds[((int) ServiceTypes.Bolt).ToString()]; - - settings.photonAppId = appKey; - AppIdOrEmail = appKey; - - BoltLog.Info("You new App ID: {0}", AppIdOrEmail); - } - else - { - BoltLog.Warn( - "It was not possible to process your request, please go to the Photon Cloud Dashboard."); - BoltLog.Warn("Return Code: {0}", - AccountServiceReturnCodes.ReturnCodes[response.ReturnCode]); - } - - requestingAppId = false; - EditorUtility.ClearProgressBar(); - }, (err) => - { - BoltLog.Error(err); - - requestingAppId = false; - EditorUtility.ClearProgressBar(); - }); - - if (requestingAppId) - { - BoltLog.Info("Requesting your new App ID"); - } - else - { - BoltLog.Warn( - "It was not possible to process your request, please go to the Photon Cloud Dashboard."); - EditorUtility.ClearProgressBar(); - } - } - catch (Exception ex) - { - EditorUtility.DisplayDialog("Error", ex.Message, "ok"); - } - } - else if (IsAppId(AppIdOrEmail)) - { - settings.photonAppId = AppIdOrEmail; - return true; - } - else - { - ShowNotification(new GUIContent("Please specify a valid Photon Bolt App ID or Email.")); - } - - return false; - }; - } - } - - private void DrawSupport() - { - DrawInputWithLabel("Bolt Support", () => - { - GUILayout.BeginVertical(); - GUILayout.Space(5); - GUILayout.Label(BoltWizardText.SUPPORT, textLabel); - GUILayout.EndVertical(); - }, false); - GUILayout.Space(15); - - DrawStepOption(discordIcon, discordHeader, discordText, - callback: OpenURL("https://discord.gg/0ya6ZpOvnShSCtbb")); - DrawStepOption(bugtrackerIcon, bugtrackerHeader, bugtrackerText, - callback: OpenURL("https://github.com/BoltEngine/Bolt-Tracker")); - DrawStepOption(documentationIcon, documentationHeader, documentationText, - callback: OpenURL("https://doc.photonengine.com/en-us/bolt/current/setup/overview")); - DrawStepOption(reviewIcon, reviewHeader, reviewText, - callback: OpenURL("https://assetstore.unity.com/packages/tools/network/photon-bolt-free-127156")); - - // Action - - if (beforeNextCallback == null) - { - beforeNextCallback = () => - { - RunCompiler = EditorUtility.DisplayDialog(BoltWizardText.FINISH_TITLE, BoltWizardText.FINISH_QUESTION, - "Yes", "No"); - return true; - }; - } - } - - private void DrawNavMenu() - { - GUILayout.Space(5); - DrawMenuHeader("Installation Steps"); - GUILayout.Space(10); - - DrawStepOption(introIcon, new GUIContent("Bolt Wizard Intro"), - active: currentStage == - BoltSetupStage.Intro); - - DrawStepOption(releaseIcon, new GUIContent("Release History"), - active: currentStage == - BoltSetupStage.ReleaseHistory); - - DrawStepOption(photonCloudIcon, new GUIContent("Photon Cloud"), - active: currentStage == - BoltSetupStage.Photon); - - DrawStepOption(boltIcon, new GUIContent("Bolt"), - active: currentStage == - BoltSetupStage.Bolt); - - DrawStepOption(discordIcon, new GUIContent("Support"), - active: currentStage == - BoltSetupStage.Support); - - GUILayout.FlexibleSpace(); - GUILayout.Label(BoltNetwork.CurrentVersion, textLabel); - GUILayout.Space(5); - } - - void DrawHeader() - { - GUILayout.BeginHorizontal(); - GUILayout.FlexibleSpace(); - GUILayout.Label(Resources.Load("BoltLogo"), GUILayout.Width(200), GUILayout.Height(109)); - GUILayout.FlexibleSpace(); - GUILayout.EndHorizontal(); - } - - void DrawFooter() - { - GUILayout.BeginHorizontal(); - GUILayout.FlexibleSpace(); - - EditorGUI.BeginDisabledGroup((int) currentStage == 1); + EditorGUI.BeginDisabledGroup((int)currentStage == 1); #if !BOLT_CLOUD if (currentStage == BoltSetupStage.Photon) @@ -782,281 +785,282 @@ public partial class BoltWizardWindow : EditorWindow } #endif - if (GUILayout.Button("Back", GUILayout.Width(ButtonWidth))) - { - beforeNextCallback = null; - BackStep(); - } - - EditorGUI.EndDisabledGroup(); - - var nextLabel = "Next"; - - switch (currentStage) - { - case BoltSetupStage.Photon: - nextLabel = AccountService.IsValidEmail(AppIdOrEmail) ? "Register by Email" : nextLabel; - break; - case BoltSetupStage.Support: - nextLabel = "Done"; - break; - default: - nextLabel = "Next"; - break; - } - - if (GUILayout.Button(nextLabel, GUILayout.Width(ButtonWidth))) - { - if (beforeNextCallback == null || beforeNextCallback()) - { - if (currentStage == BoltSetupStage.Support) - { - EditorPrefs.SetBool(FirstStartupKey, true); - Close(); - - if (RunCompiler) - { - BoltMenuItems.RunCompiler(); - } - } - - NextStep(); - beforeNextCallback = null; - } - } - - GUILayout.Space(5); - GUILayout.EndHorizontal(); - GUILayout.Space(5); - } - - // Utils - - private void Save() - { - if (watch.ElapsedMilliseconds > 5000) - { - watch.Reset(); - watch.Start(); - - EditorUtility.SetDirty(BoltRuntimeSettings.instance); - AssetDatabase.SaveAssets(); - } - } - - void DrawMenuHeader(String text) - { - GUILayout.BeginHorizontal(); - GUILayout.FlexibleSpace(); - - GUILayout.Label(text, headerLargeLabel); - - GUILayout.FlexibleSpace(); - GUILayout.EndHorizontal(); - } - - void DrawInputWithLabel(String label, Action gui, bool horizontal = true, bool box = false, int labelSize = 220) - { - GUILayout.Space(10); - - if (horizontal) - { - if (box) - { - GUILayout.BeginHorizontal(stepStyle); - } - else - { - GUILayout.BeginHorizontal(); - } - } - else - { - if (box) - { - GUILayout.BeginVertical(stepStyle); - } - else - { - GUILayout.BeginVertical(); - } - } - - GUILayout.Label(label, headerStyle, GUILayout.Width(labelSize)); - //GUILayout.Space(5); - - gui(); - - GUILayout.Space(5); - - if (horizontal) - { - GUILayout.EndHorizontal(); - } - else - { - GUILayout.EndVertical(); - } - } - - void DrawInstallOption(BoltInstalls install) - { - BoltPackage package = packageInfo[install]; - - Action action = () => - { - if (package.installTest()) - { - ShowNotification(new GUIContent("Package already installed")); - return; - } - - Install(package); - }; - - bool packageExists = PackageExists(package.name); - - Action ignoredAction; - if (packageExists == true) - { - ignoredAction = () => { ShowNotification(new GUIContent("One of the dependencies is missing")); }; - } - else - { - if (install == BoltInstalls.Core) - { - ignoredAction = () => - { - ShowNotification(new GUIContent("Bolt Core is no longer required. You are ready to go.")); - }; - } - else - { - ignoredAction = () => - { - ShowNotification(new GUIContent("Please contact us at developer@photonengine.com")); - }; - } - - EditorGUI.BeginDisabledGroup(true); - } - - DrawStepOption(samplesIcon, new GUIContent(package.title), new GUIContent(package.description), - package.installTest(), action, ignoredAction); - - if (packageExists == false) - { - EditorGUI.EndDisabledGroup(); - } - } - - void DrawStepOption(Texture2D icon, GUIContent header, GUIContent description = null, bool? active = null, - Action callback = null, Action ignoredCallback = null) - { - GUILayout.BeginHorizontal(stepStyle); - - if (icon != null) - { - GUILayout.Label(icon, iconSection, GUILayout.Width(32), GUILayout.Height(32)); - } - - var height = icon != null ? 32 : 16; - - GUILayout.BeginVertical(GUILayout.MinHeight(height)); - GUILayout.FlexibleSpace(); - - GUILayout.Label(header, headerLabel, GUILayout.MinWidth(120)); - - if (description != null) - { - GUILayout.Label(description, textLabel); - } - - GUILayout.FlexibleSpace(); - GUILayout.EndVertical(); - - if (active == true) - { - GUILayout.Label(activeIcon, iconSection, GUILayout.Width(height), GUILayout.Height(height)); - } - else if (active == false) - { - GUILayout.Label(inactiveIcon, iconSection, GUILayout.Width(height), GUILayout.Height(height)); - } - - GUILayout.EndHorizontal(); - - if (callback != null) - { - var rect = GUILayoutUtility.GetLastRect(); - EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); - - if (rect.Contains(Event.current.mousePosition)) - { - if (Event.current.type == EventType.MouseDown) - { - callback(); - GUIUtility.ExitGUI(); - } - else if (Event.current.type == EventType.Ignore && Event.current.rawType == EventType.MouseDown) - { - if (ignoredCallback != null) - { - ignoredCallback(); - } - } - } - } - } - - void NextStep() - { - currentStage += (int) currentStage < Enum.GetValues(typeof(BoltSetupStage)).Length ? 1 : 0; - } - - void BackStep() - { - currentStage -= (int) currentStage > 1 ? 1 : 0; - } - - bool IsInstalled(params BoltInstalls[] installs) - { - foreach (var pack in installs) - { - if (!packageInfo[pack].installTest()) - { - return false; - } - } - - return true; - } - - void Install(BoltPackage package) - { - string packageName = package.name; - PackageFlags flags = package.packageFlags; - - if ((flags & PackageFlags.WarnForProjectOverwrite) == PackageFlags.WarnForProjectOverwrite) - { - if (ProjectExists()) - { - if (EditorUtility.DisplayDialog("Warning", - "Importing this package will overwrite the existing bolt project file that contains all your states, events, etc. Are you sure?", - "Yes", "No") == false) - { - return; - } - } - } - - if ((flags & PackageFlags.RunInitialSetup) == PackageFlags.RunInitialSetup) - { - InitialSetup(); - } - - AssetDatabase.ImportPackage(PackagePath(packageName), false); - - currentStage = BoltSetupStage.Bolt; - } -} \ No newline at end of file + if (GUILayout.Button("Back", GUILayout.Width(ButtonWidth))) + { + beforeNextCallback = null; + BackStep(); + } + + EditorGUI.EndDisabledGroup(); + + var nextLabel = "Next"; + + switch (currentStage) + { + case BoltSetupStage.Photon: + nextLabel = AccountService.IsValidEmail(AppIdOrEmail) ? "Register by Email" : nextLabel; + break; + case BoltSetupStage.Support: + nextLabel = "Done"; + break; + default: + nextLabel = "Next"; + break; + } + + if (GUILayout.Button(nextLabel, GUILayout.Width(ButtonWidth))) + { + if (beforeNextCallback == null || beforeNextCallback()) + { + if (currentStage == BoltSetupStage.Support) + { + EditorPrefs.SetBool(FirstStartupKey, true); + Close(); + + if (RunCompiler) + { + BoltMenuItems.RunCompiler(); + } + } + + NextStep(); + beforeNextCallback = null; + } + } + + GUILayout.Space(5); + GUILayout.EndHorizontal(); + GUILayout.Space(5); + } + + // Utils + + private void Save() + { + if (watch.ElapsedMilliseconds > 5000) + { + watch.Reset(); + watch.Start(); + + EditorUtility.SetDirty(BoltRuntimeSettings.instance); + AssetDatabase.SaveAssets(); + } + } + + void DrawMenuHeader(String text) + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + GUILayout.Label(text, headerLargeLabel); + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + + void DrawInputWithLabel(String label, Action gui, bool horizontal = true, bool box = false, int labelSize = 220) + { + GUILayout.Space(10); + + if (horizontal) + { + if (box) + { + GUILayout.BeginHorizontal(stepStyle); + } + else + { + GUILayout.BeginHorizontal(); + } + } + else + { + if (box) + { + GUILayout.BeginVertical(stepStyle); + } + else + { + GUILayout.BeginVertical(); + } + } + + GUILayout.Label(label, headerStyle, GUILayout.Width(labelSize)); + //GUILayout.Space(5); + + gui(); + + GUILayout.Space(5); + + if (horizontal) + { + GUILayout.EndHorizontal(); + } + else + { + GUILayout.EndVertical(); + } + } + + void DrawInstallOption(BoltInstalls install) + { + BoltPackage package = packageInfo[install]; + + Action action = () => + { + if (package.installTest()) + { + ShowNotification(new GUIContent("Package already installed")); + return; + } + + Install(package); + }; + + bool packageExists = PackageExists(package.name); + + Action ignoredAction; + if (packageExists == true) + { + ignoredAction = () => { ShowNotification(new GUIContent("One of the dependencies is missing")); }; + } + else + { + if (install == BoltInstalls.Core) + { + ignoredAction = () => + { + ShowNotification(new GUIContent("Bolt Core is no longer required. You are ready to go.")); + }; + } + else + { + ignoredAction = () => + { + ShowNotification(new GUIContent("Please contact us at developer@photonengine.com")); + }; + } + + EditorGUI.BeginDisabledGroup(true); + } + + DrawStepOption(samplesIcon, new GUIContent(package.title), new GUIContent(package.description), + package.installTest(), action, ignoredAction); + + if (packageExists == false) + { + EditorGUI.EndDisabledGroup(); + } + } + + void DrawStepOption(Texture2D icon, GUIContent header, GUIContent description = null, bool? active = null, + Action callback = null, Action ignoredCallback = null) + { + GUILayout.BeginHorizontal(stepStyle); + + if (icon != null) + { + GUILayout.Label(icon, iconSection, GUILayout.Width(32), GUILayout.Height(32)); + } + + var height = icon != null ? 32 : 16; + + GUILayout.BeginVertical(GUILayout.MinHeight(height)); + GUILayout.FlexibleSpace(); + + GUILayout.Label(header, headerLabel, GUILayout.MinWidth(120)); + + if (description != null) + { + GUILayout.Label(description, textLabel); + } + + GUILayout.FlexibleSpace(); + GUILayout.EndVertical(); + + if (active == true) + { + GUILayout.Label(activeIcon, iconSection, GUILayout.Width(height), GUILayout.Height(height)); + } + else if (active == false) + { + GUILayout.Label(inactiveIcon, iconSection, GUILayout.Width(height), GUILayout.Height(height)); + } + + GUILayout.EndHorizontal(); + + if (callback != null) + { + var rect = GUILayoutUtility.GetLastRect(); + EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); + + if (rect.Contains(Event.current.mousePosition)) + { + if (Event.current.type == EventType.MouseDown) + { + callback(); + GUIUtility.ExitGUI(); + } + else if (Event.current.type == EventType.Ignore && Event.current.rawType == EventType.MouseDown) + { + if (ignoredCallback != null) + { + ignoredCallback(); + } + } + } + } + } + + void NextStep() + { + currentStage += (int)currentStage < Enum.GetValues(typeof(BoltSetupStage)).Length ? 1 : 0; + } + + void BackStep() + { + currentStage -= (int)currentStage > 1 ? 1 : 0; + } + + bool IsInstalled(params BoltInstalls[] installs) + { + foreach (var pack in installs) + { + if (!packageInfo[pack].installTest()) + { + return false; + } + } + + return true; + } + + void Install(BoltPackage package) + { + string packageName = package.name; + PackageFlags flags = package.packageFlags; + + if ((flags & PackageFlags.WarnForProjectOverwrite) == PackageFlags.WarnForProjectOverwrite) + { + if (ProjectExists()) + { + if (EditorUtility.DisplayDialog("Warning", + "Importing this package will overwrite the existing bolt project file that contains all your states, events, etc. Are you sure?", + "Yes", "No") == false) + { + return; + } + } + } + + if ((flags & PackageFlags.RunInitialSetup) == PackageFlags.RunInitialSetup) + { + InitialSetup(); + } + + AssetDatabase.ImportPackage(PackagePath(packageName), false); + + currentStage = BoltSetupStage.Bolt; + } + } +} diff --git a/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindowUtils.cs b/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindowUtils.cs index 4233ed6..d2b917d 100644 --- a/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindowUtils.cs +++ b/Assets/Photon/PhotonBolt/editor/scripts/BoltWizardWindowUtils.cs @@ -1,232 +1,244 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; +using Photon.Bolt.Editor.Utils; using UnityEditor; using UnityEngine; -using Bolt.Editor; -public partial class BoltWizardWindow +namespace Photon.Bolt.Editor { - [Flags] - enum PackageFlags + public partial class BoltWizardWindow { - WarnForProjectOverwrite = 1 << 1, - RunInitialSetup = 1 << 2 - } + [Flags] + enum PackageFlags + { + WarnForProjectOverwrite = 1 << 1, + RunInitialSetup = 1 << 2 + } - class BoltWizardText - { - internal static readonly string WINDOW_TITLE = "Bolt Wizard"; - internal static readonly string SUPPORT = "You can contact the Bolt Team or Photon Services using one of the following links. You can also go to Bolt Documentation in order to get started with Photon Bolt."; - internal static readonly string PACKAGES = "Here you will be able to select all packages you want to use into your project. Packages marked green are already installed. \nClick to install."; - internal static readonly string PHOTON = "In this step, you will configure your Photon Cloud credentials in order to use our servers for matchmaking, relay and much more. Please fill all fields with your desired configuration."; - internal static readonly string PHOTON_DASH = "Go to Dashboard to create your App ID: "; - - internal static readonly string CONNECTION_TITLE = "Connecting"; - internal static readonly string CONNECTION_INFO = "Connecting to the account service..."; - - internal static readonly string FINISH_TITLE = "Bolt Setup Complete"; - internal static readonly string FINISH_QUESTION = "In order to finish the setup, Bolt needs to compile all Assets, do you want to proceed? If you opt to not compile now, you can run it on \"Bolt/Compile Assembly\"."; - - internal static readonly string CLOSE_MSG_TITLE = "Incomplete Installation"; - internal static readonly string CLOSE_MSG_QUESTION = "Are you sure you want to exit the Wizard?"; - internal static readonly string DISCORD_TEXT = "Join the Bolt Discord Community."; - internal static readonly string DISCORD_HEADER = "Community"; - internal static readonly string BUGTRACKER_TEXT = "Open bugtracker on github."; - internal static readonly string BUGTRACKER_HEADER = "Bug Tracker"; - internal static readonly string DOCUMENTATION_TEXT = "Open the documentation."; - internal static readonly string DOCUMENTATION_HEADER = "Documentation"; - internal static readonly string REVIEW_TEXT = "Please, let others know what you think about Bolt."; - internal static readonly string REVIEW_HEADER = "Leave a review"; - internal static readonly string SAMPLES_TEXT = "Import the samples package."; - internal static readonly string SAMPLES_HEADER = "Samples"; - internal static readonly string WIZARD_INTRO = -@"Hello! Welcome to Bolt Wizard! + class BoltWizardText + { + internal static readonly string WINDOW_TITLE = "Bolt Wizard"; + internal static readonly string SUPPORT = "You can contact the Bolt Team or Photon Services using one of the following links. You can also go to Bolt Documentation in order to get started with Photon Bolt."; + internal static readonly string PACKAGES = "Here you will be able to select all packages you want to use into your project. Packages marked green are already installed. \nClick to install."; + internal static readonly string PHOTON = "In this step, you will configure your Photon Cloud credentials in order to use our servers for matchmaking, relay and much more. Please fill all fields with your desired configuration."; + internal static readonly string PHOTON_DASH = "Go to Dashboard to create your App ID: "; + + internal static readonly string CONNECTION_TITLE = "Connecting"; + internal static readonly string CONNECTION_INFO = "Connecting to the account service..."; + + internal static readonly string FINISH_TITLE = "Bolt Setup Complete"; + internal static readonly string FINISH_QUESTION = "In order to finish the setup, Bolt needs to compile all Assets, do you want to proceed? If you opt to not compile now, you can run it on \"Bolt/Compile Assembly\"."; + + internal static readonly string CLOSE_MSG_TITLE = "Incomplete Installation"; + internal static readonly string CLOSE_MSG_QUESTION = "Are you sure you want to exit the Wizard?"; + internal static readonly string DISCORD_TEXT = "Join the Bolt Discord Community."; + internal static readonly string DISCORD_HEADER = "Community"; + internal static readonly string BUGTRACKER_TEXT = "Open bugtracker on github."; + internal static readonly string BUGTRACKER_HEADER = "Bug Tracker"; + internal static readonly string DOCUMENTATION_TEXT = "Open the documentation."; + internal static readonly string DOCUMENTATION_HEADER = "Documentation"; + internal static readonly string REVIEW_TEXT = "Please, let others know what you think about Bolt."; + internal static readonly string REVIEW_HEADER = "Leave a review"; + internal static readonly string SAMPLES_TEXT = "Import the samples package."; + internal static readonly string SAMPLES_HEADER = "Samples"; + internal static readonly string WIZARD_INTRO = + @"Hello! Welcome to Bolt Wizard! We are glad that you decided to use our products and services. Here at Photon, we work hard to make your multiplayer game easier to build and much more fun to play. This is a simple step by step configuration that you can follow and in just a few minutes you will be ready to use Bolt in all its power. If you have any doubt, please to our Getting Started page. Please, feel free to click on the Next button, and get started."; - } + } - class BoltPackage - { - public string name; - public string title; - public string description; - public Func installTest; - public PackageFlags packageFlags = default(PackageFlags); - } + class BoltPackage + { + public string name; + public string title; + public string description; + public Func installTest; + public PackageFlags packageFlags = default(PackageFlags); + } - enum BoltSetupStage - { - Intro = 1, - ReleaseHistory = 2, - Photon = 3, - Bolt = 4, - Support = 5 - } + enum BoltSetupStage + { + Intro = 1, + ReleaseHistory = 2, + Photon = 3, + Bolt = 4, + Support = 5 + } - [Flags] - enum BoltInstalls - { - Core = 1 << 0, - Mobile = 1 << 1, - Samples = 1 << 3, - XB1 = 1 << 4, - PS4 = 1 << 5 - } + [Flags] + enum BoltInstalls + { + Core = 1 << 0, + Mobile = 1 << 1, + Samples = 1 << 3, + XB1 = 1 << 4, + PS4 = 1 << 5 + } - String PackagePath(String packageName) - { - return Path.Combine(BoltPathUtility.PackagesPath, packageName + ".unitypackage"); - } + String PackagePath(String packageName) + { + return Path.Combine(BoltPathUtility.PackagesPath, packageName + ".unitypackage"); + } - Boolean PackageExists(String packageName) - { - return File.Exists(PackagePath(packageName)); - } + Boolean PackageExists(String packageName) + { + return File.Exists(PackagePath(packageName)); + } - Boolean ProjectExists() - { - return File.Exists(BoltPathUtility.ProjectPath); - } + Boolean ProjectExists() + { + return File.Exists(BoltPathUtility.ProjectPath); + } - Boolean MainPackageInstalled() - { - string SETTINGS_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltRuntimeSettings.asset"); - string PREFABDB_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltPrefabDatabase.asset"); + Boolean MainPackageInstalled() + { + string SETTINGS_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltRuntimeSettings.asset"); + string PREFABDB_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltPrefabDatabase.asset"); - return File.Exists(SETTINGS_PATH) && File.Exists(PREFABDB_PATH); - } + return File.Exists(SETTINGS_PATH) && File.Exists(PREFABDB_PATH); + } - Boolean SamplesPackageInstalled() - { - return Directory.Exists("Assets/samples"); - } + Boolean SamplesPackageInstalled() + { + return Directory.Exists("Assets/samples"); + } - Boolean XB1PackageInstalled() - { - return File.Exists("Assets/Plugins/XB1.dll"); - } + Boolean XB1PackageInstalled() + { + return File.Exists("Assets/Plugins/XB1.dll"); + } - Boolean PS4PackageInstalled() - { - return File.Exists("Assets/Plugins/PS4.dll"); - } + Boolean PS4PackageInstalled() + { + return File.Exists("Assets/Plugins/PS4.dll"); + } - Boolean MobilePackageInstalled() - { - return Directory.Exists("Assets/Plugins/iOS") && Directory.Exists("Assets/Plugins/Android"); - } + Boolean MobilePackageInstalled() + { + return Directory.Exists("Assets/Plugins/iOS") && Directory.Exists("Assets/Plugins/Android"); + } - Action OpenURL(String url, params System.Object[] args) - { - return () => + Action OpenURL(String url, params System.Object[] args) { - if (args.Length > 0) + return () => { - url = String.Format(url, args); - } - - Application.OpenURL(url); - }; - } + if (args.Length > 0) + { + url = String.Format(url, args); + } - void InitialSetup() - { - string SETTINGS_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltRuntimeSettings.asset"); - string PREFABDB_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltPrefabDatabase.asset"); + Application.OpenURL(url); + }; + } - if (!AssetDatabase.LoadAssetAtPath(SETTINGS_PATH, typeof(BoltRuntimeSettings))) + void InitialSetup() { - BoltRuntimeSettings settings = CreateInstance(); - settings.masterServerGameId = Guid.NewGuid().ToString().ToUpperInvariant(); + string SETTINGS_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltRuntimeSettings.asset"); + string PREFABDB_PATH = Path.Combine(BoltPathUtility.ResourcesPath, "BoltPrefabDatabase.asset"); - AssetDatabase.CreateAsset(settings, SETTINGS_PATH); - AssetDatabase.ImportAsset(SETTINGS_PATH, ImportAssetOptions.Default); - } + if (!AssetDatabase.LoadAssetAtPath(SETTINGS_PATH, typeof(BoltRuntimeSettings))) + { + BoltRuntimeSettings settings = CreateInstance(); - if (!AssetDatabase.LoadAssetAtPath(PREFABDB_PATH, typeof(Bolt.PrefabDatabase))) - { - AssetDatabase.CreateAsset(CreateInstance(), PREFABDB_PATH); - AssetDatabase.ImportAsset(PREFABDB_PATH, ImportAssetOptions.Default); - } + AssetDatabase.CreateAsset(settings, SETTINGS_PATH); + AssetDatabase.ImportAsset(SETTINGS_PATH, ImportAssetOptions.Default); + } - BoltMenuItems.RunCompiler(); - } + if (!AssetDatabase.LoadAssetAtPath(PREFABDB_PATH, typeof(PrefabDatabase))) + { + AssetDatabase.CreateAsset(CreateInstance(), PREFABDB_PATH); + AssetDatabase.ImportAsset(PREFABDB_PATH, ImportAssetOptions.Default); + } - static bool IsAppId(string val) - { - try + BoltMenuItems.RunCompiler(); + } + + static bool IsAppId(string val) { + try + { #pragma warning disable RECS0026 // Possible unassigned object created by 'new' - new Guid(val); + new Guid(val); #pragma warning restore RECS0026 // Possible unassigned object created by 'new' + } + catch + { + return false; + } + return true; } - catch - { - return false; - } - return true; - } - private void PrepareReleaseHistoryText() - { - var text = (TextAsset)AssetDatabase.LoadAssetAtPath(Path.Combine(BoltPathUtility.BasePath, "release_history.txt"), typeof(TextAsset)); - var baseText = text.text; - - var regexVersion = new Regex(@"(\b(\d+\.)?\d+\.\d+\.\d+\n)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); - var regexAdded = new Regex(@"\b(Added:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); - var regexChanged = new Regex(@"\b(Changed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); - var regexFixed = new Regex(@"\b(Fixed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); - var regexRemoved = new Regex(@"\b(Removed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); + private void PrepareReleaseHistoryText() + { + var text = (TextAsset)AssetDatabase.LoadAssetAtPath(Path.Combine(BoltPathUtility.BasePath, "release_history.txt"), typeof(TextAsset)); + var baseText = text.text; - var matches = regexVersion.Matches(baseText); + var regexVersion = new Regex(@"^(\d+\.?)+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); + var regexAdded = new Regex(@"\b(Added:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); + var regexChanged = new Regex(@"\b(Changed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); + var regexFixed = new Regex(@"\b(Fixed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); + var regexRemoved = new Regex(@"\b(Removed:)(.*)\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); - if (matches.Count > 0) - { - var currentVersionMatch = matches[0]; - var lastVersionMatch = currentVersionMatch.NextMatch(); + var matches = regexVersion.Matches(baseText); - if (currentVersionMatch.Success && lastVersionMatch.Success) + if (matches.Count > 0) { - var header = currentVersionMatch.Value.Trim(); - var mainText = baseText.Substring(currentVersionMatch.Index + currentVersionMatch.Length, - lastVersionMatch.Index - lastVersionMatch.Length - 1).Trim(); + var currentVersionMatch = matches[0]; + var lastVersionMatch = currentVersionMatch.NextMatch(); - var resultAdded = regexAdded.Matches(mainText); - var resultChanged = regexChanged.Matches(mainText); - var resultFixed = regexFixed.Matches(mainText); - var resultRemoved = regexRemoved.Matches(mainText); - - Func> itemProcessor = (match) => + if (currentVersionMatch.Success && lastVersionMatch.Success) { - var resultList = new List(); - for (var index = 0; index < match.Count; index++) + var header = currentVersionMatch.Value.Trim(); + var mainText = baseText.Substring(currentVersionMatch.Index + currentVersionMatch.Length, + lastVersionMatch.Index - lastVersionMatch.Length - 1).Trim(); + + var resultAdded = regexAdded.Matches(mainText); + var resultChanged = regexChanged.Matches(mainText); + var resultFixed = regexFixed.Matches(mainText); + var resultRemoved = regexRemoved.Matches(mainText); + + Func> itemProcessor = (match) => { - var result = match[index]; - resultList.Add(result.Groups[2].Value.Trim()); - } - return resultList; - }; - - ReleaseHistoryHeader = header; - ReleaseHistoryTextAdded = itemProcessor(resultAdded); - ReleaseHistoryTextChanged = itemProcessor(resultChanged); - ReleaseHistoryTextFixed = itemProcessor(resultFixed); - ReleaseHistoryTextRemoved = itemProcessor(resultRemoved); + var resultList = new List(); + for (var index = 0; index < match.Count; index++) + { + var result = match[index]; + resultList.Add(result.Groups[2].Value.Trim()); + } + return resultList; + }; + + ReleaseHistoryHeader = header; + ReleaseHistoryTextAdded = itemProcessor(resultAdded); + ReleaseHistoryTextChanged = itemProcessor(resultChanged); + ReleaseHistoryTextFixed = itemProcessor(resultFixed); + ReleaseHistoryTextRemoved = itemProcessor(resultRemoved); + } + } + else + { + ReleaseHistoryHeader = "Please look the file release_history.txt"; + ReleaseHistoryTextAdded = new List(); + ReleaseHistoryTextChanged = new List(); + ReleaseHistoryTextFixed = new List(); + ReleaseHistoryTextRemoved = new List(); } } - else + + public static bool Toggle(bool value) { - ReleaseHistoryHeader = "Please look the file release_history.txt"; - ReleaseHistoryTextAdded = new List(); - ReleaseHistoryTextChanged = new List(); - ReleaseHistoryTextFixed = new List(); - ReleaseHistoryTextRemoved = new List(); + var toggle = new GUIStyle("Toggle") + { + margin = new RectOffset(), + padding = new RectOffset() + }; + return EditorGUILayout.Toggle(value, toggle, GUILayout.Width(15)); } } } diff --git a/Assets/Photon/PhotonBolt/packages/bolt_samples.unitypackage b/Assets/Photon/PhotonBolt/packages/bolt_samples.unitypackage index e474730..296fcf0 100644 Binary files a/Assets/Photon/PhotonBolt/packages/bolt_samples.unitypackage and b/Assets/Photon/PhotonBolt/packages/bolt_samples.unitypackage differ diff --git a/Assets/Photon/PhotonBolt/project.json b/Assets/Photon/PhotonBolt/project.json index f1426e5..3fc8f0a 100644 --- a/Assets/Photon/PhotonBolt/project.json +++ b/Assets/Photon/PhotonBolt/project.json @@ -1,9 +1,9 @@ { - "$type": "Bolt.Compiler.Assets.BoltProject, bolt.compiler", + "$type": "Photon.Bolt.Compiler.Assets.BoltProject, bolt.compiler", "Filters": [], "Assets": [ { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "CurrentZone", @@ -12,11 +12,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -30,10 +30,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -47,11 +47,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeObject, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeObject, bolt.compiler", "StructGuid": "b039d403-d16b-4af0-a44f-fc5eb7d3b496" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -65,10 +65,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -82,10 +82,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -99,10 +99,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -116,10 +116,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -133,10 +133,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -150,10 +150,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -167,11 +167,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -185,11 +185,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -203,10 +203,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -220,10 +220,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -237,10 +237,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -254,10 +254,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -271,7 +271,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -283,7 +283,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -297,7 +297,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -309,7 +309,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -323,11 +323,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -341,7 +341,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -353,7 +353,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -367,7 +367,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -379,7 +379,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -459,7 +459,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.ObjectDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.ObjectDefinition, bolt.compiler", "Properties": [ { "Name": "OriginZone", @@ -468,11 +468,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -486,11 +486,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -504,7 +504,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -516,7 +516,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -530,10 +530,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -546,7 +546,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "ConnectionId", @@ -555,11 +555,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -573,11 +573,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -591,10 +591,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -608,11 +608,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -626,11 +626,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -644,10 +644,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -661,11 +661,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -745,7 +745,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Player", @@ -754,10 +754,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -767,11 +767,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -781,11 +781,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -795,7 +795,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Formation", @@ -803,10 +803,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -815,11 +815,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -829,10 +829,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -841,10 +841,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -854,7 +854,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "UnitClass", @@ -863,11 +863,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -881,10 +881,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -898,11 +898,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -916,11 +916,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -934,11 +934,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -952,11 +952,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -970,7 +970,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -982,7 +982,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -996,7 +996,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -1008,7 +1008,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1022,10 +1022,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1039,10 +1039,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1056,11 +1056,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1074,7 +1074,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -1086,7 +1086,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1100,11 +1100,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1118,11 +1118,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1136,11 +1136,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1220,7 +1220,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "ProductionQueue", @@ -1229,15 +1229,15 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeArray, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeArray, bolt.compiler", "ElementCount": 10, "ElementType": { - "$type": "Bolt.Compiler.PropertyTypeObject, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeObject, bolt.compiler", "StructGuid": "1cc5b915-f4e9-46d4-bae3-de6b38d6dd82" } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1318,7 +1318,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Factory", @@ -1327,10 +1327,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1340,11 +1340,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1354,10 +1354,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -1367,7 +1367,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.ObjectDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.ObjectDefinition, bolt.compiler", "Properties": [ { "Name": "UnitClass", @@ -1376,11 +1376,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1394,7 +1394,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -1406,7 +1406,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1420,10 +1420,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1436,7 +1436,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "FormationList", @@ -1445,10 +1445,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1462,11 +1462,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1480,11 +1480,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1498,14 +1498,14 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeArray, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeArray, bolt.compiler", "ElementCount": 10, "ElementType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1519,11 +1519,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1537,10 +1537,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1554,11 +1554,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1572,7 +1572,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -1584,7 +1584,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1664,7 +1664,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Attacker", @@ -1673,10 +1673,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1686,10 +1686,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1699,11 +1699,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -1713,7 +1713,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "Battle", @@ -1722,10 +1722,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1739,11 +1739,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1757,11 +1757,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1775,10 +1775,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1792,14 +1792,14 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeArray, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeArray, bolt.compiler", "ElementCount": 30, "ElementType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1813,10 +1813,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeNetworkId, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1830,10 +1830,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeArray, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeArray, bolt.compiler", "ElementCount": 30, "ElementType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -1846,7 +1846,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -1926,7 +1926,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Unit", @@ -1935,10 +1935,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1948,10 +1948,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -1961,11 +1961,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -1975,7 +1975,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Unit", @@ -1984,10 +1984,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -1997,7 +1997,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Attacker", @@ -2006,10 +2006,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2019,10 +2019,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2032,10 +2032,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2045,11 +2045,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2059,10 +2059,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeBool, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeBool, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2073,7 +2073,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "StorageCapacity", @@ -2082,11 +2082,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2100,11 +2100,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2118,10 +2118,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2135,7 +2135,7 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeFloat, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeFloat, bolt.compiler", "Compression": { "MinValue": -2048, "MaxValue": 2048, @@ -2147,7 +2147,7 @@ } }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2161,11 +2161,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2179,10 +2179,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2262,7 +2262,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Formation", @@ -2271,10 +2271,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2284,10 +2284,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2296,7 +2296,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "EntityCount", @@ -2305,11 +2305,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2318,7 +2318,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Unit", @@ -2327,10 +2327,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2340,10 +2340,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2352,7 +2352,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "Unit", @@ -2361,10 +2361,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2373,7 +2373,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [], "EntitySenders": 1, "GlobalSenders": 3, @@ -2382,7 +2382,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.EventDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.EventDefinition, bolt.compiler", "Properties": [ { "Name": "ItemName", @@ -2391,11 +2391,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2405,11 +2405,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2418,10 +2418,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } }, { @@ -2430,10 +2430,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeEntity, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeEntity, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyEventSettings, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyEventSettings, bolt.compiler" } } ], @@ -2442,7 +2442,7 @@ "Groups": [] }, { - "$type": "Bolt.Compiler.StateDefinition, bolt.compiler", + "$type": "Photon.Bolt.Compiler.StateDefinition, bolt.compiler", "Properties": [ { "Name": "PlanetName", @@ -2451,11 +2451,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeString, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeString, bolt.compiler", "MaxLength": 1 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2469,11 +2469,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2487,11 +2487,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2505,10 +2505,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2522,10 +2522,10 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" + "$type": "Photon.Bolt.Compiler.PropertyTypeProtocolToken, bolt.compiler" }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, @@ -2539,11 +2539,11 @@ "ReplicationMode": 1, "Priority": 1, "PropertyType": { - "$type": "Bolt.Compiler.PropertyTypeInteger, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyTypeInteger, bolt.compiler", "MaxValue": 255 }, "AssetSettings": { - "$type": "Bolt.Compiler.PropertyStateSettings, bolt.compiler", + "$type": "Photon.Bolt.Compiler.PropertyStateSettings, bolt.compiler", "ExtrapolationErrorTolerance": 0.25, "_ExtrapolationCorrectionFrames": 6, "ExtrapolationMaxFrames": 9, diff --git a/Assets/Photon/PhotonBolt/release_history.txt b/Assets/Photon/PhotonBolt/release_history.txt index d3ed405..0c8b730 100644 --- a/Assets/Photon/PhotonBolt/release_history.txt +++ b/Assets/Photon/PhotonBolt/release_history.txt @@ -1,3 +1,127 @@ +1.3.0 + +Added: Cache for incoming/outcoming EndPoints, in order to reduce memory allocation when sending/receiving data from the internal sockets. +Added: Cache for Assemblies in the project for quick loading GlobalEventListener after a restart. +Added: New property in the Bolt Settings to control the Stream Package Size. +Added: Object pooling for data blocks used by the Stream System, in order to reduce memory allocations. +Added: BoltNetwork.FindConnection to retrieve a Connection reference based on the Connection ID. Works only if the peer contains the Connection on the internal list. + +Changed: Complete refactor of Bolt namespaces [breaking change]. +Changed: Minimal supported Unity version is now 2019.4 LTS. +Changed: Realtime SDK to version v4.1.5.4. +Changed: Major refactoring on NAT Punch System. +Changed: Bolt SDK now targets .NET Framework 4.6.2, meaning that your Unity project must support this target (.NET 4.x or .NET Standard 2.0). +Changed: Refactor in the Stream System to reduced memory allocations. +Changed: Entity Proxy creation request behavior. Instead of a request on every package, now it waits for a confirmation or a lost package to re-send the request. +Changed: Auto registration of PhotonRoomProperties Protocol Token. +Changed: Exception will be raised if two or more Prefabs share the same name. +Changed: Review Prefab Database Loading Async Process, Prefabs can be loaded asynchronously before starting Bolt. + +Fixed: NullReference Exception when passing an invalid Session reference to Matchmaking Join. +Fixed: NullReference when Shutdown Bolt in SinglePlayer mode. +Fixed: IndexException if more than 32 hitboxes (max) are registered on a single entity. +Fixed: Using specific IPv4 passed as an argument when starting Bolt, instead of using the one from the first valid network adapter. +Fixed: Invalid Operation check when creating or joining a session. +Fixed: Exception in Log System when running Bolt in non-English systems. + +Removed: Obsolete methods from GlobalEventListener. +Removed: Outdated plugins from the SDK package. + +1.2.14 + +Added: Help links to Bolt Settings window. +Added: New ProtocolToken Type (PooledProtocolToken) that makes use of a new pooling system just for Tokens. The Pooling system works with Commands and Events for now. +Added: New ProtocolToken Registry. This will scan the project looking for Protocol Token implementations and register automatically when Bolt starts. +Added: Explicit log message when the peer receives an unknown ProtocolToken ID. +Added: Option to show BoltHitboxBody snapshot history for debugging purposes. + +Changed: Project JSON file is now saved only with the indented formatting. This helps when merging the file using a Source Control Version System. +Changed: Boolean properties optimization to speed up lookup and modifications. Can have an impact if the network layout makes extensive use of booleans. +Changed: Bolt Physics Pooling System for BoltPhysicsHit, grating better memory management. +Changed: Refresh BoltHitbox Component UI. +Changed: Photon Realtime version to v4.1.4.4. + +Fixed: High memory allocation when running Bolt Physics checks, mainly on raycasts against spheres. +Fixed: High memory allocation when creating Commands. Updated pooling system. +Fixed: Memory allocation by the Bolt GUI elements. +Fixed: Events Pooling System. Before only received events were pooled, now local raised events are also pooled. +Fixed: Internal UdpEndPoint fields order, fixing issues with the endpoint serialization representation in native format. +Fixed: Delay to shutdown client when the game server shutdown. Now, when the client detects the server is leaving the session, it will shutdown too. +Fixed: Instant Commands. Now instant commands will execute all previous command on the queue before running, keeping the consistency on the insertion order. +Fixed: PS4 Serialization methods for native translation of EndPoints. +Fixed: Reliable Stream receiver order. This prevents the receiving peer to discard packets of not fully completed streams. +Fixed: NullReferenceException when disposing of data packets. +Fixed: Return Error code instead of OK when joining a session and the action expires due timeout. + +1.2.13 + +Added: Fallback connection protocol. If the peer is not able to connect via UDP, it will switch to a TCP connection with the Photon Cloud. +Added: Packet Encryption system. +Added: Optional Scene IProtocolToken argument when creating a new Session using the BoltMatchmaking API. +Added: Support for Gameye Session Hosting. +Added: New Events API. +Added: New metadata field to the matchmaking API with information about the current connected Lobby, like the number of players and number of rooms. + +Changed: BoltEntity property of the search algorithm for IPriorityCalculator and IReplicationFilter. Now it's set to NONE by default, as most of the time, those implementations are not used. +Changed: When you start Bolt, and there are GlobalListenners for the current scene, they will be loaded and receive events, which includes 'SceneLoadLocalDone', for example. +Changed: Bolt Debug Start window. Now it's possible to select the build type (Development and/or with Scripts Only), and a small UI refresh. +Changed: GlobalListenner 'SessionCreated' to 'SessionCreatedOrUpdated'. +Changed: Included a warning when running Bolt without a valid AppID. +Changed: Reverted GlobalEventListener checks on Scene load. Now it's using again a Regex check to load or unload the Script automatically. +Changed: Included warning if Bolt Packet Size is set above 1200 bytes, as this is the max size recommended. + +Fixed: Shutdown procedure when the Server disconnects from a Relayed Connection. Now the client shutdown itself when it detects the server leaving the room. +Fixed: EnableLANBroadcast issue when shutdown and restart, the client tries to connect to an old LAN Server. +Fixed: Double library initialization in the PlayFab Sample. +Fixed: Unable to restart Bolt from the BoltShutdownBegin callback. +Fixed: Support to the Unity New Input System when using the Bolt Debug logs. +Fixed: PS4 Connection instability when running more than 1 console per network. +Fixed: Exception when checking Single Player mode with Bolt not started. +Fixed: High CPU usage when displaying Array property values from BoltEntities. Now the UI counts with a dropdown system and is lighter. +Fixed: Difference between the Lag Compensated frame running on Client and on Server. +Fixed: Debug Start does not load Scene when running as Client on Unity Editor. +Fixed: Bolt does not Compile in Release Mode. +Fixed: Changing state properties from inside another property callback can be missed and never be synchronized. +Fixed: NullReference on BoltEntity Inspector Drawer when dealing with String properties. +Fixed: SceneLoadRemoteDone callback Token that was passing the wrong token. +Fixed: SceneLoadLocalDone callback order of execution and not firing. Now the callback will fire after the BoltStartDone on all loaded GlobalEventListeners for the currently loaded scene. +Fixed: BoltNetwork.RemoveGlobalEventCallback does not remove previously registered callback. +Fixed: DebugStart not starting as Server and not connecting to Game Server as Client. + +Removed: Zeuz support. +Removed: BoltNetwork.Connect(UdpSession, IProtocolToken), use instead BoltMatchmaking.Join(UdpSession, ...) + +1.2.12 + +Added: Option to pass an IProtocolToken when connecting to a "localhost" Game Server. This is useful when using the "Debug Start" utility to pass a token when connecting. +Added: "StreamDataStarted" callback to Reliable Stream System. The callback fires when a new data stream started to be received. +Added: "StreamDataProgress" callback to Reliable Stream System. The callback fires when a new piece of data from an incoming stream has been received. +Added: "StreamDataAborted" callback to Reliable Stream System. The callback fires when an incoming stream of data has been aborted. This can happen because the remote peer was disconnected or the hash check fails. +Added: Button in the "Debug Start" to run the Build in Single Player mode. +Added: Support for Custom Authentication. Now you will be able to pass Authentication Values before starting Bolt, and then check the credentials of your players using your own auth service. +Added: Photon Platform metadata now includes more properties: "UserId", "Nickname" and "Data". All information is related to the Custom Authentication support. +Added: "BoltStartFailed" callback with a "UdpConnectionDisconnectReason" as argument, signaling the fail reason. This callback will replace the normal callback without the argument on future versions. +Added: "SessionConnectFailed" callback with a "UdpSessionError" to signal errors when trying to join a new Game Session. This callback will replace the normal callback without the argument on future versions. +Added: "SessionCreationFailed" callback with a "UdpSessionError" to signal errors when trying to create a new Game Session. This callback will replace the normal callback without the argument on future versions. + +Changed: Deprecated "BoltShutdownBegin" callback without "UdpConnectionDisconnectReason" as argument. +Changed: Deprecated "SceneLoad" callbacks without "IProtocolToken" as an argument. This change aims to follow the Bolt pattern of using callbacks with the "IProtocolToken". +Changed: Update version of Photon Realtime to 4.1.3.0. +Changed: Package Overflow check. It warns the user when trying to package a ProtocolToken that exceeds the maximum package size. +Changed: Warning when Photon Application ID is not set. +Changed: Update Console integrations with the latest Bolt SDK. +Changed: Photon Platform metadata key for the current Region: from "region" to "Region". The lowercase version still exists but will be removed on future versions. +Changed: Debug Scene visuals. + +Fixed: Debug Scene issue of Obsolete component in Camera. +Fixed: Timeout connection in the background. The application will continue to ping the Game Server in the background, maintaining the connection. +Fixed: Data Stream in Reliable Mode. The major issue was a Memory Leak after finishing the transmission. +Fixed: Source Provider MissingMethodException that may occur on some versions of the Unity Editor. +Fixed: Bolt Compiler does not work in Release Mode. +Fixed: Bolt cannot be started if invoking ShutdownImmediate before BoltStartDone. + +Removed: Overload BoltNetwork.Connect(udpSession, userJoinToken). You should use the method from the BoltMatchmaking API in order to join a Game Session (BoltMatchmaking.JoinSession(udpSession, userJoinToken)). + 1.2.11 Added: GlobalEventListener callback documentation. diff --git a/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset b/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset index 1ec6a2f..cd7974e 100644 --- a/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset +++ b/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset @@ -9,7 +9,7 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 763834002, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: -1148507213, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: BoltPrefabDatabase m_EditorClassIdentifier: DatabaseMode: 0 @@ -23,4 +23,5 @@ MonoBehaviour: - {fileID: 4678135251219452000, guid: 9ae35d7f911b63f4f95f432141dd5746, type: 3} - {fileID: 3262827332414082260, guid: f05198a1b03fe2b4e8042a9349c41aa3, type: 3} - {fileID: 8890686142670377634, guid: e369f02fbeb5a9046aaa40a9b89a8973, type: 3} - SearchPaths: [] + SearchPaths: + - Assets/GWConquest/Prefabs diff --git a/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset.meta b/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset.meta index 2287f4d..80f36a2 100644 --- a/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset.meta +++ b/Assets/Photon/PhotonBolt/resources/BoltPrefabDatabase.asset.meta @@ -1,4 +1,8 @@ fileFormatVersion: 2 -guid: 4d82c2835c7a28b459ba672f2d493435 +guid: 65b0205959f4b0b49842a048846922cc NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset b/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset index bff8371..c07780b 100644 --- a/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset +++ b/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset @@ -9,13 +9,14 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 95238504, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} + m_Script: {fileID: 2106054330, guid: 5b00bf8b25851d440940a40ec23344f4, type: 3} m_Name: BoltRuntimeSettings m_EditorClassIdentifier: _config: framesPerSecond: 60 - packetSize: 1280 + packetSize: 1200 packetMaxEventSize: 512 + packetStreamSize: 4096 maxEntityPriority: 65536 maxPropertyPriority: 2048 scopeMode: 0 @@ -42,24 +43,23 @@ MonoBehaviour: connectionTimeout: 10000 connectionRequestTimeout: 500 connectionRequestAttempts: 20 + connectionLocalRequestAttempts: 5 disableAutoSceneLoading: 0 EnableIPv6: 0 debugClientCount: 1 - debugStartPort: 50538 + debugStartPort: 54321 + debugBuildMode: 1 debugStartMapName: GalaxyMap - debugPlayAsServer: 1 + debugPlayAsServer: 0 showDebugInfo: 0 overrideTimeScale: 1 - logUncaughtExceptions: 1 debugEditorMode: 1 consoleToggleKey: 9 consoleVisibleByDefault: 0 compilationWarnLevel: 4 editorSkin: 4 scopeModeHideWarningInGui: 0 - showHelpButtons: 1 - masterServerGameId: 09A20926-601A-4EF4-BFEE-374761B0D2A5 - showBoltEntityHints: 0 + showBoltEntityHints: 1 serializeProjectAsText: 0 photonAppId: e44b4d31-ecbe-43ed-a111-d190991125de photonUsePunch: 1 @@ -69,9 +69,8 @@ MonoBehaviour: globalEntityPriorityCalculatorQueryOption: 3 globalEntityReplicationFilterQueryOption: 3 a2sServerPort: 21777 - enableA2sServer: 0 - RoomUpdateRate: 5 - RoomCreateTimeout: 20 - RoomJoinTimeout: 20 + enableA2sServer: 1 + RoomCreateTimeout: 10 + RoomJoinTimeout: 10 enableClientMetrics: 0 enableSourceProvider: 0 diff --git a/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset.meta b/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset.meta index 52514da..9db8011 100644 --- a/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset.meta +++ b/Assets/Photon/PhotonBolt/resources/BoltRuntimeSettings.asset.meta @@ -1,4 +1,8 @@ fileFormatVersion: 2 guid: dc43410f031439e4cab6920194ae2705 NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonBolt/scenes/BoltDebugScene.unity b/Assets/Photon/PhotonBolt/scenes/BoltDebugScene.unity index 9f8ad40..d231045 100644 --- a/Assets/Photon/PhotonBolt/scenes/BoltDebugScene.unity +++ b/Assets/Photon/PhotonBolt/scenes/BoltDebugScene.unity @@ -13,7 +13,7 @@ OcclusionCullingSettings: --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 - serializedVersion: 8 + serializedVersion: 9 m_Fog: 0 m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} m_FogMode: 3 @@ -38,7 +38,8 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657838, g: 0.49641234, b: 0.57481676, a: 1} + m_IndirectSpecularColor: {r: 0.37311953, g: 0.38074014, b: 0.3587274, a: 1} + m_UseRadianceAmbientProbe: 0 --- !u!157 &4 LightmapSettings: m_ObjectHideFlags: 0 @@ -49,20 +50,19 @@ LightmapSettings: m_BounceScale: 1 m_IndirectOutputScale: 1 m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 m_EnvironmentLightingMode: 0 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 1 m_LightmapEditorSettings: - serializedVersion: 9 + serializedVersion: 12 m_Resolution: 2 m_BakeResolution: 40 - m_TextureWidth: 1024 - m_TextureHeight: 1024 + m_AtlasSize: 1024 m_AO: 0 m_AOMaxDistance: 1 m_CompAOExponent: 0 m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 @@ -77,10 +77,16 @@ LightmapSettings: m_PVRDirectSampleCount: 32 m_PVRSampleCount: 500 m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 m_PVRFilterTypeDirect: 0 m_PVRFilterTypeIndirect: 0 m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 + m_PVREnvironmentMIS: 0 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 m_PVRFilteringGaussRadiusIndirect: 5 @@ -88,7 +94,9 @@ LightmapSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} m_UseShadowmask: 0 --- !u!196 &5 @@ -113,77 +121,91 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} ---- !u!1 &198367753 +--- !u!1 &367979120 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - component: {fileID: 198367755} - - component: {fileID: 198367754} - m_Layer: 0 - m_Name: Directional Light + - component: {fileID: 367979121} + - component: {fileID: 367979123} + - component: {fileID: 367979122} + m_Layer: 5 + m_Name: Text m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!108 &198367754 -Light: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 198367753} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &198367755 -Transform: +--- !u!224 &367979121 +RectTransform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 198367753} - m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605} - m_LocalPosition: {x: 0, y: 3, z: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 367979120} + 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: 0} + m_Father: {fileID: 1670489437} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 110, y: 0} + m_SizeDelta: {x: 200, y: 100} + m_Pivot: {x: 0, y: 1} +--- !u!114 &367979122 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 367979120} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.99997437, b: 0.9999913, a: 1} + m_RaycastTarget: 1 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 36 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 42 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Photon Bolt +--- !u!222 &367979123 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 367979120} + m_CullTransparentMesh: 0 --- !u!1 &947583843 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - component: {fileID: 947583845} - component: {fileID: 947583844} @@ -197,8 +219,9 @@ GameObject: --- !u!114 &947583844 MonoBehaviour: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 947583843} m_Enabled: 1 m_EditorHideFlags: 0 @@ -208,66 +231,225 @@ MonoBehaviour: --- !u!4 &947583845 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 947583843} 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: 0} - m_RootOrder: 2 + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &986390537 +--- !u!1 &1233091604 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - component: {fileID: 986390542} - - component: {fileID: 986390541} - - component: {fileID: 986390540} - - component: {fileID: 986390539} - - component: {fileID: 986390538} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera + - component: {fileID: 1233091608} + - component: {fileID: 1233091607} + - component: {fileID: 1233091606} + - component: {fileID: 1233091605} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!81 &986390538 -AudioListener: +--- !u!114 &1233091605 +MonoBehaviour: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 986390537} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1233091604} m_Enabled: 1 ---- !u!124 &986390539 -Behaviour: + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1233091606 +MonoBehaviour: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 986390537} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1233091604} m_Enabled: 1 ---- !u!92 &986390540 -Behaviour: + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 1 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &1233091607 +Canvas: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 986390537} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1233091604} m_Enabled: 1 ---- !u!20 &986390541 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1233091608 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1233091604} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1781609919} + - {fileID: 1670489437} + m_Father: {fileID: 0} + 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, y: 0} +--- !u!1 &1609382569 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1609382570} + - component: {fileID: 1609382572} + - component: {fileID: 1609382571} + m_Layer: 5 + m_Name: Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1609382570 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1609382569} + 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: 1670489437} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1609382571 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1609382569} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 1abf0ef6bcd6f4d33852c878c3400bc4, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1609382572 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1609382569} + m_CullTransparentMesh: 0 +--- !u!1 &1648222790 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1648222792} + - component: {fileID: 1648222791} + m_Layer: 0 + m_Name: Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!20 &1648222791 Camera: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 986390537} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1648222790} m_Enabled: 1 serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.28627452, g: 0.38823533, b: 0.5137255, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -279,7 +461,7 @@ Camera: field of view: 60 orthographic: 0 orthographic size: 5 - m_Depth: -1 + m_Depth: 0 m_CullingMask: serializedVersion: 2 m_Bits: 4294967295 @@ -288,22 +470,150 @@ Camera: m_TargetDisplay: 0 m_TargetEye: 3 m_HDR: 0 - m_AllowMSAA: 1 + m_AllowMSAA: 0 m_AllowDynamicResolution: 0 m_ForceIntoRT: 0 m_OcclusionCulling: 1 m_StereoConvergence: 10 m_StereoSeparation: 0.022 ---- !u!4 &986390542 +--- !u!4 &1648222792 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 986390537} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1648222790} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1670489436 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1670489437} + - component: {fileID: 1670489438} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1670489437 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1670489436} + 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: 1609382570} + - {fileID: 367979121} + m_Father: {fileID: 1233091608} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 140} + m_SizeDelta: {x: 295, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1670489438 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1670489436} + m_CullTransparentMesh: 0 +--- !u!1 &1781609918 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1781609919} + - component: {fileID: 1781609921} + - component: {fileID: 1781609920} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1781609919 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1781609918} + 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: 1233091608} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -140} + m_SizeDelta: {x: 680, y: 166.42} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1781609920 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1781609918} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.99997437, b: 0.9999913, a: 1} + m_RaycastTarget: 1 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 32 + 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: 'Debug Scene + + + Your Game Scene is being loaded...' +--- !u!222 &1781609921 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1781609918} + m_CullTransparentMesh: 0 diff --git a/Assets/Photon/PhotonBolt/scripts/BoltConsoleWriter.cs b/Assets/Photon/PhotonBolt/scripts/BoltConsoleWriter.cs index 24cdece..5d2c4e6 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltConsoleWriter.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltConsoleWriter.cs @@ -1,75 +1,85 @@ -using Microsoft.Win32.SafeHandles; using System; using System.IO; using System.Runtime.InteropServices; using System.Text; using UnityEngine; -namespace Bolt { - public static class ConsoleWriter { +namespace Photon.Bolt +{ + public static class ConsoleWriter + { #if UNITY_STANDALONE_WIN - static class PInvoke { - public const int STD_OUTPUT_HANDLE = -11; + static class PInvoke + { + public const int STD_OUTPUT_HANDLE = -11; - [DllImport("kernel32.dll", SetLastError = true)] - static public extern bool AttachConsole(uint dwProcessId); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool AttachConsole(uint dwProcessId); - [DllImport("kernel32.dll", SetLastError = true)] - static public extern bool AllocConsole(); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool AllocConsole(); - [DllImport("kernel32.dll", SetLastError = true)] - static public extern bool FreeConsole(); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool FreeConsole(); - [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] - static public extern IntPtr GetStdHandle(int nStdHandle); + [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr GetStdHandle(int nStdHandle); - [DllImport("kernel32.dll")] - static public extern bool SetConsoleTitle(string lpConsoleTitle); - } + [DllImport("kernel32.dll")] + public static extern bool SetConsoleTitle(string lpConsoleTitle); + } - static TextWriter realOut; + static TextWriter realOut; #endif - public static void Open() { + public static void Open() + { #if UNITY_STANDALONE_WIN - if (realOut == null) { - realOut = Console.Out; - } + if (realOut == null) + { + realOut = Console.Out; + } - var hasConsole = PInvoke.AttachConsole(0x0ffffffff); - if (hasConsole == false) { - PInvoke.AllocConsole(); - } + var hasConsole = PInvoke.AttachConsole(0x0ffffffff); + if (hasConsole == false) + { + PInvoke.AllocConsole(); + } - try { - // grab handle ptr - var outHandlePtr = PInvoke.GetStdHandle(PInvoke.STD_OUTPUT_HANDLE); + try + { + // grab handle ptr + var outHandlePtr = PInvoke.GetStdHandle(PInvoke.STD_OUTPUT_HANDLE); - // we can then create a filestream from this handle + // we can then create a filestream from this handle #pragma warning disable 0618 - var fileStream = new FileStream(outHandlePtr, FileAccess.Write); + var fileStream = new FileStream(outHandlePtr, FileAccess.Write); #pragma warning restore 0618 - // and then create a new stream writer (using ASCII) - var stdOut = new StreamWriter(fileStream, Encoding.ASCII); - stdOut.AutoFlush = true; + // and then create a new stream writer (using ASCII) + var stdOut = new StreamWriter(fileStream, Encoding.ASCII) + { + AutoFlush = true + }; - // and force unity to use this - Console.SetOut(stdOut); - } - catch (System.Exception e) { - Debug.Log(e); - } + // and force unity to use this + Console.SetOut(stdOut); + } + catch (Exception e) + { + Debug.Log(e); + } #endif - } + } - public static void Close() { + public static void Close() + { #if UNITY_STANDALONE_WIN - PInvoke.FreeConsole(); + PInvoke.FreeConsole(); - Console.SetOut(realOut); - realOut = null; + Console.SetOut(realOut); + realOut = null; #endif - } - } -} \ No newline at end of file + } + } +} diff --git a/Assets/Photon/PhotonBolt/scripts/BoltDebugStart.cs b/Assets/Photon/PhotonBolt/scripts/BoltDebugStart.cs index c7394d1..b2c3fe3 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltDebugStart.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltDebugStart.cs @@ -1,84 +1,102 @@ -using UdpKit; +using System.Collections; +using Photon.Bolt.Internal; +using Photon.Bolt.Utils; +using UdpKit; using UnityEngine; + +#if UNITY_EDITOR_OSX using Process = System.Diagnostics.Process; +#endif -public partial class BoltDebugStart : BoltInternal.GlobalEventListenerBase +namespace Photon.Bolt { - UdpEndPoint _serverEndPoint; - UdpEndPoint _clientEndPoint; - - void Awake() - { - DontDestroyOnLoad(gameObject); - - Application.targetFrameRate = 60; - } - - void Start() - { + public partial class BoltDebugStart : GlobalEventListenerBase + { + void Awake() + { + Application.targetFrameRate = 60; + } + + void Start() + { #if UNITY_EDITOR_OSX - Process p = new Process(); - p.StartInfo.FileName = "osascript"; - p.StartInfo.Arguments = + Process p = new Process(); + p.StartInfo.FileName = "osascript"; + p.StartInfo.Arguments = - @"-e 'tell application """ + UnityEditor.PlayerSettings.productName + @""" + @"-e 'tell application """ + UnityEditor.PlayerSettings.productName + @""" activate end tell'"; - p.Start(); + p.Start(); #endif - BoltRuntimeSettings settings = BoltRuntimeSettings.instance; - - _serverEndPoint = new UdpEndPoint(UdpIPv4Address.Localhost, (ushort)settings.debugStartPort); - _clientEndPoint = new UdpEndPoint(UdpIPv4Address.Localhost, 0); - - BoltConfig cfg; - - cfg = settings.GetConfigCopy(); - cfg.connectionTimeout = 60000000; - cfg.connectionRequestTimeout = 500; - cfg.connectionRequestAttempts = 1000; - - if (string.IsNullOrEmpty(settings.debugStartMapName) == false) - { - if (BoltDebugStartSettings.DebugStartIsServer) - { - BoltLauncher.StartServer(_serverEndPoint, cfg); - } - else if (BoltDebugStartSettings.DebugStartIsClient) - { - BoltLauncher.StartClient(_clientEndPoint, cfg); - } - - BoltDebugStartSettings.PositionWindow(); - } - else - { - BoltLog.Error("No map found to start from"); - } - } - - public override void BoltStartFailed() - { - BoltLog.Error("Failed to start debug mode"); - } - - public override void BoltStartDone() - { - if (BoltNetwork.IsServer) - { - BoltNetwork.LoadScene(BoltRuntimeSettings.instance.debugStartMapName); - } - else - { - BoltNetwork.Connect((ushort)BoltRuntimeSettings.instance.debugStartPort); - } - } - - public override void SceneLoadLocalDone(string map) - { - Destroy(gameObject); - } + var settings = BoltRuntimeSettings.instance; + + var cfg = settings.GetConfigCopy(); + cfg.connectionTimeout = 60000000; + cfg.connectionRequestTimeout = 500; + cfg.connectionRequestAttempts = 1000; + + if (string.IsNullOrEmpty(settings.debugStartMapName) == false) + { + if (BoltDebugStartSettings.DebugStartIsServer) + { + BoltLog.Warn("Starting as SERVER"); + + var serverEndPoint = new UdpEndPoint(UdpIPv4Address.Localhost, (ushort)settings.debugStartPort); + + BoltLauncher.StartServer(serverEndPoint, cfg); + } + else if (BoltDebugStartSettings.DebugStartIsClient) + { + BoltLog.Warn("Starting as CLIENT"); + + var clientEndPoint = new UdpEndPoint(UdpIPv4Address.Localhost, 0); + + BoltLauncher.StartClient(clientEndPoint, cfg); + } + else if (BoltDebugStartSettings.DebugStartIsSinglePlayer) + { + BoltLog.Warn("Starting as SINGLE PLAYER"); + + BoltLauncher.StartSinglePlayer(cfg); + } + + BoltDebugStartSettings.PositionWindow(); + } + else + { + BoltLog.Error("No map found to start from"); + } + } + + public override void BoltStartFailed(UdpConnectionDisconnectReason disconnectReason) + { + BoltLog.Error("Failed to start debug mode"); + } + + public override void BoltStartDone() + { + if (BoltNetwork.IsServer || BoltNetwork.IsSinglePlayer) + { + BoltNetwork.LoadScene(BoltRuntimeSettings.instance.debugStartMapName); + } + else if (BoltNetwork.IsClient) + { + StartCoroutine(DelayClientConnect()); + } + } + + private IEnumerator DelayClientConnect() + { + for (int i = 0; i < 5; i++) + { + BoltLog.Info("Connecting in {0} seconds...", 5 - i); + yield return new WaitForSeconds(1); + } + + BoltNetwork.Connect((ushort)BoltRuntimeSettings.instance.debugStartPort); + } + } } - diff --git a/Assets/Photon/PhotonBolt/scripts/BoltDebugStartSettings.cs b/Assets/Photon/PhotonBolt/scripts/BoltDebugStartSettings.cs index bfc2c90..c1fd699 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltDebugStartSettings.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltDebugStartSettings.cs @@ -1,163 +1,196 @@ +using Photon.Bolt.Utils; + +#if UNITY_STANDALONE +using System.Runtime.InteropServices; using System; using System.Linq; -using System.Runtime.InteropServices; +#endif -public class BoltDebugStartSettings +namespace Photon.Bolt { + public class BoltDebugStartSettings + { #if UNITY_EDITOR - public static bool DebugStartIsServer - { - get { return BoltRuntimeSettings.instance.debugEditorMode == BoltEditorStartMode.Server; } - } - - public static bool DebugStartIsClient - { - get { return BoltRuntimeSettings.instance.debugEditorMode == BoltEditorStartMode.Client; } - } - - public static int WindowIndex - { - get { return -1; } - } + public static bool DebugStartIsSinglePlayer + { + get { return BoltRuntimeSettings.instance.debugEditorMode == BoltEditorStartMode.None; } + } + + public static bool DebugStartIsServer + { + get { return BoltRuntimeSettings.instance.debugEditorMode == BoltEditorStartMode.Server; } + } + + public static bool DebugStartIsClient + { + get { return BoltRuntimeSettings.instance.debugEditorMode == BoltEditorStartMode.Client; } + } + + public static int WindowIndex + { + get { return -1; } + } #elif UNITY_STANDALONE - public static bool DebugStartIsServer - { - get { return Environment.GetCommandLineArgs().Contains("--bolt-debugstart-server"); } - } - - public static bool DebugStartIsClient - { - get { return Environment.GetCommandLineArgs().Contains("--bolt-debugstart-client"); } - } - - public static int WindowIndex - { - get - { - foreach (string arg in Environment.GetCommandLineArgs()) - { - if (arg.StartsWith("--bolt-window-index-")) - { - return int.Parse(arg.Replace("--bolt-window-index-", "")); - } - } - - return 0; - } - } + public static bool DebugStartIsSinglePlayer + { + get { return false; } + } + + public static bool DebugStartIsServer + { + get { return Environment.GetCommandLineArgs().Contains("--bolt-debugstart-server"); } + } + + public static bool DebugStartIsClient + { + get { return Environment.GetCommandLineArgs().Contains("--bolt-debugstart-client"); } + } + + public static int WindowIndex + { + get + { + foreach (string arg in Environment.GetCommandLineArgs()) + { + if (arg.StartsWith("--bolt-window-index-")) + { + return int.Parse(arg.Replace("--bolt-window-index-", "")); + } + } + + return 0; + } + } #else - public static bool DebugStartIsServer - { - get { return false; } - } - - public static bool DebugStartIsClient - { - get { return false; } - } - - public static int WindowIndex - { - get { return -1; } - } + public static bool DebugStartIsSinglePlayer + { + get { return false; } + } + + public static bool DebugStartIsServer + { + get { return false; } + } + + public static bool DebugStartIsClient + { + get { return false; } + } + + public static int WindowIndex + { + get { return -1; } + } #endif #if UNITY_STANDALONE_WIN && !UNITY_EDITOR - static readonly object handle = new object(); - static HandleRef unityHandle = new HandleRef(); - - static class HWND { - public static IntPtr - NoTopMost = new IntPtr(-2), - TopMost = new IntPtr(-1), - Top = new IntPtr(0), - Bottom = new IntPtr(1); - } - - static class SWP { - public static readonly int - NOSIZE = 0x0001, - NOMOVE = 0x0002, - NOZORDER = 0x0004, - NOREDRAW = 0x0008, - NOACTIVATE = 0x0010, - DRAWFRAME = 0x0020, - FRAMECHANGED = 0x0020, - SHOWWINDOW = 0x0040, - HIDEWINDOW = 0x0080, - NOCOPYBITS = 0x0100, - NOOWNERZORDER = 0x0200, - NOREPOSITION = 0x0200, - NOSENDCHANGING = 0x0400, - DEFERERASE = 0x2000, - ASYNCWINDOWPOS = 0x4000; - } - - delegate bool EnumWindowsProc (IntPtr hWnd, IntPtr lParam); - - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern int GetWindowThreadProcessId (HandleRef handle, out int processId); - - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern bool EnumWindows (EnumWindowsProc callback, IntPtr extraData); - - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern int GetSystemMetrics (int index); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - static extern bool SetWindowPos (IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); - - static bool Window (IntPtr hWnd, IntPtr lParam) { - int pid = -1; - int unity_pid = System.Diagnostics.Process.GetCurrentProcess().Id; - - GetWindowThreadProcessId(new HandleRef(handle, hWnd), out pid); - - if (pid == unity_pid) { - unityHandle = new HandleRef(handle, hWnd); - return false; - } - - return true; - } - - public static void PositionWindow () { - if (DebugStartIsClient || DebugStartIsServer) { - EnumWindows(Window, IntPtr.Zero); - - if (unityHandle.Wrapper != null) { - int ww = UnityEngine.Screen.width; - int wh = UnityEngine.Screen.height; - - int x = 0; - int y = 0; - int w = GetSystemMetrics(0); - int h = GetSystemMetrics(1); - - if (DebugStartIsServer) { - x = w / 2 - (ww / 2); - y = h / 2 - (wh / 2); - - } else { - switch (WindowIndex % 4) { - case 1: x = w - ww; break; - case 2: y = h - wh; break; - case 3: - x = w - ww; - y = h - wh; - break; - } - } - - SetWindowPos(unityHandle.Handle, HWND.Top, x, y, ww, wh, SWP.NOSIZE); - } - } - } + static readonly object handle = new object(); + static HandleRef unityHandle = new HandleRef(); + + static class HWND + { + public static IntPtr + NoTopMost = new IntPtr(-2), + TopMost = new IntPtr(-1), + Top = new IntPtr(0), + Bottom = new IntPtr(1); + } + + static class SWP + { + public static readonly int + NOSIZE = 0x0001, + NOMOVE = 0x0002, + NOZORDER = 0x0004, + NOREDRAW = 0x0008, + NOACTIVATE = 0x0010, + DRAWFRAME = 0x0020, + FRAMECHANGED = 0x0020, + SHOWWINDOW = 0x0040, + HIDEWINDOW = 0x0080, + NOCOPYBITS = 0x0100, + NOOWNERZORDER = 0x0200, + NOREPOSITION = 0x0200, + NOSENDCHANGING = 0x0400, + DEFERERASE = 0x2000, + ASYNCWINDOWPOS = 0x4000; + } + + delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern int GetWindowThreadProcessId(HandleRef handle, out int processId); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern bool EnumWindows(EnumWindowsProc callback, IntPtr extraData); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern int GetSystemMetrics(int index); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); + + static bool Window(IntPtr hWnd, IntPtr lParam) + { + int pid = -1; + int unity_pid = System.Diagnostics.Process.GetCurrentProcess().Id; + + GetWindowThreadProcessId(new HandleRef(handle, hWnd), out pid); + + if (pid == unity_pid) + { + unityHandle = new HandleRef(handle, hWnd); + return false; + } + + return true; + } + + public static void PositionWindow() + { + if (DebugStartIsClient || DebugStartIsServer) + { + EnumWindows(Window, IntPtr.Zero); + + if (unityHandle.Wrapper != null) + { + int ww = UnityEngine.Screen.width; + int wh = UnityEngine.Screen.height; + + int x = 0; + int y = 0; + int w = GetSystemMetrics(0); + int h = GetSystemMetrics(1); + + if (DebugStartIsServer) + { + x = w / 2 - (ww / 2); + y = h / 2 - (wh / 2); + + } + else + { + switch (WindowIndex % 4) + { + case 1: x = w - ww; break; + case 2: y = h - wh; break; + case 3: + x = w - ww; + y = h - wh; + break; + } + } + + SetWindowPos(unityHandle.Handle, HWND.Top, x, y, ww, wh, SWP.NOSIZE); + } + } + } #else - public static void PositionWindow() - { + public static void PositionWindow() + { - } + } #endif + } } diff --git a/Assets/Photon/PhotonBolt/scripts/BoltDynamicData.cs b/Assets/Photon/PhotonBolt/scripts/BoltDynamicData.cs index 64f8bdd..c50c0f0 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltDynamicData.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltDynamicData.cs @@ -1,20 +1,48 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using BoltInternal; +using Photon.Bolt.Collections; +using Photon.Bolt.Internal; +using Photon.Bolt.Utils; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.Scripting; -namespace Bolt +namespace Photon.Bolt { [Preserve] public static class BoltDynamicData { + private static Dictionary _assemblies; + + private static List> _globalBehaviours; + + private static Dictionary GetAssemblies + { + get + { + if (_assemblies == null) + { + _assemblies = new Dictionary(); + + foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) + { + var name = asm.GetName().Name; + if (_assemblies.ContainsKey(name) == false) + { + _assemblies.Add(name, asm); + } + } + } + + return _assemblies; + } + } + public static void Setup() { - BoltNetworkInternal.DebugDrawer = new BoltInternal.UnityDebugDrawer(); + BoltNetworkInternal.DebugDrawer = new UnityDebugDrawer(); #if UNITY_PRO_LICENSE BoltNetworkInternal.UsingUnityPro = true; @@ -26,8 +54,8 @@ namespace Bolt BoltNetworkInternal.GetSceneName = GetSceneName; BoltNetworkInternal.GetSceneIndex = GetSceneIndex; BoltNetworkInternal.GetGlobalBehaviourTypes = GetGlobalBehaviourTypes; - BoltNetworkInternal.EnvironmentSetup = BoltInternal.BoltNetworkInternal_User.EnvironmentSetup; - BoltNetworkInternal.EnvironmentReset = BoltInternal.BoltNetworkInternal_User.EnvironmentReset; + BoltNetworkInternal.EnvironmentSetup = BoltNetworkInternal_User.EnvironmentSetup; + BoltNetworkInternal.EnvironmentReset = BoltNetworkInternal_User.EnvironmentReset; // Setup Unity Config @@ -39,45 +67,66 @@ namespace Bolt UnitySettings.IsBuildDotNet = true; #endif - UnitySettings.CurrentPlatform = Application.platform; - } + UnitySettings.CurrentPlatform = Application.platform; + } - static int GetActiveSceneIndex() + private static int GetActiveSceneIndex() { - return SceneManager.GetActiveScene().buildIndex; + return GetSceneIndex(SceneManager.GetActiveScene().name); } - static int GetSceneIndex(string name) + private static int GetSceneIndex(string name) { - return BoltInternal.BoltScenes_Internal.GetSceneIndex(name); + try + { + return BoltScenes_Internal.GetSceneIndex(name); + } + catch + { + return -1; + } } - static string GetSceneName(int index) + private static string GetSceneName(int index) { - return BoltInternal.BoltScenes_Internal.GetSceneName(index); + try + { + return BoltScenes_Internal.GetSceneName(index); + } + catch + { + return null; + } } - static public List> GetGlobalBehaviourTypes() + private static List> GetGlobalBehaviourTypes() { - List> result = new List>(); + if (_globalBehaviours == null) + { + _globalBehaviours = new List>(); + } + else + { + _globalBehaviours.Clear(); + } try { var asmIter = BoltAssemblies.AllAssemblies; while (asmIter.MoveNext()) { - var asm = GetAssemblyByName(asmIter.Current); - if (asm == null) { continue; } - - foreach (Type type in asm.GetTypes()) + if (GetAssemblies.TryGetValue(asmIter.Current, out var asm)) { - if (typeof(MonoBehaviour).IsAssignableFrom(type)) + foreach (Type type in asm.GetTypes()) { - var attrs = (BoltGlobalBehaviourAttribute[]) type.GetCustomAttributes(typeof(BoltGlobalBehaviourAttribute), false); - - if (attrs.Length == 1) + if (typeof(MonoBehaviour).IsAssignableFrom(type)) { - result.Add(new STuple(attrs[0], type)); + var attrs = (BoltGlobalBehaviourAttribute[])type.GetCustomAttributes(typeof(BoltGlobalBehaviourAttribute), false); + + if (attrs.Length == 1) + { + _globalBehaviours.Add(new STuple(attrs[0], type)); + } } } } @@ -88,12 +137,7 @@ namespace Bolt BoltLog.Exception(e); } - return result; - } - - static Assembly GetAssemblyByName(string name) - { - return AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(assembly => assembly.GetName().Name == name); + return _globalBehaviours; } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonBolt/scripts/BoltExecutionOrderAttribute.cs b/Assets/Photon/PhotonBolt/scripts/BoltExecutionOrderAttribute.cs index 1f82742..91daabd 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltExecutionOrderAttribute.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltExecutionOrderAttribute.cs @@ -1,36 +1,39 @@ -using System; +using System; -/// -/// Sets the Unity script execution order -/// -/// -/// *Example:* Setting the execution order of a manager class using an attribute. -/// -/// ```csharp -/// [BoltExecutionOrder(-5000)] -/// public class SoundManager : MonoBehaviour -/// { -/// void Awake() { -/// ConfigureSoundSettings(); -/// } -/// } -/// ``` -/// -[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] -public sealed class BoltExecutionOrderAttribute : Attribute +namespace Photon.Bolt { - readonly int _executionOrder; - - public BoltExecutionOrderAttribute(int order) - { - _executionOrder = order; - } - /// - /// The order of this script in execution (lower is earlier) + /// Sets the Unity script execution order /// - public int executionOrder + /// + /// *Example:* Setting the execution order of a manager class using an attribute. + /// + /// ```csharp + /// [BoltExecutionOrder(-5000)] + /// public class SoundManager : MonoBehaviour + /// { + /// void Awake() { + /// ConfigureSoundSettings(); + /// } + /// } + /// ``` + /// + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + public sealed class BoltExecutionOrderAttribute : Attribute { - get { return _executionOrder; } + readonly int _executionOrder; + + public BoltExecutionOrderAttribute(int order) + { + _executionOrder = order; + } + + /// + /// The order of this script in execution (lower is earlier) + /// + public int executionOrder + { + get { return _executionOrder; } + } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs b/Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs deleted file mode 100644 index 6dd8c7e..0000000 --- a/Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Reflection; -using UdpKit; -using UnityEngine; - -public static class BoltNetworkUtils -{ - public static Action Combine(this Action self, Action action) - { - return (Action)Delegate.Combine(self, action); - } -} diff --git a/Assets/Photon/PhotonBolt/scripts/BoltUnityDebugDrawer.cs b/Assets/Photon/PhotonBolt/scripts/BoltUnityDebugDrawer.cs index 71f9b23..b301adc 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltUnityDebugDrawer.cs +++ b/Assets/Photon/PhotonBolt/scripts/BoltUnityDebugDrawer.cs @@ -1,93 +1,137 @@ -using UnityEngine; -using System.Diagnostics; +using UnityEngine; +using Photon.Bolt.Utils; #if UNITY_EDITOR using UnityEditor; #endif -namespace BoltInternal +namespace Photon.Bolt.Internal { - public class UnityDebugDrawer : IDebugDrawer - { - bool isEditor; + public class UnityDebugDrawer : IDebugDrawer + { + bool isEditor; - void IDebugDrawer.IsEditor(bool isEditor) - { - this.isEditor = isEditor; - } + void IDebugDrawer.IsEditor(bool isEditor) + { + this.isEditor = isEditor; + } - void IDebugDrawer.SelectGameObject(GameObject gameObject) - { + void IDebugDrawer.SelectGameObject(GameObject gameObject) + { #if UNITY_EDITOR - if (!isEditor) - { - Selection.activeGameObject = gameObject; - } + if (!isEditor) + { + Selection.activeGameObject = gameObject; + } #endif - } + } - void IDebugDrawer.Indent(int level) - { + void IDebugDrawer.Indent(int level) + { #if UNITY_EDITOR - if (isEditor) - { - EditorGUI.indentLevel = level; - return; - } + if (isEditor) + { + EditorGUI.indentLevel = level; + return; + } #endif - } + } - void IDebugDrawer.Label(string text) - { + void IDebugDrawer.Label(string text) + { #if UNITY_EDITOR - if (isEditor) - { - GUILayout.Label(text); - return; - } + if (isEditor) + { + GUILayout.Label(text); + return; + } #endif - Bolt.DebugInfo.Label(text); - } + DebugInfo.Label(text); + } - void IDebugDrawer.LabelBold(string text) - { + void IDebugDrawer.LabelBold(string text) + { #if UNITY_EDITOR - if (isEditor) - { - GUILayout.Label(text, EditorStyles.boldLabel); - return; - } + if (isEditor) + { + GUILayout.Label(text, EditorStyles.boldLabel); + return; + } #endif - Bolt.DebugInfo.LabelBold(text); - } + DebugInfo.LabelBold(text); + } - void IDebugDrawer.LabelField(string text, object value) - { + void IDebugDrawer.LabelField(string text, object value) + { #if UNITY_EDITOR - if (isEditor) - { - EditorGUILayout.LabelField(text, value.ToString()); - return; - } + if (isEditor) + { + EditorGUILayout.LabelField(text, value.ToString()); + return; + } #endif - Bolt.DebugInfo.LabelField(text, value); - } + DebugInfo.LabelField(text, value); + } - void IDebugDrawer.Separator() - { + void IDebugDrawer.Separator() + { #if UNITY_EDITOR - if (isEditor) - { - EditorGUILayout.Separator(); - return; - } + if (isEditor) + { + EditorGUILayout.Separator(); + return; + } #endif - GUILayout.Space(2); - } + GUILayout.Space(2); + } - } -} \ No newline at end of file + void IDebugDrawer.DrawObjectArray(IDebugDrawerObjectArray root) + { +#if UNITY_EDITOR + if (isEditor) + { + var fields = root.GetChildren(); + + for (int i = 0; i < fields.Length; i++) + { + DrawObjectArrayItem(fields[i]); + } + + return; + } +#endif + } + + private void DrawObjectArrayItem(IDebugDrawerObjectArray item) + { +#if UNITY_EDITOR + var fields = item.GetChildren(); + + if (fields.Length > 0) + { + item.IsVisible = EditorGUILayout.Foldout(item.IsVisible, item.GetName(), true); + + if (item.IsVisible) + { + EditorGUI.indentLevel++; + + for (int i = 0; i < fields.Length; i++) + { + DrawObjectArrayItem(fields[i]); + } + + EditorGUI.indentLevel--; + } + } + else + { + (this as IDebugDrawer).LabelField(item.GetName(), item.GetValue()); + } +#endif + } + } +} diff --git a/Assets/Photon/PhotonLibs.meta b/Assets/Photon/PhotonLibs.meta index ded578d..05f4c17 100644 --- a/Assets/Photon/PhotonLibs.meta +++ b/Assets/Photon/PhotonLibs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 3647887b8e3e878429d3b999a90df02d +guid: ee1734b1a7bac244bb5f15ecd778b5f2 folderAsset: yes DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll index 5589de7..b0f9d49 100644 Binary files a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll and b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll differ diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb deleted file mode 100644 index 114915b..0000000 Binary files a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb and /dev/null differ diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.meta b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.meta index 32ab5a4..236ab31 100644 --- a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.meta +++ b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.meta @@ -40,7 +40,7 @@ PluginImporter: settings: CPU: AnyCPU DontProcess: False - PlaceholderPath: Assets/Plugins/Photon3Unity3D.dll + PlaceholderPath: Assets/Photon/PhotonLibs/Photon3Unity3D.dll SDK: AnySDK ScriptingBackend: DotNet Win: @@ -56,7 +56,7 @@ PluginImporter: settings: CPU: AnyCPU DontProcess: False - PlaceholderPath: Assets/Plugins/Photon3Unity3D.dll + PlaceholderPath: Assets/Photon/PhotonLibs/Photon3Unity3D.dll SDK: AnySDK ScriptingBackend: DotNet iOS: diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pdb b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pdb index 49eb0de..c44d6aa 100644 Binary files a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pdb and b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pdb differ diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pri b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pri index fa910b6..889f87b 100644 Binary files a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pri and b/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.pri differ diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll b/Assets/Photon/PhotonLibs/Photon3Unity3D.dll index 978c53e..6faae7d 100644 Binary files a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll and b/Assets/Photon/PhotonLibs/Photon3Unity3D.dll differ diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb b/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb deleted file mode 100644 index f6e55b1..0000000 Binary files a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb and /dev/null differ diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.meta b/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.meta index a1d5384..3348027 100644 --- a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.meta +++ b/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.meta @@ -6,101 +6,186 @@ labels: - Photon - Networking PluginImporter: - serializedVersion: 1 + externalObjects: {} + serializedVersion: 2 iconMap: {} executionOrder: {} + defineConstraints: [] isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 platformData: - Android: - enabled: 1 - settings: - CPU: AnyCPU - Any: + - first: + '': Any + second: enabled: 0 - settings: {} - Editor: - enabled: 1 settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: AnyOS - Linux: - enabled: 1 - settings: - CPU: x86 - Linux64: - enabled: 1 - settings: - CPU: x86_64 - LinuxUniversal: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude WindowsStoreApps: 1 + Exclude iOS: 1 + - first: + '': Lumin + second: enabled: 1 settings: {} - OSXIntel: + - first: + '': OSXIntel + second: enabled: 1 settings: CPU: AnyCPU - OSXIntel64: + - first: + '': OSXIntel64 + second: enabled: 1 settings: CPU: AnyCPU - OSXUniversal: - enabled: 1 - settings: {} - WP8: + - first: + '': WP8 + second: enabled: 1 settings: CPU: AnyCPU DontProcess: False - PlaceholderPath: + PlaceholderPath: SDK: AnySDK ScriptingBackend: Il2Cpp - Web: + - first: + '': Web + second: enabled: 1 settings: {} - WebGL: + - first: + '': WebStreamed + second: enabled: 1 settings: {} - WebStreamed: + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: WebGL + second: enabled: 1 settings: {} - Win: + - first: + Facebook: Win + second: enabled: 1 settings: CPU: AnyCPU - Win64: + - first: + Facebook: Win64 + second: enabled: 1 settings: CPU: AnyCPU - WindowsStoreApps: + - first: + Nintendo Switch: Switch + second: + enabled: 1 + settings: {} + - first: + PS4: PS4 + second: enabled: 1 + settings: {} + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 settings: CPU: AnyCPU - DontProcess: False - PlaceholderPath: - SDK: AnySDK - ScriptingBackend: Il2Cpp - iOS: - enabled: 1 + - first: + Standalone: Win + second: + enabled: 0 settings: - CompileFlags: - FrameworkDependencies: - tvOS: - enabled: 1 + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 0 settings: - CompileFlags: - FrameworkDependencies: - PS4: - enabled: 1 - settings: {} - Switch: - enabled: 1 + CPU: AnyCPU + - first: + WebGL: WebGL + second: + enabled: 0 settings: {} - XboxOne: + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + DontProcess: false + PlaceholderPath: + SDK: AnySDK + ScriptingBackend: Il2Cpp + - first: + XboxOne: XboxOne + second: enabled: 1 settings: {} - Lumin: + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: enabled: 1 - settings: {} - userData: - assetBundleName: - assetBundleVariant: + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.pdb b/Assets/Photon/PhotonLibs/Photon3Unity3D.pdb index 4c9e3f7..27fadee 100644 Binary files a/Assets/Photon/PhotonLibs/Photon3Unity3D.pdb and b/Assets/Photon/PhotonLibs/Photon3Unity3D.pdb differ diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.xml b/Assets/Photon/PhotonLibs/Photon3Unity3D.xml index 4114c0b..a024ed0 100644 --- a/Assets/Photon/PhotonLibs/Photon3Unity3D.xml +++ b/Assets/Photon/PhotonLibs/Photon3Unity3D.xml @@ -4,211 +4,295 @@ Photon3Unity3D - + - This is a substitute for the Hashtable class, missing in: Win8RT and Windows Phone. It uses a Dictionary<object,object> as base. + Initializes a new instance of the class. - - Please be aware that this class might act differently than the Hashtable equivalent. - As far as Photon is concerned, the substitution is sufficiently precise. - - + - Creates a shallow copy of the Hashtable. + Gets the public key that can be used by another DiffieHellmanCryptoProvider object + to generate a shared secret agreement. - - A shallow copy of a collection copies only the elements of the collection, whether they are - reference types or value types, but it does not copy the objects that the references refer - to. The references in the new collection point to the same objects that the references in - the original collection point to. - - Shallow copy of the Hashtable. - + - Contains several (more or less) useful static methods, mostly used for debugging. + Derives the shared key is generated from the secret agreement between two parties, + given a byte array that contains the second party's public key. + + The second party's public key. + - + + Interface for Photon's DiffieHellman/Payload Encryption. + + - Gets the local machine's "milliseconds since start" value (precision is described in remarks). + Provides classical Diffie-Hellman Modular Exponentiation Groups defined by the + OAKLEY Key Determination Protocol (RFC 2412). - - This method uses Environment.TickCount (cheap but with only 16ms precision). - PhotonPeer.LocalMsTimestampDelegate is available to set the delegate (unless already connected). - - Fraction of the current time in Milliseconds (this is not a proper datetime timestamp). - + - Creates a background thread that calls the passed function in 100ms intervals, as long as that returns true. + Gets the genrator (N) used by the the well known groups 1,2 and 5. - + - Creates a background thread that calls the passed function in intervals, as long as that returns true. + Gets the 768 bit prime for the well known group 1. - - With StopBackgroundCalls, you can stop threads started with this method. - The resulting ThreadAbortException is caught and discarded. - - The function to call. Must return true, if it should be called again. Returning false ends the thread. - Milliseconds to sleep between calls of myThread. Default: 100ms. - An optional name for the task to help debugging. Null or empty won't set the thread.Name. - + - Calls Abort on the thread with the given id (= index of the thread list) + Gets the 1024 bit prime for the well known group 2. - - The resulting ThreadAbortException is caught and discarded. - - The unique ID of the thread. - True if the thread is canceled and false otherwise, e.g. if the thread with the given ID does not exist. - + - Calls Abort on all threads that were started via StartBackgroundCalls. + Gets the 1536 bit prime for the well known group 5. - - The resulting ThreadAbortException is caught and discarded. - - True if any thread got aborted. - + + A slice of memory that should be pooled and reused. Wraps a byte-array. + + This is a serializable datatype for the .Net clients. It will serialize and transfer as byte[]. + If PhotonPeer.UseByteArraySlicePoolForEvents is enabled, byte-arrays in (incoming) events will be deserialized as + ByteArraySlice. + + Adjust your OnEvent code accordingly. + + + + The buffer for the slice. + + + The position where the content starts in Buffer. + + + The length of the data in the Buffer. + + - Writes the exception's stack trace to the received stream. + Internal constructor - these instances will be part of the pooling system. - Exception to obtain information from. - Output sream used to write to. + The pool to return to. + The index to return to (in the related returnPool). - + - Writes the exception's stack trace to the received stream. Writes to: System.Diagnostics.Debug. + Create a new ByteArraySlice. The buffer supplied will be used. Usage is similar to ArraySegment. - Exception to obtain information from. + Not part of pooling. - + - This method returns a string, representing the content of the given IDictionary. - Returns "null" if parameter is null. + Creates a ByteArraySlice, which is not pooled. It has no Buffer. + + Not part of pooling. + + + + If this item was fetched from a ByteArraySlicePool, this will return it. - - IDictionary to return as string. - - The string representation of keys and values in IDictionary. + True if this was a pooled item and it successfully was returned. + If it does not belong to a pool nothing will happen, and false will be returned. - + + Resets Count and Offset to 0 each. + + + Tiered pool for ByteArraySlices. Reduces the allocations once enough slices are available. + + - This method returns a string, representing the content of the given IDictionary. - Returns "null" if parameter is null. + Requests for buffers smaller than 2^minStackIndex will use 2^minStackIndex. This value avoids allocations of smaller rarely used buffers. + Set this to a lower value if you will never need sizes larger than byte[2^minStackIndex] - IDictionary to return as string. - - + + Count of allocations this pool did. + + + Creates a new pool. + + - Converts a byte-array to string (useful as debugging output). - Uses BitConverter.ToString(list) internally after a null-check of list. + Get a ByteArraySlice from pool. This overload handles user supplied byte[] and byte count and can be used as a non-boxing alternative to ArraySegment<byte>. - Byte-array to convert to string. - - List of bytes as string. - - + - Class to wrap static access to the random.Next() call in a thread safe manner. + Get byte[] wrapper from pool. This overload accepts a bytecount and will return a wrapper with a byte[] that size or greater. - + - Defines block size for encryption/decryption algorithm + Releasing a ByteArraySlice, will put it back into the pool, if it was acquired from one. + The ByteArraySlice to return to the pool. + True if this slice was returned to some pool. False if not. - + - Defines reusedIvBytes size for encryption/decryption algorithm + Clears all pool items with byte array sizes between lower and upper inclusively. + + Use this if you sent some unusually large RaiseEvents and believe the buffers of that size + will not be needed again, and you would like to free up the buffer memory. + - + - Defines HMAC size for packet authentication algorithm + Replacement for Dictionary<K,V> which does not allocate memory during usage. + Key type. + Value type. - + - Encryption/decryption algorithm implementation + This is a substitute for the Hashtable class, missing in: Win8RT and Windows Phone. It uses a Dictionary<object,object> as base. + + Please be aware that this class might act differently than the Hashtable equivalent. + As far as Photon is concerned, the substitution is sufficiently precise. + - + - Packet authentication algorithm impelmenation + Translates the byte key into the pre-boxed byte before doing the lookup. + + - + - Implemenation of encryption for "Datagram Encryption". + Creates a shallow copy of the Hashtable. + + A shallow copy of a collection copies only the elements of the collection, whether they are + reference types or value types, but it does not copy the objects that the references refer + to. The references in the new collection point to the same objects that the references in + the original collection point to. + + Shallow copy of the Hashtable. - + + Interface for DatagramEncryptor implementations. + + + Initialize the encryptor. + + - Defines block size for encryption/decryption algorithm + Encryption/decryption algorithm implementation - + - Defines IV size for encryption/decryption algorithm + Packet authentication algorithm impelmenation - + - Defines HMAC size for packet authentication algorithm + Implementation of encryption for "Datagram Encryption". - + Initialize + + + + Number for reliable unsequenced commands (separate from "standard" reliable sequenced). Used to avoid duplicates. + + + The highest number of reliable unsequenced commands that arrived (and all commands before). + + + Any reliable unsequenced number that's been received, which is higher than the current highest in complete sequence (reliableUnsequencedNumbersCompletelyReceived). + + + Checks and queues incoming reliable unsequenced commands ("send" or "fragment"), if they haven't been received yet. + The command to check and queue. + True if the command is new and got queued (or could be executed/dispatched). + + + One list for all channels keeps sent commands (for re-sending). + + + One pool of ACK byte arrays ( 20 bytes each) for all channels to keep acknowledgements. + + + Gets enabled by "request" from server (not by client). + + + Initial PeerId as used in Connect command. If EnableServerTracing is false. + + + Initial PeerId to enable Photon Tracing, as used in Connect command. See: EnableServerTracing. - + - Encrypts data. puts them into output buffer and prepends with IV + Checks the incoming queue and Dispatches received data if possible. - - - - + If a Dispatch happened or not, which shows if more Dispatches might be needed. + + + Gets the target size for fragments. + + Caches the result for a specific MTU value. + Fragment length is different, when datagram encryption is used (so this caches two values in fact). + - + - Finishes current HMAC + gathers acks until udp-packet is full and sends it! - - + + Queue of commands that need resending. Used instead of a method local field as optimization. + + + Queue of received commands. ReceiveIncomingCommands will queue commands, except ACKs which Execute immediately. + + - Decrypts buffer containing HMAC + gathers commands from all (out)queues until udp-packet is full and sends it! - encrypted data prepened by IV - offset in the buffer - len of data to decrypt - /// len of decrypted data - - + + + Checks if any channel has a outgoing reliable command. + + True if any channel has a outgoing reliable command. False otherwise. + + - Checkes wheter data have corect HMAC or not + Checks connected state and channel before operation is serialized and enqueued for sending. - buffer with data and HMAC - len of data including HMAC - true if check pass, false otherwise + if operation could be enqueued + + + reliable-udp-level function to send some byte[] to the server via un/reliable command + only called when a custom operation should be send + the invocation ID for this operation (the payload) + + + reads incoming udp-packages to create and queue incoming commands* + + + Queues incoming commands in the correct order as either unreliable, reliable or unsequenced. + If queued or not. + + + removes commands which are acknowledged* @@ -304,8 +388,7 @@ When you join a room, the server will assign a consecutive number to each client: the - "actorNr" or "player number". This is sent back in the OperationResult's - Parameters as value of key . + "actorNr" or "player number". This is sent back in the operation result. Fetch your actorNr of a Join response like this: int actorNr = (int)operationResponse[(byte)OperationCode.ActorNr]; @@ -350,46 +433,571 @@ The event currently being dispatched. - - - The bytes between Position and Length are copied to the beginning of the buffer. Length decreased by Position. Position set to 0. - + + The protocol for this socket, defined in constructor. - - - Brings StreamBuffer to the state as after writing of 'length' bytes. Returned buffer and offset can be used to actually fill "written" segment with data. - + + Address, as defined via a Connect() call. Including protocol, port and or path. + This is set in the constructor and in Connect() again. Typically the address does not change after the IPhotonSocket is instantiated. - - - Sets stream length. If current position is greater than specified value, it's set to the value. - - - SetLength(0) resets the stream to initial state but preserves underlying byte[] buffer. - + + Contains only the server's hostname (stripped protocol, port and or path). Set in IPhotonSocket.Connect(). - - - Guarantees that the buffer is at least neededSize bytes. - + + Contains the IP address of the previously resolved ServerAddress (or empty, if GetIpAddress wasn't used). - - - Value range for a Peer's connection and initialization state, as returned by the PeerState property. - - - While this is not the same as the StatusCode of IPhotonPeerListener.OnStatusChanged(), it directly relates to it. - In most cases, it makes more sense to build a game's state on top of the OnStatusChanged() as you get changes. - + + Contains only the server's port address (as string). Set in IphotonSocket.Connect(). - - The peer is disconnected and can't call Operations. Call Connect(). + + Where available, this exposes if the server's address was resolved into an IPv6 address or not. - - The peer is establishing the connection: opening a socket, exchanging packages with Photon. + + + Provides the protocol string, of the current PhotonPeer.SerializationProtocolType to be used for WebSocket connections. + + + Any WebSocket wrapper could access this to get the desired binary protocol for the connection. + Some WebSocket implementations use a static value of the same name and need to be updated. + + The value is not cached and each call will create the needed string on the fly. + - - The connection is established and now sends the application name to Photon. + + + Separates the given address into address (host name or IP) and port. Port must be included after colon! + + + This method expects any address to include a port. The final ':' in addressAndPort has to separate it. + IPv6 addresses have multiple colons and must use brackets to separate address from port. + + Examples: + ns.exitgames.com:5058 + http://[2001:db8:1f70::999:de8:7648:6e8]:100/ + [2001:db8:1f70::999:de8:7648:6e8]:100 + See: + http://serverfault.com/questions/205793/how-can-one-distinguish-the-host-and-the-port-in-an-ipv6-url + + + + Wraps a DNS call to provide an array of addresses, sorted to have the IPv6 ones first. + + This skips a DNS lookup, if the hostname is an IPv4 address. Then only this address is used as is. + The DNS lookup may take a while, so it is recommended to do this in a thread. Also, it may fail entirely. + + + IPAddress array for hostname, sorted to put any IPv6 addresses first.
+ If the DNS lookup fails, HandleException(StatusCode.ExceptionOnConnect) gets called and null returned. + Then the socket should not attempt to connect. +
+
+ + + Returns null or the IPAddress representing the address, doing Dns resolution if needed. + + Only returns IPv4 or IPv6 adresses, no others. + The string address of a server (hostname or IP). + IPAddress for the string address or null, if the address is neither IPv4, IPv6 or some hostname that could be resolved. + + + Variants of the Photon specific serialization protocol used for operations, responses, events and data. + + + Version 1.6 (outdated). + + + Version 1.8. + + + + + + + Serialize creates a byte-array from the given object and returns it. + + The object to serialize + The serialized byte-array + + + + Deserialize returns an object reassembled from the given StreamBuffer. + + The buffer to be Deserialized + The Deserialized object + + + + Deserialize returns an object reassembled from the given byte-array. + + The byte-array to be Deserialized + The Deserialized object + + + + Interface for (UDP) traffic capturing. + + + + Indicates if the PhotonPeer should call Record or not. + + + Implement to record network traffic. Called by PhotonPeer for each UDP message sent and received. + + The buffer will not contain Ethernet Header, IP, UDP level data. Only the payload received by the client. + + It is advised to not use NetworkSimulation when recording traffic. + The recording is done on the timing of actual receive- and send-calls and internal simulation would offset the timing. + + Buffer to be sent or received. Check length value for actual content length. + Length of the network data. + Indicates incoming (true) or outgoing (false) traffic. + The local peerId for the connection. Defaults to 0xFFFF until assigned by the Server. + The currently used IPhotonSocket of this Peer. Enables you to track the connection endpoint. + + + Internal class for "commands" - the package in which operations are sent. + + + Size of the Payload, which may be null. + + + Checks commandFlags & FV_UNRELIABLE_UNSEQUENCED. + + + Checks commandFlags & FV_RELIABLE. + + + + ACKs should never be created as NCommand. use CreateACK to wrtie the serialized ACK right away... + + + + + + + + + this variant does only create outgoing commands and increments . incoming ones are created from a DataInputStream + + + this variant does only create outgoing commands and increments . incoming ones are created from a DataInputStream + + + reads the command values (commandHeader and command-values) from incoming bytestream and populates the incoming command* + + + + A simulation item is an action that can be queued to simulate network lag. + + + + With this, the actual delay can be measured, compared to the intended lag. + + + Timestamp after which this item must be executed. + + + Action to execute when the lag-time passed. + + + Starts a new Stopwatch + + + + A set of network simulation settings, enabled (and disabled) by PhotonPeer.IsSimulationEnabled. + + + For performance reasons, the lag and jitter settings can't be produced exactly. + In some cases, the resulting lag will be up to 20ms bigger than the lag settings. + Even if all settings are 0, simulation will be used. Set PhotonPeer.IsSimulationEnabled + to false to disable it if no longer needed. + + All lag, jitter and loss is additional to the current, real network conditions. + If the network is slow in reality, this will add even more lag. + The jitter values will affect the lag positive and negative, so the lag settings + describe the medium lag even with jitter. The jitter influence is: [-jitter..+jitter]. + Packets "lost" due to OutgoingLossPercentage count for BytesOut and LostPackagesOut. + Packets "lost" due to IncomingLossPercentage count for BytesIn and LostPackagesIn. + + + + internal + + + internal + + + internal + + + internal + + + internal + + + internal + + + internal + + + This setting overrides all other settings and turns simulation on/off. Default: false. + + + Outgoing packages delay in ms. Default: 100. + + + Randomizes OutgoingLag by [-OutgoingJitter..+OutgoingJitter]. Default: 0. + + + Percentage of outgoing packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + + Incoming packages delay in ms. Default: 100. + + + Randomizes IncomingLag by [-IncomingJitter..+IncomingJitter]. Default: 0. + + + Percentage of incoming packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + + Counts how many outgoing packages actually got lost. TCP connections ignore loss and this stays 0. + + + Counts how many incoming packages actually got lost. TCP connections ignore loss and this stays 0. + + + Provides an overview of the current values in form of a string. + String summary. + + + + The pool this wrapper should return to when released/disposed. + + + + + Gets value and if it belongs to the static pool, returns the wrapper to pool. + + + + + + Boxes the value and returns boxed object. Releases the wrapper. + + + + + + Removes this WrapperStruct from pooling. + + + + Returns a String which represents the value of this instance. + String which represents the value of this instance. + + + Returns a String which represents the type (in brackets and value of this instance. + String which represents the type (in brackets) and value of this instance. + + + + staticPool is used for implicit casting. This is not threadsafe, so casting between T and StructWrapper should only be done on the Unity main thread. + + + + + Replacement for object.GetType() that first checks to see if object is a WrappedStruct. + If so returns the StructWrapper T type, otherwise just returns object.GetType(). + + + + + + + Wrap a struct in a pooled StructWrapper. + + + + + Wrap a struct in a pooled StructWrapper. Pulls wrapper from the static pool. Wrapper is returned to pool when Unwrapped. + Slighty faster version of Wrap() that is hard wired to pull from the static pool. Use the persistant bool argument to make a permanent unpooled wrapper. + + + + + Tests if object is either a cast T, or a wrapped T + + + + + Remove all wrappers in hashtable from pooling, so they can remain cached and used later. + + + + + + Unwraps any WrapperStructs, boxes their value, releases hashtable entry with the boxed value. Releases the wrappers. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is will not be returned to its pool until it is Unwrapped, or the pool is cleared. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is will not be returned to its pool until it is Unwrapped, or the pool is cleared. + + + + + Will get the object using the key. If the key is invalid, will return null. + + + + + + + Returns + + + + + + Param code. Used in internal op: InitEncryption. + + + Encryption-Mode code. Used in internal op: InitEncryption. + + + Param code. Used in internal op: InitEncryption. + + + Code of internal op: InitEncryption. + + + TODO: Code of internal op: Ping (used in PUN binary websockets). + + + Result code for any (internal) operation. + + + + This is the replacement for the const values used in eNet like: PS_DISCONNECTED, PS_CONNECTED, etc. + + + + No connection is available. Use connect. + + + Establishing a connection already. The app should wait for a status callback. + + + + The low level connection with Photon is established. On connect, the library will automatically + send an Init package to select the application it connects to (see also PhotonPeer.Connect()). + When the Init is done, IPhotonPeerListener.OnStatusChanged() is called with connect. + + Please note that calling operations is only possible after the OnStatusChanged() with StatusCode.Connect. + + + Connection going to be ended. Wait for status callback. + + + Acknowledging a disconnect from Photon. Wait for status callback. + + + Connection not properly disconnected. + + + The server's address, as set by a Connect() call, including any protocol, ports and or path. + If rHTTP is used, this can be set directly. + + + + This is the (low level) connection state of the peer. It's internal and based on eNet's states. + + Applications can read the "high level" state as PhotonPeer.PeerState, which uses a different enum. + + + Byte count of last sent operation (set during serialization). + + + Byte count of last dispatched message (set during dispatch/deserialization). + + + The command that's currently being dispatched. + + + This ID is assigned by the Realtime Server upon connection. + The application does not have to care about this, but it is useful in debugging. + + + + The serverTimeOffset is serverTimestamp - localTime. Used to approximate the serverTimestamp with help of localTime + + + + + Count of all bytes going out (including headers) + + + + + Count of all bytes coming in (including headers) + + + + Set via Connect(..., customObject) and sent in Init-Request. + + + Sent on connect in an Init Request. + + + Temporary cache of AppId. Used in Connect() to keep the AppId until we send the Init-Request (after the network-level (and Enet) connect). + + + Set to timeInt, whenever SendOutgoingCommands actually checks outgoing queues to send them. Must be connected. + + + Maximum Transfer Unit to be used for UDP+TCP + + + If IPhotonSocket.Connected is true, this value shows if the server's address resolved as IPv6 address. + + You must check the socket's IsConnected state. Otherwise, this value is not initialized. + Sent to server in Init-Request. + + + + + Writes and "Init Request", which initializes the connection / application used server-side. + + Uses this.ServerAddress, this.AppId, this.PhotonToken and CustomInitData and some more values. + Bytes of the init request. + + + Called when the server's Init Response arrived. + + + Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. + This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. + + + Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. + This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. + + + Returns the UDP Payload starting with Magic Number for binary protocol + + + + Checks outgoing queues for commands to send and puts them on their way. + This creates one package per go in UDP. + + If commands are not sent, cause they didn't fit into the package that's sent. + + + + Checks the incoming queue and Dispatches received data if possible. + + If a Dispatch happened or not, which shows if more Dispatches might be needed. + + + + Internally uses an operation to exchange encryption keys with the server. + + If the op could be sent. + + + + Gets the currently used settings for the built-in network simulation. + Please check the description of NetworkSimulationSet for more details. + + + + + Core of the Network Simulation, which is available in Debug builds. + Called by a timer in intervals. + + + + EnetPeer will set this value, so trafficstats can use it. TCP has 0 bytes per package extra + + + See PhotonPeer value. + + + See PhotonPeer value. + + + See PhotonPeer value. + + + See PhotonPeer value. + + + + Value range for a Peer's connection and initialization state, as returned by the PeerState property. + + + While this is not the same as the StatusCode of IPhotonPeerListener.OnStatusChanged(), it directly relates to it. + In most cases, it makes more sense to build a game's state on top of the OnStatusChanged() as you get changes. + + + + The peer is disconnected and can't call Operations. Call Connect(). + + + The peer is establishing the connection: opening a socket, exchanging packages with Photon. + + + The connection is established and now sends the application name to Photon. You set the "application name" by calling PhotonPeer.Connect(). @@ -437,6 +1045,9 @@ Most complete workflow description (but lots of debug output), info, warnings and errors. + + Build target framework supported by this dll. + Instances of the PhotonPeer class are used to connect to a Photon server and communicate with it. @@ -478,16 +1089,35 @@ See LocalMsTimestampDelegate. - - False if this library build contains C# Socket code. If true, you must set some type as SocketImplementation before connecting. - Where dynamic linking is available, this library will attempt to load a native Photon "Encryptor" plugin library for "Datagram Encryption". Fallback to a managed implementation. This value is always true. + + Obsolete and ignored. Size of CommandLog. Default is 0, no logging. + + + Obsolete and ignored. Converts the CommandLog into a readable table-like string with summary. + + + False if this library build contains C# Socket code. If true, you must set some type as SocketImplementation before connecting. + True if the library was compiled with DEBUG setting. + + Version of the Native Encryptor API compiled into this assembly. Defines which PhotonEncryptorPlugin needs to be used. + + + Target framework this dll was built for. + + + Global toggle to avoid callbacks from native plugins. Defaults to false, meaning: "callbacks enabled". + Callbacks from native code will fail on some platforms, which is why you can disable them. + + + Can be used to remove/hide the AppId from websocket connect paths. + A simplified identifier for client SDKs. Photon's APIs might modify this (as a dll can be used in more than one product). Helps debugging. @@ -497,17 +1127,65 @@ Version of this library as string. + + Checks if a native library for network sockets (PhotonSocketPlugin.dll) is available. To use it, see remarks. + + When the native socket library is available, the SocketNative class may be used as socket implementation. + + If the SocketImplementationConfig is null, the SocketNative class is assigned for UDP, TCP and WebSocket. + + Alternatively the type SocketNative (or other) can be assigend in the SocketImplementationConfig. + + The SocketNative class in this assembly is compiled for dynamic linking. + A class "SocketNativeSource" can be made available for you to compile it along with your source for + platforms that use static linking (e.g. for iOS and some consoles). + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + Checks if native library for Payload Encryption (PhotonCryptoPlugin.dll) is available. Used automatically. + + While the encryptor Type for Datagram Encryption can be defined, Payload Encryption + will always use built-in types as encryptor. + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + Checks if a native library for Datagram Encryption is available. To use it, see remarks. + + If the PhotonPeer.EncryptorType is set, this type is used as implementation for Datagram Encryption. + If it's not set, a native plugin is used if available. As fallback, a managed implementation is being used. + + Note: The native plugin is performing much better than the managed alternatives. + This is why we make the plugin available for various platforms. + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + + Checks availability and completeness of native libs and sets respective "available" values. + + Enables selection of a (Photon-)serialization protocol. Used in Connect methods. Defaults to SerializationProtocol.GpBinaryV16; - Defines which IPhotonSocket class to use per ConnectionProtocol. + Optional definition of IPhotonSocket type per ConnectionProtocol. Several platforms have special Socket implementations and slightly different APIs. To accomodate this, switching the socket implementation for a network protocol was made available. By default, UDP and TCP have socket implementations assigned. + If a native socket plugin is available (see: PhotonPeer.NativeSocketLibAvailable), the SocketNative + class is used by default (with dynamic linking). + You only need to set the SocketImplementationConfig once, after creating a PhotonPeer and before connecting. If you switch the TransportProtocol, the correct implementation is being used. @@ -535,6 +1213,11 @@ Can be used in derived classes for Listener.DebugReturn().
+ + + Called when the client received a Disconnect Message from the server. Signals an error and provides a message to debug the case. + + Option to make the PhotonPeer reuse a single EventData instance for all incoming events. @@ -547,1072 +1230,716 @@ Changing this value acquires the same lock that DispatchIncomingCommands() uses. - - - Gets count of all bytes coming in (including headers, excluding UDP/TCP overhead) - - - - - Gets count of all bytes going out (including headers, excluding UDP/TCP overhead) - - - - - Gets the size of the dispatched event or operation-result in bytes. - This value is set before OnEvent() or OnOperationResponse() is called (within DispatchIncomingCommands()). - - - Get this value directly in OnEvent() or OnOperationResponse(). Example: - void OnEvent(...) { - int eventSizeInBytes = this.peer.ByteCountCurrentDispatch; - //... - - void OnOperationResponse(...) { - int resultSizeInBytes = this.peer.ByteCountCurrentDispatch; - //... - - - - Returns the debug string of the event or operation-response currently being dispatched or string. Empty if none. - In a release build of the lib, this will always be empty. - - - - Gets the size of the last serialized operation call in bytes. - The value includes all headers for this single operation but excludes those of UDP, Enet Package Headers and TCP. - - - Get this value immediately after calling an operation. - Example: - - this.loadbalancingClient.OpJoinRoom("myroom"); - int opjoinByteCount = this.loadbalancingClient.ByteCountLastOperation; - - - - Size of CommandLog. Default is 0, no logging. - - A bigger log is better for debugging but uses more memory. - Get the log as string via CommandLogToString. - - - - Converts the CommandLog into a readable table-like string with summary. - - Sent reliable commands begin with SND. Their acknowledgements with ACK. - ACKs list the reliable sequence number of the command they acknowledge (not their own). - Careful: This method should not be called frequently, as it's time- and memory-consuming to create the log. - - - - - Debugging option to tell the Photon Server to log all datagrams. - - - - - Up to 4 resend attempts for a reliable command can be done in quick succession (after RTT+4*Variance). - - - By default 0. Any later resend attempt will then double the time before the next resend. - Max value = 4; - Make sure to adjust SentCountAllowance to a slightly higher value, as more repeats will get done. - - - - - This is the (low level) state of the connection to the server of a PhotonPeer. Managed internally and read-only. - - - Don't mix this up with the StatusCode provided in IPhotonListener.OnStatusChanged(). - Applications should use the StatusCode of OnStatusChanged() to track their state, as - it also covers the higher level initialization between a client and Photon. - - - - - This peer's ID as assigned by the server or 0 if not using UDP. Will be 0xFFFF before the client connects. - - Used for debugging only. This value is not useful in everyday Photon usage. - - - (default=2) minimum number of open connections - - - (default=6) maximum number of open connections, should be > RhttpMinConnections - - - - Count of all currently received but not-yet-Dispatched reliable commands - (events and operation results) from all channels. - - - - - Count of all commands currently queued as outgoing, including all channels and reliable, unreliable. - - - - - - Gets / sets the number of channels available in UDP connections with Photon. - Photon Channels are only supported for UDP. - The default ChannelCount is 2. Channel IDs start with 0 and 255 is a internal channel. - - - - - While not connected, this controls if the next connection(s) should use a per-package CRC checksum. - - - While turned on, the client and server will add a CRC checksum to every sent package. - The checksum enables both sides to detect and ignore packages that were corrupted during transfer. - Corrupted packages have the same impact as lost packages: They require a re-send, adding a delay - and could lead to timeouts. - - Building the checksum has a low processing overhead but increases integrity of sent and received data. - Packages discarded due to failed CRC cecks are counted in PhotonPeer.PacketLossByCrc. - - - - - Count of packages dropped due to failed CRC checks for this connection. - - - - - - Count of packages dropped due to wrong challenge for this connection. - - - - - Gets the count of sent but not yet acknowledged commands (for UDP connections). - - - - - Count of commands that got repeated (due to local repeat-timing before an ACK was received). - - - - - Number of send retries before a peer is considered lost/disconnected. Default: 7. - - - The initial timeout countdown of a command is calculated by the current roundTripTime + 4 * roundTripTimeVariance. - Please note that the timeout span until a command will be resent is not constant, but based on - the roundtrip time at the initial sending, which will be doubled with every failed retry. - - DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the - client first, depending on the values and Roundtrip Time. - - - + - Caps the initial timing for repeats of reliable commands. In milliseconds. Default: 400ms. + Enables a deserialization optimization for incoming events. Defaults to false. - Unless acknowledged, reliable commands are repeated initially after: current roundTripTime + 4 * roundTripTimeVariance. + When enabled, byte-arrays in incoming Photon events are deserialized into pooled ByteArraySlice instances (wrappers for byte[]). + This improves the memory footprint for receiving byte-arrays in events. - As this value can be very high when there was exceptional lag, InitialResendTimeMax makes sure that commands - get repeated several times before they may trigger a timeout. - - - - - Sets the milliseconds without reliable command before a ping command (reliable) will be sent (Default: 1000ms). - - - The ping command is used to keep track of the connection in case the client does not send reliable commands - by itself. - A ping (or reliable commands) will update the RoundTripTime calculation. - - - - - Milliseconds before an individual command must be ACKed by server - after this a timeout-disconnect is triggered. - - - DisconnectTimeout is not an exact value for a timeout. The exact timing of the timeout depends on the frequency - of Service() calls and commands that are sent with long roundtrip-times and variance are checked less often for - re-sending! + When used, you have to release the (pooled) ByteArraySlice instances. - DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the - client first, depending on the values and Roundtrip Time. - Default: 10000 ms. - - - - - Approximated Environment.TickCount value of server (while connected). - - - UDP: The server's timestamp is automatically fetched after connecting (once). This is done - internally by a command which is acknowledged immediately by the server. - TCP: The server's timestamp fetched with each ping but set only after connecting (once). + Adjust your handling of EventData accordingly: - The approximation will be off by +/- 10ms in most cases. Per peer/client and connection, the - offset will be constant (unless FetchServerTimestamp() is used). A constant offset should be - better to adjust for. Unfortunately there is no way to find out how much the local value - differs from the original. + The ByteArraySlice.Buffer will usually be bigger than the send/received byte-array. + Check the ByteArraySlice.Count and read only the actually received bytes. + The Buffer is reused and not cleared. The Offset will be 0 for incoming events. - The approximation adds RoundtripTime / 2 and uses this.LocalTimeInMilliSeconds to calculate - in-between values (this property returns a new value per tick). + Important: + While the peer will acquire the ByteArraySlice and passes it to OnEvent, the game code has to call ByteArraySlice.Release() + when the slice is no longer needed. - The value sent by Photon equals Environment.TickCount in the logic layer. - - - 0 until connected. - While connected, the value is an approximation of the server's current timestamp. - - - - - This setter for the (local-) timestamp delegate replaces the default Environment.TickCount with any equal function. - - - About Environment.TickCount: - The value of this property is derived from the system timer and is stored as a 32-bit signed integer. - Consequently, if the system runs continuously, TickCount will increment from zero to Int32..::.MaxValue - for approximately 24.9 days, then jump to Int32..::.MinValue, which is a negative number, then increment - back to zero during the next 24.9 days. - - Exception is thrown peer.PeerState is not PS_DISCONNECTED. - - - The internally used "per connection" time value, which is updated infrequently, when the library executes some connectio-related tasks. - - This integer value is an infrequently updated value by design. - The lib internally sets the value when it sends outgoing commands or reads incoming packages. - This is based on SupportClass.GetTickCount() and an initial time value per (server) connection. - This value is also used in low level Enet commands as sent time and optional logging. - - - - The last ConnectionTime value, when some ACKs were sent out by this client. - Only applicable to UDP connections. - - - The last ConnectionTime value, when SendOutgoingCommands actually checked outgoing queues to send them. Must be connected. - Available for UDP and TCP connections. - - - Measures the maximum milliseconds spent in PhotonSocket.Send(). + Send either byte[], ArraySegment or use the ByteArraySlicePool to acquire ByteArraySlices to send. + - - Time until a reliable command is acknowledged by the server. + + + Instance of a ByteArraySlicePool. UseByteArraySlicePoolForEvents defines if this PhotonPeer is using the pool for deserialization of byte[] in Photon events. - The value measures network latency and for UDP it includes the server's ACK-delay (setting in config). - In TCP, there is no ACK-delay, so the value is slightly lower (if you use default settings for Photon). - - RoundTripTime is updated constantly. Every reliable command will contribute a fraction to this value. + ByteArraySlice is a serializable datatype of the Photon .Net client library. + It helps avoid allocations by being pooled and (optionally) used in incoming Photon events (see: UseByteArraySlicePoolForEvents). - This is also the approximate time until a raised event reaches another client or until an operation - result is available. + You can also use the pool to acquire ByteArraySlice instances for serialization. + RaiseEvent will auto-release all ByteArraySlice instances passed in. - + - Changes of the roundtriptime as variance value. Gives a hint about how much the time is changing. + This debug setting enables a new send-ordering for commands. Defaults to true and commands are sent in the order they are created. Set to false to use Enet ordering. - - The last measured rountrip time for this connection. - - + - Timestamp of the last time anything (!) was received from the server (including low level Ping, ACKs, events and operation-returns). + Gets count of all bytes coming in (including headers, excluding UDP/TCP overhead) - - This is not the time when something was dispatched. If you enable NetworkSimulation, this value is affected as well. - - + - The server address which was used in PhotonPeer.Connect() or null (before Connect() was called). + Gets count of all bytes going out (including headers, excluding UDP/TCP overhead) - - The ServerAddress can only be changed for HTTP connections (to replace one that goes through a Loadbalancer with a direct URL). - - - Contains the IP address of the previously resolved ServerAddress (or empty, if address wasn't resolved with the internal methods). + + + Gets the size of the dispatched event or operation-result in bytes. + This value is set before OnEvent() or OnOperationResponse() is called (within DispatchIncomingCommands()). + + + Get this value directly in OnEvent() or OnOperationResponse(). Example: + void OnEvent(...) { + int eventSizeInBytes = this.peer.ByteCountCurrentDispatch; + //... + + void OnOperationResponse(...) { + int resultSizeInBytes = this.peer.ByteCountCurrentDispatch; + //... + - - The protocol this peer is currently connected/connecting with (or 0). + + Returns the debug string of the event or operation-response currently being dispatched or string. Empty if none. + In a release build of the lib, this will always be empty. - - This is the transport protocol to be used for next connect (see remarks). - The TransportProtocol can be changed anytime but it will not change the - currently active connection. Instead, TransportProtocol will be applied on next Connect. - + + + Gets the size of the last serialized operation call in bytes. + The value includes all headers for this single operation but excludes those of UDP, Enet Package Headers and TCP. + + + Get this value immediately after calling an operation. + Example: + + this.loadbalancingClient.OpJoinRoom("myroom"); + int opjoinByteCount = this.loadbalancingClient.ByteCountLastOperation; + - - - Gets or sets the network simulation "enabled" setting. - Changing this value also locks this peer's sending and when setting false, - the internally used queues are executed (so setting to false can take some cycles). - + + If set, the TrafficRecorder will be used to capture all traffic. + + If null or not Enabled, the recorder is not being used. + Release builds of this library will never record traffic for performance reasons. + + See ITrafficRecorder docs. + - + - Gets the settings for built-in Network Simulation for this peer instance - while IsSimulationEnabled will enable or disable them. - Once obtained, the settings can be modified by changing the properties. + Debugging option to tell the Photon Server to log all datagrams. - + - Defines the initial size of an internally used StreamBuffer for Tcp. - The StreamBuffer is used to aggregate operation into (less) send calls, - which uses less resoures. + Up to 4 resend attempts for a reliable command can be done in quick succession (after RTT+4*Variance). - The size is not restricing the buffer and does not affect when outgoing data is actually sent. + By default 0. Any later resend attempt will then double the time before the next resend. + Max value = 4; + Make sure to adjust SentCountAllowance to a slightly higher value, as more repeats will get done. - + - The Maximum Trasfer Unit (MTU) defines the (network-level) packet-content size that is - guaranteed to arrive at the server in one piece. The Photon Protocol uses this - size to split larger data into packets and for receive-buffers of packets. + This is the (low level) state of the connection to the server of a PhotonPeer. Managed internally and read-only. - This value affects the Packet-content. The resulting UDP packages will have additional - headers that also count against the package size (so it's bigger than this limit in the end) - Setting this value while being connected is not allowed and will throw an Exception. - Minimum is 576. Huge values won't speed up connections in most cases! + Don't mix this up with the StatusCode provided in IPhotonListener.OnStatusChanged(). + Applications should use the StatusCode of OnStatusChanged() to track their state, as + it also covers the higher level initialization between a client and Photon. - - - This property is set internally, when OpExchangeKeysForEncryption successfully finished. - While it's true, encryption can be used for operations. - - - - - While true, the peer will not send any other commands except ACKs (used in UDP connections). - - - - Defines if Key Exchange for Encryption is done asynchronously in another thread. - - - - Gets the byte-count of incoming "low level" messages, which are either Enet Commands or Tcp Messages. - These include all headers, except those of the underlying internet protocol Udp or Tcp. - - - + - Gets the byte-count of outgoing "low level" messages, which are either Enet Commands or Tcp Messages. - These include all headers, except those of the underlying internet protocol Udp or Tcp. + This peer's ID as assigned by the server or 0 if not using UDP. Will be 0xFFFF before the client connects. + Used for debugging only. This value is not useful in everyday Photon usage. - + - Gets a statistic of incoming and outgoing traffic, split by operation, operation-result and event. + Count of all currently received but not-yet-Dispatched reliable commands + (events and operation results) from all channels. - - Operations are outgoing traffic, results and events are incoming. - Includes the per-command header sizes (Udp: Enet Command Header or Tcp: Message Header). - - + - Returns the count of milliseconds the stats are enabled for tracking. + Count of all commands currently queued as outgoing, including all channels and reliable, unreliable. - + - Enables or disables collection of statistics in TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel. + Sets a new (temporary) size of the MessageBufferPool to reuse memory where possible. - Setting this to true, also starts the stopwatch to measure the timespan the stats are collected. - Enables the traffic statistics of a peer: TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel (nothing else). - Default value: false (disabled). + The MessageBufferPool is a Queue<StreamBuffer> for performance reasons. + This methods dequeues from the MessageBufferPool to get the Count equal to countOfBuffers, + then it calls MessageBufferPool.TrimExcess(). + New size of the pool. Clears the pool if <= 0. - - - Creates new instances of TrafficStats and starts a new timer for those. - - - + - Returns a string of the most interesting connection statistics. - When you have issues on the client side, these might contain hints about the issue's cause. + Gets / sets the number of channels available in UDP connections with Photon. + Photon Channels are only supported for UDP. + The default ChannelCount is 2. Channel IDs start with 0 and 255 is a internal channel. - If true, Incoming and Outgoing low-level stats are included in the string. - Stats as string. - - - Implements the message-protocol, based on the underlying network protocol (udp, tcp, http). - - - PayloadEncryption Secret. Message payloads get encrypted with it individually and on demand. - - - Setter for the Datagram Encryptor instance. Used at next connect. - If null, the PhotonPeer will create a default encryptor instance. - - - The datagram encryptor used for the current connection. Applied internally in InitDatagramEncryption. - + - Creates a new PhotonPeer instance to communicate with Photon and selects the transport protocol. We recommend UDP. + Enables the client so send the "encrypted" flag on secure connections. Incompatible with Server SDK 4.x. - a IPhotonPeerListener implementation - Protocol to use to connect to Photon. - - - - Connects to a Photon server. This wraps up DNS name resolution, sending the AppId and establishing encryption. - - - This method does a DNS lookup (if necessary) and connects to the given serverAddress. - - The return value gives you feedback if the address has the correct format. If so, this - starts the process to establish the connection itself, which might take a few seconds. - - When the connection is established, a callback to IPhotonPeerListener.OnStatusChanged - will be done. If the connection can't be established, despite having a valid address, - the OnStatusChanged is called with an error-value. - - The applicationName defines the application logic to use server-side and it should match the name of - one of the apps in your server's config. - - By default, the applicationName is "LoadBalancing" but there is also the "MmoDemo". - You can setup your own application and name it any way you like. - - - Address of the Photon server. Format: ip:port (e.g. 127.0.0.1:5055) or hostname:port (e.g. localhost:5055) - - - The name of the application to use within Photon or the appId of PhotonCloud. - Should match a "Name" for an application, as setup in your PhotonServer.config. - - - true if IP is available (DNS name is resolved) and server is being connected. false on error. - - - - - Connects to a Photon server. This wraps up DNS name resolution, sending the AppId and establishing encryption. - - - This method does a DNS lookup (if necessary) and connects to the given serverAddress. - - The return value gives you feedback if the address has the correct format. If so, this - starts the process to establish the connection itself, which might take a few seconds. - - When the connection is established, a callback to IPhotonPeerListener.OnStatusChanged - will be done. If the connection can't be established, despite having a valid address, - the OnStatusChanged is called with an error-value. - - The applicationName defines the application logic to use server-side and it should match the name of - one of the apps in your server's config. - - By default, the applicationName is "LoadBalancing" but there is also the "MmoDemo". - You can setup your own application and name it any way you like. - - - Address of the Photon server. Format: ip:port (e.g. 127.0.0.1:5055) or hostname:port (e.g. localhost:5055) - - - The name of the application to use within Photon or the appId of PhotonCloud. - Should match a "Name" for an application, as setup in your PhotonServer.config. - - - Allows you to send some data, which may be used by server during peer creation - (e.g. as additional authentication info). - You can use any serializable data type of Photon. - Helpful for self-hosted solutions. Server will read this info on peer creation stage, - and may reject client without creating of peer if auth info is invalid. - - - true if IP is available (DNS name is resolved) and server is being connected. false on error. - - + - This method initiates a mutual disconnect between this client and the server. + While not connected, this controls if the next connection(s) should use a per-package CRC checksum. - Calling this method does not immediately close a connection. Disconnect lets the server - know that this client is no longer listening. For the server, this is a much faster way - to detect that the client is gone but it requires the client to send a few final messages. - - On completion, OnStatusChanged is called with the StatusCode.Disconnect. - - If the client is disconnected already or the connection thread is stopped, then there is no callback. + While turned on, the client and server will add a CRC checksum to every sent package. + The checksum enables both sides to detect and ignore packages that were corrupted during transfer. + Corrupted packages have the same impact as lost packages: They require a re-send, adding a delay + and could lead to timeouts. - The default server logic will leave any joined game and trigger the respective event - () for the remaining players. + Building the checksum has a low processing overhead but increases integrity of sent and received data. + Packages discarded due to failed CRC cecks are counted in PhotonPeer.PacketLossByCrc. - + - This method immediately closes a connection (pure client side) and ends related listening Threads. + Count of packages dropped due to failed CRC checks for this connection. - - Unlike Disconnect, this method will simply stop to listen to the server. Udp connections will timeout. - If the connections was open, this will trigger a callback to OnStatusChanged with code StatusCode.Disconnect. - + - - - This will fetch the server's timestamp and update the approximation for property ServerTimeInMilliseconds. - - - The server time approximation will NOT become more accurate by repeated calls. Accuracy currently depends - on a single roundtrip which is done as fast as possible. - - The command used for this is immediately acknowledged by the server. This makes sure the roundtrip time is - low and the timestamp + rountriptime / 2 is close to the original value. - + + + Count of packages dropped due to wrong challenge for this connection. + - - - This method creates a public key for this client and exchanges it with the server. - - - Encryption is not instantly available but calls OnStatusChanged when it finishes. - Check for StatusCode EncryptionEstablished and EncryptionFailedToEstablish. - - Calling this method sets IsEncryptionAvailable to false. - This method must be called before the "encrypt" parameter of OpCustom can be used. - - If operation could be enqueued for sending + + + Gets the count of sent but not yet acknowledged commands (for UDP connections). + - + - Initializes Datagram Encryption. + Count of commands that got repeated (due to local repeat-timing before an ACK was received). - secret used to chipher udp packets - secret used for authentication of udp packets - + - This method excutes DispatchIncomingCommands and SendOutgoingCommands in your application Thread-context. + Number of send retries before a peer is considered lost/disconnected. Default: 7. - The Photon client libraries are designed to fit easily into a game or application. The application - is in control of the context (thread) in which incoming events and responses are executed and has - full control of the creation of UDP/TCP packages. - - Sending packages and dispatching received messages are two separate tasks. Service combines them - into one method at the cost of control. It calls DispatchIncomingCommands and SendOutgoingCommands. - - Call this method regularly (2..20 times a second). + The initial timeout countdown of a command is calculated by the current roundTripTime + 4 * roundTripTimeVariance. + Please note that the timeout span until a command will be resent is not constant, but based on + the roundtrip time at the initial sending, which will be doubled with every failed retry. - This will Dispatch ANY remaining buffered responses and events AND will send queued outgoing commands. - Fewer calls might be more effective if a device cannot send many packets per second, as multiple - operations might be combined into one package. + DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the + client first, depending on the values and Roundtrip Time. - - You could replace Service by: - - while (DispatchIncomingCommands()); //Dispatch until everything is Dispatched... - SendOutgoingCommands(); //Send a UDP/TCP package with outgoing messages - - - - + - Creates and sends a UDP/TCP package with outgoing commands (operations and acknowledgements). Also called by Service(). + Caps the initial timing for repeats of reliable commands. In milliseconds. Default: 400ms. - As the Photon library does not create any UDP/TCP packages by itself. Instead, the application - fully controls how many packages are sent and when. A tradeoff, an application will - lose connection, if it is no longer calling SendOutgoingCommands or Service. - - If multiple operations and ACKs are waiting to be sent, they will be aggregated into one - package. The package fills in this order: - ACKs for received commands - A "Ping" - only if no reliable data was sent for a while - Starting with the lowest Channel-Nr: - Reliable Commands in channel - Unreliable Commands in channel - - This gives a higher priority to lower channels. - - A longer interval between sends will lower the overhead per sent operation but - increase the internal delay (which adds "lag"). + Unless acknowledged, reliable commands are repeated initially after: current roundTripTime + 4 * roundTripTimeVariance. - Call this 2..20 times per second (depending on your target platform). + As this value can be very high when there was exceptional lag, InitialResendTimeMax makes sure that commands + get repeated several times before they may trigger a timeout. - The if commands are not yet sent. Udp limits it's package size, Tcp doesnt. - + - Dispatching received messages (commands), causes callbacks for events, responses and state changes within a IPhotonPeerListener. + Sets the time between pings being sent automatically. They measure the roundtrip time and keep connections from closing. Default: 1000. - DispatchIncomingCommands only executes a single received - command per call. If a command was dispatched, the return value is true and the method - should be called again. - - This method is called by Service() until currently available commands are dispatched. - In general, this method should be called until it returns false. In a few cases, it might - make sense to pause dispatching (if a certain state is reached and the app needs to load - data, before it should handle new events). + For Photon's reliable UDP connections, pings are skipped if any reliable command was sent during the specified TimePingInterval. + Any reliable command is used to update the RoundTripTime and RoundTripTimeVariance. - The callbacks to the peer's IPhotonPeerListener are executed in the same thread that is - calling DispatchIncomingCommands. This makes things easier in a game loop: Event execution - won't clash with painting objects or the game logic. + When using TCP and WebSockets, the ping is of interest to measure the roundtrip and to keep a connection open, should nothing else + With those two protocols, the ping is used to update the RoundTripTime and RoundTripTimeVariance. - + - Prepares your operation (code and parameters) to be sent to the Photon Server with specified SendOptions. + Time in milliseconds before any sent reliable command triggers a timeout disconnect, unless acknowledged by the receiver. Default: 10000. - This method serializes and enqueues the operation right away while the actual sending happens later. - To be able to aggregate operations/messages, the Photon client sends packages only when you call SendOutgoingCommands(). + DisconnectTimeout is not an exact value for a timeout. The exact timing of the timeout depends on the frequency + of Service() calls and the roundtrip time. Commands sent with long roundtrip-times and variance are checked less + often for re-sending. - The sendOptions specify how the operation gets sent exactly. - Keep in mind that some transport protocols don't support unreliable or unsequenced transport. - In that case, the sendOptions might be ignored. + DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the + client first, depending on the values and Roundtrip Time. - The operationCode must be known by the server's logic or won't be processed. - In almost all cases, sending an operation will result in a OperationResponse (see: IPhotonPeerListener.OnOperationResponse). + Default: 10000 ms. Maximum setting: 65535. + Setting a negative value will apply the default timeout. - Operations are handled by their byte\-typed code. The codes of the "LoadBalancing" application are in the class . - Containing parameters as key\-value pair. The key is byte\-typed, while the value is any serializable datatype. - Wraps up DeliveryMode (reliability), Encryption and Channel values for sending. - If operation could be enqueued for sending. - - - Allows the client to send any operation to the Photon Server by setting any opCode and the operation's parameters. - - - Use this only after encryption was established by EstablishEncryption and waiting for the OnStateChanged callback. - - Operations are handled by their byte\-typed code. The codes of the - "LoadBalancing" application are in the class . - Containing parameters as key\-value pair. The key is byte\-typed, while the value is any serializable datatype. - Selects if the operation must be acknowledged or not. If false, the - operation is not guaranteed to reach the server. - The channel in which this operation should be sent. - Can only be true, while IsEncryptionAvailable is true, too. - If operation could be enqueued for sending - - - - Allows the client to send any operation to the Photon Server by setting any opCode and the operation's parameters. - - - This variant offers an alternative way to describe a operation request. Operation code and it's parameters - are wrapped up in a object. Still, the parameters are a Dictionary. - - The operation to call on Photon. - Use unreliable (false) if the call might get lost (when it's content is soon outdated). - Defines the sequence of requests this operation belongs to. - Encrypt request before sending. Depends on IsEncryptionAvailable. - If operation could be enqueued for sending - - + - Registers new types/classes for de/serialization and the fitting methods to call for this type. + Approximated Environment.TickCount value of server (while connected). - SerializeMethod and DeserializeMethod are complementary: Feed the product of serializeMethod to - the constructor, to get a comparable instance of the object. + UDP: The server's timestamp is automatically fetched after connecting (once). This is done + internally by a command which is acknowledged immediately by the server. + TCP: The server's timestamp fetched with each ping but set only after connecting (once). - After registering a Type, it can be used in events and operations and will be serialized like - built-in types. + The approximation will be off by +/- 10ms in most cases. Per peer/client and connection, the + offset will be constant (unless FetchServerTimestamp() is used). A constant offset should be + better to adjust for. Unfortunately there is no way to find out how much the local value + differs from the original. + + The approximation adds RoundtripTime / 2 and uses this.LocalTimeInMilliSeconds to calculate + in-between values (this property returns a new value per tick). + + The value sent by Photon equals Environment.TickCount in the logic layer. - Type (class) to register. - A byte-code used as shortcut during transfer of this Type. - Method delegate to create a byte[] from a customType instance. - Method delegate to create instances of customType's from byte[]. - If the Type was registered successfully. - - - Param code. Used in internal op: InitEncryption. - - - Encryption-Mode code. Used in internal op: InitEncryption. - - - Param code. Used in internal op: InitEncryption. - - - Code of internal op: InitEncryption. - - - TODO: Code of internal op: Ping (used in PUN binary websockets). - - - Result code for any (internal) operation. + + 0 until connected. + While connected, the value is an approximation of the server's current timestamp. + - + - This is the replacement for the const values used in eNet like: PS_DISCONNECTED, PS_CONNECTED, etc. + This setter for the (local-) timestamp delegate replaces the default Environment.TickCount with any equal function. + + About Environment.TickCount: + The value of this property is derived from the system timer and is stored as a 32-bit signed integer. + Consequently, if the system runs continuously, TickCount will increment from zero to Int32..::.MaxValue + for approximately 24.9 days, then jump to Int32..::.MinValue, which is a negative number, then increment + back to zero during the next 24.9 days. + + Exception is thrown peer.PeerState is not PS_DISCONNECTED. - - No connection is available. Use connect. - - - Establishing a connection already. The app should wait for a status callback. - - - - The low level connection with Photon is established. On connect, the library will automatically - send an Init package to select the application it connects to (see also PhotonPeer.Connect()). - When the Init is done, IPhotonPeerListener.OnStatusChanged() is called with connect. - - Please note that calling operations is only possible after the OnStatusChanged() with StatusCode.Connect. + + The internally used "per connection" time value, which is updated infrequently, when the library executes some connectio-related tasks. + + This integer value is an infrequently updated value by design. + The lib internally sets the value when it sends outgoing commands or reads incoming packages. + This is based on SupportClass.GetTickCount() and an initial time value per (server) connection. + This value is also used in low level Enet commands as sent time and optional logging. + - - Connection going to be ended. Wait for status callback. + + The last ConnectionTime value, when some ACKs were sent out by this client. + Only applicable to UDP connections. - - Acknowledging a disconnect from Photon. Wait for status callback. + + The last ConnectionTime value, when SendOutgoingCommands actually checked outgoing queues to send them. Must be connected. + Available for UDP and TCP connections. - - Connection not properly disconnected. + + Measures the maximum milliseconds spent in PhotonSocket.Send(). - - The server's address, as set by a Connect() call, including any protocol, ports and or path. - If rHTTP is used, this can be set directly. + + Time until a reliable command is acknowledged by the server. + + The value measures network latency and for UDP it includes the server's ACK-delay (setting in config). + In TCP, there is no ACK-delay, so the value is slightly lower (if you use default settings for Photon). + + RoundTripTime is updated constantly. Every reliable command will contribute a fraction to this value. + + This is also the approximate time until a raised event reaches another client or until an operation + result is available. + - + - This is the (low level) connection state of the peer. It's internal and based on eNet's states. + Changes of the roundtriptime as variance value. Gives a hint about how much the time is changing. - Applications can read the "high level" state as PhotonPeer.PeerState, which uses a different enum. - - - Byte count of last sent operation (set during serialization). - - - Byte count of last dispatched message (set during dispatch/deserialization). - - - The command that's currently being dispatched. - - - This ID is assigned by the Realtime Server upon connection. - The application does not have to care about this, but it is useful in debugging. - - - The serverTimeOffset is serverTimestamp - localTime. Used to approximate the serverTimestamp with help of localTime - + + The last measured roundtrip time for this connection. - + - Count of all bytes going out (including headers) + Timestamp of the last time anything (!) was received from the server (including low level Ping, ACKs, events and operation-returns). + + This is not the time when something was dispatched. If you enable NetworkSimulation, this value is affected as well. + - + - Count of all bytes coming in (including headers) + The server address which was used in PhotonPeer.Connect() or null (before Connect() was called). - - Set via Connect(..., customObject) and sent in Init-Request. - - - Temporary cache of AppId. Used in Connect() to keep the AppId until we send the Init-Request (after the network-level (and Enet) connect). - - - Set to timeInt, whenever SendOutgoingCommands actually checks outgoing queues to send them. Must be connected. - - - Maximum Transfer Unit to be used for UDP+TCP - - - If IPhotonSocket.Connected is true, this value shows if the server's address resolved as IPv6 address. - - You must check the socket's IsConnected state. Otherwise, this value is not initialized. - Sent to server in Init-Request. - - - - Connect to server and send Init (which inlcudes the appId). - If customData is not null, the new init will be used (http-based). + + Contains the IP address of the previously resolved ServerAddress (or empty, if address wasn't resolved with the internal methods). - - Called when the server's Init Response arrived. + + The protocol this peer is currently connected/connecting with (or 0). - - Returns the UDP Payload starting with Magic Number for binary protocol + + This is the transport protocol to be used for next connect (see remarks). + The TransportProtocol can be changed anytime but it will not change the + currently active connection. Instead, TransportProtocol will be applied on next Connect. + - + - Checks outgoing queues for commands to send and puts them on their way. - This creates one package per go in UDP. + Gets or sets the network simulation "enabled" setting. + Changing this value also locks this peer's sending and when setting false, + the internally used queues are executed (so setting to false can take some cycles). - If commands are not sent, cause they didn't fit into the package that's sent. - + - Checks the incoming queue and Dispatches received data if possible. + Gets the settings for built-in Network Simulation for this peer instance + while IsSimulationEnabled will enable or disable them. + Once obtained, the settings can be modified by changing the properties. - If a Dispatch happened or not, which shows if more Dispatches might be needed. - + - Internally uses an operation to exchange encryption keys with the server. + Defines the initial size of an internally used StreamBuffer for Tcp. + The StreamBuffer is used to aggregate operation into (less) send calls, + which uses less resoures. - If the op could be sent. + + The size is not restricing the buffer and does not affect when outgoing data is actually sent. + - + - Gets the currently used settings for the built-in network simulation. - Please check the description of NetworkSimulationSet for more details. + The Maximum Trasfer Unit (MTU) defines the (network-level) packet-content size that is + guaranteed to arrive at the server in one piece. The Photon Protocol uses this + size to split larger data into packets and for receive-buffers of packets. + + This value affects the Packet-content. The resulting UDP packages will have additional + headers that also count against the package size (so it's bigger than this limit in the end) + Setting this value while being connected is not allowed and will throw an Exception. + Minimum is 576. Huge values won't speed up connections in most cases! + - + - Core of the Network Simulation, which is available in Debug builds. - Called by a timer in intervals. + This property is set internally, when OpExchangeKeysForEncryption successfully finished. + While it's true, encryption can be used for operations. - - EnetPeer will set this value, so trafficstats can use it. TCP has 0 bytes per package extra - - - See PhotonPeer value. - - - See PhotonPeer value. - - - See PhotonPeer value. - - - See PhotonPeer value. - - - Size of CommandLog. Default is 0, no logging. - - - Log of sent reliable commands and incoming ACKs. - - - Log of incoming reliable commands, used to track which commands from the server this client got. Part of the PhotonPeer.CommandLogToString() result. - - - Reduce CommandLog to CommandLogSize. Oldest entries get discarded. - - - Initializes the CommandLog and InReliableLog according to CommandLogSize. A value of 0 will set both logs to 0. - - - Converts the CommandLog into a readable table-like string with summary. - - - Enum of the three options for reliability and sequencing in Photon's reliable-UDP. - - - The operation/message gets sent just once without acknowledgement or repeat. The sequence (order) of messages is guaranteed. - - - The operation/message asks for an acknowledgment. It's resent until an ACK arrived. The sequence (order) of messages is guaranteed. - - - The operation/message gets sent once (unreliable) and might arrive out of order. Best for your own sequencing (e.g. for streams). - - - The operation/message asks for an acknowledgment. It's resent until an ACK arrived and might arrive out of order. Best for your own sequencing (e.g. for streams). - - - Wraps up DeliveryMode, Encryption and Channel values for sending operations and messages. - - - Chose the DeliveryMode for this operation/message. Defaults to Unreliable. - - - If true the operation/message gets encrypted before it's sent. Defaults to false. - Before encryption can be used, it must be established. Check PhotonPeer.IsEncryptionAvailable is true. - - - The Enet channel to send in. Defaults to 0. - Channels in Photon relate to "message channels". Each channel is a sequence of messages. - - - Sets the DeliveryMode either to true: Reliable or false: Unreliable, overriding any current value. - Use this to conveniently select reliable/unreliable delivery. + + + While true, the peer will not send any other commands except ACKs (used in UDP connections). + - - One list for all channels keeps sent commands (for re-sending). + + Defines if Key Exchange for Encryption is done asynchronously in another thread. - - One pool of ACK byte arrays ( 20 bytes each) for all channels to keep acknowledgements. + + Indicates if sequence numbers should be randomized. - - Gets enabled by "request" from server (not by client). + + Initialization array, used to modify the sequence numbers of channels. - - Initial PeerId as used in Connect command. If EnableServerTracing is false. + + If GCM is used for DatagramEncryption. + If true, the randomization-value gets added to the current value, else (CBC/old style) the randomization-value replaces the current value. - - Initial PeerId to enable Photon Tracing, as used in Connect command. See: EnableServerTracing. + + + Gets the byte-count of incoming "low level" messages, which are either Enet Commands or Tcp Messages. + These include all headers, except those of the underlying internet protocol Udp or Tcp. + - + - Checks the incoming queue and Dispatches received data if possible. + Gets the byte-count of outgoing "low level" messages, which are either Enet Commands or Tcp Messages. + These include all headers, except those of the underlying internet protocol Udp or Tcp. - If a Dispatch happened or not, which shows if more Dispatches might be needed. - - Gets the target size for fragments. + + + Gets a statistic of incoming and outgoing traffic, split by operation, operation-result and event. + - Caches the result for a specific MTU value. - Fragment length is different, when datagram encryption is used (so this caches two values in fact). + Operations are outgoing traffic, results and events are incoming. + Includes the per-command header sizes (Udp: Enet Command Header or Tcp: Message Header). - - + - gathers acks until udp-packet is full and sends it! + Returns the count of milliseconds the stats are enabled for tracking. - + - gathers commands from all (out)queues until udp-packet is full and sends it! + Enables or disables collection of statistics in TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel. + + Setting this to true, also starts the stopwatch to measure the timespan the stats are collected. + Enables the traffic statistics of a peer: TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel (nothing else). + Default value: false (disabled). + - + - Checks if any channel has a outgoing reliable command. + Creates new instances of TrafficStats and starts a new timer for those. - True if any channel has a outgoing reliable command. False otherwise. - + - Checks connected state and channel before operation is serialized and enqueued for sending. + Returns a string of the most interesting connection statistics. + When you have issues on the client side, these might contain hints about the issue's cause. - if operation could be enqueued - - - reliable-udp-level function to send some byte[] to the server via un/reliable command - only called when a custom operation should be send - the invocation ID for this operation (the payload) - - - Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. - This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. - - - reads incoming udp-packages to create and queue incoming commands* - - - queues incoming commands in the correct order as either unreliable, reliable or unsequenced. return value determines if the command is queued / done. + If true, Incoming and Outgoing low-level stats are included in the string. + Stats as string. - - removes commands which are acknowledged* + + Implements the message-protocol, based on the underlying network protocol (udp, tcp, http). - - Number for reliable unsequenced commands (separate from "standard" reliable sequenced). Used to avoid duplicates. + + PayloadEncryption Secret. Message payloads get encrypted with it individually and on demand. - - The highest number of reliable unsequenced commands that arrived (and all commands before). + + Setter for the Datagram Encryptor instance. Used at next connect. + + If null, the PhotonPeer will create a default encryptor instance, which may be native or managed. + See also: PhotonPeer.NativeDatagramEncryptionLibAvailable. + - - Any reliable unsequenced number that's been received, which is higher than the current highest in complete sequence (reliableUnsequencedNumbersCompletelyReceived). + + The datagram encryptor used for the current connection. Applied internally in InitDatagramEncryption. - - Checks and queues incoming reliable unsequenced commands ("send" or "fragment"), if they haven't been received yet. - The command to check and queue. - True if the command is new and got queued (or could be executed/dispatched). + + Count of unreliable commands being discarded in case this client already dispatched a command that was newer (higher sequence number). - - Internal class for "commands" - the package in which operations are sent. + + Set per dispatch in DispatchIncomingCommands to: commandUnreliableSequenceNumber - channel.incomingUnreliableSequenceNumber. Indicates how big the (sequence)gap is, compared to the last dispatched unreliable command. - - Size of the Payload, which may be null. + + Creates a new PhotonPeer with specified transport protocol (without a IPhotonPeerListener). + Make sure to set the Listener, before using the peer. - - - - this variant does only create outgoing commands and increments . incoming ones are created from a DataInputStream + + + Creates a new PhotonPeer instance to communicate with Photon and selects the transport protocol. We recommend UDP. + + a IPhotonPeerListener implementation + Protocol to use to connect to Photon. - + - ACKs should never be created as NCommand. use CreateACK to wrtie the serialized ACK right away... + Starts connecting to the given Photon server. Non-blocking. - - - - - + + Connecting to the Photon server is done asynchronous. + Unless an error happens right away (and this returns false), wait for the call of IPhotonPeerListener.OnStatusChanged. + + + Address of a Photon server as IP:port or hostname. WebSocket connections must contain a scheme (ws:// or wss://). + + + The ID of the app to use. Typically this is a guid (for the Photon Cloud). Max 32 characters. + + + Optional custom data to be used by server during peer creation. + If used for authentication, the server is able to reject a client without creating a peer. + Must be a serializable data type of Photon. + + Custom data to send to the server in the Init request. Might be used to identify a client / user. + + True if a connection attempt will be made. False if some error could be detected early-on. + - - reads the command values (commandHeader and command-values) from incoming bytestream and populates the incoming command* + + + Starts connecting to the given Photon server. Non-blocking. + + + Connecting to the Photon server is done asynchronous. + Unless an error happens right away (and this returns false), wait for the call of IPhotonPeerListener.OnStatusChanged. + + + Address of a Photon server as IP:port or hostname. WebSocket connections must contain a scheme (ws:// or wss://). + + + Optional address of a proxy server. Only used by WebSocket connections. Set null to use none. + + + The ID of the app to use. Typically this is a guid (for the Photon Cloud). Max 32 characters. + + + Optional Photon token data to be used by server during peer creation. + If used for authentication, the server is able to reject a client without creating a peer. + Must be of type string or byte[] (as provided by server). + + Custom data to send to the server in the Init request. Might be used to identify a client / user. + + True if a connection attempt will be made. False if some error could be detected early-on. + - - TCP "Package" header: 7 bytes + + + This method initiates a mutual disconnect between this client and the server. + + + Calling this method does not immediately close a connection. Disconnect lets the server + know that this client is no longer listening. For the server, this is a much faster way + to detect that the client is gone but it requires the client to send a few final messages. + + On completion, OnStatusChanged is called with the StatusCode.Disconnect. + + If the client is disconnected already or the connection thread is stopped, then there is no callback. + + The default server logic will leave any joined game and trigger the respective event. + - - TCP "Message" header: 2 bytes + + + This method immediately closes a connection (pure client side) and ends related listening Threads. + + + Unlike Disconnect, this method will simply stop to listen to the server. Udp connections will timeout. + If the connections was open, this will trigger a callback to OnStatusChanged with code StatusCode.Disconnect. + - - TCP header combined: 9 bytes + + + This will fetch the server's timestamp and update the approximation for property ServerTimeInMilliseconds. + + + The server time approximation will NOT become more accurate by repeated calls. Accuracy currently depends + on a single roundtrip which is done as fast as possible. + + The command used for this is immediately acknowledged by the server. This makes sure the roundtrip time is + low and the timestamp + rountriptime / 2 is close to the original value. + - - Defines if the (TCP) socket implementation needs to do "framing". - The WebSocket protocol (e.g.) includes framing, so when that is used, we set DoFraming to false. + + + This method creates a public key for this client and exchanges it with the server. + + + Encryption is not instantly available but calls OnStatusChanged when it finishes. + Check for StatusCode EncryptionEstablished and EncryptionFailedToEstablish. + + Calling this method sets IsEncryptionAvailable to false. + This method must be called before the "encrypt" parameter of OpCustom can be used. + + If operation could be enqueued for sending - + - Checks the incoming queue and Dispatches received data if possible. Returns if a Dispatch happened or - not, which shows if more Dispatches might be needed. + Initializes Datagram Encryption. Optionally, the EncryptorType is being used, if set. + secret used to cipher udp packets + secret used for authentication of udp packets - + - gathers commands from all (out)queues until udp-packet is full and sends it! + Photon's Payload Encryption secret may be set by a response from the server. + The secret in form of a byte[]. - - Sends a ping in intervals to keep connection alive (server will timeout connection if nothing is sent). - Always false in this case (local queues are ignored. true would be: "call again to send remaining data"). - - - Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. - This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. - - - enqueues serialized operations to be sent as tcp stream / package - - - Sends a ping and modifies this.lastPingResult to avoid another ping for a while. + + + This method excutes DispatchIncomingCommands and SendOutgoingCommands in your application Thread-context. + + + The Photon client libraries are designed to fit easily into a game or application. The application + is in control of the context (thread) in which incoming events and responses are executed and has + full control of the creation of UDP/TCP packages. + + Sending packages and dispatching received messages are two separate tasks. Service combines them + into one method at the cost of control. It calls DispatchIncomingCommands and SendOutgoingCommands. + + Call this method regularly (2..20 times a second). + + This will Dispatch ANY remaining buffered responses and events AND will send queued outgoing commands. + Fewer calls might be more effective if a device cannot send many packets per second, as multiple + operations might be combined into one package. + + + You could replace Service by: + + while (DispatchIncomingCommands()); //Dispatch until everything is Dispatched... + SendOutgoingCommands(); //Send a UDP/TCP package with outgoing messages + + + - - reads incoming tcp-packages to create and queue incoming commands* + + + Creates and sends a UDP/TCP package with outgoing commands (operations and acknowledgements). Also called by Service(). + + + As the Photon library does not create any UDP/TCP packages by itself. Instead, the application + fully controls how many packages are sent and when. A tradeoff, an application will + lose connection, if it is no longer calling SendOutgoingCommands or Service. + + If multiple operations and ACKs are waiting to be sent, they will be aggregated into one + package. The package fills in this order: + ACKs for received commands + A "Ping" - only if no reliable data was sent for a while + Starting with the lowest Channel-Nr: + Reliable Commands in channel + Unreliable Commands in channel + + This gives a higher priority to lower channels. + + A longer interval between sends will lower the overhead per sent operation but + increase the internal delay (which adds "lag"). + + Call this 2..20 times per second (depending on your target platform). + + The if commands are not yet sent. Udp limits it's package size, Tcp doesnt. - - - Serialize creates a byte-array from the given object and returns it. - - The object to serialize - The serialized byte-array + + + Dispatching received messages (commands), causes callbacks for events, responses and state changes within a IPhotonPeerListener. + + + DispatchIncomingCommands only executes a single received + command per call. If a command was dispatched, the return value is true and the method + should be called again. + + This method is called by Service() until currently available commands are dispatched. + In general, this method should be called until it returns false. In a few cases, it might + make sense to pause dispatching (if a certain state is reached and the app needs to load + data, before it should handle new events). + + The callbacks to the peer's IPhotonPeerListener are executed in the same thread that is + calling DispatchIncomingCommands. This makes things easier in a game loop: Event execution + won't clash with painting objects or the game logic. + - - - Deserialize returns an object reassembled from the given StreamBuffer. - - The buffer to be Deserialized - The Deserialized object + + + Prepares your operation (code and parameters) to be sent to the Photon Server with specified SendOptions. + + + This method serializes and enqueues the operation right away while the actual sending happens later. + To be able to aggregate operations/messages, the Photon client sends packages only when you call SendOutgoingCommands(). + + The sendOptions specify how the operation gets sent exactly. + Keep in mind that some transport protocols don't support unreliable or unsequenced transport. + In that case, the sendOptions might be ignored. + + The operationCode must be known by the server's logic or won't be processed. + In almost all cases, sending an operation will result in a OperationResponse (see: IPhotonPeerListener.OnOperationResponse). + + Operations are handled by their byte\-typed code. The codes are defined in the Realtime API (a.k.a. LoadBalancing API). + Containing parameters as key\-value pair. The key is byte\-typed, while the value is any serializable datatype. + Wraps up DeliveryMode (reliability), Encryption and Channel values for sending. + If operation could be enqueued for sending. - - - Deserialize returns an object reassembled from the given byte-array. - - The byte-array to be Deserialized - The Deserialized object + + + Registers new types/classes for de/serialization and the fitting methods to call for this type. + + + SerializeMethod and DeserializeMethod are complementary: Feed the product of serializeMethod to + the constructor, to get a comparable instance of the object. + + After registering a Type, it can be used in events and operations and will be serialized like + built-in types. + + Type (class) to register. + A byte-code used as shortcut during transfer of this Type. + Method delegate to create a byte[] from a customType instance. + Method delegate to create instances of customType's from byte[]. + If the Type was registered successfully. @@ -1751,6 +2078,9 @@ The method will get objects passed that were registered with it in RegisterType(). Return a byte[] that resembles the object passed in. The framework will surround it with length and type info, so don't include it. + + Serialization method delegate. StreamBuffer based custom serialization methods must use this form. + Type of deserialization methods to add custom type support. @@ -1759,6 +2089,9 @@ The framwork passes in the data it got by the associated SerializeMethod. The type code and length are stripped and applied before a DeserializeMethod is called. Return a object of the type that was associated with this method through RegisterType(). + + Deserialization method delegate. StreamBuffer based custom deserialization methods must use this form. + Provides tools for the Exit Games Protocol @@ -1957,6 +2290,12 @@ DeserializeInteger returns an Integer typed value from the given stream. + + Exception type for de/serialization issues. Used in Protocol 1.8. + + + Constructor for the exception. + Unkown. GpType: 0. @@ -2067,68 +2406,65 @@ Writes integers as compressed. Either directly as zigzag-encoded or (when a type is written for this value) it can use an optimized sub-type. - - The protocol for this socket, defined in constructor. + + Enum of the three options for reliability and sequencing in Photon's reliable-UDP. - - Address, as defined via a Connect() call. Including protocol, port and or path. + + The operation/message gets sent just once without acknowledgement or repeat. The sequence (order) of messages is guaranteed. - - Contains only the server's hostname (stripped protocol, port and or path). Set in IphotonSocket.Connect(). + + The operation/message asks for an acknowledgment. It's resent until an ACK arrived. The sequence (order) of messages is guaranteed. - - Contains the IP address of the previously resolved ServerAddress (or empty, if GetIpAddress wasn't used). + + The operation/message gets sent once (unreliable) and might arrive out of order. Best for your own sequencing (e.g. for streams). - - Contains only the server's port address (as string). Set in IphotonSocket.Connect(). + + The operation/message asks for an acknowledgment. It's resent until an ACK arrived and might arrive out of order. Best for your own sequencing (e.g. for streams). - - Where available, this exposes if the server's address was resolved into an IPv6 address or not. + + Wraps up DeliveryMode, Encryption and Channel values for sending operations and messages. - - - Separates the given address into address (host name or IP) and port. Port must be included after colon! - - - This method expects any address to include a port. The final ':' in addressAndPort has to separate it. - IPv6 addresses have multiple colons and must use brackets to separate address from port. - - Examples: - ns.exitgames.com:5058 - http://[2001:db8:1f70::999:de8:7648:6e8]:100/ - [2001:db8:1f70::999:de8:7648:6e8]:100 - See: - http://serverfault.com/questions/205793/how-can-one-distinguish-the-host-and-the-port-in-an-ipv6-url - + + Default SendOptions instance for reliable sending. - - Implements a (very) simple test if a (valid) IPAddress is IPv6 by testing for colons (:). - The reason we use this, is that some DotNet platforms don't provide (or allow usage of) the System.Net namespace. - A valid IPAddress or null. - If the IPAddress.ToString() contains a colon (which means it's IPv6). + + Default SendOptions instance for unreliable sending. - - Wraps a DNS call to provide an array of addresses, sorted to have the IPv6 ones first. - - This skips a DNS lookup, if the hostname is an IPv4 address. Then only this address is used as is. - The DNS lookup may take a while, so it is recommended to do this in a thread. Also, it may fail entirely. - - - IPAddress array for hostname, sorted to put any IPv6 addresses first.
- If the DNS lookup fails, HandleException(StatusCode.ExceptionOnConnect) gets called and null returned. - Then the socket should not attempt to connect. -
+ + Chose the DeliveryMode for this operation/message. Defaults to Unreliable. + + + If true the operation/message gets encrypted before it's sent. Defaults to false. + Before encryption can be used, it must be established. Check PhotonPeer.IsEncryptionAvailable is true. + + + The Enet channel to send in. Defaults to 0. + Channels in Photon relate to "message channels". Each channel is a sequence of messages. + + + Sets the DeliveryMode either to true: Reliable or false: Unreliable, overriding any current value. + Use this to conveniently select reliable/unreliable delivery. + + + used by PhotonPeer* + + + Encapsulates the network i/o functionality for the realtime library. + + + used by PhotonPeer* + + + Endless loop, run in Receive Thread. - - - Returns null or the IPAddress representing the address, doing Dns resolution if needed. - - Only returns IPv4 or IPv6 adresses, no others. - The string address of a server (hostname or IP). - IPAddress for the string address or null, if the address is neither IPv4, IPv6 or some hostname that could be resolved. + + Internal class to encapsulate the network i/o functionality for the realtime libary. + + + used by PhotonPeer* - Internal class to encapsulate the network i/o functionality for the realtime libary. + Encapsulates the network i/o functionality for the realtime library. used by PhotonPeer* @@ -2142,106 +2478,162 @@ used by PhotonPeer* - - Internal class to encapsulate the network i/o functionality for the realtime libary. - - - used by PhotonPeer* + + + Allocates a new byte[] that is the exact used length. Use GetBuffer for nonalloc operations. + - - Endless loop, run in Receive Thread. + + + Allocates a new byte[] that is the exact used length. Use GetBuffer for nonalloc operations. + - - Internal class to encapsulate the network i/o functionality for the realtime libary. + + + The bytes between Position and Length are copied to the beginning of the buffer. Length decreased by Position. Position set to 0. + - - used by PhotonPeer* + + + Brings StreamBuffer to the state as after writing of 'length' bytes. Returned buffer and offset can be used to actually fill "written" segment with data. + - - used by PhotonPeer* + + + Sets stream length. If current position is greater than specified value, it's set to the value. + + + SetLength(0) resets the stream to initial state but preserves underlying byte[] buffer. + - + - A simulation item is an action that can be queued to simulate network lag. + Guarantees that the buffer is at least neededSize bytes. - - With this, the actual delay can be measured, compared to the intended lag. + + + Contains several (more or less) useful static methods, mostly used for debugging. + - - Timestamp after which this item must be executed. + + + Gets the local machine's "milliseconds since start" value (precision is described in remarks). + + + This method uses Environment.TickCount (cheap but with only 16ms precision). + PhotonPeer.LocalMsTimestampDelegate is available to set the delegate (unless already connected). + + Fraction of the current time in Milliseconds (this is not a proper datetime timestamp). - - Action to execute when the lag-time passed. + + + Creates a background thread that calls the passed function in intervals, as long as that returns true. + + + With StopBackgroundCalls, you can stop threads started with this method. + The resulting ThreadAbortException is caught and discarded. + + The function to call. Must return true, if it should be called again. Returning false ends the thread. + Milliseconds to sleep between calls of myThread. Default: 100ms. + An optional name for the task to help debugging. Null or empty won't set the thread.Name. - - Starts a new Stopwatch + + + Calls Abort on the thread with the given id (= index of the thread list) + + + The resulting ThreadAbortException is caught and discarded. + + The unique ID of the thread. + True if the thread is canceled and false otherwise, e.g. if the thread with the given ID does not exist. - - - A set of network simulation settings, enabled (and disabled) by PhotonPeer.IsSimulationEnabled. - - - For performance reasons, the lag and jitter settings can't be produced exactly. - In some cases, the resulting lag will be up to 20ms bigger than the lag settings. - Even if all settings are 0, simulation will be used. Set PhotonPeer.IsSimulationEnabled - to false to disable it if no longer needed. - - All lag, jitter and loss is additional to the current, real network conditions. - If the network is slow in reality, this will add even more lag. - The jitter values will affect the lag positive and negative, so the lag settings - describe the medium lag even with jitter. The jitter influence is: [-jitter..+jitter]. - Packets "lost" due to OutgoingLossPercentage count for BytesOut and LostPackagesOut. - Packets "lost" due to IncomingLossPercentage count for BytesIn and LostPackagesIn. - + + + Calls Abort on all threads that were started via StartBackgroundCalls. + + + The resulting ThreadAbortException is caught and discarded. + + True if any thread got aborted. - - internal + + + Writes the exception's stack trace to the received stream. + + Exception to obtain information from. + Output sream used to write to. - - internal + + + Writes the exception's stack trace to the received stream. Writes to: System.Diagnostics.Debug. + + Exception to obtain information from. - - internal + + + This method returns a string, representing the content of the given IDictionary. + Returns "null" if parameter is null. + + IDictionary to return as string. + - - internal + + + Converts a byte-array to string (useful as debugging output). + Uses BitConverter.ToString(list) internally after a null-check of list. + + Byte-array to convert to string. + + List of bytes as string. + - - internal + + + Class to wrap static access to the random.Next() call in a thread safe manner. + - - internal + + + An Attribute named "Preserve" tells Unity to not strip the code. + - - internal + + TCP "Package" header: 7 bytes - - This setting overrides all other settings and turns simulation on/off. Default: false. + + TCP "Message" header: 2 bytes - - Outgoing packages delay in ms. Default: 100. + + TCP header combined: 9 bytes - - Randomizes OutgoingLag by [-OutgoingJitter..+OutgoingJitter]. Default: 0. + + Defines if the (TCP) socket implementation needs to do "framing". + The WebSocket protocol (e.g.) includes framing, so when that is used, we set DoFraming to false. - - Percentage of outgoing packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + + Checks the incoming queue and Dispatches received data if possible. Returns if a Dispatch happened or + not, which shows if more Dispatches might be needed. + - - Incoming packages delay in ms. Default: 100. + + + gathers commands from all (out)queues until udp-packet is full and sends it! + - - Randomizes IncomingLag by [-IncomingJitter..+IncomingJitter]. Default: 0. + + Sends a ping in intervals to keep connection alive (server will timeout connection if nothing is sent). + Always false in this case (local queues are ignored. true would be: "call again to send remaining data"). - - Percentage of incoming packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + enqueues serialized operations to be sent as tcp stream / package - - Counts how many outgoing packages actually got lost. TCP connections ignore loss and this stays 0. + + Sends a ping and modifies this.lastPingResult to avoid another ping for a while. - - Counts how many incoming packages actually got lost. TCP connections ignore loss and this stays 0. + + reads incoming tcp-packages to create and queue incoming commands* @@ -2356,54 +2748,5 @@ Timestamp of last incoming reliable command (every second we expect a PING). - - - Provides classical Diffie-Hellman Modular Exponentiation Groups defined by the - OAKLEY Key Determination Protocol (RFC 2412). - - - - - Gets the genrator (N) used by the the well known groups 1,2 and 5. - - - - - Gets the 768 bit prime for the well known group 1. - - - - - Gets the 1024 bit prime for the well known group 2. - - - - - Gets the 1536 bit prime for the well known group 5. - - - - Interface for Photon's DiffieHellman/Payload Encryption. - - - - Initializes a new instance of the class. - - - - - Gets the public key that can be used by another DiffieHellmanCryptoProvider object - to generate a shared secret agreement. - - - - - Derives the shared key is generated from the secret agreement between two parties, - given a byte array that contains the second party's public key. - - - The second party's public key. - - diff --git a/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef b/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef deleted file mode 100644 index bdf1c96..0000000 --- a/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "PhotonWebSocket" -} diff --git a/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef.meta b/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef.meta deleted file mode 100644 index f8690be..0000000 --- a/Assets/Photon/PhotonLibs/WebSocket/PhotonWebSocket.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: a10ff188cbfd201409863c062b118e1d -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/WebSocket/SocketWebTcp.cs b/Assets/Photon/PhotonLibs/WebSocket/SocketWebTcp.cs index 52737b0..7c6ee07 100644 --- a/Assets/Photon/PhotonLibs/WebSocket/SocketWebTcp.cs +++ b/Assets/Photon/PhotonLibs/WebSocket/SocketWebTcp.cs @@ -1,4 +1,4 @@ -#if UNITY_WEBGL || WEBSOCKET || (UNITY_XBOXONE && UNITY_EDITOR) +#if UNITY_WEBGL || WEBSOCKET || ((UNITY_XBOXONE || UNITY_GAMECORE) && UNITY_EDITOR) // -------------------------------------------------------------------------------------------------------------------- // @@ -19,6 +19,12 @@ namespace ExitGames.Client.Photon using SupportClassPun = ExitGames.Client.Photon.SupportClass; + #if !(UNITY_WEBGL || NETFX_CORE) + using System.Net; + using System.Net.Sockets; + using System.Threading; + #endif + /// /// Yield Instruction to Wait for real seconds. Very important to keep connection working if Time.TimeScale is altered, we still want accurate network events /// @@ -43,10 +49,6 @@ namespace ExitGames.Client.Photon /// public class SocketWebTcp : IPhotonSocket, IDisposable { - /// Defines the binary serialization protocol for all WebSocket connections. Defaults to "GpBinaryV18", a Photon protocol. - /// This is a temporary workaround, until the serialization protocol becomes available via the PeerBase. - public static string SerializationProtocol = "GpBinaryV18"; - private WebSocket sock; private readonly object syncer = new object(); @@ -104,14 +106,94 @@ namespace ExitGames.Client.Photon MonoBehaviour mb = this.websocketConnectionObject.AddComponent(); this.websocketConnectionObject.hideFlags = HideFlags.HideInHierarchy; UnityEngine.Object.DontDestroyOnLoad(this.websocketConnectionObject); - this.sock = new WebSocket(new Uri(this.ServerAddress), SerializationProtocol); // TODO: The protocol should be set based on current PeerBase value (but that's currently not accessible) + + #if UNITY_WEBGL || NETFX_CORE + this.sock = new WebSocket(new Uri(this.ConnectAddress), this.SerializationProtocol); this.sock.Connect(); mb.StartCoroutine(this.ReceiveLoop()); + #else + + mb.StartCoroutine(this.DetectIpVersionAndConnect(mb)); + + #endif return true; } + #if !(UNITY_WEBGL || NETFX_CORE) + private bool ipVersionDetectDone; + private IEnumerator DetectIpVersionAndConnect(MonoBehaviour mb) + { + Uri uri = null; + try + { + uri = new Uri(this.ConnectAddress); + } + catch (Exception ex) + { + if (this.ReportDebugOfLevel(DebugLevel.ERROR)) + { + this.Listener.DebugReturn(DebugLevel.ERROR, "Failed to create a URI from ConnectAddress (" + ConnectAddress + "). Exception: " + ex); + } + } + + if (uri != null && uri.HostNameType == UriHostNameType.Dns) + { + ipVersionDetectDone = false; + + ThreadPool.QueueUserWorkItem(this.DetectIpVersion, uri.Host); + + while (!this.ipVersionDetectDone) + { + yield return new WaitForRealSeconds(0.1f); + } + } + + if (this.AddressResolvedAsIpv6) + { + this.ConnectAddress += "&IPv6"; + } + + if (this.ReportDebugOfLevel(DebugLevel.INFO)) + { + this.Listener.DebugReturn(DebugLevel.INFO, "DetectIpVersionAndConnect() AddressResolvedAsIpv6: " + this.AddressResolvedAsIpv6 + " ConnectAddress: " + ConnectAddress); + } + + + this.sock = new WebSocket(new Uri(this.ConnectAddress), this.SerializationProtocol); + this.sock.Connect(); + + mb.StartCoroutine(this.ReceiveLoop()); + } + + // state has to be the hostname string + private void DetectIpVersion(object state) + { + string host = state as string; + IPAddress[] ipAddresses; + try + { + ipAddresses = Dns.GetHostAddresses(host); + foreach (IPAddress ipAddress in ipAddresses) + { + if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) + { + this.AddressResolvedAsIpv6 = true; + break; + } + } + } + catch (Exception ex) + { + this.Listener.DebugReturn(DebugLevel.INFO, "DetectIpVersionAndConnect (uri: " + host + "= thread failed: " + ex); + } + + this.ipVersionDetectDone = true; + } + #endif + + public override bool Disconnect() { if (this.ReportDebugOfLevel(DebugLevel.INFO)) @@ -207,6 +289,7 @@ namespace ExitGames.Client.Photon yield return new WaitForRealSeconds(0.1f); } + if (this.sock != null) { if (this.sock.Error != null) @@ -223,6 +306,8 @@ namespace ExitGames.Client.Photon } this.State = PhotonSocketState.Connected; + this.peerBase.OnConnect(); + while (this.State == PhotonSocketState.Connected) { if (this.sock != null) diff --git a/Assets/Photon/PhotonLibs/WebSocket/WebSocket.cs b/Assets/Photon/PhotonLibs/WebSocket/WebSocket.cs index c225868..ff48baf 100644 --- a/Assets/Photon/PhotonLibs/WebSocket/WebSocket.cs +++ b/Assets/Photon/PhotonLibs/WebSocket/WebSocket.cs @@ -1,11 +1,19 @@ -#if UNITY_WEBGL || UNITY_XBOXONE || WEBSOCKET +#if UNITY_WEBGL || WEBSOCKET || ((UNITY_XBOXONE || UNITY_GAMECORE) && UNITY_EDITOR) + +// -------------------------------------------------------------------------------------------------------------------- +// +// Provided originally by Unity to cover WebSocket support in WebGL and the Editor. Modified by Exit Games GmbH. +// +// developer@exitgames.com +// -------------------------------------------------------------------------------------------------------------------- + using System; using System.Text; - #if UNITY_WEBGL && !UNITY_EDITOR using System.Runtime.InteropServices; #else +using WebSocketSharp; using System.Collections.Generic; using System.Security.Authentication; #endif @@ -17,12 +25,12 @@ public class WebSocket /// Photon uses this to agree on a serialization protocol. Either: GpBinaryV16 or GpBinaryV18. Based on enum SerializationProtocol. private string protocols = "GpBinaryV16"; - public WebSocket(Uri url, string protocols = null) + public WebSocket(Uri url, string serialization = null) { this.mUrl = url; - if (protocols != null) + if (serialization != null) { - this.protocols = protocols; + this.protocols = serialization; } string protocol = mUrl.Scheme; @@ -125,10 +133,26 @@ public class WebSocket m_Socket.SslConfiguration.EnabledSslProtocols = m_Socket.SslConfiguration.EnabledSslProtocols | (SslProtocols)(3072| 768); m_Socket.OnMessage += (sender, e) => m_Messages.Enqueue(e.RawData); m_Socket.OnOpen += (sender, e) => m_IsConnected = true; + //this.m_Socket.Log.Level = LogLevel.Debug; + //this.m_Socket.Log.Output += Output; + this.m_Socket.OnClose += SocketOnClose; m_Socket.OnError += (sender, e) => m_Error = e.Message + (e.Exception == null ? "" : " / " + e.Exception); m_Socket.ConnectAsync(); } + private void SocketOnClose(object sender, CloseEventArgs e) + { + //UnityEngine.Debug.Log(e.Code.ToString()); + + // this code is used for cases when the socket failed to get created (specifically used to detect "blocked by Windows firewall") + // for some reason this situation is not calling OnError + if (e.Code == 1006) + { + this.m_Error = e.Reason; + this.m_IsConnected = false; + } + } + public bool Connected { get { return m_IsConnected; } }// added by TS diff --git a/Assets/Photon/PhotonLibs/WebSocket/websocket-sharp.dll.meta b/Assets/Photon/PhotonLibs/WebSocket/websocket-sharp.dll.meta index a586786..099f3fc 100644 --- a/Assets/Photon/PhotonLibs/WebSocket/websocket-sharp.dll.meta +++ b/Assets/Photon/PhotonLibs/WebSocket/websocket-sharp.dll.meta @@ -1,69 +1,137 @@ fileFormatVersion: 2 guid: 748eb70bc0d7515498ef73fed155520a PluginImporter: - serializedVersion: 1 + externalObjects: {} + serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: - Android: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 0 + Exclude Linux: 0 + Exclude Linux64: 0 + Exclude LinuxUniversal: 0 + Exclude OSXUniversal: 0 + Exclude WebGL: 1 + Exclude Win: 0 + Exclude Win64: 0 + Exclude WindowsStoreApps: 1 + - first: + '': OSXIntel + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + '': OSXIntel64 + second: enabled: 0 settings: CPU: AnyCPU - Any: + - first: + '': WP8 + second: enabled: 0 + settings: + CPU: AnyCPU + DontProcess: False + PlaceholderPath: + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 1 settings: {} - Editor: + - first: + Editor: Editor + second: enabled: 1 settings: CPU: AnyCPU DefaultValueInitialized: true OS: AnyOS - Linux: - enabled: 0 - settings: - CPU: x86 - Linux64: + - first: + Facebook: Win + second: enabled: 0 settings: - CPU: x86_64 - OSXIntel: + CPU: AnyCPU + - first: + Facebook: Win64 + second: enabled: 0 settings: CPU: AnyCPU - OSXIntel64: - enabled: 0 + - first: + Standalone: Linux + second: + enabled: 1 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 1 settings: CPU: AnyCPU - WP8: - enabled: 0 + - first: + Standalone: OSXUniversal + second: + enabled: 1 settings: CPU: AnyCPU - DontProcess: False - PlaceholderPath: - Win: - enabled: 0 + - first: + Standalone: Win + second: + enabled: 1 settings: CPU: AnyCPU - Win64: - enabled: 0 + - first: + Standalone: Win64 + second: + enabled: 1 settings: CPU: AnyCPU - WindowsStoreApps: + - first: + Windows Store Apps: WindowsStoreApps + second: enabled: 0 settings: CPU: AnyCPU DontProcess: False - PlaceholderPath: + PlaceholderPath: SDK: AnySDK - XboxOne: - enabled: 1 + ScriptingBackend: AnyScriptingBackend + - first: + XboxOne: XboxOne + second: + enabled: 0 settings: {} - iOS: + - first: + iPhone: iOS + second: enabled: 0 settings: - CompileFlags: - FrameworkDependencies: - userData: - assetBundleName: - assetBundleVariant: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/changes-library.txt b/Assets/Photon/PhotonLibs/changes-library.txt index 4ef8219..b5f3782 100644 --- a/Assets/Photon/PhotonLibs/changes-library.txt +++ b/Assets/Photon/PhotonLibs/changes-library.txt @@ -3,6 +3,168 @@ Photon C# Client Library - Changelog Exit Games GmbH - www.photonengine.com - forum.photonengine.com +Version 4.1.5.2 (12. March 2021 - rev6017) + Fixed: A compatibility issue of the Native Encryptor API v2 and Unity UWP exports using the .Net Runtime as runtime. The incompatibility made the reference rewriter fail. Introduced in the Metro build of the library in v4.1.5.0. + Fixed: EncryptorNative will not use the new "native-to-managed callback API" when compiling for NETFX_CORE (UWP Metro). + +Version 4.1.5.1 (01. March 2021 - rev5999) + Note: Release as SDK. + +Version 4.1.5.1 (25. February 2021 - rev5991) + Fixed: Handling of IPv6 addresses (bug was introduced in v4.1.5.0). + +Version 4.1.5.0 (23. February 2021 - rev5986) + Added: Optional parameter CustomInitData to Connect() methods. This data/object is used in InitV3. + Changed: Parameter name for photonToken (was "customdata" or similar). + Internal: PrepareInitV3ConnectData(...) is now WriteInitRequest() without the bunch of parameters which were all coming from the PeerBase anyways. + Fixed: NonAllocDictionary.Remove will also remove the value-reference by setting a default. + Changed: Handling of server IP addresses. IpAddress.TryParse has a few false positives. Those are double-checked and may cause ServerAddressInvalid. + Changed: Failed DNS lookup uses status code: DnsExceptionOnConnect. This clarifies a set of runtime errors, which were hard to identify. + Added: StatusCode ServerAddressInvalid = 1050 and DnsExceptionOnConnect = 1051. Used in IPhotonPeerListener.OnStatusChanged(). + Changed: Native Encryptor API v2 is now required. This affects native Datagram Encryption plugins (and allows GCM / Mode 13). + Changed: PDB files are now in "portable" format. This should be equivalent to "full" (previously used) but compatible with latest Unity versions. + + +Version 4.1.4.9 (11. January 2021 - rev5966) + Fixed: EnetPeer to reset values for unsequenced commands on connect. Before, clients would send illegal command numbers after switching connections. + Added: Special handling for StructWrapper in DictionaryToString(). Pretty-prints type and value. + Added: StructWrapper.ToString() and and ParameterDictionary.ToStringFull() to simplify logging. + Fixed: Add overload in ParameterDictionary was sending ints to byte, rather than object. + Changed: NonAllocDictionary now implements IDictionary. + Changed: ValueIterator and KeyIterator now implement IEnumerator, System.Collections.IEnumerator. + Changed: PairIterator now implement IEnumerator>. + +Version 4.1.4.8 (03. December 2020 - rev5915) + Fixed: Issue with DisconnectTimeout, which could be set to int.MaxValue and force a timeout. + Note: The maximum value that is applied as DisconnectTimeout is now 65535 (ushort.MaxValue). Negative values set to default timeout. + Added: PhotonPeer.RemoveAppIdFromWebSocketPath option to skip the appid in websocket connects. Defaults to false. + Internal: PeerBase.PepareWebSocketUrl to skip the appid when RemoveAppIdFromWebSocketPath is true. Changed order of parameters. + Note: The AppId is not mandatory on the PhotonCloud but might be needed to connect to Photon OnPremise when the port does not define the app type. + +Version 4.1.4.7 (26. November 2020 - rev5893) + Fixed: PhotonClientWebSocket handling of messages > MTU. Incoming messages may be incomplete and are now reassembled. Before the fix, common result was that deserialization failed with incorrect / incomplete data. + Added: ExitGames.Client.Photon.Hashtable Add() and Remove() for byte keys. This makes sure ht.Add(0, obj) and ht.Remove(0) match how the access via ht[0] works. + +Version 4.1.4.6 (17. November 2020 - rev5865) + Changed: The EventData.Paramters dictionary is now readonly. It does not need to be settable and can no longer be null. So null-checks are removed. + Changed: If the ByteArrayPool is used for reading events, the sender's actorNumber will not longer be in the EventData parameter-table. Instead, only the Sender property is used. + Note: This makes receiving EventData events non-alloc by not adding the Sender key/value to the Parameters (which would box the int value). + Note: The EventData.Sender property was available for a while and was a better way to access the event-sender's actornumber. + Changed: PhotonPeer.SendOperation() and PhotonPeer.SendMessage() will now check a few conditions (is connected, etc) and call PeerBase.SerializeOperationToMessage(). + Internal: Changed the code path for operations and messages serialization. There are lots of internal changes for this but no externals. + Internal: Message header length is set in EnqueueMessageAsPayload along with other updates (was in TPeer.SerializeOperationToMessage()). + Removed: PhotonPeer.OpCustom(), which was already obsolete for a long time. + Added: PeerBase.IsTransportEncrypted() to help figure out if Payload Encryption should be skipped. + Changed: PeerBase.SerializeMessageToMessage no longer updates the header for TCP. Done in EnqueueMessageAsPayload, used by EnqueuePhotonMessage. + Changed: SerializeMessageToMessage to check existing value isRawMessage instead of re-checking the condition when applying message type. + Fixed: Detection of Generic-Dictionary-typed arrays. Was lacking a test if the element was of type Dictionary. + Changed: Connect(string serverAddress, string applicationName) to call variant with proxy-support directly. + Updated: Connect methods and their docs. + Removed: More of the RHTTP support. + Added: DisconnectMessage deserialization and an event for this case: PhotonPeer.OnDisconnectMessage. This does not break the dll's compatibility. + Changed: Connect() workflow. This simplified the TPeer and EnetPeer somewhat and unifies some actions that were scattered in the classes hierarchy. + Changed: PhotonPeer to create the SocketImplementationConfig in the constructor. Connect() will use this to create the actual IPhotonSocket. + Changed: TPeer.Connect and EnetPeer.Connect are a bit simpler now (don't have to create the actual IPhotonSocket). + Removed: PeerBase.SocketImplementation member. + Changed: Setter and handling for the Version.clientVersion (conditional for SERVERSDK). + Changed: Version.clientVersion is readonly, unless SERVERSDK is defined. + Changed: CreatePeerBase() will only create a new EnetPeer or TPeer on demand (if the protocol changed or there was no PeerBase implementation). + Added: Special treatment for byte-typed keys to the Photon Hashtable to avoid boxing. Pre-boxed items are stored in a static array. + Added: NonAllocDictionary support in SupportClass (DictionaryToString()). + Added: ParameterDictionary as type and support to de/serialize it. + Note: This is a WiP commit to get LoadBalancing non-allow (or less alloc). + Added: PhotonPeer.WrapIncomingStructs to control how to de-serialize responses and events. Setting this requires adjusted code. + Note: As long as WrapIncomingStructs is not set, code changes are not mandatory. + Fixed: Error message in SerializeDictionaryHeader to include the type of the value which failed (it was logging the key's type). + Changed: The PhotonClientWebSocket does a DNS request before connecting, to figure out if IPv6 should be requested by Photon servers. + Added: PhotonPeer.TargetFramework to identify the target framework that the dll was built-for. Might help identify the used variant. + Changed: Code order a little, to get obsolete fields up in the range for them. + Removed: RhttpMinConnections and RhttpMaxConnections, which were entirely obsolete. + Changed: OperationResponse indexer is not obsolete. This was used to detect where it's used. + Changed: ParameterDictionary now has a Get() method, so the API is analog to Unwrap() in this case. + Changed: EnetChannel to use NonAllocDictionary instead of Dictionary. Our replacement is internal and non-allocating for iteration. + Changed: the logging level of events possibly happening on each Service() call changed from INFO to ALL + Changed: EnqueueMessageAsPayload stats-keeping no longer throws an exception, when the delivery mode is "out of range". + Internal: Changed how the client writes acknowledgements. + Internal: TPeer.ReceiveIncomingCommands() will only log "Wrong MagicNumber", if the received length is more than 0. It also logs the length then. + Changed: PhotonClientWebSocket (in .Net Standard 2.0 dll) now checks if the clientWebSocket state is still "Open" before handling incoming data. + Changed: PhotonClientWebSocket logs INFO, when the received data has length 0 but the socket is still Open. + + +Version 4.1.4.5 (04. September 2020 - rev5733) + Fixed: Serialization of a ByteArraySlice will now release it, as described in the docs. So you can pass a ByteArraySlice to RaiseEvent and control of it is passed over to the Photon API. + Fixed: Potential issues with SupportLogger.StartBackgroundCalls() when there were 255 threads running (and or stopped). + Changed: When PhotonClientWebSocket fails to connect, this will now correctly result in a disconnect with code/reason ExceptionOnConnect. + Changed: The socket reading-thread not call it's disconnect method, if already disconnecting/disconnected. This avoids a surplus call (and callback). + Internal: The thread locking object in SocketNative is no longers static. + Note: The next release will change the native datagram encryptor api. Most likely this is the last one compatible with the old native plugin. + +Version 4.1.4.4 (29. June 2020 - rev5625) + Fixed: NonAllocDict. Capacity change was broken. This is a critical fix. + Added: Indexer to NonAllocDict to allow Dict[key] get and set. + Added: NonAllocDict.Clear() method. + +Version 4.1.4.3 (24. June 2020 - rev5622) + Added: PhotonPeer.UseByteArraySlicePoolForEvents and PhotonPeer.ByteArraySlicePool to avoid memory garbage when events consist only of a byte-array. See comments / doc. + Added: Class NonAllocDictionary as replacement for the suboptimal implementation in Mono. Some of our code relies on Dictionaries and can be optimized with this. Note: This is neither documented well yet and considered "beta" until we got feedback on some use cases. + Added: PhotonPeer.TrafficRecorder and ITrafficRecorder. This can be used to capture traffic on UDP connections. + Changed: IPhotonSocket.ConnectAddress is now a local field. Before, it accessed the peer which might already connect to another server. + Changed: Debug log for DNS resolution (INFO level). This includes a count of IPs that were returned. + Added: Static PhotonPeer.NoNativeCallbacks to disable callbacks from native code to C#. SocketNative is the first class to use NoNativeCallbacks in DnsAndConnect(). + Changed: SocketUdp and SocketTcp are now public, like other implementations. This means you can assign them to the SocketImplementationConfig and select these deliberately. + Internal: Datagram Encryption was updated and optimized. (rev5548+rev5550). Added PhotonPeer.NativeEncryptorApiVersion constant to be able to check which native encryptor API is being compiled into the assembly. + Changed: EnetPeer.ReceiveIncomingCommands(): bytesIn counter simplified: now it simply incremented by input data size. + Removed: "CommandLog" feature. It was replaced by Traffic Recording. Remaining setting values for this (in PhotonPeer) are now Obsolete and without function. + Changed: WebSocket init workflow to make it compatible with AuthOnce / AuthOnceWss. It can send an init request now. + Internal: WebSockets need to use the ConnectAddress, as the TPeer will setup the address and path as required. + Changed: The IPhotonSocket does not set the ConnectAddress again, so the Peer can set this address before connecting. This is used for WebSocket connects. + Fixed: NETFX_CORE variant of payload encryption initialization. + Added: PreserveAttribute and used it on IPhotonSocket constructors. This keeps Unity's code stripping from constructors which we need. + Fixed: A rare threading issue for UDP connections. + Internal: SupportClass.StartBackgroundCalls() and related methods are now locked. A proper cleanup of StartBackgroundCalls is pending. + Changed: SupportClass.StopBackgroundCalls(id) will now clear the reference to the used thread but not remove the entry in the list. + Changed: SupportClass.StopAllBackgroundCalls() will now clear all referenced threads. Could be used when disconnected / before another connect to reduce number of Threads. + Removed: SupportClass.CallInBackground, which was replaced by StartBackgroundCalls a while ago. + + +Version 4.1.4.2 (08. May 2020 - rev5519) + Updated: DotNet SDK (net35, UWP and .Net Standard 2.0) and Unity SDK. +Version 4.1.4.1 (30. April 2020 - rev5482) + Fixed: String serialization for characters with more bytes. UTF8.GetBytes was called with byte-count instead of character-count as parameter. +Version 4.1.4.0 (28. April 2020 - rev5474) + Internal: Changed serialization of strings to produce no memory garbage. Strings that exceed a UTF8-encoded byte-length of 32767 (short.MaxValue) are not supported in either protocol (now throwing an exception). + Internal: Improved the serialization of float, double, float-array and double-array to produce less memory garbage with better performance. + Fixed: Cross platform serialization of float and double values in protocol 1.8 (which is used by default by PUN 2). Undiscovered, the C# client was using a wrong byte-order for network. The server and native clients were receiving a wrong value. Between C# clients, everything was fine. + Added: WebSocket support built-in to the Metro / UWP assembly. The PhotonMessageWebSocket is automatically used, unless some override is defined externally. + Changed: The socket implementations now disconnect when an exception happens due to sending. This uses the StatusCode.SendError, reported via OnStatusChanged callback. The LoadBalancingClient will handle this and report a DisconnectCause.Exception. Careful when updating only the library: Handle this in LoadBalancingClient. + Changed: The internal exception logging is now in log level INFO. This means the handled exception is no longer logged as if it's not. + Internal: Reverted to using the datagram encryption API v1. The new one is not fully implemented and should not be used yet (but was in v4.1.3.0). + Fixed: If a timeout message arrives after the client disconnected locally, the timeout is neither reported (via OnStatusChanged) nor does it trigger (another) disconnect. This avoids rare issues where clients would get stuck in Disconnecting state. + Added: Initial changes to support proxies for WSS. The PhotonPeer got a Connect overload which sets the proxy address and the IPhotonSocket got ProxyServerAddress. Higher level changes are upcoming. + Fixed: When the StreamBuffer for a large message got fragmented, this goes back to the StreamBuffer pool. + Changed: ExecuteCommand() for fragments. We now use a StreamBuffer from the pool and only adjust the buffered size if needed. + Added: Static PhotonPeer.MessageBufferPoolSize() to have access to the current StreamBuffer pool size. + +Version 4.1.3.0 (23. March 2020 - rev5399) + Internal: Changed Visual Studio projects which build the C# Photon libraries. Added a .Net Standard 2.0 assembly, which has built-in WebSocket support. + Added: IPhotonSocket.SerializationProtocol property. This provides the protocol of the current PhotonPeer.SerializationProtocolType as string. + Note: Some WebSocket implementations use a static value of the same name and need to be updated! Some projects contain SocketWebTcp.cs, SocketWebTcpThread.cs or similar files. + Changed: It is now possible to signal "on demand encryption" (known as Payload Encryption within Photon terms) even on secure connections (WSS / Datagram Encryption). This is important (only) for mixed connection types. A server update is required. The Photon Cloud is updated. + Added: PhotonPeer.SendInCreationOrder. This defaults to true, enabling the new behaviour explained below. + Changed: The send order of reliable and unreliable commands (UDP). This improves throughput of unreliable commands, when there are multiple datagrams of data. Before, a datagram got filled with the reliable commands first. Only when those were gone, unreliable commands were sent. The server was discarding some messages are too late. + Updated: Pool to be used in higher level APIs. Pool.Count is now also locked. + Internal: EnetPeer ocal variable fragmentLength to currentFragmentSize. It no longer hides EnetPeer.fragmentLength, which was probably causing issues in the Native Toolchain (Master builds for HoloLens 2). + Internal: Datagram Encryption now has a new mode: GCM. It can be used seamlessly with the Photon Cloud. + Internal: Native Datagram Encryption plugins and APIs are now more efficient. + Removed: rHttp support. + +Version 4.1.2.20 (12. December 2019 - rev5296) + Changed: DiffieHellmanCryptoProviderNative is now always compiled into the assembly using dynamic linking. If the payload encryption native library is present, it will be used automatically. + Changed: Extern methods with the DllImport attribute are now public. This allows a PrelinkAll() check if the dll is available and can be loaded. + Internal: EncryptorNative will no longer use native extern methods in static fields. This causes execptions in unexpected context. + Added: PhotonPeer NativePayloadEncryptionLibAvailable, NativeDatagramEncryptionLibAvailable and NativeSocketLibAvailable values. + Changed: SocketNative is autmatically used if the native socket lib is available, based on the checks above. + Changed: The wrappers for the native libraries (sockets and datagram encryption) will now setup a debug logging callback with debug level. This requires new native libraries. Version 4.1.2.19 (13. November 2019 - rev5271) Internal: Handling for DllNotFoundException in the SocketNative.DnsAndConnect(). @@ -11,7 +173,7 @@ Version 4.1.2.19 (13. November 2019 - rev5271) Internal: Changed the access level of PeerBase.debugOut from 'internal' to 'public'. Changed: UDP socket classes now trigger a disconnect in the send methods, should the lower-level socket be disconnected. This gives us a quicker "disconnected" state in some error cases. So far, only reading-errors triggered disconnects in UDP. Changed: Logging in case of send errors. - Added: Exception handling to deserialization. This adds a safety layer for receiving messages, which can be skipped. Important: It will be unknown, what message got discarded and if it's important or if it was fake / surplus. + Added: Exception handling to deserialization. This adds a safety layer for receiving messages, which can be skipped. Important: It will be unknown, what message got discarded and if it's important or if it was fake / surplus. Fixed: Internal class EncryptorNet, which was not thread safe, so DatagramEncryption was failing sooner or later. This affected only v4.1.2.18, which was an internal release. Version 4.1.2.18 (1. October 2019 - rev5229) diff --git a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb.meta b/Assets/Photon/PhotonLibs/netstandard2.0.meta similarity index 67% rename from Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb.meta rename to Assets/Photon/PhotonLibs/netstandard2.0.meta index 13a9aba..c52d133 100644 --- a/Assets/Photon/PhotonLibs/Metro/Photon3Unity3D.dll.mdb.meta +++ b/Assets/Photon/PhotonLibs/netstandard2.0.meta @@ -1,5 +1,6 @@ fileFormatVersion: 2 -guid: 3e5f206e14e5aa74f8d1a327221f6532 +guid: beb9d2a25c882b54ab2fd9adaec2b53c +folderAsset: yes DefaultImporter: externalObjects: {} userData: diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json new file mode 100644 index 0000000..58d80cf --- /dev/null +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json @@ -0,0 +1,47 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "Photon3Unity3D/4.1.5.2": { + "dependencies": { + "NETStandard.Library": "2.0.3" + }, + "runtime": { + "Photon3Unity3D.dll": {} + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + } + } + }, + "libraries": { + "Photon3Unity3D/4.1.5.2": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json.meta b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json.meta new file mode 100644 index 0000000..c26136a --- /dev/null +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.deps.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a966b98b651e18748abf2829786b5899 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll new file mode 100644 index 0000000..dc7d100 Binary files /dev/null and b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll differ diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll.meta b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll.meta new file mode 100644 index 0000000..96b4f30 --- /dev/null +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.dll.meta @@ -0,0 +1,122 @@ +fileFormatVersion: 2 +guid: 6a558ae793155af4b9b9ab945fc64a0f +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 0 + Exclude Linux: 0 + Exclude Linux64: 0 + Exclude LinuxUniversal: 0 + Exclude OSXUniversal: 0 + Exclude WebGL: 0 + Exclude Win: 0 + Exclude Win64: 0 + Exclude WindowsStoreApps: 0 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 1 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 1 + settings: + CPU: AnyCPU + DontProcess: false + PlaceholderPath: + SDK: AnySDK + ScriptingBackend: Il2Cpp + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb new file mode 100644 index 0000000..c0ae127 Binary files /dev/null and b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb differ diff --git a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb.meta b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb.meta similarity index 74% rename from Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb.meta rename to Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb.meta index 52ea428..e8e3824 100644 --- a/Assets/Photon/PhotonLibs/Photon3Unity3D.dll.mdb.meta +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.pdb.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a6a8c659e73e91a4ba53f4aead7102da +guid: 0f6296aca03a5574eb30b4277a2076fd DefaultImporter: externalObjects: {} userData: diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml new file mode 100644 index 0000000..a024ed0 --- /dev/null +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml @@ -0,0 +1,2752 @@ + + + + Photon3Unity3D + + + + + Initializes a new instance of the class. + + + + + Gets the public key that can be used by another DiffieHellmanCryptoProvider object + to generate a shared secret agreement. + + + + + Derives the shared key is generated from the secret agreement between two parties, + given a byte array that contains the second party's public key. + + + The second party's public key. + + + + Interface for Photon's DiffieHellman/Payload Encryption. + + + + Provides classical Diffie-Hellman Modular Exponentiation Groups defined by the + OAKLEY Key Determination Protocol (RFC 2412). + + + + + Gets the genrator (N) used by the the well known groups 1,2 and 5. + + + + + Gets the 768 bit prime for the well known group 1. + + + + + Gets the 1024 bit prime for the well known group 2. + + + + + Gets the 1536 bit prime for the well known group 5. + + + + A slice of memory that should be pooled and reused. Wraps a byte-array. + + This is a serializable datatype for the .Net clients. It will serialize and transfer as byte[]. + If PhotonPeer.UseByteArraySlicePoolForEvents is enabled, byte-arrays in (incoming) events will be deserialized as + ByteArraySlice. + + Adjust your OnEvent code accordingly. + + + + The buffer for the slice. + + + The position where the content starts in Buffer. + + + The length of the data in the Buffer. + + + + Internal constructor - these instances will be part of the pooling system. + + The pool to return to. + The index to return to (in the related returnPool). + + + + Create a new ByteArraySlice. The buffer supplied will be used. Usage is similar to ArraySegment. + + Not part of pooling. + + + + Creates a ByteArraySlice, which is not pooled. It has no Buffer. + + Not part of pooling. + + + + If this item was fetched from a ByteArraySlicePool, this will return it. + + + True if this was a pooled item and it successfully was returned. + If it does not belong to a pool nothing will happen, and false will be returned. + + + + Resets Count and Offset to 0 each. + + + Tiered pool for ByteArraySlices. Reduces the allocations once enough slices are available. + + + + Requests for buffers smaller than 2^minStackIndex will use 2^minStackIndex. This value avoids allocations of smaller rarely used buffers. + Set this to a lower value if you will never need sizes larger than byte[2^minStackIndex] + + + + Count of allocations this pool did. + + + Creates a new pool. + + + + Get a ByteArraySlice from pool. This overload handles user supplied byte[] and byte count and can be used as a non-boxing alternative to ArraySegment<byte>. + + + + + Get byte[] wrapper from pool. This overload accepts a bytecount and will return a wrapper with a byte[] that size or greater. + + + + + Releasing a ByteArraySlice, will put it back into the pool, if it was acquired from one. + + The ByteArraySlice to return to the pool. + True if this slice was returned to some pool. False if not. + + + + Clears all pool items with byte array sizes between lower and upper inclusively. + + + Use this if you sent some unusually large RaiseEvents and believe the buffers of that size + will not be needed again, and you would like to free up the buffer memory. + + + + + Replacement for Dictionary<K,V> which does not allocate memory during usage. + + Key type. + Value type. + + + + This is a substitute for the Hashtable class, missing in: Win8RT and Windows Phone. It uses a Dictionary<object,object> as base. + + + Please be aware that this class might act differently than the Hashtable equivalent. + As far as Photon is concerned, the substitution is sufficiently precise. + + + + + Translates the byte key into the pre-boxed byte before doing the lookup. + + + + + + + Creates a shallow copy of the Hashtable. + + + A shallow copy of a collection copies only the elements of the collection, whether they are + reference types or value types, but it does not copy the objects that the references refer + to. The references in the new collection point to the same objects that the references in + the original collection point to. + + Shallow copy of the Hashtable. + + + Interface for DatagramEncryptor implementations. + + + Initialize the encryptor. + + + + Encryption/decryption algorithm implementation + + + + + Packet authentication algorithm impelmenation + + + + + Implementation of encryption for "Datagram Encryption". + + + + + Initialize + + + + + + + Number for reliable unsequenced commands (separate from "standard" reliable sequenced). Used to avoid duplicates. + + + The highest number of reliable unsequenced commands that arrived (and all commands before). + + + Any reliable unsequenced number that's been received, which is higher than the current highest in complete sequence (reliableUnsequencedNumbersCompletelyReceived). + + + Checks and queues incoming reliable unsequenced commands ("send" or "fragment"), if they haven't been received yet. + The command to check and queue. + True if the command is new and got queued (or could be executed/dispatched). + + + One list for all channels keeps sent commands (for re-sending). + + + One pool of ACK byte arrays ( 20 bytes each) for all channels to keep acknowledgements. + + + Gets enabled by "request" from server (not by client). + + + Initial PeerId as used in Connect command. If EnableServerTracing is false. + + + Initial PeerId to enable Photon Tracing, as used in Connect command. See: EnableServerTracing. + + + + Checks the incoming queue and Dispatches received data if possible. + + If a Dispatch happened or not, which shows if more Dispatches might be needed. + + + Gets the target size for fragments. + + Caches the result for a specific MTU value. + Fragment length is different, when datagram encryption is used (so this caches two values in fact). + + + + + + gathers acks until udp-packet is full and sends it! + + + + Queue of commands that need resending. Used instead of a method local field as optimization. + + + Queue of received commands. ReceiveIncomingCommands will queue commands, except ACKs which Execute immediately. + + + + gathers commands from all (out)queues until udp-packet is full and sends it! + + + + + Checks if any channel has a outgoing reliable command. + + True if any channel has a outgoing reliable command. False otherwise. + + + + Checks connected state and channel before operation is serialized and enqueued for sending. + + if operation could be enqueued + + + reliable-udp-level function to send some byte[] to the server via un/reliable command + only called when a custom operation should be send + the invocation ID for this operation (the payload) + + + reads incoming udp-packages to create and queue incoming commands* + + + Queues incoming commands in the correct order as either unreliable, reliable or unsequenced. + If queued or not. + + + removes commands which are acknowledged* + + + + Enumeration of situations that change the peers internal status. + Used in calls to OnStatusChanged to inform your application of various situations that might happen. + + + Most of these codes are referenced somewhere else in the documentation when they are relevant to methods. + + + + the PhotonPeer is connected.
See {@link PhotonListener#OnStatusChanged}*
+
+ + the PhotonPeer just disconnected.
See {@link PhotonListener#OnStatusChanged}*
+
+ + the PhotonPeer encountered an exception and will disconnect, too.
See {@link PhotonListener#OnStatusChanged}*
+
+ + Exception while opening the incoming connection to the server. Followed by Disconnect. + The server could be down / not running or the client has no network or a misconfigured DNS.
See {@link PhotonListener#OnStatusChanged}*
+
+ + Used on platforms that throw a security exception on connect. Unity3d does this, e.g., if a webplayer build could not fetch a policy-file from a remote server. + + + Sending command failed. Either not connected, or the requested channel is bigger than the number of initialized channels. + + + Exception, if a server cannot be connected. Followed by Disconnect. + Most likely, the server is not responding. Ask user to try again later. + + + Disconnection due to a timeout (client did no longer receive ACKs from server). Followed by Disconnect. + + + Timeout disconnect by server. The server didn't receive necessary ACKs in time. Followed by Disconnect. + + + Disconnect by server due to concurrent user limit reached (received a disconnect command). + + + (1043) Disconnect by server due to server's logic. Followed by Disconnect. + + + Disconnect by server due to unspecified reason. Followed by Disconnect. + + + (1048) Value for OnStatusChanged()-call, when the encryption-setup for secure communication finished successfully. + + + (1049) Value for OnStatusChanged()-call, when the encryption-setup failed for some reason. Check debug logs. + + + + Callback interface for the Photon client side. Must be provided to a new PhotonPeer in its constructor. + + + These methods are used by your PhotonPeer instance to keep your app updated. Read each method's + description and check out the samples to see how to use them. + + + + + Provides textual descriptions for various error conditions and noteworthy situations. + In cases where the application needs to react, a call to OnStatusChanged is used. + OnStatusChanged gives "feedback" to the game, DebugReturn provies human readable messages + on the background. + + + All debug output of the library will be reported through this method. Print it or put it in a + buffer to use it on-screen. Use PhotonPeer.DebugOut to select how verbose the output is. + + DebugLevel (severity) of the message. + Debug text. Print to System.Console or screen. + + + + Callback method which gives you (async) responses for called operations. + + + Similar to method-calling, operations can have a result. + Because operation-calls are non-blocking and executed on the server, responses are provided + after a roundtrip as call to this method. + + Example: Trying to create a room usually succeeds but can fail if the room's name is already + in use (room names are their IDs). + + This method is used as general callback for all operations. Each response corresponds to a certain + "type" of operation by its OperationCode. + + + + When you join a room, the server will assign a consecutive number to each client: the + "actorNr" or "player number". This is sent back in the operation result. + + Fetch your actorNr of a Join response like this: + int actorNr = (int)operationResponse[(byte)OperationCode.ActorNr]; + + The response to an operation\-call. + + + + OnStatusChanged is called to let the game know when asynchronous actions finished or when errors happen. + + + Not all of the many StatusCode values will apply to your game. Example: If you don't use encryption, + the respective status changes are never made. + + The values are all part of the StatusCode enumeration and described value-by-value. + + A code to identify the situation. + + + + Called whenever an event from the Photon Server is dispatched. + + + Events are used for communication between clients and allow the server to update clients anytime. + The creation of an event is often triggered by an operation (called by this client or an other). + + Each event carries a Code plus optional content in its Parameters. + Your application should identify which content to expect by the event's Code. + + Events can be defined and modified server-side. + + If you use the LoadBalancing api as basis, several events like EvJoin and EvLeave are pre-defined. + The LoadBalancing api provides the EventCode and ParameterCode classes for pre-defined events. + + Photon also allows you to come up with custom events on the fly, purely client-side. + To do so, use OpRaiseEvent. + + Events are incoming messages and as such buffered in the peer. + Calling PhotonPeer.DispatchIncomingCommands will call IPhotonPeerListener.OnEvent, to hand over received events. + + PhotonPeer.ReuseEventInstance is an option to optimize memory usage by reusing one EventData instance. + + The event currently being dispatched. + + + The protocol for this socket, defined in constructor. + + + Address, as defined via a Connect() call. Including protocol, port and or path. + This is set in the constructor and in Connect() again. Typically the address does not change after the IPhotonSocket is instantiated. + + + Contains only the server's hostname (stripped protocol, port and or path). Set in IPhotonSocket.Connect(). + + + Contains the IP address of the previously resolved ServerAddress (or empty, if GetIpAddress wasn't used). + + + Contains only the server's port address (as string). Set in IphotonSocket.Connect(). + + + Where available, this exposes if the server's address was resolved into an IPv6 address or not. + + + + Provides the protocol string, of the current PhotonPeer.SerializationProtocolType to be used for WebSocket connections. + + + Any WebSocket wrapper could access this to get the desired binary protocol for the connection. + Some WebSocket implementations use a static value of the same name and need to be updated. + + The value is not cached and each call will create the needed string on the fly. + + + + + Separates the given address into address (host name or IP) and port. Port must be included after colon! + + + This method expects any address to include a port. The final ':' in addressAndPort has to separate it. + IPv6 addresses have multiple colons and must use brackets to separate address from port. + + Examples: + ns.exitgames.com:5058 + http://[2001:db8:1f70::999:de8:7648:6e8]:100/ + [2001:db8:1f70::999:de8:7648:6e8]:100 + See: + http://serverfault.com/questions/205793/how-can-one-distinguish-the-host-and-the-port-in-an-ipv6-url + + + + Wraps a DNS call to provide an array of addresses, sorted to have the IPv6 ones first. + + This skips a DNS lookup, if the hostname is an IPv4 address. Then only this address is used as is. + The DNS lookup may take a while, so it is recommended to do this in a thread. Also, it may fail entirely. + + + IPAddress array for hostname, sorted to put any IPv6 addresses first.
+ If the DNS lookup fails, HandleException(StatusCode.ExceptionOnConnect) gets called and null returned. + Then the socket should not attempt to connect. +
+
+ + + Returns null or the IPAddress representing the address, doing Dns resolution if needed. + + Only returns IPv4 or IPv6 adresses, no others. + The string address of a server (hostname or IP). + IPAddress for the string address or null, if the address is neither IPv4, IPv6 or some hostname that could be resolved. + + + Variants of the Photon specific serialization protocol used for operations, responses, events and data. + + + Version 1.6 (outdated). + + + Version 1.8. + + + + + + + Serialize creates a byte-array from the given object and returns it. + + The object to serialize + The serialized byte-array + + + + Deserialize returns an object reassembled from the given StreamBuffer. + + The buffer to be Deserialized + The Deserialized object + + + + Deserialize returns an object reassembled from the given byte-array. + + The byte-array to be Deserialized + The Deserialized object + + + + Interface for (UDP) traffic capturing. + + + + Indicates if the PhotonPeer should call Record or not. + + + Implement to record network traffic. Called by PhotonPeer for each UDP message sent and received. + + The buffer will not contain Ethernet Header, IP, UDP level data. Only the payload received by the client. + + It is advised to not use NetworkSimulation when recording traffic. + The recording is done on the timing of actual receive- and send-calls and internal simulation would offset the timing. + + Buffer to be sent or received. Check length value for actual content length. + Length of the network data. + Indicates incoming (true) or outgoing (false) traffic. + The local peerId for the connection. Defaults to 0xFFFF until assigned by the Server. + The currently used IPhotonSocket of this Peer. Enables you to track the connection endpoint. + + + Internal class for "commands" - the package in which operations are sent. + + + Size of the Payload, which may be null. + + + Checks commandFlags & FV_UNRELIABLE_UNSEQUENCED. + + + Checks commandFlags & FV_RELIABLE. + + + + ACKs should never be created as NCommand. use CreateACK to wrtie the serialized ACK right away... + + + + + + + + + this variant does only create outgoing commands and increments . incoming ones are created from a DataInputStream + + + this variant does only create outgoing commands and increments . incoming ones are created from a DataInputStream + + + reads the command values (commandHeader and command-values) from incoming bytestream and populates the incoming command* + + + + A simulation item is an action that can be queued to simulate network lag. + + + + With this, the actual delay can be measured, compared to the intended lag. + + + Timestamp after which this item must be executed. + + + Action to execute when the lag-time passed. + + + Starts a new Stopwatch + + + + A set of network simulation settings, enabled (and disabled) by PhotonPeer.IsSimulationEnabled. + + + For performance reasons, the lag and jitter settings can't be produced exactly. + In some cases, the resulting lag will be up to 20ms bigger than the lag settings. + Even if all settings are 0, simulation will be used. Set PhotonPeer.IsSimulationEnabled + to false to disable it if no longer needed. + + All lag, jitter and loss is additional to the current, real network conditions. + If the network is slow in reality, this will add even more lag. + The jitter values will affect the lag positive and negative, so the lag settings + describe the medium lag even with jitter. The jitter influence is: [-jitter..+jitter]. + Packets "lost" due to OutgoingLossPercentage count for BytesOut and LostPackagesOut. + Packets "lost" due to IncomingLossPercentage count for BytesIn and LostPackagesIn. + + + + internal + + + internal + + + internal + + + internal + + + internal + + + internal + + + internal + + + This setting overrides all other settings and turns simulation on/off. Default: false. + + + Outgoing packages delay in ms. Default: 100. + + + Randomizes OutgoingLag by [-OutgoingJitter..+OutgoingJitter]. Default: 0. + + + Percentage of outgoing packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + + Incoming packages delay in ms. Default: 100. + + + Randomizes IncomingLag by [-IncomingJitter..+IncomingJitter]. Default: 0. + + + Percentage of incoming packets that should be lost. Between 0..100. Default: 1. TCP ignores this setting. + + + Counts how many outgoing packages actually got lost. TCP connections ignore loss and this stays 0. + + + Counts how many incoming packages actually got lost. TCP connections ignore loss and this stays 0. + + + Provides an overview of the current values in form of a string. + String summary. + + + + The pool this wrapper should return to when released/disposed. + + + + + Gets value and if it belongs to the static pool, returns the wrapper to pool. + + + + + + Boxes the value and returns boxed object. Releases the wrapper. + + + + + + Removes this WrapperStruct from pooling. + + + + Returns a String which represents the value of this instance. + String which represents the value of this instance. + + + Returns a String which represents the type (in brackets and value of this instance. + String which represents the type (in brackets) and value of this instance. + + + + staticPool is used for implicit casting. This is not threadsafe, so casting between T and StructWrapper should only be done on the Unity main thread. + + + + + Replacement for object.GetType() that first checks to see if object is a WrappedStruct. + If so returns the StructWrapper T type, otherwise just returns object.GetType(). + + + + + + + Wrap a struct in a pooled StructWrapper. + + + + + Wrap a struct in a pooled StructWrapper. Pulls wrapper from the static pool. Wrapper is returned to pool when Unwrapped. + Slighty faster version of Wrap() that is hard wired to pull from the static pool. Use the persistant bool argument to make a permanent unpooled wrapper. + + + + + Tests if object is either a cast T, or a wrapped T + + + + + Remove all wrappers in hashtable from pooling, so they can remain cached and used later. + + + + + + Unwraps any WrapperStructs, boxes their value, releases hashtable entry with the boxed value. Releases the wrappers. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is will not be returned to its pool until it is Unwrapped, or the pool is cleared. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is returned to the wrapper pool if applicable, so it is not considered safe to Unwrap multiple times, as the wrapper may be recycled. + + + + + If object is a StructWrapper, the value will be extracted. If not, the object will be cast to T. + Wrapper is will not be returned to its pool until it is Unwrapped, or the pool is cleared. + + + + + Will get the object using the key. If the key is invalid, will return null. + + + + + + + Returns + + + + + + Param code. Used in internal op: InitEncryption. + + + Encryption-Mode code. Used in internal op: InitEncryption. + + + Param code. Used in internal op: InitEncryption. + + + Code of internal op: InitEncryption. + + + TODO: Code of internal op: Ping (used in PUN binary websockets). + + + Result code for any (internal) operation. + + + + This is the replacement for the const values used in eNet like: PS_DISCONNECTED, PS_CONNECTED, etc. + + + + No connection is available. Use connect. + + + Establishing a connection already. The app should wait for a status callback. + + + + The low level connection with Photon is established. On connect, the library will automatically + send an Init package to select the application it connects to (see also PhotonPeer.Connect()). + When the Init is done, IPhotonPeerListener.OnStatusChanged() is called with connect. + + Please note that calling operations is only possible after the OnStatusChanged() with StatusCode.Connect. + + + Connection going to be ended. Wait for status callback. + + + Acknowledging a disconnect from Photon. Wait for status callback. + + + Connection not properly disconnected. + + + The server's address, as set by a Connect() call, including any protocol, ports and or path. + If rHTTP is used, this can be set directly. + + + + This is the (low level) connection state of the peer. It's internal and based on eNet's states. + + Applications can read the "high level" state as PhotonPeer.PeerState, which uses a different enum. + + + Byte count of last sent operation (set during serialization). + + + Byte count of last dispatched message (set during dispatch/deserialization). + + + The command that's currently being dispatched. + + + This ID is assigned by the Realtime Server upon connection. + The application does not have to care about this, but it is useful in debugging. + + + + The serverTimeOffset is serverTimestamp - localTime. Used to approximate the serverTimestamp with help of localTime + + + + + Count of all bytes going out (including headers) + + + + + Count of all bytes coming in (including headers) + + + + Set via Connect(..., customObject) and sent in Init-Request. + + + Sent on connect in an Init Request. + + + Temporary cache of AppId. Used in Connect() to keep the AppId until we send the Init-Request (after the network-level (and Enet) connect). + + + Set to timeInt, whenever SendOutgoingCommands actually checks outgoing queues to send them. Must be connected. + + + Maximum Transfer Unit to be used for UDP+TCP + + + If IPhotonSocket.Connected is true, this value shows if the server's address resolved as IPv6 address. + + You must check the socket's IsConnected state. Otherwise, this value is not initialized. + Sent to server in Init-Request. + + + + + Writes and "Init Request", which initializes the connection / application used server-side. + + Uses this.ServerAddress, this.AppId, this.PhotonToken and CustomInitData and some more values. + Bytes of the init request. + + + Called when the server's Init Response arrived. + + + Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. + This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. + + + Serializes an operation into our binary messages (magic number, msg-type byte and message). Optionally encrypts. + This method is mostly the same in EnetPeer, TPeer and HttpPeerBase. Also, for raw messages, we have another variant. + + + Returns the UDP Payload starting with Magic Number for binary protocol + + + + Checks outgoing queues for commands to send and puts them on their way. + This creates one package per go in UDP. + + If commands are not sent, cause they didn't fit into the package that's sent. + + + + Checks the incoming queue and Dispatches received data if possible. + + If a Dispatch happened or not, which shows if more Dispatches might be needed. + + + + Internally uses an operation to exchange encryption keys with the server. + + If the op could be sent. + + + + Gets the currently used settings for the built-in network simulation. + Please check the description of NetworkSimulationSet for more details. + + + + + Core of the Network Simulation, which is available in Debug builds. + Called by a timer in intervals. + + + + EnetPeer will set this value, so trafficstats can use it. TCP has 0 bytes per package extra + + + See PhotonPeer value. + + + See PhotonPeer value. + + + See PhotonPeer value. + + + See PhotonPeer value. + + + + Value range for a Peer's connection and initialization state, as returned by the PeerState property. + + + While this is not the same as the StatusCode of IPhotonPeerListener.OnStatusChanged(), it directly relates to it. + In most cases, it makes more sense to build a game's state on top of the OnStatusChanged() as you get changes. + + + + The peer is disconnected and can't call Operations. Call Connect(). + + + The peer is establishing the connection: opening a socket, exchanging packages with Photon. + + + The connection is established and now sends the application name to Photon. + You set the "application name" by calling PhotonPeer.Connect(). + + + The peer is connected and initialized (selected an application). You can now use operations. + + + The peer is disconnecting. It sent a disconnect to the server, which will acknowledge closing the connection. + + + + These are the options that can be used as underlying transport protocol. + + + + Use UDP to connect to Photon, which allows you to send operations reliable or unreliable on demand. + + + Use TCP to connect to Photon. + + + A TCP-based protocol commonly supported by browsers.For WebGL games mostly. Note: No WebSocket IPhotonSocket implementation is in this Assembly. + This protocol is only available in Unity exports to WebGL. + + + A TCP-based, encrypted protocol commonly supported by browsers. For WebGL games mostly. Note: No WebSocket IPhotonSocket implementation is in this Assembly. + This protocol is only available in Unity exports to WebGL. + + + + Level / amount of DebugReturn callbacks. Each debug level includes output for lower ones: OFF, ERROR, WARNING, INFO, ALL. + + + + No debug out. + + + Only error descriptions. + + + Warnings and errors. + + + Information about internal workflows, warnings and errors. + + + Most complete workflow description (but lots of debug output), info, warnings and errors. + + + Build target framework supported by this dll. + + + + Instances of the PhotonPeer class are used to connect to a Photon server and communicate with it. + + + A PhotonPeer instance allows communication with the Photon Server, which in turn distributes messages + to other PhotonPeer clients. + An application can use more than one PhotonPeer instance, which are treated as separate users on the + server. Each should have its own listener instance, to separate the operations, callbacks and events. + + + + + No effect anymore. Removed without replacement. + + + This value was used to get/set the initial capacities of command-lists. + These grow on demand but knowing their capacity is of very limited use. + Also, various command-lists grow their capacity independent from one another. + + + + + No effect anymore. Removed without replacement. + + + This was used to skip some received (and buffered) unreliable commands, to avoid situations + where the peer has aggregated a lot of (old) messages. + + + + + The WarningSize was used test all message queues for congestion. + + + + + Gets a local timestamp in milliseconds by calling SupportClass.GetTickCount(). + See LocalMsTimestampDelegate. + + + + Where dynamic linking is available, this library will attempt to load a native Photon "Encryptor" plugin library for "Datagram Encryption". + Fallback to a managed implementation. This value is always true. + + + Obsolete and ignored. Size of CommandLog. Default is 0, no logging. + + + Obsolete and ignored. Converts the CommandLog into a readable table-like string with summary. + + + False if this library build contains C# Socket code. If true, you must set some type as SocketImplementation before connecting. + + + True if the library was compiled with DEBUG setting. + + + Version of the Native Encryptor API compiled into this assembly. Defines which PhotonEncryptorPlugin needs to be used. + + + Target framework this dll was built for. + + + Global toggle to avoid callbacks from native plugins. Defaults to false, meaning: "callbacks enabled". + Callbacks from native code will fail on some platforms, which is why you can disable them. + + + Can be used to remove/hide the AppId from websocket connect paths. + + + A simplified identifier for client SDKs. Photon's APIs might modify this (as a dll can be used in more than one product). Helps debugging. + + + For the Init-request, we shift the ClientId by one and the last bit signals a "debug" (0) or "release" build (1). + + + Version of this library as string. + + + Checks if a native library for network sockets (PhotonSocketPlugin.dll) is available. To use it, see remarks. + + When the native socket library is available, the SocketNative class may be used as socket implementation. + + If the SocketImplementationConfig is null, the SocketNative class is assigned for UDP, TCP and WebSocket. + + Alternatively the type SocketNative (or other) can be assigend in the SocketImplementationConfig. + + The SocketNative class in this assembly is compiled for dynamic linking. + A class "SocketNativeSource" can be made available for you to compile it along with your source for + platforms that use static linking (e.g. for iOS and some consoles). + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + Checks if native library for Payload Encryption (PhotonCryptoPlugin.dll) is available. Used automatically. + + While the encryptor Type for Datagram Encryption can be defined, Payload Encryption + will always use built-in types as encryptor. + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + Checks if a native library for Datagram Encryption is available. To use it, see remarks. + + If the PhotonPeer.EncryptorType is set, this type is used as implementation for Datagram Encryption. + If it's not set, a native plugin is used if available. As fallback, a managed implementation is being used. + + Note: The native plugin is performing much better than the managed alternatives. + This is why we make the plugin available for various platforms. + + Note: Native libraries must match the execution platform. + Even if the native plugin is found it may fail to execute. + + + + + Checks availability and completeness of native libs and sets respective "available" values. + + + + Enables selection of a (Photon-)serialization protocol. Used in Connect methods. + Defaults to SerializationProtocol.GpBinaryV16; + + + Optional definition of IPhotonSocket type per ConnectionProtocol. + + Several platforms have special Socket implementations and slightly different APIs. + To accomodate this, switching the socket implementation for a network protocol was made available. + By default, UDP and TCP have socket implementations assigned. + + If a native socket plugin is available (see: PhotonPeer.NativeSocketLibAvailable), the SocketNative + class is used by default (with dynamic linking). + + You only need to set the SocketImplementationConfig once, after creating a PhotonPeer + and before connecting. If you switch the TransportProtocol, the correct implementation is being used. + + + + + Can be used to read the IPhotonSocket implementation at runtime (before connecting). + + + Use the SocketImplementationConfig to define which IPhotonSocket is used per ConnectionProtocol. + + + + + Sets the level (and amount) of debug output provided by the library. + + + This affects the callbacks to IPhotonPeerListener.DebugReturn. + Default Level: Error. + + + + + Gets the IPhotonPeerListener of this instance (set in constructor). + Can be used in derived classes for Listener.DebugReturn(). + + + + + Called when the client received a Disconnect Message from the server. Signals an error and provides a message to debug the case. + + + + + Option to make the PhotonPeer reuse a single EventData instance for all incoming events. + + + This reduces memory garbage. + If enabled, the event provided via OnEvent(EventData photonEvent) is invalid once the callback finished. + That event's content will get modified. Typically this is not a problem as events are rarely cached. + + Changing this value acquires the same lock that DispatchIncomingCommands() uses. + + + + + Enables a deserialization optimization for incoming events. Defaults to false. + + + When enabled, byte-arrays in incoming Photon events are deserialized into pooled ByteArraySlice instances (wrappers for byte[]). + This improves the memory footprint for receiving byte-arrays in events. + + When used, you have to release the (pooled) ByteArraySlice instances. + + Adjust your handling of EventData accordingly: + + The ByteArraySlice.Buffer will usually be bigger than the send/received byte-array. + Check the ByteArraySlice.Count and read only the actually received bytes. + The Buffer is reused and not cleared. The Offset will be 0 for incoming events. + + Important: + While the peer will acquire the ByteArraySlice and passes it to OnEvent, the game code has to call ByteArraySlice.Release() + when the slice is no longer needed. + + Send either byte[], ArraySegment or use the ByteArraySlicePool to acquire ByteArraySlices to send. + + + + + Instance of a ByteArraySlicePool. UseByteArraySlicePoolForEvents defines if this PhotonPeer is using the pool for deserialization of byte[] in Photon events. + + ByteArraySlice is a serializable datatype of the Photon .Net client library. + It helps avoid allocations by being pooled and (optionally) used in incoming Photon events (see: UseByteArraySlicePoolForEvents). + + You can also use the pool to acquire ByteArraySlice instances for serialization. + RaiseEvent will auto-release all ByteArraySlice instances passed in. + + + + + This debug setting enables a new send-ordering for commands. Defaults to true and commands are sent in the order they are created. Set to false to use Enet ordering. + + + + + Gets count of all bytes coming in (including headers, excluding UDP/TCP overhead) + + + + + Gets count of all bytes going out (including headers, excluding UDP/TCP overhead) + + + + + Gets the size of the dispatched event or operation-result in bytes. + This value is set before OnEvent() or OnOperationResponse() is called (within DispatchIncomingCommands()). + + + Get this value directly in OnEvent() or OnOperationResponse(). Example: + void OnEvent(...) { + int eventSizeInBytes = this.peer.ByteCountCurrentDispatch; + //... + + void OnOperationResponse(...) { + int resultSizeInBytes = this.peer.ByteCountCurrentDispatch; + //... + + + + Returns the debug string of the event or operation-response currently being dispatched or string. Empty if none. + In a release build of the lib, this will always be empty. + + + + Gets the size of the last serialized operation call in bytes. + The value includes all headers for this single operation but excludes those of UDP, Enet Package Headers and TCP. + + + Get this value immediately after calling an operation. + Example: + + this.loadbalancingClient.OpJoinRoom("myroom"); + int opjoinByteCount = this.loadbalancingClient.ByteCountLastOperation; + + + + If set, the TrafficRecorder will be used to capture all traffic. + + If null or not Enabled, the recorder is not being used. + Release builds of this library will never record traffic for performance reasons. + + See ITrafficRecorder docs. + + + + + Debugging option to tell the Photon Server to log all datagrams. + + + + + Up to 4 resend attempts for a reliable command can be done in quick succession (after RTT+4*Variance). + + + By default 0. Any later resend attempt will then double the time before the next resend. + Max value = 4; + Make sure to adjust SentCountAllowance to a slightly higher value, as more repeats will get done. + + + + + This is the (low level) state of the connection to the server of a PhotonPeer. Managed internally and read-only. + + + Don't mix this up with the StatusCode provided in IPhotonListener.OnStatusChanged(). + Applications should use the StatusCode of OnStatusChanged() to track their state, as + it also covers the higher level initialization between a client and Photon. + + + + + This peer's ID as assigned by the server or 0 if not using UDP. Will be 0xFFFF before the client connects. + + Used for debugging only. This value is not useful in everyday Photon usage. + + + + Count of all currently received but not-yet-Dispatched reliable commands + (events and operation results) from all channels. + + + + + Count of all commands currently queued as outgoing, including all channels and reliable, unreliable. + + + + + Sets a new (temporary) size of the MessageBufferPool to reuse memory where possible. + + + The MessageBufferPool is a Queue<StreamBuffer> for performance reasons. + This methods dequeues from the MessageBufferPool to get the Count equal to countOfBuffers, + then it calls MessageBufferPool.TrimExcess(). + + New size of the pool. Clears the pool if <= 0. + + + + Gets / sets the number of channels available in UDP connections with Photon. + Photon Channels are only supported for UDP. + The default ChannelCount is 2. Channel IDs start with 0 and 255 is a internal channel. + + + + + Enables the client so send the "encrypted" flag on secure connections. Incompatible with Server SDK 4.x. + + + + + While not connected, this controls if the next connection(s) should use a per-package CRC checksum. + + + While turned on, the client and server will add a CRC checksum to every sent package. + The checksum enables both sides to detect and ignore packages that were corrupted during transfer. + Corrupted packages have the same impact as lost packages: They require a re-send, adding a delay + and could lead to timeouts. + + Building the checksum has a low processing overhead but increases integrity of sent and received data. + Packages discarded due to failed CRC cecks are counted in PhotonPeer.PacketLossByCrc. + + + + + Count of packages dropped due to failed CRC checks for this connection. + + + + + + Count of packages dropped due to wrong challenge for this connection. + + + + + Gets the count of sent but not yet acknowledged commands (for UDP connections). + + + + + Count of commands that got repeated (due to local repeat-timing before an ACK was received). + + + + + Number of send retries before a peer is considered lost/disconnected. Default: 7. + + + The initial timeout countdown of a command is calculated by the current roundTripTime + 4 * roundTripTimeVariance. + Please note that the timeout span until a command will be resent is not constant, but based on + the roundtrip time at the initial sending, which will be doubled with every failed retry. + + DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the + client first, depending on the values and Roundtrip Time. + + + + + Caps the initial timing for repeats of reliable commands. In milliseconds. Default: 400ms. + + + Unless acknowledged, reliable commands are repeated initially after: current roundTripTime + 4 * roundTripTimeVariance. + + As this value can be very high when there was exceptional lag, InitialResendTimeMax makes sure that commands + get repeated several times before they may trigger a timeout. + + + + + Sets the time between pings being sent automatically. They measure the roundtrip time and keep connections from closing. Default: 1000. + + + For Photon's reliable UDP connections, pings are skipped if any reliable command was sent during the specified TimePingInterval. + Any reliable command is used to update the RoundTripTime and RoundTripTimeVariance. + + When using TCP and WebSockets, the ping is of interest to measure the roundtrip and to keep a connection open, should nothing else + With those two protocols, the ping is used to update the RoundTripTime and RoundTripTimeVariance. + + + + + Time in milliseconds before any sent reliable command triggers a timeout disconnect, unless acknowledged by the receiver. Default: 10000. + + + DisconnectTimeout is not an exact value for a timeout. The exact timing of the timeout depends on the frequency + of Service() calls and the roundtrip time. Commands sent with long roundtrip-times and variance are checked less + often for re-sending. + + DisconnectTimeout and SentCountAllowance are competing settings: either might trigger a disconnect on the + client first, depending on the values and Roundtrip Time. + + Default: 10000 ms. Maximum setting: 65535. + Setting a negative value will apply the default timeout. + + + + + Approximated Environment.TickCount value of server (while connected). + + + UDP: The server's timestamp is automatically fetched after connecting (once). This is done + internally by a command which is acknowledged immediately by the server. + TCP: The server's timestamp fetched with each ping but set only after connecting (once). + + The approximation will be off by +/- 10ms in most cases. Per peer/client and connection, the + offset will be constant (unless FetchServerTimestamp() is used). A constant offset should be + better to adjust for. Unfortunately there is no way to find out how much the local value + differs from the original. + + The approximation adds RoundtripTime / 2 and uses this.LocalTimeInMilliSeconds to calculate + in-between values (this property returns a new value per tick). + + The value sent by Photon equals Environment.TickCount in the logic layer. + + + 0 until connected. + While connected, the value is an approximation of the server's current timestamp. + + + + + This setter for the (local-) timestamp delegate replaces the default Environment.TickCount with any equal function. + + + About Environment.TickCount: + The value of this property is derived from the system timer and is stored as a 32-bit signed integer. + Consequently, if the system runs continuously, TickCount will increment from zero to Int32..::.MaxValue + for approximately 24.9 days, then jump to Int32..::.MinValue, which is a negative number, then increment + back to zero during the next 24.9 days. + + Exception is thrown peer.PeerState is not PS_DISCONNECTED. + + + The internally used "per connection" time value, which is updated infrequently, when the library executes some connectio-related tasks. + + This integer value is an infrequently updated value by design. + The lib internally sets the value when it sends outgoing commands or reads incoming packages. + This is based on SupportClass.GetTickCount() and an initial time value per (server) connection. + This value is also used in low level Enet commands as sent time and optional logging. + + + + The last ConnectionTime value, when some ACKs were sent out by this client. + Only applicable to UDP connections. + + + The last ConnectionTime value, when SendOutgoingCommands actually checked outgoing queues to send them. Must be connected. + Available for UDP and TCP connections. + + + Measures the maximum milliseconds spent in PhotonSocket.Send(). + + + Time until a reliable command is acknowledged by the server. + + The value measures network latency and for UDP it includes the server's ACK-delay (setting in config). + In TCP, there is no ACK-delay, so the value is slightly lower (if you use default settings for Photon). + + RoundTripTime is updated constantly. Every reliable command will contribute a fraction to this value. + + This is also the approximate time until a raised event reaches another client or until an operation + result is available. + + + + + Changes of the roundtriptime as variance value. Gives a hint about how much the time is changing. + + + + The last measured roundtrip time for this connection. + + + + Timestamp of the last time anything (!) was received from the server (including low level Ping, ACKs, events and operation-returns). + + + This is not the time when something was dispatched. If you enable NetworkSimulation, this value is affected as well. + + + + + The server address which was used in PhotonPeer.Connect() or null (before Connect() was called). + + + + Contains the IP address of the previously resolved ServerAddress (or empty, if address wasn't resolved with the internal methods). + + + The protocol this peer is currently connected/connecting with (or 0). + + + This is the transport protocol to be used for next connect (see remarks). + The TransportProtocol can be changed anytime but it will not change the + currently active connection. Instead, TransportProtocol will be applied on next Connect. + + + + + Gets or sets the network simulation "enabled" setting. + Changing this value also locks this peer's sending and when setting false, + the internally used queues are executed (so setting to false can take some cycles). + + + + + Gets the settings for built-in Network Simulation for this peer instance + while IsSimulationEnabled will enable or disable them. + Once obtained, the settings can be modified by changing the properties. + + + + + Defines the initial size of an internally used StreamBuffer for Tcp. + The StreamBuffer is used to aggregate operation into (less) send calls, + which uses less resoures. + + + The size is not restricing the buffer and does not affect when outgoing data is actually sent. + + + + + The Maximum Trasfer Unit (MTU) defines the (network-level) packet-content size that is + guaranteed to arrive at the server in one piece. The Photon Protocol uses this + size to split larger data into packets and for receive-buffers of packets. + + + This value affects the Packet-content. The resulting UDP packages will have additional + headers that also count against the package size (so it's bigger than this limit in the end) + Setting this value while being connected is not allowed and will throw an Exception. + Minimum is 576. Huge values won't speed up connections in most cases! + + + + + This property is set internally, when OpExchangeKeysForEncryption successfully finished. + While it's true, encryption can be used for operations. + + + + + While true, the peer will not send any other commands except ACKs (used in UDP connections). + + + + Defines if Key Exchange for Encryption is done asynchronously in another thread. + + + Indicates if sequence numbers should be randomized. + + + Initialization array, used to modify the sequence numbers of channels. + + + If GCM is used for DatagramEncryption. + If true, the randomization-value gets added to the current value, else (CBC/old style) the randomization-value replaces the current value. + + + + Gets the byte-count of incoming "low level" messages, which are either Enet Commands or Tcp Messages. + These include all headers, except those of the underlying internet protocol Udp or Tcp. + + + + + Gets the byte-count of outgoing "low level" messages, which are either Enet Commands or Tcp Messages. + These include all headers, except those of the underlying internet protocol Udp or Tcp. + + + + + Gets a statistic of incoming and outgoing traffic, split by operation, operation-result and event. + + + Operations are outgoing traffic, results and events are incoming. + Includes the per-command header sizes (Udp: Enet Command Header or Tcp: Message Header). + + + + + Returns the count of milliseconds the stats are enabled for tracking. + + + + + Enables or disables collection of statistics in TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel. + + + Setting this to true, also starts the stopwatch to measure the timespan the stats are collected. + Enables the traffic statistics of a peer: TrafficStatsIncoming, TrafficStatsOutgoing and TrafficstatsGameLevel (nothing else). + Default value: false (disabled). + + + + + Creates new instances of TrafficStats and starts a new timer for those. + + + + + Returns a string of the most interesting connection statistics. + When you have issues on the client side, these might contain hints about the issue's cause. + + If true, Incoming and Outgoing low-level stats are included in the string. + Stats as string. + + + Implements the message-protocol, based on the underlying network protocol (udp, tcp, http). + + + PayloadEncryption Secret. Message payloads get encrypted with it individually and on demand. + + + Setter for the Datagram Encryptor instance. Used at next connect. + + If null, the PhotonPeer will create a default encryptor instance, which may be native or managed. + See also: PhotonPeer.NativeDatagramEncryptionLibAvailable. + + + + The datagram encryptor used for the current connection. Applied internally in InitDatagramEncryption. + + + Count of unreliable commands being discarded in case this client already dispatched a command that was newer (higher sequence number). + + + Set per dispatch in DispatchIncomingCommands to: commandUnreliableSequenceNumber - channel.incomingUnreliableSequenceNumber. Indicates how big the (sequence)gap is, compared to the last dispatched unreliable command. + + + Creates a new PhotonPeer with specified transport protocol (without a IPhotonPeerListener). + Make sure to set the Listener, before using the peer. + + + + Creates a new PhotonPeer instance to communicate with Photon and selects the transport protocol. We recommend UDP. + + a IPhotonPeerListener implementation + Protocol to use to connect to Photon. + + + + Starts connecting to the given Photon server. Non-blocking. + + + Connecting to the Photon server is done asynchronous. + Unless an error happens right away (and this returns false), wait for the call of IPhotonPeerListener.OnStatusChanged. + + + Address of a Photon server as IP:port or hostname. WebSocket connections must contain a scheme (ws:// or wss://). + + + The ID of the app to use. Typically this is a guid (for the Photon Cloud). Max 32 characters. + + + Optional custom data to be used by server during peer creation. + If used for authentication, the server is able to reject a client without creating a peer. + Must be a serializable data type of Photon. + + Custom data to send to the server in the Init request. Might be used to identify a client / user. + + True if a connection attempt will be made. False if some error could be detected early-on. + + + + + Starts connecting to the given Photon server. Non-blocking. + + + Connecting to the Photon server is done asynchronous. + Unless an error happens right away (and this returns false), wait for the call of IPhotonPeerListener.OnStatusChanged. + + + Address of a Photon server as IP:port or hostname. WebSocket connections must contain a scheme (ws:// or wss://). + + + Optional address of a proxy server. Only used by WebSocket connections. Set null to use none. + + + The ID of the app to use. Typically this is a guid (for the Photon Cloud). Max 32 characters. + + + Optional Photon token data to be used by server during peer creation. + If used for authentication, the server is able to reject a client without creating a peer. + Must be of type string or byte[] (as provided by server). + + Custom data to send to the server in the Init request. Might be used to identify a client / user. + + True if a connection attempt will be made. False if some error could be detected early-on. + + + + + This method initiates a mutual disconnect between this client and the server. + + + Calling this method does not immediately close a connection. Disconnect lets the server + know that this client is no longer listening. For the server, this is a much faster way + to detect that the client is gone but it requires the client to send a few final messages. + + On completion, OnStatusChanged is called with the StatusCode.Disconnect. + + If the client is disconnected already or the connection thread is stopped, then there is no callback. + + The default server logic will leave any joined game and trigger the respective event. + + + + + This method immediately closes a connection (pure client side) and ends related listening Threads. + + + Unlike Disconnect, this method will simply stop to listen to the server. Udp connections will timeout. + If the connections was open, this will trigger a callback to OnStatusChanged with code StatusCode.Disconnect. + + + + + This will fetch the server's timestamp and update the approximation for property ServerTimeInMilliseconds. + + + The server time approximation will NOT become more accurate by repeated calls. Accuracy currently depends + on a single roundtrip which is done as fast as possible. + + The command used for this is immediately acknowledged by the server. This makes sure the roundtrip time is + low and the timestamp + rountriptime / 2 is close to the original value. + + + + + This method creates a public key for this client and exchanges it with the server. + + + Encryption is not instantly available but calls OnStatusChanged when it finishes. + Check for StatusCode EncryptionEstablished and EncryptionFailedToEstablish. + + Calling this method sets IsEncryptionAvailable to false. + This method must be called before the "encrypt" parameter of OpCustom can be used. + + If operation could be enqueued for sending + + + + Initializes Datagram Encryption. Optionally, the EncryptorType is being used, if set. + + secret used to cipher udp packets + secret used for authentication of udp packets + + + + Photon's Payload Encryption secret may be set by a response from the server. + + The secret in form of a byte[]. + + + + This method excutes DispatchIncomingCommands and SendOutgoingCommands in your application Thread-context. + + + The Photon client libraries are designed to fit easily into a game or application. The application + is in control of the context (thread) in which incoming events and responses are executed and has + full control of the creation of UDP/TCP packages. + + Sending packages and dispatching received messages are two separate tasks. Service combines them + into one method at the cost of control. It calls DispatchIncomingCommands and SendOutgoingCommands. + + Call this method regularly (2..20 times a second). + + This will Dispatch ANY remaining buffered responses and events AND will send queued outgoing commands. + Fewer calls might be more effective if a device cannot send many packets per second, as multiple + operations might be combined into one package. + + + You could replace Service by: + + while (DispatchIncomingCommands()); //Dispatch until everything is Dispatched... + SendOutgoingCommands(); //Send a UDP/TCP package with outgoing messages + + + + + + + Creates and sends a UDP/TCP package with outgoing commands (operations and acknowledgements). Also called by Service(). + + + As the Photon library does not create any UDP/TCP packages by itself. Instead, the application + fully controls how many packages are sent and when. A tradeoff, an application will + lose connection, if it is no longer calling SendOutgoingCommands or Service. + + If multiple operations and ACKs are waiting to be sent, they will be aggregated into one + package. The package fills in this order: + ACKs for received commands + A "Ping" - only if no reliable data was sent for a while + Starting with the lowest Channel-Nr: + Reliable Commands in channel + Unreliable Commands in channel + + This gives a higher priority to lower channels. + + A longer interval between sends will lower the overhead per sent operation but + increase the internal delay (which adds "lag"). + + Call this 2..20 times per second (depending on your target platform). + + The if commands are not yet sent. Udp limits it's package size, Tcp doesnt. + + + + Dispatching received messages (commands), causes callbacks for events, responses and state changes within a IPhotonPeerListener. + + + DispatchIncomingCommands only executes a single received + command per call. If a command was dispatched, the return value is true and the method + should be called again. + + This method is called by Service() until currently available commands are dispatched. + In general, this method should be called until it returns false. In a few cases, it might + make sense to pause dispatching (if a certain state is reached and the app needs to load + data, before it should handle new events). + + The callbacks to the peer's IPhotonPeerListener are executed in the same thread that is + calling DispatchIncomingCommands. This makes things easier in a game loop: Event execution + won't clash with painting objects or the game logic. + + + + + Prepares your operation (code and parameters) to be sent to the Photon Server with specified SendOptions. + + + This method serializes and enqueues the operation right away while the actual sending happens later. + To be able to aggregate operations/messages, the Photon client sends packages only when you call SendOutgoingCommands(). + + The sendOptions specify how the operation gets sent exactly. + Keep in mind that some transport protocols don't support unreliable or unsequenced transport. + In that case, the sendOptions might be ignored. + + The operationCode must be known by the server's logic or won't be processed. + In almost all cases, sending an operation will result in a OperationResponse (see: IPhotonPeerListener.OnOperationResponse). + + Operations are handled by their byte\-typed code. The codes are defined in the Realtime API (a.k.a. LoadBalancing API). + Containing parameters as key\-value pair. The key is byte\-typed, while the value is any serializable datatype. + Wraps up DeliveryMode (reliability), Encryption and Channel values for sending. + If operation could be enqueued for sending. + + + + Registers new types/classes for de/serialization and the fitting methods to call for this type. + + + SerializeMethod and DeserializeMethod are complementary: Feed the product of serializeMethod to + the constructor, to get a comparable instance of the object. + + After registering a Type, it can be used in events and operations and will be serialized like + built-in types. + + Type (class) to register. + A byte-code used as shortcut during transfer of this Type. + Method delegate to create a byte[] from a customType instance. + Method delegate to create instances of customType's from byte[]. + If the Type was registered successfully. + + + + Container for an Operation request, which is a code and parameters. + + + On the lowest level, Photon only allows byte-typed keys for operation parameters. + The values of each such parameter can be any serializable datatype: byte, int, hashtable and many more. + + + + Byte-typed code for an operation - the short identifier for the server's method to call. + + + The parameters of the operation - each identified by a byte-typed code in Photon. + + + + Contains the server's response for an operation called by this peer. + The indexer of this class actually provides access to the Parameters Dictionary. + + + The OperationCode defines the type of operation called on Photon and in turn also the Parameters that + are set in the request. Those are provided as Dictionary with byte-keys. + There are pre-defined constants for various codes defined in the LoadBalancing application. + Check: OperationCode, ParameterCode, etc. + + An operation's request is summarized by the ReturnCode: a short typed code for "Ok" or + some different result. The code's meaning is specific per operation. An optional DebugMessage can be + provided to simplify debugging. + + Each call of an operation gets an ID, called the "invocID". This can be matched to the IDs + returned with any operation calls. This way, an application could track if a certain OpRaiseEvent + call was successful. + + + + The code for the operation called initially (by this peer). + Use enums or constants to be able to handle those codes, like OperationCode does. + + + A code that "summarizes" the operation's success or failure. Specific per operation. 0 usually means "ok". + + + An optional string sent by the server to provide readable feedback in error-cases. Might be null. + + + A Dictionary of values returned by an operation, using byte-typed keys per value. + + + + Alternative access to the Parameters, which wraps up a TryGetValue() call on the Parameters Dictionary. + + The byte-code of a returned value. + The value returned by the server, or null if the key does not exist in Parameters. + + + ToString() override. + Relatively short output of OpCode and returnCode. + + + Extensive output of operation results. + To be used in debug situations only, as it returns a string for each value. + + + A Photon Event consists of a Code value and a Parameters Dictionary with the event's content (if any). + + The indexer of this class provides access to the values in Parameters. + It wraps the null check for Parameters and uses TryGetValue() for the provided key. + + Photon servers use events to send information which is not triggered by a client's operation requests (those get responses). + The Realtime API allows you to send custom events with any Code and content via OpRaiseEvent. + + + + The event code identifies the type of event. + + + The Parameters of an event is a Dictionary<byte, object>. + + + + Access to the Parameters of a Photon-defined event. Custom Events only use Code, Sender and CustomData. + + The key byte-code of a Photon event value. + The Parameters value, or null if the key does not exist in Parameters. + + + + Defines the event key containing the Sender of the event. + + + Defaults to Sender key of Realtime API events (RaiseEvent): 254. + Can be set to Chat API's ChatParameterCode.Sender: 5. + + + + + Accesses the Sender of the event via the indexer and SenderKey. The result is cached. + + + Accesses this event's Parameters[CustomDataKey], which may be null. + In that case, this returns 0 (identifying the server as sender). + + + + + Defines the event key containing the Custom Data of the event. + + + Defaults to Data key of Realtime API events (RaiseEvent): 245. + Can be set to any other value on demand. + + + + + Accesses the Custom Data of the event via the indexer and CustomDataKey. The result is cached. + + + Accesses this event's Parameters[CustomDataKey], which may be null. + + + + ToString() override. + Short output of "Event" and it's Code. + + + Extensive output of the event content. + To be used in debug situations only, as it returns a string for each value. + + + + Type of serialization methods to add custom type support. + Use PhotonPeer.ReisterType() to register new types with serialization and deserialization methods. + + The method will get objects passed that were registered with it in RegisterType(). + Return a byte[] that resembles the object passed in. The framework will surround it with length and type info, so don't include it. + + + Serialization method delegate. StreamBuffer based custom serialization methods must use this form. + + + + Type of deserialization methods to add custom type support. + Use PhotonPeer.RegisterType() to register new types with serialization and deserialization methods. + + The framwork passes in the data it got by the associated SerializeMethod. The type code and length are stripped and applied before a DeserializeMethod is called. + Return a object of the type that was associated with this method through RegisterType(). + + + Deserialization method delegate. StreamBuffer based custom deserialization methods must use this form. + + + + Provides tools for the Exit Games Protocol + + + + + Serialize creates a byte-array from the given object and returns it. + + The object to serialize + The serialized byte-array + + + + Deserialize returns an object reassembled from the given byte-array. + + The byte-array to be Deserialized + The Deserialized object + + + + Serializes a short typed value into a byte-array (target) starting at the also given targetOffset. + The altered offset is known to the caller, because it is given via a referenced parameter. + + The short value to be serialized + The byte-array to serialize the short to + The offset in the byte-array + + + + Serializes an int typed value into a byte-array (target) starting at the also given targetOffset. + The altered offset is known to the caller, because it is given via a referenced parameter. + + The int value to be serialized + The byte-array to serialize the short to + The offset in the byte-array + + + + Serializes an float typed value into a byte-array (target) starting at the also given targetOffset. + The altered offset is known to the caller, because it is given via a referenced parameter. + + The float value to be serialized + The byte-array to serialize the short to + The offset in the byte-array + + + + Deserialize fills the given int typed value with the given byte-array (source) starting at the also given offset. + The result is placed in a variable (value). There is no need to return a value because the parameter value is given by reference. + The altered offset is this way also known to the caller. + + The int value to deserialize into + The byte-array to deserialize from + The offset in the byte-array + + + + Deserialize fills the given short typed value with the given byte-array (source) starting at the also given offset. + The result is placed in a variable (value). There is no need to return a value because the parameter value is given by reference. + The altered offset is this way also known to the caller. + + The short value to deserialized into + The byte-array to deserialize from + The offset in the byte-array + + + + Deserialize fills the given float typed value with the given byte-array (source) starting at the also given offset. + The result is placed in a variable (value). There is no need to return a value because the parameter value is given by reference. + The altered offset is this way also known to the caller. + + The float value to deserialize + The byte-array to deserialize from + The offset in the byte-array + + + + Exit Games GpBinaryV16 protocol implementation + + + + + The gp type. + + + + + Unkown type. + + + + + An array of objects. + + + This type is new in version 1.5. + + + + + A boolean Value. + + + + + A byte value. + + + + + An array of bytes. + + + + + An array of objects. + + + + + A 16-bit integer value. + + + + + A 32-bit floating-point value. + + + This type is new in version 1.5. + + + + + A dictionary + + + This type is new in version 1.6. + + + + + A 64-bit floating-point value. + + + This type is new in version 1.5. + + + + + A Hashtable. + + + + + A 32-bit integer value. + + + + + An array of 32-bit integer values. + + + + + A 64-bit integer value. + + + + + A string value. + + + + + An array of string values. + + + + + A custom type. 0x63 + + + + + Null value don't have types. + + + + + Calls the correct serialization method for the passed object. + + + + + DeserializeInteger returns an Integer typed value from the given stream. + + + + Exception type for de/serialization issues. Used in Protocol 1.8. + + + Constructor for the exception. + + + Unkown. GpType: 0. + + + Boolean. GpType: 2. See: BooleanFalse, BooleanTrue. + + + Byte. GpType: 3. + + + Short. GpType: 4. + + + 32-bit floating-point value. GpType: 5. + + + 64-bit floating-point value. GpType: 6. + + + String. GpType: 7. + + + Null value don't have types. GpType: 8. + + + CompressedInt. GpType: 9. + + + CompressedLong. GpType: 10. + + + Int1. GpType: 11. + + + Int1_. GpType: 12. + + + Int2. GpType: 13. + + + Int2_. GpType: 14. + + + L1. GpType: 15. + + + L1_. GpType: 16. + + + L2. GpType: 17. + + + L2_. GpType: 18. + + + Custom Type. GpType: 19. + + + Custom Type Slim. GpType: 128 (0x80) and up. + + + Dictionary. GpType: 20. + + + Hashtable. GpType: 21. + + + ObjectArray. GpType: 23. + + + OperationRequest. GpType: 24. + + + OperationResponse. GpType: 25. + + + EventData. GpType: 26. + + + Boolean False. GpType: 27. + + + Boolean True. GpType: 28. + + + ShortZero. GpType: 29. + + + IntZero. GpType: 30. + + + LongZero. GpType: 3. + + + FloatZero. GpType: 32. + + + DoubleZero. GpType: 33. + + + ByteZero. GpType: 34. + + + Array for nested Arrays. GpType: 64 (0x40). Element count and type follows. + + + + Writes integers as compressed. Either directly as zigzag-encoded or (when a type is written for this value) it can use an optimized sub-type. + + + + Enum of the three options for reliability and sequencing in Photon's reliable-UDP. + + + The operation/message gets sent just once without acknowledgement or repeat. The sequence (order) of messages is guaranteed. + + + The operation/message asks for an acknowledgment. It's resent until an ACK arrived. The sequence (order) of messages is guaranteed. + + + The operation/message gets sent once (unreliable) and might arrive out of order. Best for your own sequencing (e.g. for streams). + + + The operation/message asks for an acknowledgment. It's resent until an ACK arrived and might arrive out of order. Best for your own sequencing (e.g. for streams). + + + Wraps up DeliveryMode, Encryption and Channel values for sending operations and messages. + + + Default SendOptions instance for reliable sending. + + + Default SendOptions instance for unreliable sending. + + + Chose the DeliveryMode for this operation/message. Defaults to Unreliable. + + + If true the operation/message gets encrypted before it's sent. Defaults to false. + Before encryption can be used, it must be established. Check PhotonPeer.IsEncryptionAvailable is true. + + + The Enet channel to send in. Defaults to 0. + Channels in Photon relate to "message channels". Each channel is a sequence of messages. + + + Sets the DeliveryMode either to true: Reliable or false: Unreliable, overriding any current value. + Use this to conveniently select reliable/unreliable delivery. + + + used by PhotonPeer* + + + Encapsulates the network i/o functionality for the realtime library. + + + used by PhotonPeer* + + + Endless loop, run in Receive Thread. + + + Internal class to encapsulate the network i/o functionality for the realtime libary. + + + used by PhotonPeer* + + + Encapsulates the network i/o functionality for the realtime library. + + + used by PhotonPeer* + + + Endless loop, run in Receive Thread. + + + Internal class to encapsulate the network i/o functionality for the realtime libary. + + + used by PhotonPeer* + + + + Allocates a new byte[] that is the exact used length. Use GetBuffer for nonalloc operations. + + + + + Allocates a new byte[] that is the exact used length. Use GetBuffer for nonalloc operations. + + + + + The bytes between Position and Length are copied to the beginning of the buffer. Length decreased by Position. Position set to 0. + + + + + Brings StreamBuffer to the state as after writing of 'length' bytes. Returned buffer and offset can be used to actually fill "written" segment with data. + + + + + Sets stream length. If current position is greater than specified value, it's set to the value. + + + SetLength(0) resets the stream to initial state but preserves underlying byte[] buffer. + + + + + Guarantees that the buffer is at least neededSize bytes. + + + + + Contains several (more or less) useful static methods, mostly used for debugging. + + + + + Gets the local machine's "milliseconds since start" value (precision is described in remarks). + + + This method uses Environment.TickCount (cheap but with only 16ms precision). + PhotonPeer.LocalMsTimestampDelegate is available to set the delegate (unless already connected). + + Fraction of the current time in Milliseconds (this is not a proper datetime timestamp). + + + + Creates a background thread that calls the passed function in intervals, as long as that returns true. + + + With StopBackgroundCalls, you can stop threads started with this method. + The resulting ThreadAbortException is caught and discarded. + + The function to call. Must return true, if it should be called again. Returning false ends the thread. + Milliseconds to sleep between calls of myThread. Default: 100ms. + An optional name for the task to help debugging. Null or empty won't set the thread.Name. + + + + Calls Abort on the thread with the given id (= index of the thread list) + + + The resulting ThreadAbortException is caught and discarded. + + The unique ID of the thread. + True if the thread is canceled and false otherwise, e.g. if the thread with the given ID does not exist. + + + + Calls Abort on all threads that were started via StartBackgroundCalls. + + + The resulting ThreadAbortException is caught and discarded. + + True if any thread got aborted. + + + + Writes the exception's stack trace to the received stream. + + Exception to obtain information from. + Output sream used to write to. + + + + Writes the exception's stack trace to the received stream. Writes to: System.Diagnostics.Debug. + + Exception to obtain information from. + + + + This method returns a string, representing the content of the given IDictionary. + Returns "null" if parameter is null. + + IDictionary to return as string. + + + + + Converts a byte-array to string (useful as debugging output). + Uses BitConverter.ToString(list) internally after a null-check of list. + + Byte-array to convert to string. + + List of bytes as string. + + + + + Class to wrap static access to the random.Next() call in a thread safe manner. + + + + + An Attribute named "Preserve" tells Unity to not strip the code. + + + + TCP "Package" header: 7 bytes + + + TCP "Message" header: 2 bytes + + + TCP header combined: 9 bytes + + + Defines if the (TCP) socket implementation needs to do "framing". + The WebSocket protocol (e.g.) includes framing, so when that is used, we set DoFraming to false. + + + + Checks the incoming queue and Dispatches received data if possible. Returns if a Dispatch happened or + not, which shows if more Dispatches might be needed. + + + + + gathers commands from all (out)queues until udp-packet is full and sends it! + + + + Sends a ping in intervals to keep connection alive (server will timeout connection if nothing is sent). + Always false in this case (local queues are ignored. true would be: "call again to send remaining data"). + + + enqueues serialized operations to be sent as tcp stream / package + + + Sends a ping and modifies this.lastPingResult to avoid another ping for a while. + + + reads incoming tcp-packages to create and queue incoming commands* + + + + Only in use as long as PhotonPeer.TrafficStatsEnabled = true; + + + + Gets sum of outgoing operations in bytes. + + + Gets count of outgoing operations. + + + Gets sum of byte-cost of incoming operation-results. + + + Gets count of incoming operation-results. + + + Gets sum of byte-cost of incoming events. + + + Gets count of incoming events. + + + + Gets longest time it took to complete a call to OnOperationResponse (in your code). + If such a callback takes long, it will lower the network performance and might lead to timeouts. + + + + Gets OperationCode that causes the LongestOpResponseCallback. See that description. + + + + Gets longest time a call to OnEvent (in your code) took. + If such a callback takes long, it will lower the network performance and might lead to timeouts. + + + + Gets EventCode that caused the LongestEventCallback. See that description. + + + + Gets longest time between subsequent calls to DispatchIncomgingCommands in milliseconds. + Note: This is not a crucial timing for the networking. Long gaps just add "local lag" to events that are available already. + + + + + Gets longest time between subsequent calls to SendOutgoingCommands in milliseconds. + Note: This is a crucial value for network stability. Without calling SendOutgoingCommands, + nothing will be sent to the server, who might time out this client. + + + + + Gets number of calls of DispatchIncomingCommands. + + + + + Gets number of calls of DispatchIncomingCommands. + + + + + Gets number of calls of SendOutgoingCommands. + + + + Gets sum of byte-cost of all "logic level" messages. + + + Gets sum of counted "logic level" messages. + + + Gets sum of byte-cost of all incoming "logic level" messages. + + + Gets sum of counted incoming "logic level" messages. + + + Gets sum of byte-cost of all outgoing "logic level" messages (= OperationByteCount). + + + Gets sum of counted outgoing "logic level" messages (= OperationCount). + + + + Resets the values that can be maxed out, like LongestDeltaBetweenDispatching. See remarks. + + + Set to 0: LongestDeltaBetweenDispatching, LongestDeltaBetweenSending, LongestEventCallback, LongestEventCallbackCode, LongestOpResponseCallback, LongestOpResponseCallbackOpCode. + Also resets internal values: timeOfLastDispatchCall and timeOfLastSendCall (so intervals are tracked correctly). + + + + Gets the byte-size of per-package headers. + + + + Counts commands created/received by this client, ignoring repeats (out command count can be higher due to repeats). + + + + Gets count of bytes as traffic, excluding UDP/TCP headers (42 bytes / x bytes). + + + Timestamp of the last incoming ACK that has been read (every PhotonPeer.TimePingInterval milliseconds this client sends a PING which must be ACKd). + + + Timestamp of last incoming reliable command (every second we expect a PING). + +
+
diff --git a/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml.meta b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml.meta new file mode 100644 index 0000000..b58d8aa --- /dev/null +++ b/Assets/Photon/PhotonLibs/netstandard2.0/Photon3Unity3D.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7015e500cd5b71244af56448dfb59804 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime.meta b/Assets/Photon/PhotonRealtime.meta index e54e75e..5ddf0d6 100644 --- a/Assets/Photon/PhotonRealtime.meta +++ b/Assets/Photon/PhotonRealtime.meta @@ -1,8 +1,9 @@ fileFormatVersion: 2 -guid: 267b3f1822e10034583d8ae12cd03c0c +guid: b54c221855bde4a4ba511877e7b6b904 folderAsset: yes +timeCreated: 1505899913 +licenseType: Store DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime/Code/AppSettings.cs b/Assets/Photon/PhotonRealtime/Code/AppSettings.cs index 33196cd..b19754a 100644 --- a/Assets/Photon/PhotonRealtime/Code/AppSettings.cs +++ b/Assets/Photon/PhotonRealtime/Code/AppSettings.cs @@ -6,11 +6,10 @@ // developer@photonengine.com // ---------------------------------------------------------------------------- -#if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER +#if UNITY_2017_4_OR_NEWER #define SUPPORTED_UNITY #endif - namespace Photon.Realtime { using System; @@ -35,8 +34,10 @@ namespace Photon.Realtime { /// AppId for Realtime or PUN. public string AppIdRealtime; + /// AppId for the Chat Api. public string AppIdChat; + /// AppId for use in the Voice Api. public string AppIdVoice; @@ -52,32 +53,141 @@ namespace Photon.Realtime /// if this IsNullOrEmpty() AND UseNameServer == true, use BestRegion. else, use a server public string FixedRegion; + /// Set to a previous BestRegionSummary value before connecting. + /// + /// This is a value used when the client connects to the "Best Region".
+ /// If this is null or empty, all regions gets pinged. Providing a previous summary on connect, + /// speeds up best region selection and makes the previously selected region "sticky".
+ /// + /// Unity clients should store the BestRegionSummary in the PlayerPrefs. + /// You can store the new result by implementing . + /// If is not null, store this string. + /// To avoid storing the value multiple times, you could set SummaryToCache to null. + ///
+ #if SUPPORTED_UNITY + [NonSerialized] + #endif + public string BestRegionSummaryFromStorage; + /// The address (hostname or IP) of the server to connect to. public string Server; + /// If not null, this sets the port of the first Photon server to connect to (that will "forward" the client as needed). public int Port; + + /// The address (hostname or IP and port) of the proxy server. + public string ProxyServer; + /// The network level protocol to use. public ConnectionProtocol Protocol = ConnectionProtocol.Udp; + /// Enables a fallback to another protocol in case a connect to the Name Server fails. + /// See: LoadBalancingClient.EnableProtocolFallback. + public bool EnableProtocolFallback = true; + + /// Defines how authentication is done. On each system, once or once via a WSS connection (safe). + public AuthModeOption AuthMode = AuthModeOption.Auth; + /// If true, the client will request the list of currently available lobbies. public bool EnableLobbyStatistics; + /// Log level for the network lib. public DebugLevel NetworkLogging = DebugLevel.ERROR; /// If true, the Server field contains a Master Server address (if any address at all). - public bool IsMasterServerAddress { get { return !this.UseNameServer; } } + public bool IsMasterServerAddress + { + get { return !this.UseNameServer; } + } + /// If true, the client should fetch the region list from the Name Server and find the one with best ping. /// See "Best Region" in the online docs. - public bool IsBestRegion { get { return this.UseNameServer && string.IsNullOrEmpty(this.FixedRegion); } } + public bool IsBestRegion + { + get { return this.UseNameServer && string.IsNullOrEmpty(this.FixedRegion); } + } + /// If true, the default nameserver address for the Photon Cloud should be used. - public bool IsDefaultNameServer { get { return this.UseNameServer && string.IsNullOrEmpty(this.Server); } } + public bool IsDefaultNameServer + { + get { return this.UseNameServer && string.IsNullOrEmpty(this.Server); } + } + /// If true, the default ports for a protocol will be used. - public bool IsDefaultPort { get { return this.Port <= 0; } } + public bool IsDefaultPort + { + get { return this.Port <= 0; } + } /// ToString but with more details. public string ToStringFull() { - return string.Format("IsBestRegion: {0} IsDefaultNameServer: {1} IsDefaultPort: {2}", this.IsBestRegion, this.IsDefaultNameServer, this.IsDefaultPort); + return string.Format( + "appId {0}{1}{2}{3}" + + "use ns: {4}, reg: {5}, {9}, " + + "{6}{7}{8}" + + "auth: {10}", + String.IsNullOrEmpty(this.AppIdRealtime) ? string.Empty : "rt: " + this.HideAppId(this.AppIdRealtime) + ", ", + String.IsNullOrEmpty(this.AppIdChat) ? string.Empty : "chat: " + this.HideAppId(this.AppIdChat) + ", ", + String.IsNullOrEmpty(this.AppIdVoice) ? string.Empty : "voice: " + this.HideAppId(this.AppIdVoice) + ", ", + String.IsNullOrEmpty(this.AppVersion) ? string.Empty : "appV: " + this.AppVersion + ", ", + this.UseNameServer, + this.IsBestRegion ? "/best/" : this.FixedRegion, + //this.BestRegionSummaryFromStorage, + String.IsNullOrEmpty(this.Server) ? string.Empty : "server: " + this.Server + ", ", + this.IsDefaultPort ? string.Empty : "port: " + this.Port + ", ", + String.IsNullOrEmpty(ProxyServer) ? string.Empty : "proxy: " + this.ProxyServer + ", ", + this.Protocol, + this.AuthMode + //this.EnableLobbyStatistics, + //this.NetworkLogging, + ); + } + + + /// Checks if a string is a Guid by attempting to create one. + /// The potential guid to check. + /// True if new Guid(val) did not fail. + public static bool IsAppId(string val) + { + try + { + new Guid(val); + } + catch + { + return false; + } + + return true; + } + + + private string HideAppId(string appId) + { + return string.IsNullOrEmpty(appId) || appId.Length < 8 + ? appId + : string.Concat(appId.Substring(0, 8), "***"); + } + + public AppSettings CopyTo(AppSettings d) + { + d.AppIdRealtime = this.AppIdRealtime; + d.AppIdChat = this.AppIdChat; + d.AppIdVoice = this.AppIdVoice; + d.AppVersion = this.AppVersion; + d.UseNameServer = this.UseNameServer; + d.FixedRegion = this.FixedRegion; + d.BestRegionSummaryFromStorage = this.BestRegionSummaryFromStorage; + d.Server = this.Server; + d.Port = this.Port; + d.ProxyServer = this.ProxyServer; + d.Protocol = this.Protocol; + d.AuthMode = this.AuthMode; + d.EnableLobbyStatistics = this.EnableLobbyStatistics; + d.NetworkLogging = this.NetworkLogging; + d.EnableProtocolFallback = this.EnableProtocolFallback; + return d; } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonRealtime/Code/ConnectionHandler.cs b/Assets/Photon/PhotonRealtime/Code/ConnectionHandler.cs index d4328fc..4ac39ee 100644 --- a/Assets/Photon/PhotonRealtime/Code/ConnectionHandler.cs +++ b/Assets/Photon/PhotonRealtime/Code/ConnectionHandler.cs @@ -56,6 +56,19 @@ namespace Photon.Realtime #if SUPPORTED_UNITY + #if UNITY_2019_4_OR_NEWER + + /// + /// Resets statics for Domain Reload + /// + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void StaticReset() + { + AppQuits = false; + } + + #endif + /// Keeps the ConnectionHandler, even if a new scene gets loaded. public bool ApplyDontDestroyOnLoad = true; diff --git a/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs b/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs new file mode 100644 index 0000000..5ec33ab --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs @@ -0,0 +1,148 @@ +// ---------------------------------------------------------------------------- +// +// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH +// +// +// Sets up support for Unity-specific types. Can be a blueprint how to register your own Custom Types for sending. +// +// developer@exitgames.com +// ---------------------------------------------------------------------------- + +#if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER +#define SUPPORTED_UNITY +#endif + +#if SUPPORTED_UNITY +namespace Photon.Realtime +{ + using Photon.Realtime; + using ExitGames.Client.Photon; + using UnityEngine; + using Debug = UnityEngine.Debug; + + + /// + /// Internally used class, containing de/serialization methods for various Unity-specific classes. + /// Adding those to the Photon serialization protocol allows you to send them in events, etc. + /// + internal static class CustomTypesUnity + { + /// Register de/serializer methods for Unity specific types. Makes the types usable in RaiseEvent and PUN. + internal static void Register() + { + PhotonPeer.RegisterType(typeof(Vector2), (byte) 'W', SerializeVector2, DeserializeVector2); + PhotonPeer.RegisterType(typeof(Vector3), (byte) 'V', SerializeVector3, DeserializeVector3); + PhotonPeer.RegisterType(typeof(Quaternion), (byte) 'Q', SerializeQuaternion, DeserializeQuaternion); + } + + + #region Custom De/Serializer Methods + + public static readonly byte[] memVector3 = new byte[3 * 4]; + + private static short SerializeVector3(StreamBuffer outStream, object customobject) + { + Vector3 vo = (Vector3) customobject; + + int index = 0; + lock (memVector3) + { + byte[] bytes = memVector3; + Protocol.Serialize(vo.x, bytes, ref index); + Protocol.Serialize(vo.y, bytes, ref index); + Protocol.Serialize(vo.z, bytes, ref index); + outStream.Write(bytes, 0, 3 * 4); + } + + return 3 * 4; + } + + private static object DeserializeVector3(StreamBuffer inStream, short length) + { + Vector3 vo = new Vector3(); + lock (memVector3) + { + inStream.Read(memVector3, 0, 3 * 4); + int index = 0; + Protocol.Deserialize(out vo.x, memVector3, ref index); + Protocol.Deserialize(out vo.y, memVector3, ref index); + Protocol.Deserialize(out vo.z, memVector3, ref index); + } + + return vo; + } + + + public static readonly byte[] memVector2 = new byte[2 * 4]; + + private static short SerializeVector2(StreamBuffer outStream, object customobject) + { + Vector2 vo = (Vector2) customobject; + lock (memVector2) + { + byte[] bytes = memVector2; + int index = 0; + Protocol.Serialize(vo.x, bytes, ref index); + Protocol.Serialize(vo.y, bytes, ref index); + outStream.Write(bytes, 0, 2 * 4); + } + + return 2 * 4; + } + + private static object DeserializeVector2(StreamBuffer inStream, short length) + { + Vector2 vo = new Vector2(); + lock (memVector2) + { + inStream.Read(memVector2, 0, 2 * 4); + int index = 0; + Protocol.Deserialize(out vo.x, memVector2, ref index); + Protocol.Deserialize(out vo.y, memVector2, ref index); + } + + return vo; + } + + + public static readonly byte[] memQuarternion = new byte[4 * 4]; + + private static short SerializeQuaternion(StreamBuffer outStream, object customobject) + { + Quaternion o = (Quaternion) customobject; + + lock (memQuarternion) + { + byte[] bytes = memQuarternion; + int index = 0; + Protocol.Serialize(o.w, bytes, ref index); + Protocol.Serialize(o.x, bytes, ref index); + Protocol.Serialize(o.y, bytes, ref index); + Protocol.Serialize(o.z, bytes, ref index); + outStream.Write(bytes, 0, 4 * 4); + } + + return 4 * 4; + } + + private static object DeserializeQuaternion(StreamBuffer inStream, short length) + { + Quaternion o = new Quaternion(); + + lock (memQuarternion) + { + inStream.Read(memQuarternion, 0, 4 * 4); + int index = 0; + Protocol.Deserialize(out o.w, memQuarternion, ref index); + Protocol.Deserialize(out o.x, memQuarternion, ref index); + Protocol.Deserialize(out o.y, memQuarternion, ref index); + Protocol.Deserialize(out o.z, memQuarternion, ref index); + } + + return o; + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs.meta b/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs.meta new file mode 100644 index 0000000..660c3f0 --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/CustomTypesUnity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c41ee868d8540674982e160cf16e0775 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime/Code/Extensions.cs b/Assets/Photon/PhotonRealtime/Code/Extensions.cs index 3a10776..40511c3 100644 --- a/Assets/Photon/PhotonRealtime/Code/Extensions.cs +++ b/Assets/Photon/PhotonRealtime/Code/Extensions.cs @@ -149,27 +149,43 @@ namespace Photon.Realtime return target; } - /// - /// This removes all key-value pairs that have a null-reference as value. - /// Photon properties are removed by setting their value to null. - /// Changes the original passed IDictionary! - /// - /// The IDictionary to strip of keys with null-values. + + /// Used by StripKeysWithNullValues. + /// + /// By making keysWithNullValue a static variable to clear before using, allocations only happen during the warm-up phase + /// as the list needs to grow. Once it hit the high water mark for keys you need to remove. + /// + private static readonly List keysWithNullValue = new List(); + + /// Removes all keys with null values. + /// + /// Photon properties are removed by setting their value to null. Changes the original IDictionary! + /// Uses lock(keysWithNullValue), which should be no problem in expected use cases. + /// + /// The IDictionary to strip of keys with null value. public static void StripKeysWithNullValues(this IDictionary original) { - object[] keys = new object[original.Count]; - original.Keys.CopyTo(keys, 0); - - for (int index = 0; index < keys.Length; index++) + lock (keysWithNullValue) { - var key = keys[index]; - if (original[key] == null) + keysWithNullValue.Clear(); + + foreach (DictionaryEntry entry in original) + { + if (entry.Value == null) + { + keysWithNullValue.Add(entry.Key); + } + } + + for (int i = 0; i < keysWithNullValue.Count; i++) { + var key = keysWithNullValue[i]; original.Remove(key); } } } + /// /// Checks if a particular integer value is in an int-array. /// diff --git a/Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs b/Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs index bcf07ff..ae36146 100644 --- a/Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs +++ b/Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs @@ -109,7 +109,10 @@ namespace Photon.Realtime ConnectedToNameServer, /// Clients disconnects (specifically) from the NameServer (usually to connect to the MasterServer). - DisconnectingFromNameServer + DisconnectingFromNameServer, + + /// Client was unable to connect to Name Server and will attempt to connect with an alternative network protocol (TCP). + ConnectWithFallbackProtocol } @@ -136,8 +139,16 @@ namespace Photon.Realtime { /// No error was tracked. None, + /// OnStatusChanged: The server is not available or the address is wrong. Make sure the port is provided and the server is up. ExceptionOnConnect, + + /// OnStatusChanged: Dns resolution for a hostname failed. The exception for this is being catched and logged with error level. + DnsExceptionOnConnect, + + /// OnStatusChanged: The server address was parsed as IPv4 illegally. An illegal address would be e.g. 192.168.1.300. IPAddress.TryParse() will let this pass but our check won't. + ServerAddressInvalid, + /// OnStatusChanged: Some internal exception caused the socket code to fail. This may happen if you attempt to connect locally but the server is not available. In doubt: Contact Exit Games. Exception, @@ -149,15 +160,19 @@ namespace Photon.Realtime /// OnStatusChanged: The server disconnected this client from within the room's logic (the C# code). DisconnectByServerLogic, + /// OnStatusChanged: The server disconnected this client for unknown reasons. DisconnectByServerReasonUnknown, /// OnOperationResponse: Authenticate in the Photon Cloud with invalid AppId. Update your subscription or contact Exit Games. InvalidAuthentication, + /// OnOperationResponse: Authenticate in the Photon Cloud with invalid client values or custom authentication setup in Cloud Dashboard. CustomAuthenticationFailed, + /// The authentication ticket should provide access to any Photon Cloud server without doing another authentication-service call. However, the ticket expired. AuthenticationTicketExpired, + /// OnOperationResponse: Authenticate (temporarily) failed when using a Photon Cloud subscription without CCU Burst. Update your subscription. MaxCcuReached, @@ -166,8 +181,16 @@ namespace Photon.Realtime /// OnOperationResponse: Operation that's (currently) not available for this client (not authorized usually). Only tracked for op Authenticate. OperationNotAllowedInCurrentState, + /// OnStatusChanged: The client disconnected from within the logic (the C# code). - DisconnectByClientLogic + DisconnectByClientLogic, + + /// The client called an operation too frequently and got disconnected due to hitting the OperationLimit. This triggers a client-side disconnect, too. + /// To protect the server, some operations have a limit. When an OperationResponse fails with ErrorCode.OperationLimitReached, the client disconnects. + DisconnectByOperationLimit, + + /// The client received a "Disconnect Message" from the server. Check the debug logs for details. + DisconnectByDisconnectMessage } /// Available server (types) for internally used field: server. @@ -182,6 +205,15 @@ namespace Photon.Realtime NameServer } + /// Defines which sort of app the LoadBalancingClient is used for: Realtime or Voice. + public enum ClientAppType + { + /// Realtime apps are for gaming / interaction. Also used by PUN 2. + Realtime, + /// Voice apps stream audio. + Voice + } + /// /// Defines how the communication gets encrypted. /// @@ -199,26 +231,33 @@ namespace Photon.Realtime /// With this encryption mode for UDP, the connection gets setup with random sequence numbers and all further datagrams get encrypted almost entirely. On-demand message encryption (like in PayloadEncryption) is unavailable. /// DatagramEncryptionRandomSequence = 11, + ///// + ///// Same as above except that GCM mode is used to encrypt data. + ///// + //DatagramEncryptionGCMRandomSequence = 12, + /// + /// Datagram Encryption with GCM. + /// + DatagramEncryptionGCM = 13, } - - public static class EncryptionDataParameters + /// Container for port definitions. + public struct PhotonPortDefinition { - /// - /// Key for encryption mode - /// - public const byte Mode = 0; - /// - /// Key for first secret - /// - public const byte Secret1 = 1; - /// - /// Key for second secret - /// - public const byte Secret2 = 2; + public static readonly PhotonPortDefinition AlternativeUdpPorts = new PhotonPortDefinition() { NameServerPort = 27000, MasterServerPort = 27001, GameServerPort = 27002}; + + /// Typical ports: UDP: 5058 or 27000, TCP: 4533, WSS: 19093 or 443. + public ushort NameServerPort; + /// Typical ports: UDP: 5056 or 27002, TCP: 4530, WSS: 19090 or 443. + public ushort MasterServerPort; + /// Typical ports: UDP: 5055 or 27001, TCP: 4531, WSS: 19091 or 443. + public ushort GameServerPort; } + + #endregion + /// /// This class implements the Photon LoadBalancing workflow by using a LoadBalancingPeer. /// It keeps a state and will automatically execute transitions between the Master and Game Servers. @@ -242,12 +281,33 @@ namespace Photon.Realtime /// public LoadBalancingPeer LoadBalancingPeer { get; private set; } + /// + /// Gets or sets the binary protocol version used by this client + /// + /// + /// Use this always instead of setting it via + /// () directly, especially when WSS protocol is used. + /// + public SerializationProtocol SerializationProtocol + { + get + { + return this.LoadBalancingPeer.SerializationProtocolType; + } + set + { + this.LoadBalancingPeer.SerializationProtocolType = value; + } + } + /// The version of your client. A new version also creates a new "virtual app" to separate players from older client versions. public string AppVersion { get; set; } /// The AppID as assigned from the Photon Cloud. If you host yourself, this is the "regular" Photon Server Application Name (most likely: "LoadBalancing"). public string AppId { get; set; } + /// The ClientAppType defines which sort of AppId should be expected. The LoadBalancingClient supports Realtime and Voice app types. Default: Realtime. + public ClientAppType ClientType { get; set; } /// User authentication values to be sent to the Photon server right after connecting. /// Set this property or pass AuthenticationValues by Connect(..., authValues). @@ -259,16 +319,19 @@ namespace Photon.Realtime /// Defines how the communication gets encrypted. public EncryptionMode EncryptionMode = EncryptionMode.PayloadEncryption; - /// The protocol which will be used on Master- and GameServer. + /// Optionally contains a protocol which will be used on Master- and GameServer. /// /// When using AuthMode = AuthModeOption.AuthOnceWss, the client uses a wss-connection on the NameServer but another protocol on the other servers. /// As the NameServer sends an address, which is different per protocol, it needs to know the expected protocol. + /// + /// This is nullable by design. In many cases, the protocol on the NameServer is not different from the other servers. + /// If set, the operation AuthOnce will contain this value and the OpAuth response on the NameServer will execute a protocol switch. /// - public ConnectionProtocol ExpectedProtocol = ConnectionProtocol.Udp; + public ConnectionProtocol? ExpectedProtocol { get; private set; } ///Simplifies getting the token for connect/init requests, if this feature is enabled. - private string TokenForInit + private object TokenForInit { get { @@ -281,7 +344,7 @@ namespace Photon.Realtime } /// Internally used cache for the server's token. Identifies a user/session and can be used to rejoin. - private string tokenCache; + private object tokenCache; /// True if this client uses a NameServer to get the Master Server address. @@ -291,31 +354,45 @@ namespace Photon.Realtime /// Name Server Host Name for Photon Cloud. Without port and without any prefix. public string NameServerHost = "ns.exitgames.com"; - /// Name Server for HTTP connections to the Photon Cloud. Includes prefix and port. - public string NameServerHttp = "http://ns.exitgames.com:80/photon/n"; - /// Name Server Address for Photon Cloud (based on current protocol). You can use the default values and usually won't have to set this value. public string NameServerAddress { get { return this.GetNameServerAddress(); } } /// Name Server port per protocol (the UDP port is different than TCP, etc). private static readonly Dictionary ProtocolToNameServerPort = new Dictionary() { { ConnectionProtocol.Udp, 5058 }, { ConnectionProtocol.Tcp, 4533 }, { ConnectionProtocol.WebSocket, 9093 }, { ConnectionProtocol.WebSocketSecure, 19093 } }; //, { ConnectionProtocol.RHttp, 6063 } }; - /// Use the alternative ports for UDP connections in the Public Cloud (27000 to 27003). + + /// Replaced by ServerPortOverrides. + [Obsolete("Set port overrides in ServerPortOverrides. Not used anymore!")] + public bool UseAlternativeUdpPorts { get; set; } + + + /// Defines overrides for server ports. Used per server-type if > 0. Important: You must change these when the protocol changes! /// - /// This should be used when players have issues with connection stability. - /// Some players reported better connectivity for Steam games. - /// The effect might vary, which is why the alternative ports are not the new default. + /// Typical ports are listed in PhotonPortDefinition. /// - /// The alternative (server) ports are 27000 up to 27003. + /// Instead of using the port provided from the servers, the specified port is used (independent of the protocol). + /// If a value is 0 (default), the port is not being replaced. /// - /// The values are appplied by replacing any incoming server-address string accordingly. - /// You only need to set this to true though. + /// Different protocols have different typical ports per server-type. + /// https://doc.photonengine.com/en-us/pun/current/reference/tcp-and-udp-port-numbers /// - /// This value does not affect TCP or WebSocket connections. + /// In case of using the AuthMode AutOnceWss, the name server's protocol is wss, while udp or tcp will be used on the master server and game server. + /// Set the ports accordingly per protocol and server. /// - public bool UseAlternativeUdpPorts { get; set; } + public PhotonPortDefinition ServerPortOverrides; + /// Enables a fallback to another protocol in case a connect to the Name Server fails. + /// + /// When connecting to the Name Server fails for a first time, the client will select an alternative + /// network protocol and re-try to connect. + /// + /// The fallback will use the default Name Server port as defined by ProtocolToNameServerPort. + /// + /// The fallback for TCP is UDP. All other protocols fallback to TCP. + /// + public bool EnableProtocolFallback { get; set; } + /// The currently used server address (if any). The type of server is define by Server property. public string CurrentServerAddress { get { return this.LoadBalancingPeer.ServerAddress; } } @@ -335,6 +412,22 @@ namespace Photon.Realtime /// public ServerConnection Server { get; private set; } + /// + /// Defines a proxy URL for WebSocket connections. Can be the proxy or point to a .pac file. + /// + /// + /// This URL supports various definitions: + /// + /// "user:pass@proxyaddress:port"
+ /// "proxyaddress:port"
+ /// "system:"
+ /// "pac:"
+ /// "pac:http://host/path/pacfile.pac"
+ /// + /// Important: Don't define a protocol, except to point to a pac file. the proxy address should not begin with http:// or https://. + ///
+ public string ProxyServerAddress; + /// Backing field for property. private ClientState state = ClientState.PeerCreated; @@ -452,6 +545,10 @@ namespace Photon.Realtime internal WebRpcCallbacksContainer WebRpcCallbackTargets; + /// Wraps up the target objects for a group of callbacks, so they can be called conveniently. + /// By using Add or Remove, objects can "subscribe" or "unsubscribe" for this group of callbacks. + internal ErrorInfoCallbacksContainer ErrorInfoCallbackTargets; + /// Summarizes (aggregates) the different causes for disconnects of a client. /// /// A disconnect can be caused by: errors in the network connection or some vital operation failing @@ -551,7 +648,7 @@ namespace Photon.Realtime } /// The current room this client is connected to (null if none available). - public Room CurrentRoom { get; private set; } + public Room CurrentRoom { get; set; } /// Is true while being in a room (this.state == ClientState.Joined). @@ -611,6 +708,38 @@ namespace Photon.Realtime /// Contains the list if enabled regions this client may use. Null, unless the client got a response to OpGetRegions. public RegionHandler RegionHandler; + /// Stores the best region summary of a previous session to speed up connecting. + private string bestRegionSummaryFromStorage; + + /// Set when the best region pinging is done. + public string SummaryToCache; + + /// Internal connection setting/flag. If the client should connect to the best region or not. + /// + /// It's set in the Connect...() methods. Only ConnectUsingSettings() sets it to true. + /// If true, client will ping available regions and select the best. + /// A bestRegionSummaryFromStorage can be used to cut the ping time short. + /// + private bool connectToBestRegion = true; + + + /// Definition of parameters for encryption data (included in Authenticate operation response). + private class EncryptionDataParameters + { + /// + /// Key for encryption mode + /// + public const byte Mode = 0; + /// + /// Key for first secret + /// + public const byte Secret1 = 1; + /// + /// Key for second secret + /// + public const byte Secret2 = 2; + } + private class CallbackTargetChange { @@ -638,17 +767,23 @@ namespace Photon.Realtime this.InRoomCallbackTargets = new InRoomCallbacksContainer(this); this.LobbyCallbackTargets = new LobbyCallbacksContainer(this); this.WebRpcCallbackTargets = new WebRpcCallbacksContainer(this); + this.ErrorInfoCallbackTargets = new ErrorInfoCallbacksContainer(this); this.LoadBalancingPeer = new LoadBalancingPeer(this, protocol); - this.LoadBalancingPeer.SerializationProtocolType = SerializationProtocol.GpBinaryV18; + this.LoadBalancingPeer.OnDisconnectMessage += this.OnDisconnectMessageReceived; + this.SerializationProtocol = SerializationProtocol.GpBinaryV18; this.LocalPlayer = this.CreatePlayer(string.Empty, -1, true, null); //TODO: Check if we can do this later + + #if SUPPORTED_UNITY + CustomTypesUnity.Register(); + #endif + #if UNITY_WEBGL if (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Tcp || this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Udp) { this.LoadBalancingPeer.Listener.DebugReturn(DebugLevel.WARNING, "WebGL requires WebSockets. Switching TransportProtocol to WebSocketSecure."); this.LoadBalancingPeer.TransportProtocol = ConnectionProtocol.WebSocketSecure; - //SocketWebTcp.SerializationProtocol = Enum.GetName(typeof(SerializationProtocol), this.LoadBalancingPeer.SerializationProtocolType); } #endif @@ -668,6 +803,8 @@ namespace Photon.Realtime this.AppVersion = gameVersion; } + public int NameServerPortInAppSettings; + /// /// Gets the NameServer Address (with prefix and port), based on the set protocol (this.LoadBalancingPeer.UsedProtocol). /// @@ -676,9 +813,16 @@ namespace Photon.Realtime { var protocolPort = 0; ProtocolToNameServerPort.TryGetValue(this.LoadBalancingPeer.TransportProtocol, out protocolPort); - if (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Udp && this.UseAlternativeUdpPorts) + + if (this.NameServerPortInAppSettings != 0) { - protocolPort = 27000; + this.DebugReturn(DebugLevel.INFO, string.Format("Using NameServerPortInAppSettings: {0}", this.NameServerPortInAppSettings)); + protocolPort = this.NameServerPortInAppSettings; + } + + if (this.ServerPortOverrides.NameServerPort > 0) + { + protocolPort = this.ServerPortOverrides.NameServerPort; } switch (this.LoadBalancingPeer.TransportProtocol) @@ -686,10 +830,6 @@ namespace Photon.Realtime case ConnectionProtocol.Udp: case ConnectionProtocol.Tcp: return string.Format("{0}:{1}", NameServerHost, protocolPort); - #if RHTTP - case ConnectionProtocol.RHttp: - return NameServerHttp; - #endif case ConnectionProtocol.WebSocket: return string.Format("ws://{0}:{1}", NameServerHost, protocolPort); case ConnectionProtocol.WebSocketSecure: @@ -699,15 +839,99 @@ namespace Photon.Realtime } } + #region Operations and Commands + // needed connect variants: + // connect to Name Server only (could include getregions) -> end after getregions + // connect to Region Master via Name Server (specific region/cluster) -> no getregions! authenticates and ends after on connected to master + // connect to Best Region via Name Server + // connect to Master Server (no Name Server, no appid) + + public virtual bool ConnectUsingSettings(AppSettings appSettings) + { + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Disconnected) + { + Debug.LogWarning("ConnectUsingSettings() failed. Can only connect while in state 'Disconnected'. Current state: " + this.LoadBalancingPeer.PeerState); + return false; + } + + if (appSettings == null) + { + this.DebugReturn(DebugLevel.ERROR, "ConnectUsingSettings failed. The appSettings can't be null.'"); + return false; + } + + this.AppId = this.ClientType == ClientAppType.Realtime ? appSettings.AppIdRealtime : appSettings.AppIdVoice; + this.AppVersion = appSettings.AppVersion; + + this.IsUsingNameServer = appSettings.UseNameServer; + this.CloudRegion = appSettings.FixedRegion; + this.connectToBestRegion = string.IsNullOrEmpty(this.CloudRegion); + + this.EnableLobbyStatistics = appSettings.EnableLobbyStatistics; + this.LoadBalancingPeer.DebugOut = appSettings.NetworkLogging; + + this.AuthMode = appSettings.AuthMode; + this.LoadBalancingPeer.TransportProtocol = (this.AuthMode == AuthModeOption.AuthOnceWss) ? ConnectionProtocol.WebSocketSecure : appSettings.Protocol; + this.ExpectedProtocol = appSettings.Protocol; + this.EnableProtocolFallback = appSettings.EnableProtocolFallback; + + this.bestRegionSummaryFromStorage = appSettings.BestRegionSummaryFromStorage; + this.DisconnectedCause = DisconnectCause.None; + + + this.CheckConnectSetupWebGl(); + this.CheckConnectSetupXboxOne(); // may throw an exception if there are issues that can not be corrected + + + if (this.IsUsingNameServer) + { + this.Server = ServerConnection.NameServer; + if (!appSettings.IsDefaultNameServer) + { + this.NameServerHost = appSettings.Server; + } + + this.ProxyServerAddress = appSettings.ProxyServer; + this.NameServerPortInAppSettings = appSettings.Port; + if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, this.ProxyServerAddress, this.AppId, this.TokenForInit)) + { + return false; + } + + this.State = ClientState.ConnectingToNameServer; + } + else + { + this.Server = ServerConnection.MasterServer; + int portToUse = appSettings.IsDefaultPort ? 5055 : appSettings.Port; // TODO: setup new (default) port config + this.MasterServerAddress = string.Format("{0}:{1}", appSettings.Server, portToUse); + + if (!this.LoadBalancingPeer.Connect(this.MasterServerAddress, this.ProxyServerAddress, this.AppId, this.TokenForInit)) + { + return false; + } + + this.State = ClientState.ConnectingToMasterServer; + } + + return true; + } + + + [Obsolete("Use ConnectToMasterServer() instead.")] + public bool Connect() + { + return this.ConnectToMasterServer(); + } /// /// Starts the "process" to connect to a Master Server, using MasterServerAddress and AppId properties. /// /// - /// To connect to the Photon Cloud, use ConnectToRegionMaster(). + /// To connect to the Photon Cloud, use ConnectUsingSettings() or ConnectToRegionMaster(). /// /// The process to connect includes several steps: the actual connecting, establishing encryption, authentification /// (of app and optionally the user) and connecting to the MasterServer @@ -722,32 +946,32 @@ namespace Photon.Realtime /// - Region not available (OnOperationResponse() for OpAuthenticate with ReturnCode == ErrorCode.InvalidRegion) /// - Subscription CCU limit reached (OnOperationResponse() for OpAuthenticate with ReturnCode == ErrorCode.MaxCcuReached) /// - public virtual bool Connect() + public virtual bool ConnectToMasterServer() { - // we check if try to connect to a self-hosted Photon Server - if (string.IsNullOrEmpty(this.AppId) || !this.IsUsingNameServer) + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Disconnected) { - // this is a workaround to use with version v4.0.29.11263 or lower, which doesn't support GpBinaryV18 yet. - this.LoadBalancingPeer.SerializationProtocolType = SerializationProtocol.GpBinaryV16; + Debug.LogWarning("ConnectToMasterServer() failed. Can only connect while in state 'Disconnected'. Current state: " + this.LoadBalancingPeer.PeerState); + return false; } - #if UNITY_WEBGL - SocketWebTcp.SerializationProtocol = Enum.GetName(typeof(SerializationProtocol), this.LoadBalancingPeer.SerializationProtocolType); - #endif - this.DisconnectedCause = DisconnectCause.None; - if (this.LoadBalancingPeer.Connect(this.MasterServerAddress, this.AppId, this.TokenForInit)) + // when using authMode AuthOnce or AuthOnceWSS, the token must be available for the init request. if it's null in that case, don't connect + if (this.AuthMode != AuthModeOption.Auth && this.TokenForInit == null) { - this.State = ClientState.ConnectingToMasterServer; - return true; + this.DebugReturn(DebugLevel.ERROR, "Connect() failed. Can't connect to MasterServer with Token == null in AuthMode: " + this.AuthMode); + return false; } - #if UNITY_XBOXONE - if (this.AuthValues == null || this.AuthValues.AuthType != CustomAuthenticationType.Xbox) + this.CheckConnectSetupWebGl(); + this.CheckConnectSetupXboxOne(); // may throw an exception if there are issues that can not be corrected + + if (this.LoadBalancingPeer.Connect(this.MasterServerAddress, this.ProxyServerAddress, this.AppId, this.TokenForInit)) { - UnityEngine.Debug.LogError("UNITY_XBOXONE builds must set AuthValues.AuthType to \"CustomAuthenticationType.Xbox\". Set this before calling any Connect method. Connect failed!"); - return false; + this.DisconnectedCause = DisconnectCause.None; + this.connectToBestRegion = false; + this.State = ClientState.ConnectingToMasterServer; + this.Server = ServerConnection.MasterServer; + return true; } - #endif return false; } @@ -760,52 +984,86 @@ namespace Photon.Realtime /// If the workflow was started or failed right away. public bool ConnectToNameServer() { + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Disconnected) + { + Debug.LogWarning("ConnectToNameServer() failed. Can only connect while in state 'Disconnected'. Current state: " + this.LoadBalancingPeer.PeerState); + return false; + } + this.IsUsingNameServer = true; this.CloudRegion = null; - #if UNITY_WEBGL - SocketWebTcp.SerializationProtocol = Enum.GetName(typeof(SerializationProtocol), this.LoadBalancingPeer.SerializationProtocolType); - #endif + + this.CheckConnectSetupWebGl(); + this.CheckConnectSetupXboxOne(); // may throw an exception if there are issues that can not be corrected + if (this.AuthMode == AuthModeOption.AuthOnceWss) { - this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; + if (this.ExpectedProtocol == null) + { + this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; + } this.LoadBalancingPeer.TransportProtocol = ConnectionProtocol.WebSocketSecure; } - else if (this.AuthMode == AuthModeOption.AuthOnce) - { - //Debug.LogWarning("Setting expected to current: "+this.LoadBalancingPeer.TransportProtocol); - this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; - } - this.DisconnectedCause = DisconnectCause.None; - if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, "NameServer", this.TokenForInit)) + if (this.LoadBalancingPeer.Connect(this.NameServerAddress, this.ProxyServerAddress, "NameServer", this.TokenForInit)) { - return false; + this.DisconnectedCause = DisconnectCause.None; + this.connectToBestRegion = false; + this.State = ClientState.ConnectingToNameServer; + this.Server = ServerConnection.NameServer; + return true; } - this.State = ClientState.ConnectingToNameServer; - return true; + return false; } /// /// Connects you to a specific region's Master Server, using the Name Server to find the IP. /// /// + /// If the region is null or empty, no connection will be made. + /// If the region (code) provided is not available, the connection process will fail on the Name Server. + /// This method connects only to the region defined. No "Best Region" pinging will be done. + /// /// If the region string does not contain a "/", this means no specific cluster is requested. /// To support "Sharding", the region gets a "/*" postfix in this case, to select a random cluster. /// /// If the operation could be sent. If false, no operation was sent. public bool ConnectToRegionMaster(string region) { + if (string.IsNullOrEmpty(region)) + { + this.DebugReturn(DebugLevel.ERROR, "ConnectToRegionMaster() failed. The region can not be null or empty."); + return false; + } + this.IsUsingNameServer = true; + if (this.State == ClientState.Authenticating) + { + if (this.LoadBalancingPeer.DebugOut >= DebugLevel.INFO) + { + this.DebugReturn(DebugLevel.INFO, "ConnectToRegionMaster() will skip calling authenticate, as the current state is 'Authenticating'. Just wait for the result."); + } + return true; + } + if (this.State == ClientState.ConnectedToNameServer) { this.CloudRegion = region; - return this.CallAuthenticate(); + + bool authenticating = this.CallAuthenticate(); + if (authenticating) + { + this.State = ClientState.Authenticating; + } + + return authenticating; } + this.LoadBalancingPeer.Disconnect(); if (!string.IsNullOrEmpty(region) && !region.Contains("/")) @@ -814,35 +1072,80 @@ namespace Photon.Realtime } this.CloudRegion = region; - #if UNITY_WEBGL - SocketWebTcp.SerializationProtocol = Enum.GetName(typeof(SerializationProtocol), this.LoadBalancingPeer.SerializationProtocolType); - #endif + + this.CheckConnectSetupWebGl(); + this.CheckConnectSetupXboxOne(); // may throw an exception if there are issues that can not be corrected + if (this.AuthMode == AuthModeOption.AuthOnceWss) { - this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; + if (this.ExpectedProtocol == null) + { + this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; + } this.LoadBalancingPeer.TransportProtocol = ConnectionProtocol.WebSocketSecure; } - else if (this.AuthMode == AuthModeOption.AuthOnce) - { - this.ExpectedProtocol = this.LoadBalancingPeer.TransportProtocol; - } + this.connectToBestRegion = false; this.DisconnectedCause = DisconnectCause.None; - if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, "NameServer", null)) + if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, this.ProxyServerAddress, "NameServer", null)) { return false; } this.State = ClientState.ConnectingToNameServer; + this.Server = ServerConnection.NameServer; return true; } + [Conditional("UNITY_WEBGL")] + private void CheckConnectSetupWebGl() + { + #if UNITY_WEBGL + if (this.LoadBalancingPeer.TransportProtocol != ConnectionProtocol.WebSocket && this.LoadBalancingPeer.TransportProtocol != ConnectionProtocol.WebSocketSecure) + { + this.DebugReturn(DebugLevel.WARNING, "WebGL requires WebSockets. Switching TransportProtocol to WebSocketSecure."); + this.LoadBalancingPeer.TransportProtocol = ConnectionProtocol.WebSocketSecure; + } + + this.EnableProtocolFallback = false; // no fallback on WebGL + #endif + } + + [Conditional("UNITY_XBOXONE"), Conditional("UNITY_GAMECORE")] + private void CheckConnectSetupXboxOne() + { + #if (UNITY_XBOXONE || UNITY_GAMECORE) && !UNITY_EDITOR + this.AuthMode = AuthModeOption.Auth; + if (this.AuthValues == null) + { + this.DebugReturn(DebugLevel.ERROR, "XBOX builds must set AuthValues. Set this before calling any Connect method. Refer to the online docs for guidance."); + throw new Exception("XBOX builds must set AuthValues."); + } + if (this.AuthValues.AuthPostData == null) + { + this.DebugReturn(DebugLevel.ERROR,"XBOX builds must use Photon's XBox Authentication and set the XSTS token by calling: PhotonNetwork.AuthValues.SetAuthPostData(xstsToken). Refer to the online docs for guidance."); + throw new Exception("XBOX builds must use Photon's XBox Authentication."); + } + if (this.AuthValues.AuthType != CustomAuthenticationType.Xbox) + { + this.DebugReturn(DebugLevel.WARNING, "XBOX builds must use AuthValues.AuthType \"CustomAuthenticationType.Xbox\". PUN sets this value now. Refer to the online docs to avoid this warning."); + this.AuthValues.AuthType = CustomAuthenticationType.Xbox; + } + if (this.LoadBalancingPeer.TransportProtocol != ConnectionProtocol.WebSocketSecure) + { + this.DebugReturn(DebugLevel.INFO, "XBOX builds must use WSS (Secure WebSockets) as Transport Protocol. Changing the protocol now."); + this.LoadBalancingPeer.TransportProtocol = ConnectionProtocol.WebSocketSecure; + } + + this.EnableProtocolFallback = false; // no transport protocol fallback on XBOX + #endif + } /// /// Privately used only for reconnecting. /// - private bool Connect(string serverAddress, ServerConnection type) + private bool Connect(string serverAddress, string proxyServerAddress, ServerConnection serverType) { // TODO: Make sure app doesn't quit right now @@ -852,14 +1155,22 @@ namespace Photon.Realtime return false; } + // when using authMode AuthOnce or AuthOnceWSS, the token must be available for the init request. if it's null in that case, don't connect + if (this.AuthMode != AuthModeOption.Auth && serverType != ServerConnection.NameServer && this.TokenForInit == null) + { + this.DebugReturn(DebugLevel.ERROR, "Connect() failed. Can't connect to " + serverType + " with Token == null in AuthMode: " + this.AuthMode); + return false; + } - // connect might fail, if the DNS name can't be resolved or if no network connection is available - this.DisconnectedCause = DisconnectCause.None; - bool connecting = this.LoadBalancingPeer.Connect(serverAddress, "", this.TokenForInit); + // connect might fail, if the DNS name can't be resolved or if no network connection is available, etc. + bool connecting = this.LoadBalancingPeer.Connect(serverAddress, proxyServerAddress, this.AppId, this.TokenForInit); if (connecting) { - switch (type) + this.DisconnectedCause = DisconnectCause.None; + this.Server = serverType; + + switch (serverType) { case ServerConnection.NameServer: State = ClientState.ConnectingToNameServer; @@ -877,27 +1188,27 @@ namespace Photon.Realtime } - /// - /// Privately used only. - /// Starts the "process" to connect to the game server (connect before a game is joined). - /// - private bool ConnectToGameServer() - { - if (this.LoadBalancingPeer.Connect(this.GameServerAddress, this.AppId, this.TokenForInit)) - { - this.State = ClientState.ConnectingToGameServer; - return true; - } - - // TODO: handle error "cant connect to GS" - return false; - } - - /// Can be used to reconnect to the master server after a disconnect. /// Common use case: Press the Lock Button on a iOS device and you get disconnected immediately. public bool ReconnectToMaster() { + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Disconnected) + { + Debug.LogWarning("ReconnectToMaster() failed. Can only connect while in state 'Disconnected'. Current state: " + this.LoadBalancingPeer.PeerState); + return false; + } + + if (string.IsNullOrEmpty(this.MasterServerAddress)) + { + this.DebugReturn(DebugLevel.WARNING, "ReconnectToMaster() failed. MasterServerAddress is null or empty."); + return false; + } + if (this.tokenCache == null) + { + this.DebugReturn(DebugLevel.WARNING, "ReconnectToMaster() failed. It seems the client doesn't have any previous authentication token to re-connect."); + return false; + } + if (this.AuthValues == null) { this.DebugReturn(DebugLevel.WARNING, "ReconnectToMaster() with AuthValues == null is not correct!"); @@ -905,11 +1216,11 @@ namespace Photon.Realtime } this.AuthValues.Token = this.tokenCache; - return this.Connect(this.MasterServerAddress, ServerConnection.MasterServer); + return this.Connect(this.MasterServerAddress, this.ProxyServerAddress, ServerConnection.MasterServer); } /// - /// Can be used to return to a room quickly, by directly reconnecting to a game server to rejoin a room. + /// Can be used to return to a room quickly by directly reconnecting to a game server to rejoin a room. /// /// /// Rejoining room will not send any player properties. Instead client will receive up-to-date ones from server. @@ -918,19 +1229,25 @@ namespace Photon.Realtime /// False, if the conditions are not met. Then, this client does not attempt the ReconnectAndRejoin. public bool ReconnectAndRejoin() { + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Disconnected) + { + Debug.LogWarning("ReconnectAndRejoin() failed. Can only connect while in state 'Disconnected'. Current state: " + this.LoadBalancingPeer.PeerState); + return false; + } + if (string.IsNullOrEmpty(this.GameServerAddress)) { - this.DebugReturn(DebugLevel.ERROR, "ReconnectAndRejoin() failed. It seems the client wasn't connected to a game server before (no address)."); + this.DebugReturn(DebugLevel.WARNING, "ReconnectAndRejoin() failed. It seems the client wasn't connected to a game server before (no address)."); return false; } if (this.enterRoomParamsCache == null) { - this.DebugReturn(DebugLevel.ERROR, "ReconnectAndRejoin() failed. It seems the client doesn't have any previous room to re-join."); + this.DebugReturn(DebugLevel.WARNING, "ReconnectAndRejoin() failed. It seems the client doesn't have any previous room to re-join."); return false; } if (this.tokenCache == null) { - this.DebugReturn(DebugLevel.ERROR, "ReconnectAndRejoin() failed. It seems the client doesn't have any previous authentication token to re-connect."); + this.DebugReturn(DebugLevel.WARNING, "ReconnectAndRejoin() failed. It seems the client doesn't have any previous authentication token to re-connect."); return false; } @@ -944,28 +1261,32 @@ namespace Photon.Realtime if (!string.IsNullOrEmpty(this.GameServerAddress) && this.enterRoomParamsCache != null) { this.lastJoinType = JoinType.JoinRoom; - this.enterRoomParamsCache.RejoinOnly = true; - return this.Connect(this.GameServerAddress, ServerConnection.GameServer); + this.enterRoomParamsCache.JoinMode = JoinMode.RejoinOnly; + return this.Connect(this.GameServerAddress, this.ProxyServerAddress, ServerConnection.GameServer); } return false; } - /// Disconnects this client from any server and sets this.State if the connection is successfuly closed. - public void Disconnect() + /// Disconnects the peer from a server or stays disconnected. If the client / peer was connected, a callback will be triggered. + /// + /// This method will not change the current State, if this client State is PeerCreated, Disconnecting or Disconnected. + /// In those cases, there is also no callback for the disconnect. The DisconnectedCause will only change if the client was connected. + /// + public void Disconnect(DisconnectCause cause = DisconnectCause.DisconnectByClientLogic) { + if (this.State == ClientState.Disconnecting || this.State == ClientState.PeerCreated) + { + this.DebugReturn(DebugLevel.INFO, "Disconnect() call gets skipped due to State " + this.State + ". DisconnectedCause: " + this.DisconnectedCause + " Parameter cause: " + cause); + return; + } + if (this.State != ClientState.Disconnected) { this.State = ClientState.Disconnecting; - this.DisconnectedCause = DisconnectCause.DisconnectByClientLogic; + this.DisconnectedCause = cause; this.LoadBalancingPeer.Disconnect(); - - //// we can set this high-level state if the low-level (connection)state is "disconnected" - //if (this.LoadBalancingPeer.PeerState == PeerStateValue.Disconnected || this.LoadBalancingPeer.PeerState == PeerStateValue.InitializingApplication) - //{ - // this.State = ClientState.Disconnected; - //} } } @@ -1025,6 +1346,11 @@ namespace Photon.Realtime private bool CallAuthenticate() { + if (this.IsUsingNameServer && this.Server != ServerConnection.NameServer && (this.AuthValues == null || this.AuthValues.Token == null)) + { + this.DebugReturn(DebugLevel.ERROR, "Authenticate without Token is only allowed on Name Server. Connecting to: " + this.Server + " on: " + this.CurrentServerAddress + ". State: " + this.State); + } + if (this.AuthMode == AuthModeOption.Auth) { if (!this.CheckIfOpCanBeSent(OperationCode.Authenticate, this.Server, "Authenticate")) @@ -1039,7 +1365,9 @@ namespace Photon.Realtime { return false; } - return this.LoadBalancingPeer.OpAuthenticateOnce(this.AppId, this.AppVersion, this.AuthValues, this.CloudRegion, this.EncryptionMode, this.ExpectedProtocol); + + ConnectionProtocol targetProtocolPastNameServer = this.ExpectedProtocol != null ? (ConnectionProtocol) this.ExpectedProtocol : this.LoadBalancingPeer.TransportProtocol; + return this.LoadBalancingPeer.OpAuthenticateOnce(this.AppId, this.AppVersion, this.AuthValues, this.CloudRegion, this.EncryptionMode, targetProtocolPastNameServer); } } @@ -1292,6 +1620,29 @@ namespace Photon.Realtime } + /// + /// Attempts to join a room that matches the specified filter and creates a room if none found. + /// + /// + /// This operation is a combination of filter-based random matchmaking with the option to create a new room, + /// if no fitting room exists. + /// The benefit of that is that the room creation is done by the same operation and the room can be found + /// by the very next client, looking for similar rooms. + /// + /// There are separate parameters for joining and creating a room. + /// + /// This method can only be called while connected to a Master Server. + /// This client's State is set to ClientState.Joining immediately. + /// + /// Either IMatchmakingCallbacks.OnJoinedRoom or IMatchmakingCallbacks.OnCreatedRoom get called. + /// + /// More about matchmaking: + /// https://doc.photonengine.com/en-us/realtime/current/reference/matchmaking-and-lobby + /// + /// Check the return value to make sure the operation will be called on the server. + /// Note: There will be no callbacks if this method returned false. + /// + /// If the operation will be sent (requires connection to Master Server). public bool OpJoinRandomOrCreateRoom(OpJoinRandomRoomParams opJoinRandomRoomParams, EnterRoomParams createRoomParams) { if (!this.CheckIfOpCanBeSent(OperationCode.JoinRandomGame, this.Server, "OpJoinRandomOrCreateRoom")) @@ -1308,7 +1659,7 @@ namespace Photon.Realtime createRoomParams = new EnterRoomParams(); } - createRoomParams.CreateIfNotExists = true; + createRoomParams.JoinMode = JoinMode.CreateIfNotExists; this.enterRoomParamsCache = createRoomParams; this.enterRoomParamsCache.Lobby = opJoinRandomRoomParams.TypedLobby; this.enterRoomParamsCache.ExpectedUsers = opJoinRandomRoomParams.ExpectedUsers; @@ -1420,7 +1771,7 @@ namespace Photon.Realtime public bool OpJoinOrCreateRoom(EnterRoomParams enterRoomParams) { bool onGameServer = this.Server == ServerConnection.GameServer; - enterRoomParams.CreateIfNotExists = true; + enterRoomParams.JoinMode = JoinMode.CreateIfNotExists; enterRoomParams.OnGameServer = onGameServer; if (!onGameServer) { @@ -1493,7 +1844,7 @@ namespace Photon.Realtime bool sending = this.LoadBalancingPeer.OpJoinRoom(enterRoomParams); if (sending) { - this.lastJoinType = (enterRoomParams.CreateIfNotExists) ? JoinType.JoinOrCreateRoom : JoinType.JoinRoom; + this.lastJoinType = enterRoomParams.JoinMode == JoinMode.CreateIfNotExists ? JoinType.JoinOrCreateRoom : JoinType.JoinRoom; this.State = ClientState.Joining; } return sending; @@ -1525,7 +1876,7 @@ namespace Photon.Realtime this.enterRoomParamsCache = opParams; opParams.RoomName = roomName; opParams.OnGameServer = onGameServer; - opParams.RejoinOnly = true; + opParams.JoinMode = JoinMode.RejoinOnly; bool sending = this.LoadBalancingPeer.OpJoinRoom(opParams); if (sending) @@ -1559,13 +1910,17 @@ namespace Photon.Realtime } this.State = ClientState.Leaving; + this.GameServerAddress = String.Empty; + this.enterRoomParamsCache = null; return this.LoadBalancingPeer.OpLeaveRoom(becomeInactive, sendAuthCookie); } - /// Gets a list of games matching a SQL-like where clause. + /// Gets a list of rooms matching the (non empty) SQL filter for the given SQL-typed lobby. /// - /// Operation is only available for lobbies of type SqlLobby. + /// Operation is only available for lobbies of type SqlLobby and the filter can not be empty. + /// It will check those conditions and fail locally, returning false. + /// /// This is an async request which triggers a OnOperationResponse() call. /// /// @@ -1578,6 +1933,17 @@ namespace Photon.Realtime { return false; } + if (string.IsNullOrEmpty(sqlLobbyFilter)) + { + this.DebugReturn(DebugLevel.ERROR, "Operation GetGameList requires a filter."); + return false; + } + if (typedLobby.Type != LobbyType.SqlLobby) + { + this.DebugReturn(DebugLevel.ERROR, "Operation GetGameList can only be used for lobbies of type SqlLobby."); + return false; + } + return this.LoadBalancingPeer.OpGetGameList(typedLobby, sqlLobbyFilter); } @@ -1624,16 +1990,25 @@ namespace Photon.Realtime /// Hashtable of Custom Properties that changes. /// Provide some keys/values to use as condition for setting the new values. Client must be in room. /// Defines if the set properties should be forwarded to a WebHook. Client must be in room. + /// + /// False if propertiesToSet is null or empty or have zero string keys. + /// If not in a room, returns true if local player and expectedProperties and webFlags are null. + /// False if actorNr is lower than or equal to zero. + /// Otherwise, returns if the operation could be sent to the server. + /// public bool OpSetCustomPropertiesOfActor(int actorNr, Hashtable propertiesToSet, Hashtable expectedProperties = null, WebFlags webFlags = null) { - + if (propertiesToSet == null || propertiesToSet.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetCustomPropertiesOfActor() failed. propertiesToSet must not be null nor empty."); + return false; + } if (this.CurrentRoom == null) { // if you attempt to set this player's values without conditions, then fine: if (expectedProperties == null && webFlags == null && this.LocalPlayer != null && this.LocalPlayer.ActorNumber == actorNr) { - this.LocalPlayer.SetCustomProperties(propertiesToSet); - return true; + return this.LocalPlayer.SetCustomProperties(propertiesToSet); } if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ERROR) @@ -1645,7 +2020,11 @@ namespace Photon.Realtime Hashtable customActorProperties = new Hashtable(); customActorProperties.MergeStringKeys(propertiesToSet); - + if (customActorProperties.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetCustomPropertiesOfActor() failed. Only string keys allowed for custom properties."); + return false; + } return this.OpSetPropertiesOfActor(actorNr, customActorProperties, expectedProperties, webFlags); } @@ -1658,16 +2037,22 @@ namespace Photon.Realtime { return false; } - if (expectedProperties == null || expectedProperties.Count == 0) + if (actorProperties == null || actorProperties.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetPropertiesOfActor() failed. actorProperties must not be null nor empty."); + return false; + } + bool res = this.LoadBalancingPeer.OpSetPropertiesOfActor(actorNr, actorProperties, expectedProperties, webFlags); + if (res && !this.CurrentRoom.BroadcastPropertiesChangeToAll && (expectedProperties == null || expectedProperties.Count == 0)) { Player target = this.CurrentRoom.GetPlayer(actorNr); if (target != null) { target.InternalCacheProperties(actorProperties); + this.InRoomCallbackTargets.OnPlayerPropertiesUpdate(target, actorProperties); } } - - return this.LoadBalancingPeer.OpSetPropertiesOfActor(actorNr, actorProperties, expectedProperties, webFlags); + return res; } @@ -1712,35 +2097,55 @@ namespace Photon.Realtime /// Hashtable of Custom Properties that changes. /// Provide some keys/values to use as condition for setting the new values. /// Defines web flags for an optional PathProperties webhook. + /// + /// False if propertiesToSet is null or empty or have zero string keys. + /// Otherwise, returns if the operation could be sent to the server. + /// public bool OpSetCustomPropertiesOfRoom(Hashtable propertiesToSet, Hashtable expectedProperties = null, WebFlags webFlags = null) { + if (propertiesToSet == null || propertiesToSet.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetCustomPropertiesOfRoom() failed. propertiesToSet must not be null nor empty."); + return false; + } Hashtable customGameProps = new Hashtable(); customGameProps.MergeStringKeys(propertiesToSet); - + if (customGameProps.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetCustomPropertiesOfRoom() failed. Only string keys are allowed for custom properties."); + return false; + } return this.OpSetPropertiesOfRoom(customGameProps, expectedProperties, webFlags); } - protected internal void OpSetPropertyOfRoom(byte propCode, object value) + protected internal bool OpSetPropertyOfRoom(byte propCode, object value) { Hashtable properties = new Hashtable(); properties[propCode] = value; - this.OpSetPropertiesOfRoom(properties); + return this.OpSetPropertiesOfRoom(properties); } /// Internally used to cache and set properties (including well known properties). /// Requires being in a room (because this attempts to send an operation which will fail otherwise). - public bool OpSetPropertiesOfRoom(Hashtable gameProperties, Hashtable expectedProperties = null, WebFlags webFlags = null) + protected internal bool OpSetPropertiesOfRoom(Hashtable gameProperties, Hashtable expectedProperties = null, WebFlags webFlags = null) { if (!this.CheckIfOpCanBeSent(OperationCode.SetProperties, this.Server, "SetProperties")) { return false; } - if (expectedProperties == null || expectedProperties.Count == 0) + if (gameProperties == null || gameProperties.Count == 0) + { + this.DebugReturn(DebugLevel.ERROR, "OpSetPropertiesOfRoom() failed. gameProperties must not be null nor empty."); + return false; + } + bool res = this.LoadBalancingPeer.OpSetPropertiesOfRoom(gameProperties, expectedProperties, webFlags); + if (res && !this.CurrentRoom.BroadcastPropertiesChangeToAll && (expectedProperties == null || expectedProperties.Count == 0)) { this.CurrentRoom.InternalCacheProperties(gameProperties); + this.InRoomCallbackTargets.OnRoomPropertiesUpdate(gameProperties); } - return this.LoadBalancingPeer.OpSetPropertiesOfRoom(gameProperties, expectedProperties, webFlags); + return res; } @@ -1931,30 +2336,39 @@ namespace Photon.Realtime Hashtable gameProperties = (Hashtable)operationResponse[ParameterCode.GameProperties]; this.ReadoutProperties(gameProperties, actorProperties, 0); + object temp; + if (operationResponse.Parameters.TryGetValue(ParameterCode.RoomOptionFlags, out temp)) + { + this.CurrentRoom.InternalCacheRoomFlags((int)temp); + } + this.State = ClientState.Joined; - switch (operationResponse.OperationCode) + + // the callbacks OnCreatedRoom and OnJoinedRoom are called in the event join. it contains important info about the room and players. + // unless there will be no room events (RoomOptions.SuppressRoomEvents = true) + if (this.CurrentRoom.SuppressRoomEvents) { - case OperationCode.CreateGame: + if (this.lastJoinType == JoinType.CreateRoom || (this.lastJoinType == JoinType.JoinOrCreateRoom && this.LocalPlayer.ActorNumber == 1)) + { this.MatchMakingCallbackTargets.OnCreatedRoom(); - break; - case OperationCode.JoinGame: - case OperationCode.JoinRandomGame: - // "game joined" should be called in another place (the join ev contains important info for the room). - break; + } + + this.MatchMakingCallbackTargets.OnJoinedRoom(); } } + private void UpdatedActorList(int[] actorsInGame) { if (actorsInGame != null) { - foreach (int userId in actorsInGame) + foreach (int actorNumber in actorsInGame) { - Player target = this.CurrentRoom.GetPlayer(userId); + Player target = this.CurrentRoom.GetPlayer(actorNumber); if (target == null) { - this.CurrentRoom.StorePlayer(this.CreatePlayer(string.Empty, userId, false, null)); + this.CurrentRoom.StorePlayer(this.CreatePlayer(string.Empty, actorNumber, false, null)); } } } @@ -2043,6 +2457,7 @@ namespace Photon.Realtime this.DebugReturn(DebugLevel.ERROR, string.Format("Operation {0} ({1}) can't be sent because peer is null", opName, opCode)); return false; } + if (!this.CheckIfOpAllowedOnServer(opCode, serverConnection)) { if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ERROR) @@ -2051,12 +2466,26 @@ namespace Photon.Realtime } return false; } + if (!this.CheckIfClientIsReadyToCallOperation(opCode)) { - if (this.LoadBalancingPeer.DebugOut >= DebugLevel.ERROR) + DebugLevel levelToReport = DebugLevel.ERROR; + if (opCode == OperationCode.RaiseEvent && (this.State == ClientState.Leaving || this.State == ClientState.Disconnecting || this.State == ClientState.DisconnectingFromGameServer)) + { + levelToReport = DebugLevel.INFO; + } + + if (this.LoadBalancingPeer.DebugOut >= levelToReport) { - this.DebugReturn(DebugLevel.ERROR, string.Format("Operation {0} ({1}) not called because client is not connected or not ready yet, client state: {2}", opName, opCode, Enum.GetName(typeof(ClientState), this.State))); + this.DebugReturn(levelToReport, string.Format("Operation {0} ({1}) not called because client is not connected or not ready yet, client state: {2}", opName, opCode, Enum.GetName(typeof(ClientState), this.State))); } + + return false; + } + + if (this.LoadBalancingPeer.PeerState != PeerStateValue.Connected) + { + this.DebugReturn(DebugLevel.ERROR, string.Format("Operation {0} ({1}) can't be sent because peer is not connected, peer state: {2}", opName, opCode, this.LoadBalancingPeer.PeerState)); return false; } return true; @@ -2174,7 +2603,7 @@ namespace Photon.Realtime // if (operationResponse.ReturnCode != 0) this.DebugReturn(DebugLevel.ERROR, operationResponse.ToStringFull()); // use the "secret" or "token" whenever we get it. doesn't really matter if it's in AuthResponse. - if (operationResponse.Parameters.ContainsKey(ParameterCode.Secret)) + if (operationResponse.Parameters.ContainsKey(ParameterCode.Token)) { if (this.AuthValues == null) { @@ -2182,10 +2611,16 @@ namespace Photon.Realtime //this.DebugReturn(DebugLevel.ERROR, "Server returned secret. Created AuthValues."); } - this.AuthValues.Token = operationResponse[ParameterCode.Secret] as string; + this.AuthValues.Token = operationResponse[ParameterCode.Token] as string; this.tokenCache = this.AuthValues.Token; } + // if the operation limit was reached, disconnect (but still execute the operation response). + if (operationResponse.ReturnCode == ErrorCode.OperationLimitReached) + { + this.Disconnect(DisconnectCause.DisconnectByOperationLimit); + } + switch (operationResponse.OperationCode) { case OperationCode.Authenticate: @@ -2199,7 +2634,6 @@ namespace Photon.Realtime { case ErrorCode.InvalidAuthentication: this.DisconnectedCause = DisconnectCause.InvalidAuthentication; - this.ConnectionCallbackTargets.OnDisconnected(DisconnectCause.InvalidAuthentication); break; case ErrorCode.CustomAuthenticationFailed: this.DisconnectedCause = DisconnectCause.CustomAuthenticationFailed; @@ -2207,22 +2641,19 @@ namespace Photon.Realtime break; case ErrorCode.InvalidRegion: this.DisconnectedCause = DisconnectCause.InvalidRegion; - this.ConnectionCallbackTargets.OnDisconnected(DisconnectCause.InvalidRegion); break; case ErrorCode.MaxCcuReached: this.DisconnectedCause = DisconnectCause.MaxCcuReached; - this.ConnectionCallbackTargets.OnDisconnected(DisconnectCause.MaxCcuReached); break; case ErrorCode.OperationNotAllowedInCurrentState: this.DisconnectedCause = DisconnectCause.OperationNotAllowedInCurrentState; break; case ErrorCode.AuthenticationTicketExpired: this.DisconnectedCause = DisconnectCause.AuthenticationTicketExpired; - this.ConnectionCallbackTargets.OnDisconnected(DisconnectCause.AuthenticationTicketExpired); break; } - this.Disconnect(); + this.Disconnect(this.DisconnectedCause); break; // if auth didn't succeed, we disconnect (above) and exit this operation's handling } @@ -2260,16 +2691,18 @@ namespace Photon.Realtime // on the NameServer, authenticate returns the MasterServer address for a region and we hop off to there this.MasterServerAddress = operationResponse[ParameterCode.Address] as string; - if (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Udp && this.UseAlternativeUdpPorts) + if (this.ServerPortOverrides.MasterServerPort != 0) { - // TODO: Make this work with AuthOnceWss, which uses WSS on NameServer but "expects" to use UDP... - this.MasterServerAddress = this.MasterServerAddress.Replace("5058", "27000").Replace("5055", "27001").Replace("5056", "27002"); + //Debug.LogWarning("Incoming MasterServer Address: "+this.MasterServerAddress); + this.MasterServerAddress = ReplacePortWithAlternative(this.MasterServerAddress, this.ServerPortOverrides.MasterServerPort); + //Debug.LogWarning("New MasterServer Address: "+this.MasterServerAddress); } - if (this.AuthMode == AuthModeOption.AuthOnceWss) + if (this.AuthMode == AuthModeOption.AuthOnceWss && this.ExpectedProtocol != null) { - this.DebugReturn(DebugLevel.INFO, string.Format("Due to AuthOnceWss, switching TransportProtocol to ExpectedProtocol: {0}.", this.ExpectedProtocol)); - this.LoadBalancingPeer.TransportProtocol = this.ExpectedProtocol; + this.DebugReturn(DebugLevel.INFO, string.Format("AuthOnceWss mode. Auth response switches TransportProtocol to ExpectedProtocol: {0}.", this.ExpectedProtocol)); + this.LoadBalancingPeer.TransportProtocol = (ConnectionProtocol)this.ExpectedProtocol; + this.ExpectedProtocol = null; } this.DisconnectToReconnect(); } @@ -2295,7 +2728,7 @@ namespace Photon.Realtime { this.State = ClientState.Joining; - if (this.enterRoomParamsCache.RejoinOnly) + if (this.enterRoomParamsCache.JoinMode == JoinMode.RejoinOnly) { this.enterRoomParamsCache.PlayerProperties = null; } @@ -2303,7 +2736,11 @@ namespace Photon.Realtime { Hashtable allProps = new Hashtable(); allProps.Merge(this.LocalPlayer.CustomProperties); - allProps[ActorProperties.PlayerName] = this.LocalPlayer.NickName; + + if (!string.IsNullOrEmpty(this.LocalPlayer.NickName)) + { + allProps[ActorProperties.PlayerName] = this.LocalPlayer.NickName; + } this.enterRoomParamsCache.PlayerProperties = allProps; } @@ -2335,20 +2772,19 @@ namespace Photon.Realtime if (operationResponse.ReturnCode == ErrorCode.InvalidAuthentication) { - this.DebugReturn(DebugLevel.ERROR, string.Format("The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account.")); - this.ConnectionCallbackTargets.OnCustomAuthenticationFailed("Invalid Authentication"); - - this.Disconnect(); + this.DebugReturn(DebugLevel.ERROR, string.Format("GetRegions failed. AppId is unknown on the (cloud) server. "+operationResponse.DebugMessage)); + this.Disconnect(DisconnectCause.InvalidAuthentication); break; } if (operationResponse.ReturnCode != ErrorCode.Ok) { - this.DebugReturn(DebugLevel.ERROR, "GetRegions failed. Can't provide regions list. Error: " + operationResponse.ReturnCode + ": " + operationResponse.DebugMessage); + this.DebugReturn(DebugLevel.ERROR, "GetRegions failed. Can't provide regions list. ReturnCode: " + operationResponse.ReturnCode + ": " + operationResponse.DebugMessage); + this.Disconnect(DisconnectCause.InvalidAuthentication); break; } if (this.RegionHandler == null) { - this.RegionHandler = new RegionHandler(); + this.RegionHandler = new RegionHandler(this.ServerPortOverrides.MasterServerPort); } if (this.RegionHandler.IsPinging) @@ -2359,6 +2795,12 @@ namespace Photon.Realtime this.RegionHandler.SetRegions(operationResponse); this.ConnectionCallbackTargets.OnRegionListReceived(this.RegionHandler); + + if (this.connectToBestRegion) + { + // ping minimal regions (if one is known) and connect + this.RegionHandler.PingMinimumOfRegions(this.OnRegionPingCompleted, this.bestRegionSummaryFromStorage); + } break; case OperationCode.JoinRandomGame: // this happens only on the master server. on gameserver this is a "regular" join @@ -2387,9 +2829,11 @@ namespace Photon.Realtime else { this.GameServerAddress = (string)operationResponse[ParameterCode.Address]; - if (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Udp && this.UseAlternativeUdpPorts) + if (this.ServerPortOverrides.GameServerPort != 0) { - this.GameServerAddress = this.GameServerAddress.Replace("5058", "27000").Replace("5055", "27001").Replace("5056", "27002"); + //Debug.LogWarning("Incoming GameServer Address: " + this.GameServerAddress); + this.GameServerAddress = ReplacePortWithAlternative(this.GameServerAddress, this.ServerPortOverrides.GameServerPort); + //Debug.LogWarning("New GameServer Address: " + this.GameServerAddress); } string roomName = operationResponse[ParameterCode.RoomName] as string; @@ -2428,7 +2872,6 @@ namespace Photon.Realtime case OperationCode.LeaveLobby: this.State = ClientState.ConnectedToMasterServer; - // TODO: clean room list?! this.LobbyCallbackTargets.OnLeftLobby(); break; @@ -2559,7 +3002,7 @@ namespace Photon.Realtime } } - // authenticate in all other cases + // authenticate in all other cases (using the CloudRegion, if available) bool authenticating = this.CallAuthenticate(); if (authenticating) { @@ -2571,23 +3014,40 @@ namespace Photon.Realtime } break; - case StatusCode.Disconnect: // disconnect due to connection exception is handled below (don't connect to GS or master in that case) - - this.ChangeLocalID(-1); this.friendListRequested = null; bool wasInRoom = this.CurrentRoom != null; this.CurrentRoom = null; // players get cleaned up inside this, too, except LocalPlayer (which we keep) + this.ChangeLocalID(-1); // depends on this.CurrentRoom, so it must be called after updating that if (this.Server == ServerConnection.GameServer && wasInRoom) { this.MatchMakingCallbackTargets.OnLeftRoom(); } + if (this.ExpectedProtocol != null && this.LoadBalancingPeer.TransportProtocol != this.ExpectedProtocol) + { + this.DebugReturn(DebugLevel.INFO, string.Format("On disconnect switches TransportProtocol to ExpectedProtocol: {0}.", this.ExpectedProtocol)); + this.LoadBalancingPeer.TransportProtocol = (ConnectionProtocol)this.ExpectedProtocol; + this.ExpectedProtocol = null; + } + switch (this.State) { + case ClientState.ConnectWithFallbackProtocol: + this.EnableProtocolFallback = false; // the client does a fallback only one time + this.LoadBalancingPeer.TransportProtocol = (this.LoadBalancingPeer.TransportProtocol == ConnectionProtocol.Tcp) ? ConnectionProtocol.Udp : ConnectionProtocol.Tcp; + this.NameServerPortInAppSettings = 0; // this does not affect the ServerSettings file, just a variable at runtime + this.ServerPortOverrides = new PhotonPortDefinition(); // use default ports for the fallback + + if (!this.LoadBalancingPeer.Connect(this.NameServerAddress, this.ProxyServerAddress, this.AppId, this.TokenForInit)) + { + return; + } + this.State = ClientState.ConnectingToNameServer; + break; case ClientState.PeerCreated: case ClientState.Disconnecting: if (this.AuthValues != null) @@ -2600,11 +3060,11 @@ namespace Photon.Realtime case ClientState.DisconnectingFromGameServer: case ClientState.DisconnectingFromNameServer: - this.Connect(); // this gets the client back to the Master Server + this.ConnectToMasterServer(); // this gets the client back to the Master Server break; case ClientState.DisconnectingFromMasterServer: - this.ConnectToGameServer(); // this connects the client with the Game Server (when joining/creating a room) + this.Connect(this.GameServerAddress, this.ProxyServerAddress, ServerConnection.GameServer); // this connects the client with the Game Server (when joining/creating a room) break; case ClientState.Disconnected: @@ -2624,7 +3084,7 @@ namespace Photon.Realtime this.AuthValues.Token = null; // when leaving the server, invalidate the secret (but not the auth values) } this.State = ClientState.Disconnected; - this.ConnectionCallbackTargets.OnDisconnected(DisconnectCause.None); + this.ConnectionCallbackTargets.OnDisconnected(this.DisconnectedCause); break; } break; @@ -2634,13 +3094,32 @@ namespace Photon.Realtime this.DisconnectedCause = DisconnectCause.MaxCcuReached; this.State = ClientState.Disconnecting; break; + case StatusCode.DnsExceptionOnConnect: + this.DisconnectedCause = DisconnectCause.DnsExceptionOnConnect; + this.State = ClientState.Disconnecting; + break; + case StatusCode.ServerAddressInvalid: + this.DisconnectedCause = DisconnectCause.ServerAddressInvalid; + this.State = ClientState.Disconnecting; + break; case StatusCode.ExceptionOnConnect: case StatusCode.SecurityExceptionOnConnect: + case StatusCode.EncryptionFailedToEstablish: this.DisconnectedCause = DisconnectCause.ExceptionOnConnect; - this.State = ClientState.Disconnecting; + + // if enabled, the client can attempt to connect with another networking-protocol to check if that connects + if (this.EnableProtocolFallback && this.State == ClientState.ConnectingToNameServer) + { + this.State = ClientState.ConnectWithFallbackProtocol; + } + else + { + this.State = ClientState.Disconnecting; + } break; case StatusCode.Exception: case StatusCode.ExceptionOnReceive: + case StatusCode.SendError: this.DisconnectedCause = DisconnectCause.Exception; this.State = ClientState.Disconnecting; break; @@ -2658,7 +3137,16 @@ namespace Photon.Realtime break; case StatusCode.TimeoutDisconnect: this.DisconnectedCause = DisconnectCause.ClientTimeout; - this.State = ClientState.Disconnecting; + + // if enabled, the client can attempt to connect with another networking-protocol to check if that connects + if (this.EnableProtocolFallback && this.State == ClientState.ConnectingToNameServer) + { + this.State = ClientState.ConnectWithFallbackProtocol; + } + else + { + this.State = ClientState.Disconnecting; + } break; } } @@ -2677,7 +3165,6 @@ namespace Photon.Realtime { case EventCode.GameList: case EventCode.GameListUpdate: - List _RoomInfoList = new List(); Hashtable games = (Hashtable)photonEvent[ParameterCode.GameList]; @@ -2702,6 +3189,7 @@ namespace Photon.Realtime { originatingPlayer.InternalCacheProperties(actorProperties); originatingPlayer.IsInactive = false; + originatingPlayer.HasRejoined = actorNr != this.LocalPlayer.ActorNumber; // event is for non-local player, who is known (by ActorNumber), so it's a returning player } if (actorNr == this.LocalPlayer.ActorNumber) @@ -2709,8 +3197,12 @@ namespace Photon.Realtime // in this player's own join event, we get a complete list of players in the room, so check if we know each of the int[] actorsInRoom = (int[])photonEvent[ParameterCode.ActorList]; this.UpdatedActorList(actorsInRoom); + + // any operation that does a "rejoin" will set this value to true. this can indicate if the local player returns to a room. + originatingPlayer.HasRejoined = this.enterRoomParamsCache.JoinMode == JoinMode.RejoinOnly; + // joinWithCreateOnDemand can turn an OpJoin into creating the room. Then actorNumber is 1 and callback: OnCreatedRoom() - if (this.lastJoinType == JoinType.JoinOrCreateRoom && this.LocalPlayer.ActorNumber == 1) + if (this.lastJoinType == JoinType.CreateRoom || (this.lastJoinType == JoinType.JoinOrCreateRoom && this.LocalPlayer.ActorNumber == 1)) { this.MatchMakingCallbackTargets.OnCreatedRoom(); } @@ -2738,6 +3230,7 @@ namespace Photon.Realtime } else { + originatingPlayer.IsInactive = false; this.CurrentRoom.RemovePlayer(actorNr); } } @@ -2752,7 +3245,7 @@ namespace Photon.Realtime } } // finally, send notification that a player left - this.InRoomCallbackTargets.OnPlayerLeftRoom(originatingPlayer); // TODO: make sure it's clear how to separate "inactive"- from "abandon"-leave, as well as kicked out + this.InRoomCallbackTargets.OnPlayerLeftRoom(originatingPlayer); break; case EventCode.PropertiesChanged: @@ -2787,10 +3280,22 @@ namespace Photon.Realtime case EventCode.LobbyStats: string[] names = photonEvent[ParameterCode.LobbyName] as string[]; - byte[] types = photonEvent[ParameterCode.LobbyType] as byte[]; int[] peers = photonEvent[ParameterCode.PeerCount] as int[]; int[] rooms = photonEvent[ParameterCode.GameCount] as int[]; + byte[] types; + ByteArraySlice slice = photonEvent[ParameterCode.LobbyType] as ByteArraySlice; + bool useByteArraySlice = slice != null; + + if (useByteArraySlice) + { + types = slice.Buffer; + } + else + { + types = photonEvent[ParameterCode.LobbyType] as byte[]; + } + this.lobbyStatistics.Clear(); for (int i = 0; i < names.Length; i++) { @@ -2803,11 +3308,16 @@ namespace Photon.Realtime this.lobbyStatistics.Add(info); } + if (useByteArraySlice) + { + slice.Release(); + } + this.LobbyCallbackTargets.OnLobbyStatisticsUpdate(this.lobbyStatistics); break; case EventCode.ErrorInfo: - // if (this.OnEventAction != null) this.OnEventAction(photonEvent); // this gets called below for all events! + this.ErrorInfoCallbackTargets.OnErrorInfo(new ErrorInfo(photonEvent)); break; case EventCode.AuthEvent: @@ -2816,7 +3326,7 @@ namespace Photon.Realtime this.AuthValues = new AuthenticationValues(); } - this.AuthValues.Token = photonEvent[ParameterCode.Secret] as string; + this.AuthValues.Token = photonEvent[ParameterCode.Token] as string; this.tokenCache = this.AuthValues.Token; break; @@ -2834,6 +3344,41 @@ namespace Photon.Realtime #endregion + + private void OnDisconnectMessageReceived(DisconnectMessage obj) + { + this.DebugReturn(DebugLevel.ERROR, string.Format("Got DisconnectMessage. Code: {0} Msg: \"{1}\". Debug Info: {2}", obj.Code, obj.DebugMessage, obj.Parameters.ToStringFull())); + this.Disconnect(DisconnectCause.DisconnectByDisconnectMessage); + } + + + /// A callback of the RegionHandler, provided in OnRegionListReceived. + /// The regionHandler wraps up best region and other region relevant info. + private void OnRegionPingCompleted(RegionHandler regionHandler) + { + //Debug.Log("OnRegionPingCompleted " + regionHandler.BestRegion); + //Debug.Log("RegionPingSummary: " + regionHandler.SummaryToCache); + this.SummaryToCache = regionHandler.SummaryToCache; + this.ConnectToRegionMaster(regionHandler.BestRegion.Code); + } + + + protected internal static string ReplacePortWithAlternative(string address, ushort replacementPort) + { + bool webSocket = address.StartsWith("ws"); + if (webSocket) + { + UriBuilder urib = new UriBuilder(address); + urib.Port = replacementPort; + return urib.ToString(); + } + else + { + UriBuilder urib = new UriBuilder(string.Format("scheme://{0}", address)); + return string.Format("{0}:{1}", urib.Host, replacementPort); + } + } + private void SetupEncryption(Dictionary encryptionData) { var mode = (EncryptionMode)(byte)encryptionData[EncryptionDataParameters.Mode]; @@ -2851,6 +3396,12 @@ namespace Photon.Realtime this.LoadBalancingPeer.InitDatagramEncryption(secret1, secret2, mode == EncryptionMode.DatagramEncryptionRandomSequence); } break; + case EncryptionMode.DatagramEncryptionGCM: + { + byte[] secret1 = (byte[])encryptionData[EncryptionDataParameters.Secret1]; + this.LoadBalancingPeer.InitDatagramEncryption(secret1, null, true, true); + } + break; default: throw new ArgumentOutOfRangeException(); } @@ -2860,70 +3411,41 @@ namespace Photon.Realtime /// /// This operation makes Photon call your custom web-service by path/name with the given parameters (converted into Json). + /// Use as a callback. /// /// /// A WebRPC calls a custom, http-based function on a server you provide. The uriPath is relative to a "base path" /// which is configured server-side. The sent parameters get converted from C# types to Json. Vice versa, the response /// of the web-service will be converted to C# types and sent back as normal operation response. /// - /// /// To use this feature, you have to setup your server: /// /// For a Photon Cloud application, /// visit the Dashboard and setup "WebHooks". The BaseUrl is used for WebRPCs as well. /// - /// - /// The response by Photon will call OnOperationResponse() with Code: OperationCode.WebRpc. - /// To get this response, you can derive the LoadBalancingClient, or (much easier) you set a suitable - /// OnOpResponseAction to be called. - /// - /// - /// It's important to understand that the OperationResponse tells you if the WebRPC could be called or not - /// but the content of the response will contain the values the web-service sent (if any). - /// If the web-service could not execute the request, it might return another error and a message. This is - /// inside the OperationResponse. - /// - /// The class WebRpcResponse is a helper-class that extracts the most valuable content from the WebRPC + /// The class is a helper-class that extracts the most valuable content from the WebRPC /// response. /// - /// - /// To get a WebRPC response, set a OnOpResponseAction: - /// - /// this.OnOpResponseAction = this.OpResponseHandler; - /// - /// It could look like this: - /// - /// public void OpResponseHandler(OperationResponse operationResponse) - /// { - /// if (operationResponse.OperationCode == OperationCode.WebRpc) - /// { - /// if (operationResponse.ReturnCode != 0) - /// { - /// Console.WriteLine("WebRpc failed. Response: " + operationResponse.ToStringFull()); - /// } - /// else - /// { - /// WebRpcResponse webResponse = new WebRpcResponse(operationResponse); - /// Console.WriteLine(webResponse.DebugMessage); // message from the webserver - /// - /// // do something with the response... - /// } - /// } - /// } - /// /// The url path to call, relative to the baseUrl configured on Photon's server-side. /// The parameters to send to the web-service method. /// Defines if the authentication cookie gets sent to a WebHook (if setup). public bool OpWebRpc(string uriPath, object parameters, bool sendAuthCookie = false) { - if (!this.CheckIfOpAllowedOnServer(OperationCode.WebRpc, this.Server)) + if (string.IsNullOrEmpty(uriPath)) + { + this.DebugReturn(DebugLevel.ERROR, "WebRPC method name must not be null nor empty."); + return false; + } + if (!this.CheckIfOpCanBeSent(OperationCode.WebRpc, this.Server, "WebRpc")) { - this.DebugReturn(DebugLevel.ERROR, string.Format("Operation {0} ({1}) not allowed on current server ({2})", "WebRPC", OperationCode.WebRpc, this.Server)); return false; } Dictionary opParameters = new Dictionary(); opParameters.Add(ParameterCode.UriPath, uriPath); - opParameters.Add(ParameterCode.WebRpcParameters, parameters); + if (parameters != null) + { + opParameters.Add(ParameterCode.WebRpcParameters, parameters); + } if (sendAuthCookie) { opParameters.Add(ParameterCode.EventForward, WebFlags.SendAuthCookieConst); @@ -3011,6 +3533,7 @@ namespace Photon.Realtime this.UpdateCallbackTarget(change, this.MatchMakingCallbackTargets); this.UpdateCallbackTarget(change, this.LobbyCallbackTargets); this.UpdateCallbackTarget(change, this.WebRpcCallbackTargets); + this.UpdateCallbackTarget(change, this.ErrorInfoCallbackTargets); IOnEventCallback onEventCallback = change.Target as IOnEventCallback; if (onEventCallback != null) @@ -3420,9 +3943,97 @@ namespace Photon.Realtime /// Please note: Class OperationResponse is in a namespace which needs to be "used":
/// using ExitGames.Client.Photon; // includes OperationResponse (and other classes) ///
+ /// + /// public void OnWebRpcResponse(OperationResponse response) + /// { + /// Debug.LogFormat("WebRPC operation response {0}", response.ToStringFull()); + /// switch (response.ReturnCode) + /// { + /// case ErrorCode.Ok: + /// WebRpcResponse webRpcResponse = new WebRpcResponse(response); + /// Debug.LogFormat("Parsed WebRPC response {0}", response.ToStringFull()); + /// if (string.IsNullOrEmpty(webRpcResponse.Name)) + /// { + /// Debug.LogError("Unexpected: WebRPC response did not contain WebRPC method name"); + /// } + /// if (webRpcResponse.ResultCode == 0) // success + /// { + /// switch (webRpcResponse.Name) + /// { + /// // todo: add your code here + /// case GetGameListWebRpcMethodName: // example + /// // ... + /// break; + /// } + /// } + /// else if (webRpcResponse.ResultCode == -1) + /// { + /// Debug.LogErrorFormat("Web server did not return ResultCode for WebRPC method=\"{0}\", Message={1}", webRpcResponse.Name, webRpcResponse.Message); + /// } + /// else + /// { + /// Debug.LogErrorFormat("Web server returned ResultCode={0} for WebRPC method=\"{1}\", Message={2}", webRpcResponse.ResultCode, webRpcResponse.Name, webRpcResponse.Message); + /// } + /// break; + /// case ErrorCode.ExternalHttpCallFailed: // web service unreachable + /// Debug.LogErrorFormat("WebRPC call failed as request could not be sent to the server. {0}", response.DebugMessage); + /// break; + /// case ErrorCode.HttpLimitReached: // too many WebRPCs in a short period of time + /// // the debug message should contain the limit exceeded + /// Debug.LogErrorFormat("WebRPCs rate limit exceeded: {0}", response.DebugMessage); + /// break; + /// case ErrorCode.InvalidOperation: // WebRPC not configured at all OR not configured properly OR trying to send on name server + /// if (PhotonNetwork.Server == ServerConnection.NameServer) + /// { + /// Debug.LogErrorFormat("WebRPC not supported on NameServer. {0}", response.DebugMessage); + /// } + /// else + /// { + /// Debug.LogErrorFormat("WebRPC not properly configured or not configured at all. {0}", response.DebugMessage); + /// } + /// break; + /// default: + /// // other unknown error, unexpected + /// Debug.LogErrorFormat("Unexpected error, {0} {1}", response.ReturnCode, response.DebugMessage); + /// break; + /// } + /// } + /// + /// void OnWebRpcResponse(OperationResponse response); } + /// + /// Interface for event callback for the Realtime Api. + /// + /// + /// Classes that implement this interface must be registered to get callbacks for various situations. + /// + /// To register for callbacks, call and pass the class implementing this interface + /// To stop getting callbacks, call and pass the class implementing this interface + /// + /// + /// \ingroup callbacks + public interface IErrorInfoCallback + { + /// + /// Called when the client receives an event from the server indicating that an error happened there. + /// + /// + /// In most cases this could be either: + /// 1. an error from webhooks plugin (if HasErrorInfo is enabled), read more here: + /// https://doc.photonengine.com/en-us/realtime/current/gameplay/web-extensions/webhooks#options + /// 2. an error sent from a custom server plugin via PluginHost.BroadcastErrorInfoEvent, see example here: + /// https://doc.photonengine.com/en-us/server/current/plugins/manual#handling_http_response + /// 3. an error sent from the server, for example, when the limit of cached events has been exceeded in the room + /// (all clients will be disconnected and the room will be closed in this case) + /// read more here: https://doc.photonengine.com/en-us/realtime/current/gameplay/cached-events#special_considerations + /// + /// If you implement or you will also get this event. + /// + /// Object containing information about the error + void OnErrorInfo(ErrorInfo errorInfo); + } /// /// Container type for callbacks defined by IConnectionCallbacks. See LoadBalancingCallbackTargets. @@ -3739,4 +4350,65 @@ namespace Photon.Realtime } } } + + + /// + /// Container type for callbacks defined by . See . + /// + /// + /// While the interfaces of callbacks wrap up the methods that will be called, + /// the container classes implement a simple way to call a method on all registered objects. + /// + internal class ErrorInfoCallbacksContainer : List, IErrorInfoCallback + { + private LoadBalancingClient client; + + public ErrorInfoCallbacksContainer(LoadBalancingClient client) + { + this.client = client; + } + + public void OnErrorInfo(ErrorInfo errorInfo) + { + this.client.UpdateCallbackTargets(); + foreach (IErrorInfoCallback target in this) + { + target.OnErrorInfo(errorInfo); + } + } + } + + /// + /// Class wrapping the received event. + /// + /// + /// This is passed inside callback. + /// If you implement or you will also get but not parsed. + /// + /// In most cases this could be either: + /// 1. an error from webhooks plugin (if HasErrorInfo is enabled), read more here: + /// https://doc.photonengine.com/en-us/realtime/current/gameplay/web-extensions/webhooks#options + /// 2. an error sent from a custom server plugin via PluginHost.BroadcastErrorInfoEvent, see example here: + /// https://doc.photonengine.com/en-us/server/current/plugins/manual#handling_http_response + /// 3. an error sent from the server, for example, when the limit of cached events has been exceeded in the room + /// (all clients will be disconnected and the room will be closed in this case) + /// read more here: https://doc.photonengine.com/en-us/realtime/current/gameplay/cached-events#special_considerations + /// + public class ErrorInfo + { + /// + /// String containing information about the error. + /// + public readonly string Info; + + public ErrorInfo(EventData eventData) + { + this.Info = eventData[ParameterCode.Info] as string; + } + + public override string ToString() + { + return string.Format("ErrorInfo: {0}", this.Info); + } + } } \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/LoadbalancingPeer.cs b/Assets/Photon/PhotonRealtime/Code/LoadbalancingPeer.cs index e8fae8b..65b0785 100644 --- a/Assets/Photon/PhotonRealtime/Code/LoadbalancingPeer.cs +++ b/Assets/Photon/PhotonRealtime/Code/LoadbalancingPeer.cs @@ -40,9 +40,19 @@ namespace Photon.Realtime /// public class LoadBalancingPeer : PhotonPeer { - protected internal static Type PingImplementation = null; + /// Obsolete accessor to the RegionHandler.PingImplementation. + [Obsolete("Use RegionHandler.PingImplementation directly.")] + protected internal static Type PingImplementation + { + get { return RegionHandler.PingImplementation; } + set { RegionHandler.PingImplementation = value; } + } - private readonly Dictionary opRaiseEventParameters = new Dictionary(); // used in OpRaiseEvent() (avoids lots of new Dictionary() calls) + + private readonly Pool paramDictionaryPool = new Pool( + () => new ParameterDictionary(), + x => x.Clear(), + 1); // used in OpRaiseEvent() (avoids lots of new Dictionary() calls) /// @@ -71,19 +81,8 @@ namespace Photon.Realtime [System.Diagnostics.Conditional("SUPPORTED_UNITY")] private void ConfigUnitySockets() { - #if !NETFX_CORE && !NO_SOCKET - PingImplementation = typeof(PingMono); - #endif - #if UNITY_WEBGL - PingImplementation = typeof(PingHttp); - #endif - #if !UNITY_EDITOR && NETFX_CORE - PingImplementation = typeof(PingWindowsStore); - #endif - - Type websocketType = null; - #if UNITY_XBOXONE && !UNITY_EDITOR + #if (UNITY_XBOXONE || UNITY_GAMECORE) && !UNITY_EDITOR websocketType = Type.GetType("ExitGames.Client.Photon.SocketNativeSource, PhotonRealtime", false); if (websocketType == null) { @@ -95,7 +94,7 @@ namespace Photon.Realtime } if (websocketType == null) { - Debug.LogError("UNITY_XBOXONE is defined but peer could not find SocketNativeSource. Check your project files to make sure the native WSS implementation is available. Won't connect."); + UnityEngine.Debug.LogError("XBOX is defined but peer could not find SocketNativeSource. Check your project files to make sure the native WSS implementation is available. Won't connect."); } #else // to support WebGL export in Unity, we find and assign the SocketWebTcp class (if it's in the project). @@ -117,7 +116,7 @@ namespace Photon.Realtime this.SocketImplementationConfig[ConnectionProtocol.WebSocketSecure] = websocketType; } - #if NET_4_6 && (UNITY_EDITOR || !ENABLE_IL2CPP) + #if NET_4_6 && (UNITY_EDITOR || !ENABLE_IL2CPP) && !NETFX_CORE this.SocketImplementationConfig[ConnectionProtocol.Udp] = typeof(SocketUdpAsync); this.SocketImplementationConfig[ConnectionProtocol.Tcp] = typeof(SocketTcpAsync); #endif @@ -169,21 +168,10 @@ namespace Photon.Realtime this.Listener.DebugReturn(DebugLevel.INFO, "OpLeaveLobby()"); } - return this.SendOperation(OperationCode.LeaveLobby, null, SendOptions.SendReliable); + return this.SendOperation(OperationCode.LeaveLobby, (Dictionary)null, SendOptions.SendReliable); } - /// Used in the RoomOptionFlags parameter, this bitmask toggles options in the room. - enum RoomOptionBit : int - { - CheckUserOnJoin = 0x01, // toggles a check of the UserId when joining (enabling returning to a game) - DeleteCacheOnLeave = 0x02, // deletes cache on leave - SuppressRoomEvents = 0x04, // suppresses all room events - PublishUserId = 0x08, // signals that we should publish userId - DeleteNullProps = 0x10, // signals that we should remove property if its value was set to null. see RoomOption to Delete Null Properties - BroadcastPropsChangeToAll = 0x20, // signals that we should send PropertyChanged event to all room players including initiator - } - /// Used by OpJoinRoom and by OpCreateRoom alike. private void RoomOptionsToOpParameters(Dictionary op, RoomOptions roomOptions, bool usePropertiesKey = false) { @@ -252,6 +240,11 @@ namespace Photon.Realtime flags = flags | (int)RoomOptionBit.SuppressRoomEvents; op[ParameterCode.SuppressRoomEvents] = true; } + if (roomOptions.SuppressPlayerInfo) + { + flags = flags | (int)RoomOptionBit.SuppressPlayerInfo; + } + if (roomOptions.Plugins != null) { op[ParameterCode.Plugins] = roomOptions.Plugins; @@ -312,8 +305,8 @@ namespace Photon.Realtime if (opParams.PlayerProperties != null && opParams.PlayerProperties.Count > 0) { op[ParameterCode.PlayerProperties] = opParams.PlayerProperties; - op[ParameterCode.Broadcast] = true; // TODO: check if this also makes sense when creating a room?! // broadcast actor properties } + op[ParameterCode.Broadcast] = true; // broadcast actor properties this.RoomOptionsToOpParameters(op, opParams.RoomOptions); } @@ -347,7 +340,7 @@ namespace Photon.Realtime op[ParameterCode.RoomName] = opParams.RoomName; } - if (opParams.CreateIfNotExists) + if (opParams.JoinMode == JoinMode.CreateIfNotExists) { op[ParameterCode.JoinMode] = (byte)JoinMode.CreateIfNotExists; if (opParams.Lobby != null && !opParams.Lobby.IsDefault) @@ -356,8 +349,7 @@ namespace Photon.Realtime op[ParameterCode.LobbyType] = (byte)opParams.Lobby.Type; } } - - if (opParams.RejoinOnly) + else if (opParams.JoinMode == JoinMode.RejoinOnly) { op[ParameterCode.JoinMode] = (byte)JoinMode.RejoinOnly; // changed from JoinMode.JoinOrRejoin } @@ -372,10 +364,10 @@ namespace Photon.Realtime if (opParams.PlayerProperties != null && opParams.PlayerProperties.Count > 0) { op[ParameterCode.PlayerProperties] = opParams.PlayerProperties; - op[ParameterCode.Broadcast] = true; // broadcast actor properties } + op[ParameterCode.Broadcast] = true; // broadcast actor properties - if (opParams.CreateIfNotExists) + if (opParams.JoinMode == JoinMode.CreateIfNotExists) { this.RoomOptionsToOpParameters(op, opParams.RoomOptions); } @@ -641,11 +633,11 @@ namespace Photon.Realtime this.Listener.DebugReturn(DebugLevel.INFO, "OpSetPropertiesOfActor()"); } - if (actorNr <= 0 || actorProperties == null) + if (actorNr <= 0 || actorProperties == null || actorProperties.Count == 0) { if (this.DebugOut >= DebugLevel.INFO) { - this.Listener.DebugReturn(DebugLevel.INFO, "OpSetPropertiesOfActor not sent. ActorNr must be > 0 and actorProperties != null."); + this.Listener.DebugReturn(DebugLevel.INFO, "OpSetPropertiesOfActor not sent. ActorNr must be > 0 and actorProperties must be not null nor empty."); } return false; } @@ -668,11 +660,11 @@ namespace Photon.Realtime } - protected void OpSetPropertyOfRoom(byte propCode, object value) + protected bool OpSetPropertyOfRoom(byte propCode, object value) { Hashtable properties = new Hashtable(); properties[propCode] = value; - this.OpSetPropertiesOfRoom(properties); + return this.OpSetPropertiesOfRoom(properties); } public bool OpSetCustomPropertiesOfRoom(Hashtable gameProperties) @@ -694,6 +686,14 @@ namespace Photon.Realtime { this.Listener.DebugReturn(DebugLevel.INFO, "OpSetPropertiesOfRoom()"); } + if (gameProperties == null || gameProperties.Count == 0) + { + if (this.DebugOut >= DebugLevel.INFO) + { + this.Listener.DebugReturn(DebugLevel.INFO, "OpSetPropertiesOfRoom not sent. gameProperties must be not null nor empty."); + } + return false; + } Dictionary opParameters = new Dictionary(); opParameters.Add(ParameterCode.Properties, gameProperties); @@ -743,7 +743,7 @@ namespace Photon.Realtime // shortcut, if we have a Token if (authValues != null && authValues.Token != null) { - opParameters[ParameterCode.Secret] = authValues.Token; + opParameters[ParameterCode.Token] = authValues.Token; return this.SendOperation(OperationCode.Authenticate, opParameters, SendOptions.SendReliable); // we don't have to encrypt, when we have a token (which is encrypted) } @@ -781,7 +781,7 @@ namespace Photon.Realtime } } - return this.SendOperation(OperationCode.Authenticate, opParameters, new SendOptions() { Reliability = true, Encrypt = this.IsEncryptionAvailable }); + return this.SendOperation(OperationCode.Authenticate, opParameters, new SendOptions() { Reliability = true, Encrypt = true }); } @@ -805,16 +805,15 @@ namespace Photon.Realtime { if (this.DebugOut >= DebugLevel.INFO) { - this.Listener.DebugReturn(DebugLevel.INFO, "OpAuthenticateOnce()"); + this.Listener.DebugReturn(DebugLevel.INFO, "OpAuthenticateOnce(): authValues = " + authValues + ", region = " + regionCode + ", encryption = " + encryptionMode); } - var opParameters = new Dictionary(); // shortcut, if we have a Token if (authValues != null && authValues.Token != null) { - opParameters[ParameterCode.Secret] = authValues.Token; + opParameters[ParameterCode.Token] = authValues.Token; return this.SendOperation(OperationCode.AuthenticateOnce, opParameters, SendOptions.SendReliable); // we don't have to encrypt, when we have a token (which is encrypted) } @@ -845,9 +844,9 @@ namespace Photon.Realtime if (authValues.AuthType != CustomAuthenticationType.None) { opParameters[ParameterCode.ClientAuthenticationType] = (byte)authValues.AuthType; - if (!string.IsNullOrEmpty(authValues.Token)) + if (authValues.Token != null) { - opParameters[ParameterCode.Secret] = authValues.Token; + opParameters[ParameterCode.Token] = authValues.Token; } else { @@ -863,7 +862,7 @@ namespace Photon.Realtime } } - return this.SendOperation(OperationCode.AuthenticateOnce, opParameters, new SendOptions() { Reliability = true, Encrypt = this.IsEncryptionAvailable }); + return this.SendOperation(OperationCode.AuthenticateOnce, opParameters, new SendOptions() { Reliability = true, Encrypt = true }); } /// @@ -912,56 +911,63 @@ namespace Photon.Realtime /// If operation could be enqueued for sending. Sent when calling: Service or SendOutgoingCommands. public virtual bool OpRaiseEvent(byte eventCode, object customEventContent, RaiseEventOptions raiseEventOptions, SendOptions sendOptions) { - this.opRaiseEventParameters.Clear(); // re-used private variable to avoid many new Dictionary() calls (garbage collection) - if (raiseEventOptions != null) + var paramDict = this.paramDictionaryPool.Acquire(); + try { - if (raiseEventOptions.CachingOption != EventCaching.DoNotCache) + if (raiseEventOptions != null) { - this.opRaiseEventParameters[(byte)ParameterCode.Cache] = (byte)raiseEventOptions.CachingOption; + if (raiseEventOptions.CachingOption != EventCaching.DoNotCache) + { + paramDict.Add(ParameterCode.Cache, (byte)raiseEventOptions.CachingOption); + } + switch (raiseEventOptions.CachingOption) + { + case EventCaching.SliceSetIndex: + case EventCaching.SlicePurgeIndex: + case EventCaching.SlicePurgeUpToIndex: + //this.opParameters[(byte) ParameterCode.CacheSliceIndex] = + // (byte) raiseEventOptions.CacheSliceIndex; + return this.SendOperation(OperationCode.RaiseEvent, paramDict, sendOptions); + case EventCaching.SliceIncreaseIndex: + case EventCaching.RemoveFromRoomCacheForActorsLeft: + return this.SendOperation(OperationCode.RaiseEvent, paramDict, sendOptions); + case EventCaching.RemoveFromRoomCache: + if (raiseEventOptions.TargetActors != null) + { + paramDict.Add(ParameterCode.ActorList, raiseEventOptions.TargetActors); + } + break; + default: + if (raiseEventOptions.TargetActors != null) + { + paramDict.Add(ParameterCode.ActorList, raiseEventOptions.TargetActors); + } + else if (raiseEventOptions.InterestGroup != 0) + { + paramDict.Add(ParameterCode.Group, (byte)raiseEventOptions.InterestGroup); + } + else if (raiseEventOptions.Receivers != ReceiverGroup.Others) + { + paramDict.Add(ParameterCode.ReceiverGroup, (byte)raiseEventOptions.Receivers); + } + if (raiseEventOptions.Flags.HttpForward) + { + paramDict.Add(ParameterCode.EventForward, (byte)raiseEventOptions.Flags.WebhookFlags); + } + break; + } } - switch (raiseEventOptions.CachingOption) + paramDict.Add(ParameterCode.Code, (byte)eventCode); + if (customEventContent != null) { - case EventCaching.SliceSetIndex: - case EventCaching.SlicePurgeIndex: - case EventCaching.SlicePurgeUpToIndex: - //this.opParameters[(byte) ParameterCode.CacheSliceIndex] = - // (byte) raiseEventOptions.CacheSliceIndex; - return this.SendOperation(OperationCode.RaiseEvent, this.opRaiseEventParameters, sendOptions); - case EventCaching.SliceIncreaseIndex: - case EventCaching.RemoveFromRoomCacheForActorsLeft: - return this.SendOperation(OperationCode.RaiseEvent, this.opRaiseEventParameters, sendOptions); - case EventCaching.RemoveFromRoomCache: - if (raiseEventOptions.TargetActors != null) - { - this.opRaiseEventParameters[(byte)ParameterCode.ActorList] = raiseEventOptions.TargetActors; - } - break; - default: - if (raiseEventOptions.TargetActors != null) - { - this.opRaiseEventParameters[(byte)ParameterCode.ActorList] = raiseEventOptions.TargetActors; - } - else if (raiseEventOptions.InterestGroup != 0) - { - this.opRaiseEventParameters[(byte)ParameterCode.Group] = raiseEventOptions.InterestGroup; - } - else if (raiseEventOptions.Receivers != ReceiverGroup.Others) - { - this.opRaiseEventParameters[(byte)ParameterCode.ReceiverGroup] = (byte)raiseEventOptions.Receivers; - } - if (raiseEventOptions.Flags.HttpForward) - { - this.opRaiseEventParameters[(byte)ParameterCode.EventForward] = raiseEventOptions.Flags.WebhookFlags; - } - break; + paramDict.Add(ParameterCode.Data, (object)customEventContent); } + return this.SendOperation(OperationCode.RaiseEvent, paramDict, sendOptions); } - this.opRaiseEventParameters[(byte)ParameterCode.Code] = (byte)eventCode; - if (customEventContent != null) + finally { - this.opRaiseEventParameters[(byte)ParameterCode.Data] = customEventContent; + this.paramDictionaryPool.Release(paramDict); } - return this.SendOperation(OperationCode.RaiseEvent, this.opRaiseEventParameters, sendOptions); } @@ -995,6 +1001,17 @@ namespace Photon.Realtime } } + /// Used in the RoomOptionFlags parameter, this bitmask toggles options in the room. + internal enum RoomOptionBit : int + { + CheckUserOnJoin = 0x01, // toggles a check of the UserId when joining (enabling returning to a game) + DeleteCacheOnLeave = 0x02, // deletes cache on leave + SuppressRoomEvents = 0x04, // suppresses all room events + PublishUserId = 0x08, // signals that we should publish userId + DeleteNullProps = 0x10, // signals that we should remove property if its value was set to null. see RoomOption to Delete Null Properties + BroadcastPropsChangeToAll = 0x20, // signals that we should send PropertyChanged event to all room players including initiator + SuppressPlayerInfo = 0x40, // disables events join and leave from the server as well as property broadcasts in a room (to minimize traffic) + } /// /// Options for OpFindFriends can be combined to filter which rooms of friends are returned. @@ -1030,26 +1047,45 @@ namespace Photon.Realtime } - + /// + /// Parameters for the matchmaking of JoinRandomRoom and JoinRandomOrCreateRoom. + /// + /// + /// More about matchmaking: . + /// public class OpJoinRandomRoomParams { + /// The custom room properties a room must have to fit. All key-values must be present to match. In SQL Lobby, use SqlLobbyFilter instead. public Hashtable ExpectedCustomRoomProperties; + /// Filters by the MaxPlayers value of rooms. public byte ExpectedMaxPlayers; + /// The MatchmakingMode affects how rooms get filled. By default, the server fills rooms. public MatchmakingMode MatchingType; + /// The lobby in which to match. The type affects how filters are applied. public TypedLobby TypedLobby; + /// SQL query to filter room matches. For default-typed lobbies, use ExpectedCustomRoomProperties instead. public string SqlLobbyFilter; + /// The expected users list blocks player slots for your friends or team mates to join the room, too. + /// See: https://doc.photonengine.com/en-us/pun/v2/lobby-and-matchmaking/matchmaking-and-lobby#matchmaking_slot_reservation public string[] ExpectedUsers; } + /// Parameters for creating rooms. public class EnterRoomParams { + /// The name of the room to create. If null, the server generates a unique name. If not null, it must be unique and new or will cause an error. public string RoomName; + /// The RoomOptions define the optional behaviour of rooms. public RoomOptions RoomOptions; + /// A lobby to attach the new room to. If set, this overrides a joined lobby (if any). public TypedLobby Lobby; + /// The custom player properties that describe this client / user. Keys must be strings. public Hashtable PlayerProperties; + /// Internally used value to skip some values when the operation is sent to the Master Server. protected internal bool OnGameServer = true; // defaults to true! better send more parameter than too few (GS needs all) - public bool CreateIfNotExists; - public bool RejoinOnly; + /// Internally used value to check which join mode we should call. + protected internal JoinMode JoinMode; + /// A list of users who are expected to join the room along with this client. Reserves slots for rooms with MaxPlayers value. public string[] ExpectedUsers; } @@ -1203,6 +1239,11 @@ namespace Photon.Realtime /// public const int ExternalHttpCallFailed = 32744; // 0x7FFF - 23, + /// + /// (32743) for operations with defined limits (as in calls per second, content count or size). + /// + public const int OperationLimitReached = 32743; // 0x7FFF - 24, + /// /// (32742) Server error during matchmaking with slot reservation. E.g. the reserved slots can not exceed MaxPlayers. /// @@ -1323,10 +1364,10 @@ namespace Photon.Realtime [Obsolete("Use PropertiesChanged now.")] public const byte SetProperties = (byte)253; - /// (252) When player left game unexpected and the room has a playerTtl != 0, this event is fired to let everyone know about the timeout. + /// (252) When player left game unexpected and the room has a playerTtl != 0, this event is fired to let everyone know about the timeout. /// Obsolete. Replaced by Leave. public const byte Disconnect = LiteEventCode.Disconnect; - /// (251) Sent by Photon Cloud when a plugin-call or webhook-call failed. Usually, the execution on the server continues, despite the issue. Contains: ParameterCode.Info. + /// (251) Sent by Photon Cloud when a plugin-call or webhook-call failed or events cache limit exceeded. Usually, the execution on the server continues, despite the issue. Contains: ParameterCode.Info. /// public const byte ErrorInfo = 251; @@ -1395,7 +1436,7 @@ namespace Photon.Realtime public const byte GameList = 222; /// (221) Internally used to establish encryption - public const byte Secret = 221; + public const byte Token = 221; /// (220) Version of your application public const byte AppVersion = 220; @@ -1418,7 +1459,7 @@ namespace Photon.Realtime /// (250) Code for broadcast parameter of OpSetProperties method. public const byte Broadcast = (byte)250; - /// (252) Code for list of players in a room. Currently not used. + /// (252) Code for list of players in a room. public const byte ActorList = (byte)252; /// (254) Code of the Actor of an operation. Used for property get and set. @@ -1838,6 +1879,9 @@ namespace Photon.Realtime /// public bool SuppressRoomEvents { get; set; } + /// Disables events join and leave from the server as well as property broadcasts in a room (to minimize traffic) + public bool SuppressPlayerInfo { get; set; } + /// /// Defines if the UserIds of players get "published" in the room. Useful for FindFriends, if players want to play another game together. /// @@ -2021,7 +2065,7 @@ namespace Photon.Realtime /// public enum CustomAuthenticationType : byte { - /// Use a custom authentification service. Currently the only implemented option. + /// Use a custom authentication service. Currently the only implemented option. Custom = 0, /// Authenticates users by their Steam Account. Set auth values accordingly! @@ -2044,6 +2088,9 @@ namespace Photon.Realtime /// Authenticates users by their NSA ID. NintendoSwitch = 11, + + /// Authenticates users by their PSN Account and token (on PS5). + Playstation5 = 12, /// Disables custom authentification. Same as not providing any AuthenticationValues for connect (more precisely for: OpAuthenticate). None = byte.MaxValue @@ -2074,7 +2121,8 @@ namespace Photon.Realtime /// See AuthType. private CustomAuthenticationType authType = CustomAuthenticationType.None; - /// The type of custom authentication provider that should be used. Currently only "Custom" or "None" (turns this off). + /// The type of authentication provider that should be used. Defaults to None (no auth whatsoever). + /// Several auth providers are available and CustomAuthenticationType.Custom can be used if you build your own service. public CustomAuthenticationType AuthType { get { return authType; } @@ -2092,8 +2140,9 @@ namespace Photon.Realtime /// Maps to operation parameter 214. public object AuthPostData { get; private set; } - /// After initial authentication, Photon provides a token for this client / user, which is subsequently used as (cached) validation. - public string Token { get; set; } + /// Internal Photon token. After initial authentication, Photon provides a token for this client, subsequently used as (cached) validation. + /// Any token for custom authentication should be set via SetAuthPostData or AddAuthParameter. + public object Token { get; protected internal set; } /// The UserId should be a unique identifier per user. This is for finding friends, etc.. /// See remarks of AuthValues for info about how this is set and used. @@ -2113,7 +2162,7 @@ namespace Photon.Realtime } /// Sets the data to be passed-on to the auth service via POST. - /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. Each SetAuthPostData replaces any previous value. + /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. /// String data to be used in the body of the POST request. Null or empty string will set AuthPostData to null. public virtual void SetAuthPostData(string stringData) { @@ -2121,7 +2170,7 @@ namespace Photon.Realtime } /// Sets the data to be passed-on to the auth service via POST. - /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. Each SetAuthPostData replaces any previous value. + /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. /// Binary token / auth-data to pass on. public virtual void SetAuthPostData(byte[] byteData) { @@ -2129,7 +2178,7 @@ namespace Photon.Realtime } /// Sets data to be passed-on to the auth service as Json (Content-Type: "application/json") via Post. - /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. Each SetAuthPostData replaces any previous value. + /// AuthPostData is just one value. Each SetAuthPostData replaces any previous value. It can be either a string, a byte[] or a dictionary. /// A authentication-data dictionary will be converted to Json and passed to the Auth webservice via HTTP Post. public virtual void SetAuthPostData(Dictionary dictData) { @@ -2146,9 +2195,32 @@ namespace Photon.Realtime this.AuthGetParameters = string.Format("{0}{1}{2}={3}", this.AuthGetParameters, ampersand, System.Uri.EscapeDataString(key), System.Uri.EscapeDataString(value)); } + /// + /// Transform this object into string. + /// + /// String info about this object's values. public override string ToString() { - return string.Format("AuthenticationValues Type: {3} UserId: {0}, GetParameters: {1} Token available: {2}", this.UserId, this.AuthGetParameters, !string.IsNullOrEmpty(this.Token), this.AuthType); + return string.Format("AuthenticationValues = AuthType: {0} UserId: {1}{2}{3}{4}", + this.AuthType, + this.UserId, + string.IsNullOrEmpty(this.AuthGetParameters) ? " GetParameters: yes" : "", + this.AuthPostData == null ? "" : " PostData: yes", + this.Token == null ? "" : " Token: yes"); + } + + /// + /// Make a copy of the current object. + /// + /// The object to be copied into. + /// The copied object. + public AuthenticationValues CopyTo(AuthenticationValues copy) + { + copy.AuthType = this.AuthType; + copy.AuthGetParameters = this.AuthGetParameters; + copy.AuthPostData = this.AuthPostData; + copy.UserId = this.UserId; + return copy; } } -} \ No newline at end of file +} diff --git a/Assets/Photon/PhotonRealtime/Code/PhotonPing.cs b/Assets/Photon/PhotonRealtime/Code/PhotonPing.cs index cbf0864..3c873c7 100644 --- a/Assets/Photon/PhotonRealtime/Code/PhotonPing.cs +++ b/Assets/Photon/PhotonRealtime/Code/PhotonPing.cs @@ -1,28 +1,49 @@ -using System; -using System.Collections; -using System.Threading; - -#if NETFX_CORE -using System.Diagnostics; -using Windows.Foundation; -using Windows.Networking; -using Windows.Networking.Sockets; -using Windows.Storage.Streams; -#endif - -#if !NO_SOCKET && !NETFX_CORE -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Sockets; -#endif +// ---------------------------------------------------------------------------- +// +// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH +// +// +// This file includes various PhotonPing implementations for different APIs, +// platforms and protocols. +// The RegionPinger class is the instance which selects the Ping implementation +// to use. +// +// developer@exitgames.com +// ---------------------------------------------------------------------------- namespace Photon.Realtime { + using System; + using System.Collections; + using System.Threading; + + #if NETFX_CORE + using System.Diagnostics; + using Windows.Foundation; + using Windows.Networking; + using Windows.Networking.Sockets; + using Windows.Storage.Streams; + #endif + + #if !NO_SOCKET && !NETFX_CORE + using System.Collections.Generic; + using System.Diagnostics; + using System.Net.Sockets; + #endif + + #if UNITY_WEBGL + // import WWW class + using UnityEngine; + #endif + /// + /// Abstract implementation of PhotonPing, ase for pinging servers to find the "Best Region". + /// public abstract class PhotonPing : IDisposable { public string DebugString = ""; + public bool Successful; protected internal bool GotResult; @@ -33,7 +54,7 @@ namespace Photon.Realtime protected internal byte PingId; - private static readonly Random RandomIdProvider = new Random(); + private static readonly System.Random RandomIdProvider = new System.Random(); public virtual bool StartPing(string ip) { @@ -50,7 +71,6 @@ namespace Photon.Realtime throw new NotImplementedException(); } - protected internal void Init() { this.GotResult = false; @@ -70,7 +90,7 @@ namespace Photon.Realtime /// /// Sends a "Photon Ping" to a server. /// - /// Address in IPv4 or IPv6 format. An address containing a '.' will be interpretet as IPv4. + /// Address in IPv4 or IPv6 format. An address containing a '.' will be interpreted as IPv4. /// True if the Photon Ping could be sent. public override bool StartPing(string ip) { @@ -90,13 +110,14 @@ namespace Photon.Realtime } this.sock.ReceiveTimeout = 5000; - this.sock.Connect(ip, 5055); + int port = (RegionHandler.PortToPingOverride != 0) ? RegionHandler.PortToPingOverride : 5055; + this.sock.Connect(ip, port); } this.PingBytes[this.PingBytes.Length - 1] = this.PingId; this.sock.Send(this.PingBytes); - this.PingBytes[this.PingBytes.Length - 1] = (byte)(this.PingId+1); // invalidate the result, as we re-use the buffer + this.PingBytes[this.PingBytes.Length - 1] = (byte)(this.PingId+1); // this buffer is re-used for the result/receive. invalidate the result now. } catch (Exception e) { @@ -111,15 +132,29 @@ namespace Photon.Realtime { if (this.GotResult || this.sock == null) { - return true; + return true; // this just indicates the ping is no longer waiting. this.Successful value defines if the roundtrip completed } - if (!this.sock.Poll(0, SelectMode.SelectRead)) + int read = 0; + try { - return false; - } + if (!this.sock.Poll(0, SelectMode.SelectRead)) + { + return false; + } - int read = this.sock.Receive(this.PingBytes, SocketFlags.None); + read = this.sock.Receive(this.PingBytes, SocketFlags.None); + } + catch (Exception ex) + { + if (this.sock != null) + { + this.sock.Close(); + this.sock = null; + } + this.DebugString += " Exception of socket! " + ex.GetType() + " "; + return true; // this just indicates the ping is no longer waiting. this.Successful value defines if the roundtrip completed + } bool replyMatch = this.PingBytes[this.PingBytes.Length - 1] == this.PingId && read == this.PingLength; if (!replyMatch) @@ -151,7 +186,7 @@ namespace Photon.Realtime #if NETFX_CORE - /// Windows store API implementation of PhotonPing + /// Windows store API implementation of PhotonPing, based on DatagramSocket for UDP. public class PingWindowsStore : PhotonPing { private DatagramSocket sock; @@ -159,54 +194,67 @@ namespace Photon.Realtime public override bool StartPing(string host) { - base.Init(); + lock (this.syncer) + { + this.Init(); - EndpointPair endPoint = new EndpointPair(null, string.Empty, new HostName(host), "5055"); - this.sock = new DatagramSocket(); - this.sock.MessageReceived += OnMessageReceived; + int port = (RegionHandler.PortToPingOverride != 0) ? RegionHandler.PortToPingOverride : 5055; + EndpointPair endPoint = new EndpointPair(null, string.Empty, new HostName(host), port.ToString()); + this.sock = new DatagramSocket(); + this.sock.MessageReceived += this.OnMessageReceived; - var result = this.sock.ConnectAsync(endPoint); - result.Completed = this.OnConnected; - this.DebugString += " End StartPing"; - return true; + IAsyncAction result = this.sock.ConnectAsync(endPoint); + result.Completed = this.OnConnected; + this.DebugString += " End StartPing"; + return true; + } } public override bool Done() { - return this.GotResult; + lock (this.syncer) + { + return this.GotResult || this.sock == null; // this just indicates the ping is no longer waiting. this.Successful value defines if the roundtrip completed + } } public override void Dispose() { - this.sock = null; + lock (this.syncer) + { + this.sock = null; + } } private void OnConnected(IAsyncAction asyncinfo, AsyncStatus asyncstatus) { - if (asyncinfo.AsTask().IsCompleted) + lock (this.syncer) { - PingBytes[PingBytes.Length - 1] = PingId; + if (asyncinfo.AsTask().IsCompleted && !asyncinfo.AsTask().IsFaulted && this.sock != null && this.sock.Information.RemoteAddress != null) + { + this.PingBytes[this.PingBytes.Length - 1] = this.PingId; - DataWriter writer; - writer = new DataWriter(sock.OutputStream); - writer.WriteBytes(PingBytes); - var res = writer.StoreAsync(); - res.AsTask().Wait(100); + DataWriter writer; + writer = new DataWriter(this.sock.OutputStream); + writer.WriteBytes(this.PingBytes); + DataWriterStoreOperation res = writer.StoreAsync(); + res.AsTask().Wait(100); - writer.DetachStream(); - writer.Dispose(); + this.PingBytes[this.PingBytes.Length - 1] = (byte)(this.PingId + 1); // this buffer is re-used for the result/receive. invalidate the result now. - PingBytes[PingBytes.Length - 1] = (byte)(PingId - 1); - } - else - { - // TODO: handle error + writer.DetachStream(); + writer.Dispose(); + } + else + { + this.sock = null; // will cause Done() to return true but this.Successful defines if the roundtrip completed + } } } private void OnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { - lock (syncer) + lock (this.syncer) { DataReader reader = null; try @@ -215,15 +263,14 @@ namespace Photon.Realtime uint receivedByteCount = reader.UnconsumedBufferLength; if (receivedByteCount > 0) { - var resultBytes = new byte[receivedByteCount]; + byte[] resultBytes = new byte[receivedByteCount]; reader.ReadBytes(resultBytes); //TODO: check result bytes! - this.Successful = receivedByteCount == PingLength && resultBytes[resultBytes.Length - 1] == PingId; + this.Successful = receivedByteCount == this.PingLength && resultBytes[resultBytes.Length - 1] == this.PingId; this.GotResult = true; - } } catch @@ -397,4 +444,37 @@ namespace Photon.Realtime } #endif #endif + + + #if UNITY_WEBGL + public class PingHttp : PhotonPing + { + private WWW webRequest; + + public override bool StartPing(string address) + { + base.Init(); + + address = "https://" + address + "/photon/m/?ping&r=" + UnityEngine.Random.Range(0, 10000); + this.webRequest = new WWW(address); + return true; + } + + public override bool Done() + { + if (this.webRequest.isDone) + { + Successful = true; + return true; + } + + return false; + } + + public override void Dispose() + { + this.webRequest.Dispose(); + } + } + #endif } \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/PhotonPingClasses.cs b/Assets/Photon/PhotonRealtime/Code/PhotonPingClasses.cs index 346e5b4..70f0337 100644 --- a/Assets/Photon/PhotonRealtime/Code/PhotonPingClasses.cs +++ b/Assets/Photon/PhotonRealtime/Code/PhotonPingClasses.cs @@ -1,61 +1 @@ -// ---------------------------------------------------------------------------- -// -// Loadbalancing Framework for Photon - Copyright (C) 2018 Exit Games GmbH -// -// -// Provides implementations of the PhotonPing for various platforms and -// use cases. -// -// developer@photonengine.com -// ---------------------------------------------------------------------------- - -#if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER -#define SUPPORTED_UNITY -#endif - -#if SUPPORTED_UNITY -namespace Photon.Realtime -{ - using System; - using System.Net.Sockets; - using ExitGames.Client.Photon; - - #if UNITY_WEBGL - // import WWW class - using UnityEngine; - #endif - - - #if UNITY_WEBGL - public class PingHttp : PhotonPing - { - private WWW webRequest; - - public override bool StartPing(string address) - { - base.Init(); - - address = "https://" + address + "/photon/m/?ping&r=" + UnityEngine.Random.Range(0, 10000); - this.webRequest = new WWW(address); - return true; - } - - public override bool Done() - { - if (this.webRequest.isDone) - { - Successful = true; - return true; - } - - return false; - } - - public override void Dispose() - { - this.webRequest.Dispose(); - } - } - #endif -} -#endif \ No newline at end of file +// this file is no longer used. it can be deleted safely. \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/PhotonRealtime.asmdef b/Assets/Photon/PhotonRealtime/Code/PhotonRealtime.asmdef index 7da2fff..b472f01 100644 --- a/Assets/Photon/PhotonRealtime/Code/PhotonRealtime.asmdef +++ b/Assets/Photon/PhotonRealtime/Code/PhotonRealtime.asmdef @@ -1,10 +1,6 @@ { "name": "PhotonRealtime", - "references": [ - "PhotonWebSocket" - ], - "optionalUnityReferences": [], + "references": [], "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false + "excludePlatforms": [] } \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/Player.cs b/Assets/Photon/PhotonRealtime/Code/Player.cs index 14f84fc..4058889 100644 --- a/Assets/Photon/PhotonRealtime/Code/Player.cs +++ b/Assets/Photon/PhotonRealtime/Code/Player.cs @@ -60,6 +60,12 @@ namespace Photon.Realtime public readonly bool IsLocal; + public bool HasRejoined + { + get; internal set; + } + + /// Background field for nickName. private string nickName = string.Empty; @@ -238,7 +244,7 @@ namespace Photon.Realtime /// This only updates the CustomProperties and doesn't send them to the server. /// Mostly used when creating new remote players, where the server sends their properties. /// - public virtual void InternalCacheProperties(Hashtable properties) + protected internal virtual void InternalCacheProperties(Hashtable properties) { if (properties == null || properties.Count == 0 || this.CustomProperties.Equals(properties)) { @@ -374,52 +380,73 @@ namespace Photon.Realtime /// Hashtable of Custom Properties to be set. /// If non-null, these are the property-values the server will check as condition for this update. /// Defines if this SetCustomProperties-operation gets forwarded to your WebHooks. Client must be in room. - public void SetCustomProperties(Hashtable propertiesToSet, Hashtable expectedValues = null, WebFlags webFlags = null) + /// + /// False if propertiesToSet is null or empty or have zero string keys. + /// True in offline mode even if expectedProperties or webFlags are used. + /// If not in a room, returns true if local player and expectedValues and webFlags are null. + /// (Use this to cache properties to be sent when joining a room). + /// Otherwise, returns if this operation could be sent to the server. + /// + public bool SetCustomProperties(Hashtable propertiesToSet, Hashtable expectedValues = null, WebFlags webFlags = null) { - if (propertiesToSet == null) + if (propertiesToSet == null || propertiesToSet.Count == 0) { - return; + return false; } Hashtable customProps = propertiesToSet.StripToStringKeys() as Hashtable; - Hashtable customPropsToCheck = expectedValues.StripToStringKeys() as Hashtable; - - - // no expected values -> set and callback - bool noCas = customPropsToCheck == null || customPropsToCheck.Count == 0; - - - if (noCas) - { - this.CustomProperties.Merge(customProps); - this.CustomProperties.StripKeysWithNullValues(); - } if (this.RoomReference != null) { if (this.RoomReference.IsOffline) { + if (customProps.Count == 0) + { + return false; + } + this.CustomProperties.Merge(customProps); + this.CustomProperties.StripKeysWithNullValues(); // invoking callbacks this.RoomReference.LoadBalancingClient.InRoomCallbackTargets.OnPlayerPropertiesUpdate(this, customProps); + return true; } else { + Hashtable customPropsToCheck = expectedValues.StripToStringKeys() as Hashtable; + // send (sync) these new values if in online room - this.RoomReference.LoadBalancingClient.LoadBalancingPeer.OpSetPropertiesOfActor(this.actorNumber, customProps, customPropsToCheck, webFlags); + return this.RoomReference.LoadBalancingClient.OpSetPropertiesOfActor(this.actorNumber, customProps, customPropsToCheck, webFlags); } } + if (this.IsLocal) + { + if (customProps.Count == 0) + { + return false; + } + if (expectedValues == null && webFlags == null) + { + this.CustomProperties.Merge(customProps); + this.CustomProperties.StripKeysWithNullValues(); + return true; + } + } + + return false; } /// Uses OpSetPropertiesOfActor to sync this player's NickName (server is being updated with this.NickName). - private void SetPlayerNameProperty() + private bool SetPlayerNameProperty() { if (this.RoomReference != null && !this.RoomReference.IsOffline) { Hashtable properties = new Hashtable(); properties[ActorProperties.PlayerName] = this.nickName; - this.RoomReference.LoadBalancingClient.LoadBalancingPeer.OpSetPropertiesOfActor(this.ActorNumber, properties); + return this.RoomReference.LoadBalancingClient.OpSetPropertiesOfActor(this.ActorNumber, properties); } + + return false; } } } \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/Region.cs b/Assets/Photon/PhotonRealtime/Code/Region.cs index 8d92300..2341631 100644 --- a/Assets/Photon/PhotonRealtime/Code/Region.cs +++ b/Assets/Photon/PhotonRealtime/Code/Region.cs @@ -83,7 +83,7 @@ namespace Photon.Realtime } else { - return string.Format("{0}[{2}]: {1}ms ", regionCluster, this.Ping, this.HostAndPort); + return string.Format("{0}[{2}]: {1}ms", regionCluster, this.Ping, this.HostAndPort); } } } diff --git a/Assets/Photon/PhotonRealtime/Code/RegionHandler.cs b/Assets/Photon/PhotonRealtime/Code/RegionHandler.cs index 32cb977..b5c898f 100644 --- a/Assets/Photon/PhotonRealtime/Code/RegionHandler.cs +++ b/Assets/Photon/PhotonRealtime/Code/RegionHandler.cs @@ -9,6 +9,7 @@ // developer@photonengine.com // ---------------------------------------------------------------------------- + #if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER #define SUPPORTED_UNITY #endif @@ -21,6 +22,7 @@ namespace Photon.Realtime { using System; using System.Text; + using System.Threading; using System.Net; using System.Collections; using System.Collections.Generic; @@ -53,6 +55,10 @@ namespace Photon.Realtime /// public class RegionHandler { + /// The implementation of PhotonPing to use for region pinging (Best Region detection). + /// Defaults to null, which means the Type is set automatically. + public static Type PingImplementation; + /// A list of region names for the Photon Cloud. Set by the result of OpGetRegions(). /// /// Implement ILoadBalancingCallbacks and register for the callbacks to get OnRegionListReceived(RegionHandler regionHandler). @@ -80,7 +86,7 @@ namespace Photon.Realtime return this.bestRegionCache; } - this.EnabledRegions.Sort((a, b) => { return (a.Ping == b.Ping) ? 0 : (a.Ping < b.Ping) ? -1 : 1; }); + this.EnabledRegions.Sort((a, b) => a.Ping.CompareTo(b.Ping) ); this.bestRegionCache = this.EnabledRegions[0]; return this.bestRegionCache; @@ -106,32 +112,17 @@ namespace Photon.Realtime } } - #if PING_VIA_COROUTINE - private ConnectionHandler connectionHandler; - - public RegionHandler() - { - this.connectionHandler = UnityEngine.Object.FindObjectOfType(); - if (!connectionHandler) - { - Debug.LogError("ConnectionHandler component not found. It is required to start regions ping coroutine."); - } - } - #endif - public string GetResults() { StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Region Pinging Result: {0}\n", this.BestRegion.ToString()); - if (this.pingerList != null) + foreach (RegionPinger region in this.pingerList) { - foreach (RegionPinger region in this.pingerList) - { - sb.AppendFormat(region.GetResults() + "\n"); - } + sb.AppendFormat(region.GetResults() + "\n"); } - sb.AppendFormat("Previous summary: {0}", this.previousSummaryProvided); + return sb.ToString(); } @@ -154,13 +145,19 @@ namespace Photon.Realtime //Debug.LogError("The region arrays from Name Server are not ok. Must be non-null and same length. " + (regions == null) + " " + (servers == null) + "\n" + opGetRegions.ToStringFull()); return; } - + this.bestRegionCache = null; this.EnabledRegions = new List(regions.Length); for (int i = 0; i < regions.Length; i++) { - Region tmp = new Region(regions[i], servers[i]); + string server = servers[i]; + if (PortToPingOverride != 0) + { + server = LoadBalancingClient.ReplacePortWithAlternative(servers[i], PortToPingOverride); + } + + Region tmp = new Region(regions[i], server); if (string.IsNullOrEmpty(tmp.Code)) { continue; @@ -173,12 +170,21 @@ namespace Photon.Realtime this.availableRegionCodes = string.Join(",", regions); } - private List pingerList; + private List pingerList = new List(); private Action onCompleteCall; private int previousPing; public bool IsPinging { get; private set; } private string previousSummaryProvided; + protected internal static ushort PortToPingOverride; + + + public RegionHandler(ushort masterServerPortOverride = 0) + { + PortToPingOverride = masterServerPortOverride; + } + + public bool PingMinimumOfRegions(Action onCompleteCallback, string previousSummary) { if (this.EnabledRegions == null || this.EnabledRegions.Count == 0) @@ -191,7 +197,7 @@ namespace Photon.Realtime if (this.IsPinging) { //TODO: log warning - //Debug.LogWarning("PingMinimumOfRegions() skipped, because this RegionHander is already pinging some regions."); + //Debug.LogWarning("PingMinimumOfRegions() skipped, because this RegionHandler is already pinging some regions."); return false; } @@ -241,13 +247,16 @@ namespace Photon.Realtime // let's check only the preferred region to detect if it's still "good enough" this.previousPing = prevBestRegionPing; + Region preferred = this.EnabledRegions.Find(r => r.Code.Equals(prevBestRegionCode)); RegionPinger singlePinger = new RegionPinger(preferred, this.OnPreferredRegionPinged); - #if PING_VIA_COROUTINE - singlePinger.Start(this.connectionHandler); - #else + + lock (this.pingerList) + { + this.pingerList.Add(singlePinger); + } + singlePinger.Start(); - #endif return true; } @@ -261,6 +270,9 @@ namespace Photon.Realtime { this.IsPinging = false; this.onCompleteCall(this); + #if PING_VIA_COROUTINE + MonoBehaviourEmpty.SelfDestroy(); + #endif } } @@ -274,16 +286,16 @@ namespace Photon.Realtime return false; } - this.pingerList = new List(); - foreach (Region region in this.EnabledRegions) + lock (this.pingerList) { - RegionPinger rp = new RegionPinger(region, this.OnRegionDone); - this.pingerList.Add(rp); - #if PING_VIA_COROUTINE - rp.Start(this.connectionHandler); // TODO: check return value - #else - rp.Start(); // TODO: check return value - #endif + this.pingerList.Clear(); + + foreach (Region region in this.EnabledRegions) + { + RegionPinger rp = new RegionPinger(region, this.OnRegionDone); + this.pingerList.Add(rp); + rp.Start(); // TODO: check return value + } } return true; @@ -291,17 +303,29 @@ namespace Photon.Realtime private void OnRegionDone(Region region) { - this.bestRegionCache = null; - foreach (RegionPinger pinger in this.pingerList) + lock (this.pingerList) { - if (!pinger.Done) + if (this.IsPinging == false) { return; } + + this.bestRegionCache = null; + foreach (RegionPinger pinger in this.pingerList) + { + if (!pinger.Done) + { + return; + } + } + + this.IsPinging = false; } - this.IsPinging = false; this.onCompleteCall(this); + #if PING_VIA_COROUTINE + MonoBehaviourEmpty.SelfDestroy(); + #endif } } @@ -331,42 +355,57 @@ namespace Photon.Realtime this.onDoneCall = onDoneCallback; } + /// Selects the best fitting ping implementation or uses the one set in RegionHandler.PingImplementation. + /// PhotonPing instance to use. private PhotonPing GetPingImplementation() { PhotonPing ping = null; - #if !NETFX_CORE - if (LoadBalancingPeer.PingImplementation == typeof(PingMono)) + // using each type explicitly in the conditional code, makes sure Unity doesn't strip the class / constructor. + + #if !UNITY_EDITOR && NETFX_CORE + if (RegionHandler.PingImplementation == null || RegionHandler.PingImplementation == typeof(PingWindowsStore)) { - ping = new PingMono(); // using this type explicitly saves it from IL2CPP bytecode stripping + ping = new PingWindowsStore(); } - #endif - #if NATIVE_SOCKETS - if (LoadBalancingPeer.PingImplementation == typeof(PingNativeDynamic)) + #elif NATIVE_SOCKETS || NO_SOCKET + if (RegionHandler.PingImplementation == null || RegionHandler.PingImplementation == typeof(PingNativeDynamic)) { ping = new PingNativeDynamic(); } - #endif - #if UNITY_WEBGL - if (LoadBalancingPeer.PingImplementation == typeof(PingHttp)) + #elif UNITY_WEBGL + if (RegionHandler.PingImplementation == null || RegionHandler.PingImplementation == typeof(PingHttp)) { ping = new PingHttp(); } + #else + if (RegionHandler.PingImplementation == null || RegionHandler.PingImplementation == typeof(PingMono)) + { + ping = new PingMono(); + } #endif if (ping == null) { - ping = (PhotonPing)Activator.CreateInstance(LoadBalancingPeer.PingImplementation); + if (RegionHandler.PingImplementation != null) + { + ping = (PhotonPing)Activator.CreateInstance(RegionHandler.PingImplementation); + } } return ping; } - #if PING_VIA_COROUTINE - public bool Start(ConnectionHandler connectionHandler) - #else + + /// + /// Starts the ping routine for the assigned region. + /// + /// + /// Pinging runs in a ThreadPool worker item or (if needed) in a Thread. + /// WebGL runs pinging on the Main Thread as coroutine. + /// + /// Always true. public bool Start() - #endif { // all addresses for Photon region servers will contain a :port ending. this needs to be removed first. // PhotonPing.StartPing() requires a plain (IP) address without port or protocol-prefix (on all but Windows 8.1 and WebGL platforms). @@ -386,24 +425,37 @@ namespace Photon.Realtime this.CurrentAttempt = 0; this.rttResults = new List(Attempts); + #if PING_VIA_COROUTINE - if (connectionHandler) + MonoBehaviourEmpty.Instance.StartCoroutine(this.RegionPingCoroutine()); + #else + bool queued = false; + #if !NETFX_CORE + try { - connectionHandler.StartCoroutine(this.RegionPingCoroutine()); + queued = ThreadPool.QueueUserWorkItem(this.RegionPingPooled); } - else + catch { - Debug.LogError("ConnectionHandler component is null or destroyed. It is required to start regions ping coroutine."); + queued = false; + } + #endif + if (!queued) + { + SupportClass.StartBackgroundCalls(this.RegionPingThreaded, 0, "RegionPing_" + this.region.Code + "_" + this.region.Cluster); } - #elif UNITY_SWITCH - SupportClass.StartBackgroundCalls(this.RegionPingThreaded, 0); - #else - SupportClass.StartBackgroundCalls(this.RegionPingThreaded, 0, "RegionPing_" + this.region.Code+"_"+this.region.Cluster); #endif + return true; } + // wraps RegionPingThreaded() to get the signature compatible with ThreadPool.QueueUserWorkItem + protected internal void RegionPingPooled(object context) + { + this.RegionPingThreaded(); + } + protected internal bool RegionPingThreaded() { this.region.Ping = PingWhenFailed; @@ -533,14 +585,16 @@ namespace Photon.Realtime yield return new WaitForSeconds(0.1f); } + //Debug.Log("Done: "+ this.region.Code); this.Done = true; - this.ping.Dispose(); + this.ping.Dispose(); this.onDoneCall(this.region); yield return null; } #endif + public string GetResults() { return string.Format("{0}: {1} ({2})", this.region.Code, this.region.Ping, this.rttResults.ToStringFull()); @@ -608,4 +662,38 @@ namespace Photon.Realtime return ipv4Address; } } -} \ No newline at end of file + + #if PING_VIA_COROUTINE + internal class MonoBehaviourEmpty : MonoBehaviour + { + private static bool instanceSet; // to avoid instance null check which may be incorrect + private static MonoBehaviourEmpty instance; + + public static MonoBehaviourEmpty Instance + { + get + { + if (instanceSet) + { + return instance; + } + GameObject go = new GameObject(); + DontDestroyOnLoad(go); + go.name = "RegionPinger"; + instance = go.AddComponent(); + instanceSet = true; + return instance; + } + } + + public static void SelfDestroy() + { + if (instanceSet) + { + instanceSet = false; + Destroy(instance.gameObject); + } + } + } + #endif +} diff --git a/Assets/Photon/PhotonRealtime/Code/Room.cs b/Assets/Photon/PhotonRealtime/Code/Room.cs index c4621d7..5f4036f 100644 --- a/Assets/Photon/PhotonRealtime/Code/Room.cs +++ b/Assets/Photon/PhotonRealtime/Code/Room.cs @@ -274,8 +274,15 @@ namespace Photon.Realtime } /// - /// Gets if this room uses autoCleanUp to remove all (buffered) RPCs and instantiated GameObjects when a player leaves. + /// Gets if this room cleans up the event cache when a player (actor) leaves. /// + /// + /// This affects which events joining players get. + /// + /// Set in room creation via RoomOptions.CleanupCacheOnLeave. + /// + /// Within PUN, auto cleanup of events means that cached RPCs and instantiated networked objects are deleted from the room. + /// public bool AutoCleanUp { get @@ -284,6 +291,22 @@ namespace Photon.Realtime } } + /// Define if the client who calls SetProperties should receive the properties update event or not. + public bool BroadcastPropertiesChangeToAll { get; private set; } + /// Define if Join and Leave events should not be sent to clients in the room. + public bool SuppressRoomEvents { get; private set; } + /// Extends SuppressRoomEvents: Define if Join and Leave events but also the actors' list and their respective properties should not be sent to clients. + public bool SuppressPlayerInfo { get; private set; } + /// Define if UserIds of the players are broadcast in the room. Useful for FindFriends and reserving slots for expected users. + public bool PublishUserId { get; private set; } + /// Define if actor or room properties with null values are removed on the server or kept. + public bool DeleteNullProperties { get; private set; } + + #if SERVERSDK + /// Define if rooms should have unique UserId per actor and that UserIds are used instead of actor number in rejoin. + public bool CheckUserOnJoin { get; private set; } + #endif + /// Creates a Room (representation) with given name and properties and the "listing options" as provided by parameters. /// Name of the room (can be null until it's actually created on server). @@ -305,6 +328,22 @@ namespace Photon.Realtime } + /// Read (received) room option flags into related bool parameters. + /// This is for internal use. The operation response for join and create room operations is read this way. + /// + internal void InternalCacheRoomFlags(int roomFlags) + { + this.BroadcastPropertiesChangeToAll = (roomFlags & (int)RoomOptionBit.BroadcastPropsChangeToAll) != 0; + this.SuppressRoomEvents = (roomFlags & (int)RoomOptionBit.SuppressRoomEvents) != 0; + this.SuppressPlayerInfo = (roomFlags & (int)RoomOptionBit.SuppressPlayerInfo) != 0; + this.PublishUserId = (roomFlags & (int)RoomOptionBit.PublishUserId) != 0; + this.DeleteNullProperties = (roomFlags & (int)RoomOptionBit.DeleteNullProps) != 0; + #if SERVERSDK + this.CheckUserOnJoin = (roomFlags & (int)RoomOptionBit.CheckUserOnJoin) != 0; + #endif + this.autoCleanUp = (roomFlags & (int)RoomOptionBit.DeleteCacheOnLeave) != 0; + } + protected internal override void InternalCacheProperties(Hashtable propertiesToCache) { int oldMasterId = this.masterClientId; @@ -358,12 +397,25 @@ namespace Photon.Realtime /// Hashtable of Custom Properties that changes. /// Provide some keys/values to use as condition for setting the new values. Client must be in room. /// Defines if this SetCustomProperties-operation gets forwarded to your WebHooks. Client must be in room. - public virtual void SetCustomProperties(Hashtable propertiesToSet, Hashtable expectedProperties = null, WebFlags webFlags = null) + /// + /// False if propertiesToSet is null or empty or have zero string keys. + /// True in offline mode even if expectedProperties or webFlags are used. + /// Otherwise, returns if this operation could be sent to the server. + /// + public virtual bool SetCustomProperties(Hashtable propertiesToSet, Hashtable expectedProperties = null, WebFlags webFlags = null) { + if (propertiesToSet == null || propertiesToSet.Count == 0) + { + return false; + } Hashtable customProps = propertiesToSet.StripToStringKeys() as Hashtable; if (this.isOffline) { + if (customProps.Count == 0) + { + return false; + } // Merge and delete values. this.CustomProperties.Merge(customProps); this.CustomProperties.StripKeysWithNullValues(); @@ -374,16 +426,11 @@ namespace Photon.Realtime } else { - // merge (and delete null-values), unless we use CAS (expected props) - if (expectedProperties == null || expectedProperties.Count == 0) - { - this.CustomProperties.Merge(customProps); - this.CustomProperties.StripKeysWithNullValues(); - } - // send (sync) these new values if in online room - this.LoadBalancingClient.LoadBalancingPeer.OpSetPropertiesOfRoom(customProps, expectedProperties, webFlags); + return this.LoadBalancingClient.OpSetPropertiesOfRoom(customProps, expectedProperties, webFlags); } + + return true; } /// @@ -392,18 +439,17 @@ namespace Photon.Realtime /// /// Limit the amount of properties sent to users in the lobby to improve speed and stability. /// - /// An array of custom room property names to forward to the lobby. - public void SetPropertiesListedInLobby(string[] propertiesListedInLobby) + /// An array of custom room property names to forward to the lobby. + /// If the operation could be sent to the server. + public bool SetPropertiesListedInLobby(string[] lobbyProps) { - Hashtable customProps = new Hashtable(); - customProps[GamePropertyKey.PropsListedInLobby] = propertiesListedInLobby; - - bool sent = this.LoadBalancingClient.OpSetPropertiesOfRoom(customProps); - - if (sent) + if (this.isOffline) { - this.propertiesListedInLobby = propertiesListedInLobby; + return false; } + Hashtable customProps = new Hashtable(); + customProps[GamePropertyKey.PropsListedInLobby] = lobbyProps; + return this.LoadBalancingClient.OpSetPropertiesOfRoom(customProps); } @@ -446,6 +492,10 @@ namespace Photon.Realtime /// False when this operation couldn't be done currently. Requires a v4 Photon Server. public bool SetMasterClient(Player masterClientPlayer) { + if (this.isOffline) + { + return false; + } Hashtable newProps = new Hashtable() { { GamePropertyKey.MasterClientId, masterClientPlayer.ActorNumber } }; Hashtable prevProps = new Hashtable() { { GamePropertyKey.MasterClientId, this.MasterClientId } }; return this.LoadBalancingClient.OpSetPropertiesOfRoom(newProps, prevProps); @@ -476,11 +526,11 @@ namespace Photon.Realtime this.Players[player.ActorNumber] = player; player.RoomReference = this; - // while initializing the room, the players are not guaranteed to be added in-order - if (this.MasterClientId == 0 || player.ActorNumber < this.MasterClientId) - { - this.masterClientId = player.ActorNumber; - } + //// while initializing the room, the players are not guaranteed to be added in-order + //if (this.MasterClientId == 0 || player.ActorNumber < this.MasterClientId) + //{ + // this.masterClientId = player.ActorNumber; + //} return player; } @@ -490,11 +540,14 @@ namespace Photon.Realtime /// Only useful when in a Room, as IDs are only valid per Room. /// /// ID to look for. + /// If true, the Master Client is returned for ID == 0. /// The player with the ID or null. - public virtual Player GetPlayer(int id) + public virtual Player GetPlayer(int id, bool findMaster = false) { + int idToFind = (findMaster && id == 0) ? this.MasterClientId : id; + Player result = null; - this.Players.TryGetValue(id, out result); + this.Players.TryGetValue(idToFind, out result); return result; } @@ -510,15 +563,55 @@ namespace Photon.Realtime /// /// Internals: This methods wraps up setting the ExpectedUsers property of a room. /// - public void ClearExpectedUsers() + /// If the operation could be sent to the server. + public bool ClearExpectedUsers() { - Hashtable props = new Hashtable(); - props[GamePropertyKey.ExpectedUsers] = new string[0]; - Hashtable expected = new Hashtable(); - expected[GamePropertyKey.ExpectedUsers] = this.ExpectedUsers; - this.LoadBalancingClient.OpSetPropertiesOfRoom(props, expected); + if (this.ExpectedUsers == null || this.ExpectedUsers.Length == 0) + { + return false; + } + return this.SetExpectedUsers(new string[0], this.ExpectedUsers); } + /// + /// Attempts to update the expected users from the server's Slot Reservation list. + /// + /// + /// Note that this operation can conflict with new/other users joining. They might be + /// adding users to the list of expected users before or after this client called SetExpectedUsers. + /// + /// This room's expectedUsers value will update, when the server sends a successful update. + /// + /// Internals: This methods wraps up setting the ExpectedUsers property of a room. + /// + /// The new array of UserIDs to be reserved in the room. + /// If the operation could be sent to the server. + public bool SetExpectedUsers(string[] newExpectedUsers) + { + if (newExpectedUsers == null || newExpectedUsers.Length == 0) + { + this.LoadBalancingClient.DebugReturn(DebugLevel.ERROR, "newExpectedUsers array is null or empty, call Room.ClearExpectedUsers() instead if this is what you want."); + return false; + } + return this.SetExpectedUsers(newExpectedUsers, this.ExpectedUsers); + } + + private bool SetExpectedUsers(string[] newExpectedUsers, string[] oldExpectedUsers) + { + if (this.isOffline) + { + return false; + } + Hashtable gameProperties = new Hashtable(1); + gameProperties.Add(GamePropertyKey.ExpectedUsers, newExpectedUsers); + Hashtable expectedProperties = null; + if (oldExpectedUsers != null) + { + expectedProperties = new Hashtable(1); + expectedProperties.Add(GamePropertyKey.ExpectedUsers, oldExpectedUsers); + } + return this.LoadBalancingClient.OpSetPropertiesOfRoom(gameProperties, expectedProperties); + } /// Returns a summary of this Room instance as string. /// Summary of this Room instance. diff --git a/Assets/Photon/PhotonRealtime/Code/SupportLogger.cs b/Assets/Photon/PhotonRealtime/Code/SupportLogger.cs index ef0aee3..1cd4a0a 100644 --- a/Assets/Photon/PhotonRealtime/Code/SupportLogger.cs +++ b/Assets/Photon/PhotonRealtime/Code/SupportLogger.cs @@ -24,6 +24,8 @@ namespace Photon.Realtime using Stopwatch = System.Diagnostics.Stopwatch; + using ExitGames.Client.Photon; + #if SUPPORTED_UNITY using UnityEngine; #endif @@ -42,7 +44,7 @@ namespace Photon.Realtime #if SUPPORTED_UNITY [DisallowMultipleComponent] [AddComponentMenu("")] // hide from Unity Menus and searches - public class SupportLogger : MonoBehaviour, IConnectionCallbacks , IMatchmakingCallbacks , IInRoomCallbacks, ILobbyCallbacks + public class SupportLogger : MonoBehaviour, IConnectionCallbacks , IMatchmakingCallbacks , IInRoomCallbacks, ILobbyCallbacks, IErrorInfoCallback #else public class SupportLogger : IConnectionCallbacks, IInRoomCallbacks, IMatchmakingCallbacks , ILobbyCallbacks #endif @@ -87,6 +89,8 @@ namespace Photon.Realtime #if SUPPORTED_UNITY protected void Start() { + this.LogBasics(); + if (this.startStopwatch == null) { this.startStopwatch = new Stopwatch(); @@ -94,9 +98,14 @@ namespace Photon.Realtime } } + protected void OnDestroy() + { + this.Client = null; // will remove this SupportLogger as callback target + } + protected void OnApplicationPause(bool pause) { - Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnApplicationPause: " + pause + " connected: " + (this.client == null ? "false" : this.client.IsConnected.ToString())); + Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnApplicationPause: " + pause + " connected: " + (this.client == null ? "no (client is null)" : this.client.IsConnected.ToString())); } protected void OnApplicationQuit() @@ -193,18 +202,58 @@ namespace Photon.Realtime { if (this.client != null) { + List buildProperties = new List(10); + #if SUPPORTED_UNITY + buildProperties.Add(Application.unityVersion); + buildProperties.Add(Application.platform.ToString()); + #endif + #if ENABLE_IL2CPP + buildProperties.Add("ENABLE_IL2CPP"); + #endif + #if ENABLE_MONO + buildProperties.Add("ENABLE_MONO"); + #endif + #if DEBUG + buildProperties.Add("DEBUG"); + #endif + #if MASTER + buildProperties.Add("MASTER"); + #endif + #if NET_4_6 + buildProperties.Add("NET_4_6"); + #endif + #if NET_STANDARD_2_0 + buildProperties.Add("NET_STANDARD_2_0"); + #endif + #if NETFX_CORE + buildProperties.Add("NETFX_CORE"); + #endif + #if NET_LEGACY + buildProperties.Add("NET_LEGACY"); + #endif + #if UNITY_64 + buildProperties.Add("UNITY_64"); + #endif + + StringBuilder sb = new StringBuilder(); + string appIdShort = string.IsNullOrEmpty(this.client.AppId) || this.client.AppId.Length < 8 ? this.client.AppId : string.Concat(this.client.AppId.Substring(0, 8), "***"); + sb.AppendFormat("{0} SupportLogger Info: ", this.GetFormattedTimestamp()); - sb.AppendFormat("AppID: \"{0}\" AppVersion: \"{1}\" UserId: {3} PeerID: {2} ", - string.IsNullOrEmpty(this.client.AppId) || this.client.AppId.Length < 8 - ? this.client.AppId - : string.Concat(this.client.AppId.Substring(0, 8), "***"), this.client.AppVersion, this.client.LoadBalancingPeer.PeerID, - this.client.UserId); - //NOTE: this.client.LoadBalancingPeer.ServerIpAddress requires Photon3Unity3d.dll v4.1.2.5 and up - sb.AppendFormat("NameServer: {0} Server: {1} IP: {2} Region: {3}", this.client.NameServerHost, this.client.CurrentServerAddress, this.client.LoadBalancingPeer.ServerIpAddress, this.client.CloudRegion); - - Debug.Log(sb.ToString()); + sb.AppendFormat("AppID: \"{0}\" AppVersion: \"{1}\" Client: v{2} ({4}) Build: {3} ", appIdShort, this.client.AppVersion, this.client.LoadBalancingPeer.ClientVersion, string.Join(", ", buildProperties.ToArray()), this.client.LoadBalancingPeer.TargetFramework); + if (this.client != null && this.client.LoadBalancingPeer != null && this.client.LoadBalancingPeer.SocketImplementation != null) + { + sb.AppendFormat("Socket: {0} ", this.client.LoadBalancingPeer.SocketImplementation.Name); + } + + sb.AppendFormat("UserId: \"{0}\" AuthType: {1} AuthMode: {2} {3} ", this.client.UserId, (this.client.AuthValues != null) ? this.client.AuthValues.AuthType.ToString() : "N/A", this.client.AuthMode, this.client.EncryptionMode); + + sb.AppendFormat("State: {0} ", this.client.State); + sb.AppendFormat("PeerID: {0} ", this.client.LoadBalancingPeer.PeerID); + sb.AppendFormat("NameServer: {0} Current Server: {1} IP: {2} Region: {3} ", this.client.NameServerHost, this.client.CurrentServerAddress, this.client.LoadBalancingPeer.ServerIpAddress, this.client.CloudRegion); + + Debug.LogWarning(sb.ToString()); } } @@ -258,6 +307,7 @@ namespace Photon.Realtime public void OnJoinRoomFailed(short returnCode, string message) { + Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnJoinRoomFailed(" + returnCode+","+message+")."); } public void OnJoinRandomFailed(short returnCode, string message) @@ -288,7 +338,6 @@ namespace Photon.Realtime public void OnRegionListReceived(RegionHandler regionHandler) { Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnRegionListReceived(regionHandler)."); - this.LogBasics(); } public void OnRoomListUpdate(List roomList) @@ -337,7 +386,7 @@ namespace Photon.Realtime } -#if !SUPPORTED_UNITY + #if !SUPPORTED_UNITY private static class Debug { public static void Log(string msg) @@ -353,6 +402,11 @@ namespace Photon.Realtime System.Diagnostics.Debug.WriteLine(msg); } } -#endif + #endif + + public void OnErrorInfo(ErrorInfo errorInfo) + { + Debug.LogError(errorInfo.ToString()); + } } } \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/Unity.meta b/Assets/Photon/PhotonRealtime/Code/Unity.meta new file mode 100644 index 0000000..96bf0ee --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fa14aa576f7e18f4bb6c4c93368a235d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/Editor.meta b/Assets/Photon/PhotonRealtime/Code/Unity/Editor.meta new file mode 100644 index 0000000..4d10118 --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a02814c0303a60f488813e6111993aaa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs new file mode 100644 index 0000000..958454e --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs @@ -0,0 +1,260 @@ +// ---------------------------------------------------------------------------- +// +// Photon Cloud Account Service - Copyright (C) 2012 Exit Games GmbH +// +// +// Provides methods to register a new user-account for the Photon Cloud and +// get the resulting appId. +// +// developer@exitgames.com +// ---------------------------------------------------------------------------- + +#if UNITY_2017_4_OR_NEWER +#define SUPPORTED_UNITY +#endif + + +#if UNITY_EDITOR + +namespace Photon.Realtime +{ + using System; + using UnityEngine; + using System.Collections.Generic; + using System.Text.RegularExpressions; + using ExitGames.Client.Photon; + + + /// + /// Creates a instance of the Account Service to register Photon Cloud accounts. + /// + public class AccountService + { + private const string ServiceUrl = "https://partner.photonengine.com/api/{0}/User/RegisterEx"; + + private readonly Dictionary RequestHeaders = new Dictionary + { + { "Content-Type", "application/json" }, + { "x-functions-key", "" } + }; + + private const string DefaultContext = "Unity"; + + private const string DefaultToken = "VQ920wVUieLHT9c3v1ZCbytaLXpXbktUztKb3iYLCdiRKjUagcl6eg=="; + + /// + /// third parties custom context, if null, defaults to DefaultContext property value + /// + public string CustomContext = null; + + /// + /// third parties custom token. If null, defaults to DefaultToken property value + /// + public string CustomToken = null; + + /// + /// If this AccountService instance is currently waiting for a response. While pending, RegisterByEmail is blocked. + /// + public bool RequestPendingResult = false; + + /// + /// Attempts to create a Photon Cloud Account asynchronously. Blocked while RequestPendingResult is true. + /// + /// + /// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt. + /// + /// Email of the account. + /// Defines which type of Photon-service is being requested. + /// Called when the result is available. + /// Called when the request failed. + public bool RegisterByEmail(string email, List serviceTypes, Action callback = null, Action errorCallback = null) + { + if (this.RequestPendingResult) + { + Debug.LogError("Registration request pending result. Not sending another."); + return false; + } + + if (!IsValidEmail(email)) + { + Debug.LogErrorFormat("Email \"{0}\" is not valid", email); + return false; + } + + string serviceTypeString = GetServiceTypesFromList(serviceTypes); + if (string.IsNullOrEmpty(serviceTypeString)) + { + Debug.LogError("serviceTypes string is null or empty"); + return false; + } + + string fullUrl = GetUrlWithQueryStringEscaped(email, serviceTypeString); + + RequestHeaders["x-functions-key"] = string.IsNullOrEmpty(CustomToken) ? DefaultToken : CustomToken; + + + this.RequestPendingResult = true; + + PhotonEditorUtils.StartCoroutine( + PhotonEditorUtils.HttpPost(fullUrl, + RequestHeaders, + null, + s => + { + this.RequestPendingResult = false; + //Debug.LogWarningFormat("received response {0}", s); + if (string.IsNullOrEmpty(s)) + { + if (errorCallback != null) + { + errorCallback("Server's response was empty. Please register through account website during this service interruption."); + } + } + else + { + AccountServiceResponse ase = this.ParseResult(s); + if (ase == null) + { + if (errorCallback != null) + { + errorCallback("Error parsing registration response. Please try registering from account website"); + } + } + else if (callback != null) + { + callback(ase); + } + } + }, + e => + { + this.RequestPendingResult = false; + if (errorCallback != null) + { + errorCallback(e); + } + }) + ); + return true; + } + + + private string GetUrlWithQueryStringEscaped(string email, string serviceTypes) + { + string emailEscaped = UnityEngine.Networking.UnityWebRequest.EscapeURL(email); + string st = UnityEngine.Networking.UnityWebRequest.EscapeURL(serviceTypes); + string uv = UnityEngine.Networking.UnityWebRequest.EscapeURL(Application.unityVersion); + string av = UnityEngine.Networking.UnityWebRequest.EscapeURL(new PhotonPeer(ConnectionProtocol.Udp).ClientVersion); + string serviceUrl = string.Format(ServiceUrl, string.IsNullOrEmpty(CustomContext) ? DefaultContext : CustomContext ); + + return string.Format("{0}?email={1}&st={2}&uv={3}&av={4}", serviceUrl, emailEscaped, st, uv, av); + } + + /// + /// Reads the Json response and applies it to local properties. + /// + /// + private AccountServiceResponse ParseResult(string result) + { + try + { + AccountServiceResponse res = JsonUtility.FromJson(result); + // Unity's JsonUtility does not support deserializing Dictionary, we manually parse it, dirty & ugly af, better then using a 3rd party lib + if (res.ReturnCode == AccountServiceReturnCodes.Success) + { + string[] parts = result.Split(new[] { "\"ApplicationIds\":{" }, StringSplitOptions.RemoveEmptyEntries); + parts = parts[1].Split('}'); + string applicationIds = parts[0]; + if (!string.IsNullOrEmpty(applicationIds)) + { + parts = applicationIds.Split(new[] { ',', '"', ':' }, StringSplitOptions.RemoveEmptyEntries); + res.ApplicationIds = new Dictionary(parts.Length / 2); + for (int i = 0; i < parts.Length; i = i + 2) + { + res.ApplicationIds.Add(parts[i], parts[i + 1]); + } + } + else + { + Debug.LogError("The server did not return any AppId, ApplicationIds was empty in the response."); + return null; + } + } + return res; + } + catch (Exception ex) // probably JSON parsing exception, check if returned string is valid JSON + { + Debug.LogException(ex); + return null; + } + } + + /// + /// Turns the list items to a comma separated string. Returns null if list is null or empty. + /// + /// List of service types. + /// Returns null if list is null or empty. + private static string GetServiceTypesFromList(List appTypes) + { + if (appTypes == null || appTypes.Count <= 0) + { + return null; + } + + string serviceTypes = ((int)appTypes[0]).ToString(); + for (int i = 1; i < appTypes.Count; i++) + { + int appType = (int)appTypes[i]; + serviceTypes = string.Format("{0},{1}", serviceTypes, appType); + } + + return serviceTypes; + } + + // RFC2822 compliant matching 99.9% of all email addresses in actual use today + // according to http://www.regular-expressions.info/email.html [22.02.2012] + private static Regex reg = new Regex("^((?>[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+\\x20*|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\"\\x20*)*(?<))?((?!\\.)(?>\\.?[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+)+|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\")@(((?!-)[a-zA-Z\\d\\-]+(?)$", + RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); + public static bool IsValidEmail(string mailAddress) + { + if (string.IsNullOrEmpty(mailAddress)) + { + return false; + } + var result = reg.Match(mailAddress); + return result.Success; + } + } + + [Serializable] + public class AccountServiceResponse + { + public int ReturnCode; + public string Message; + public Dictionary ApplicationIds; // Unity's JsonUtility does not support deserializing Dictionary + } + + + public class AccountServiceReturnCodes + { + public static int Success = 0; + public static int EmailAlreadyRegistered = 8; + public static int InvalidParameters = 12; + } + + public enum ServiceTypes + { + Realtime = 0, + Turnbased = 1, + Chat = 2, + Voice = 3, + TrueSync = 4, + Pun = 5, + Thunder = 6, + Quantum = 7, + Fusion = 8, + Bolt = 20 + } +} + +#endif \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs.meta b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs.meta new file mode 100644 index 0000000..a070b17 --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 166dfe22956ef0341b28e18d0499e363 +labels: +- ExitGames +- PUN +- Photon +- Networking +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs new file mode 100644 index 0000000..08e4588 --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs @@ -0,0 +1,319 @@ +// ---------------------------------------------------------------------------- +// +// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH +// +// +// Unity Editor Utils +// +// developer@exitgames.com +// ---------------------------------------------------------------------------- + +#pragma warning disable 618 // Deprecation warnings + + +#if UNITY_2017_4_OR_NEWER +#define SUPPORTED_UNITY +#endif + + +#if UNITY_EDITOR + +namespace Photon.Realtime +{ + using System; + using System.Collections.Generic; + using System.Linq; + + using UnityEditor; + using UnityEngine; + + using System.IO; + using System.Text; + using UnityEngine.Networking; + + + [InitializeOnLoad] + public static class PhotonEditorUtils + { + /// True if the ChatClient of the Photon Chat API is available. If so, the editor may (e.g.) show additional options in settings. + public static bool HasChat; + + /// True if the VoiceClient of the Photon Voice API is available. If so, the editor may (e.g.) show additional options in settings. + public static bool HasVoice; + + public static bool HasPun; + + /// True if the PhotonEditorUtils checked the available products / APIs. If so, the editor may (e.g.) show additional options in settings. + public static bool HasCheckedProducts; + + static PhotonEditorUtils() + { + HasVoice = Type.GetType("Photon.Voice.VoiceClient, Assembly-CSharp") != null || Type.GetType("Photon.Voice.VoiceClient, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Voice.VoiceClient, PhotonVoice.API") != null; + HasChat = Type.GetType("Photon.Chat.ChatClient, Assembly-CSharp") != null || Type.GetType("Photon.Chat.ChatClient, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Chat.ChatClient, PhotonChat") != null; + HasPun = Type.GetType("Photon.Pun.PhotonNetwork, Assembly-CSharp") != null || Type.GetType("Photon.Pun.PhotonNetwork, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Pun.PhotonNetwork, PhotonUnityNetworking") != null; + PhotonEditorUtils.HasCheckedProducts = true; + + if (EditorPrefs.HasKey("DisablePun") && EditorPrefs.GetBool("DisablePun")) + { + HasPun = false; + } + + if (HasPun) + { + // MOUNTING SYMBOLS + #if !PHOTON_UNITY_NETWORKING + AddScriptingDefineSymbolToAllBuildTargetGroups("PHOTON_UNITY_NETWORKING"); + #endif + + #if !PUN_2_0_OR_NEWER + AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_0_OR_NEWER"); + #endif + + #if !PUN_2_OR_NEWER + AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_OR_NEWER"); + #endif + + #if !PUN_2_19_OR_NEWER + AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_19_OR_NEWER"); + #endif + } + } + + /// + /// Adds a given scripting define symbol to all build target groups + /// You can see all scripting define symbols ( not the internal ones, only the one for this project), in the PlayerSettings inspector + /// + /// Define symbol. + public static void AddScriptingDefineSymbolToAllBuildTargetGroups(string defineSymbol) + { + foreach (BuildTarget target in Enum.GetValues(typeof(BuildTarget))) + { + BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); + + if (group == BuildTargetGroup.Unknown) + { + continue; + } + + var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()).ToList(); + + if (!defineSymbols.Contains(defineSymbol)) + { + defineSymbols.Add(defineSymbol); + + try + { + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defineSymbols.ToArray())); + } + catch (Exception e) + { + Debug.Log("Could not set Photon " + defineSymbol + " defines for build target: " + target + " group: " + group + " " + e); + } + } + } + } + + + /// + /// Removes PUN2's Script Define Symbols from project + /// + public static void CleanUpPunDefineSymbols() + { + foreach (BuildTarget target in Enum.GetValues(typeof(BuildTarget))) + { + BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); + + if (group == BuildTargetGroup.Unknown) + { + continue; + } + + var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group) + .Split(';') + .Select(d => d.Trim()) + .ToList(); + + List newDefineSymbols = new List(); + foreach (var symbol in defineSymbols) + { + if ("PHOTON_UNITY_NETWORKING".Equals(symbol) || symbol.StartsWith("PUN_2_")) + { + continue; + } + + newDefineSymbols.Add(symbol); + } + + try + { + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", newDefineSymbols.ToArray())); + } + catch (Exception e) + { + Debug.LogErrorFormat("Could not set clean up PUN2's define symbols for build target: {0} group: {1}, {2}", target, group, e); + } + } + } + + + /// + /// Gets the parent directory of a path. Recursive Function, will return null if parentName not found + /// + /// The parent directory + /// Path. + /// Parent name. + public static string GetParent(string path, string parentName) + { + var dir = new DirectoryInfo(path); + + if (dir.Parent == null) + { + return null; + } + + if (string.IsNullOrEmpty(parentName)) + { + return dir.Parent.FullName; + } + + if (dir.Parent.Name == parentName) + { + return dir.Parent.FullName; + } + + return GetParent(dir.Parent.FullName, parentName); + } + + /// + /// Check if a GameObject is a prefab asset or part of a prefab asset, as opposed to an instance in the scene hierarchy + /// + /// true, if a prefab asset or part of it, false otherwise. + /// The GameObject to check + public static bool IsPrefab(GameObject go) + { + #if UNITY_2018_3_OR_NEWER + return UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage(go) != null || EditorUtility.IsPersistent(go); + #else + return EditorUtility.IsPersistent(go); + #endif + } + + //https://forum.unity.com/threads/using-unitywebrequest-in-editor-tools.397466/#post-4485181 + public static void StartCoroutine(System.Collections.IEnumerator update) + { + EditorApplication.CallbackFunction closureCallback = null; + + closureCallback = () => + { + try + { + if (update.MoveNext() == false) + { + EditorApplication.update -= closureCallback; + } + } + catch (Exception ex) + { + Debug.LogException(ex); + EditorApplication.update -= closureCallback; + } + }; + + EditorApplication.update += closureCallback; + } + + public static System.Collections.IEnumerator HttpPost(string url, Dictionary headers, byte[] payload, Action successCallback, Action errorCallback) + { + using (UnityWebRequest w = new UnityWebRequest(url, "POST")) + { + if (payload != null) + { + w.uploadHandler = new UploadHandlerRaw(payload); + } + w.downloadHandler = new DownloadHandlerBuffer(); + if (headers != null) + { + foreach (var header in headers) + { + w.SetRequestHeader(header.Key, header.Value); + } + } + + #if UNITY_2017_2_OR_NEWER + yield return w.SendWebRequest(); + #else + yield return w.Send(); + #endif + + while (w.isDone == false) + yield return null; + + #if UNITY_2020_2_OR_NEWER + if (w.result == UnityWebRequest.Result.ProtocolError || w.result == UnityWebRequest.Result.ConnectionError || w.result == UnityWebRequest.Result.DataProcessingError) + #elif UNITY_2017_1_OR_NEWER + if (w.isNetworkError || w.isHttpError) + #endif + { + if (errorCallback != null) + { + errorCallback(w.error); + } + } + else + { + if (successCallback != null) + { + successCallback(w.downloadHandler.text); + } + } + } + } + /// + /// Creates a Foldout using a toggle with (GUIStyle)"Foldout") and a separate label. This is a workaround for 2019.3 foldout arrows not working. + /// + /// + /// + /// Returns the new isExpanded value. + public static bool Foldout(this SerializedProperty isExpanded, GUIContent label) + { + var rect = EditorGUILayout.GetControlRect(); + bool newvalue = EditorGUI.Toggle(new Rect(rect) { xMin = rect.xMin + 2 }, GUIContent.none, isExpanded.boolValue, (GUIStyle)"Foldout"); + EditorGUI.LabelField(new Rect(rect) { xMin = rect.xMin + 15 }, label); + if (newvalue != isExpanded.boolValue) + { + isExpanded.boolValue = newvalue; + isExpanded.serializedObject.ApplyModifiedProperties(); + } + return newvalue; + } + + /// + /// Creates a Foldout using a toggle with (GUIStyle)"Foldout") and a separate label. This is a workaround for 2019.3 foldout arrows not working. + /// + /// + /// + /// Returns the new isExpanded value. + public static bool Foldout(this bool isExpanded, GUIContent label) + { + var rect = EditorGUILayout.GetControlRect(); + bool newvalue = EditorGUI.Toggle(new Rect(rect) { xMin = rect.xMin + 2 }, GUIContent.none, isExpanded, (GUIStyle)"Foldout"); + EditorGUI.LabelField(new Rect(rect) { xMin = rect.xMin + 15 }, label); + return newvalue; + } + } + + + public class CleanUpDefinesOnPunDelete : UnityEditor.AssetModificationProcessor + { + public static AssetDeleteResult OnWillDeleteAsset(string assetPath, RemoveAssetOptions rao) + { + if ("Assets/Photon/PhotonUnityNetworking".Equals(assetPath)) + { + PhotonEditorUtils.CleanUpPunDefineSymbols(); + } + + return AssetDeleteResult.DidNotDelete; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs.meta b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs.meta similarity index 78% rename from Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs.meta rename to Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs.meta index 04bb413..90d608f 100644 --- a/Assets/Photon/PhotonBolt/scripts/BoltNetworkUtils.cs.meta +++ b/Assets/Photon/PhotonRealtime/Code/Unity/Editor/PhotonEditorUtils.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7525078204d8214418eb193fd44cac4b +guid: 607340ca505d53d4f8e785423fac7964 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs b/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs new file mode 100644 index 0000000..66b57eb --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs @@ -0,0 +1,116 @@ +// ----------------------------------------------------------------------- +// +// +// developer@photonengine.com +// ---------------------------------------------------------------------------- + +#if UNITY_2017_4_OR_NEWER +#define SUPPORTED_UNITY +#endif + + +#if !PHOTON_UNITY_NETWORKING + +namespace Photon.Realtime +{ + using System; + using System.IO; + using UnityEditor; + using UnityEngine; + /// + /// Collection of connection-relevant settings, used internally by PhotonNetwork.ConnectUsingSettings. + /// + /// + /// Includes the AppSettings class from the Realtime APIs plus some other, PUN-relevant, settings. + [Serializable] + [HelpURL("https://doc.photonengine.com/en-us/pun/v2/getting-started/initial-setup")] + public class PhotonAppSettings : ScriptableObject + { + [Tooltip("Core Photon Server/Cloud settings.")] + public AppSettings AppSettings; + + #if UNITY_EDITOR + [HideInInspector] + public bool DisableAutoOpenWizard; + //public bool ShowSettings; + //public bool DevRegionSetOnce; + #endif + + private static PhotonAppSettings instance; + + /// Serialized server settings, written by the Setup Wizard for use in ConnectUsingSettings. + public static PhotonAppSettings Instance + { + get + { + if (instance == null) + { + LoadOrCreateSettings(); + } + + return instance; + } + + private set { instance = value; } + } + + + + public static void LoadOrCreateSettings() + { + if (instance != null) + { + Debug.LogWarning("Instance is not null. Will not LoadOrCreateSettings()."); + return; + } + + + #if UNITY_EDITOR + // let's check if the AssetDatabase finds the file; aimed to avoid multiple files being created, potentially a futile step + AssetDatabase.Refresh(); + #endif + + // try to load the resource / asset (ServerSettings a.k.a. PhotonServerSettings) + instance = (PhotonAppSettings)Resources.Load(typeof(PhotonAppSettings).Name, typeof(PhotonAppSettings)); + if (instance != null) + { + //Debug.LogWarning("Settings from Resources."); // DEBUG + return; + } + + + // create it if not loaded + if (instance == null) + { + instance = (PhotonAppSettings)CreateInstance(typeof(PhotonAppSettings)); + if (instance == null) + { + Debug.LogError("Failed to create ServerSettings. PUN is unable to run this way. If you deleted it from the project, reload the Editor."); + return; + } + + //Debug.LogWarning("Settings created!"); // DEBUG + } + + // in the editor, store the settings file as it's not loaded + #if UNITY_EDITOR + string punResourcesDirectory = "Assets/Photon/Resources/"; + string serverSettingsAssetPath = punResourcesDirectory + typeof(PhotonAppSettings).Name + ".asset"; + string serverSettingsDirectory = Path.GetDirectoryName(serverSettingsAssetPath); + + if (!Directory.Exists(serverSettingsDirectory)) + { + Directory.CreateDirectory(serverSettingsDirectory); + AssetDatabase.ImportAsset(serverSettingsDirectory); + } + + AssetDatabase.CreateAsset(instance, serverSettingsAssetPath); + AssetDatabase.SaveAssets(); + + + //Debug.Log("Settings stored to DB."); // DEBUG + #endif + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs.meta b/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs.meta new file mode 100644 index 0000000..63c192e --- /dev/null +++ b/Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a389b614f52fbf347a1533dbbf245033 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Photon/PhotonRealtime/Code/changes-realtime.txt b/Assets/Photon/PhotonRealtime/Code/changes-realtime.txt index 99e2152..14244f8 100644 --- a/Assets/Photon/PhotonRealtime/Code/changes-realtime.txt +++ b/Assets/Photon/PhotonRealtime/Code/changes-realtime.txt @@ -3,6 +3,148 @@ Photon Realtime C# Client - Changelog Exit Games GmbH - www.photonengine.com - forum.photonengine.com +Version 4.1.5.4 (13. April 2021) + Changed: Connect-methods in the LoadBalancingClient now fail "early" when the peer is already connected. This prevents unintentional modifications of the state and auth token. + Added: The LoadBalancingClient will now check if the token is available when the AuthMode 'AuthOnce' or 'AuthOnceWss' require it. If it's not available, the client will log an error and prevent the connection attempt. If this happens, the client is already in a bad state and won't connect anyways. + +Version 4.1.5.3 (07. April 2021) + Fixed: Protocol Fallback will now connect correctly when a fixed region is set. + Changed: ConnectUsingSettings internally sets connectToBestRegion value, based on CloudRegion (equals appSettings.FixedRegion). This avoids pinging when a fixed region is set. Leads to callback OnDisconnected(InvalidRegion). + +Version 4.1.5.2 (12. March 2021) + Changed: Region pinging will now apply port overrides for the Master Server port for UDP and address-based pinging (in the address and the UDP pings). + Changed: The RegionHandler gets the override port from lbc.ServerPortOverrides.MasterServerPort. If it's 0, the default port 5055 is being used. + Changed: The LoadBalancingClient.ReplacePortWithAlternative is now static and internal and can be used by the RegionHandler. + Added: TargetFramework (of the used dll) to SupportLogger output. + Added: Room.GetPlayer() option to find the Master Client, if the id is 0 (which is commonly used as "owned/controlled by the room, so it requires the Master Client). + +Version 4.1.5.1 (09. March 2021) + Removed: Setting of protocol 1.6 when connecting directly to a Master Server. This was a workaround for older Photon Server SDKs. + Note: If you host Photon yourself, you can set the LoadBalancingClient.SerializationProtocol to SerializationProtocol.GpBinaryV16, before you connect. + Changed: OpLeaveRoom will now clear the GameServerAddress and private room-entering cache. This cleans the state and prevents accidental success for ReconnectAndRejoinRoom calls. + Changed: ReconnectToMaster will check if MasterServerAddress and authToken are known. These are minimum requirements to reconnect to the master (after a connection loss). + Added: CustomAuthenticationType.Playstation5 (value 12). + +Version 4.1.5.0 (23. February 2021) + Added: LoadBalancingClient.ClientType and related code. Defines which sort of AppId should be expected. The LoadBalancingClient supports Realtime and Voice app types. Default: Realtime. + Note: This allows using AppSettings for Voice and Realtime clients more easily. ConnectUsingSettings will pick the relevant appid with this info. + Moved: EncryptionDataParameters class to become an internal class of the LoadBalancingClient (it was not used outside of LBC). + Removed: Room.StorePlayer was trying to calculate the Master Client (and was wrong about it). This triggered a OnMasterClientSwitched() callback in some cases of rejoining a room. + +Version 4.1.4.9 (12. January 2021) + Internal: EncryptionMode.DatagramEncryptionGCMRandomSequence (12) with .DatagramEncryptionGCM (13). + Internal: TokenForInit is now an object instead of a string. This also affects the AuthenticationValues class. This enables the server to send a byte[], which is more effective than a string. + Changed: Exposed all RoomOptions in Room class. Room.PublishUserId, Room.DeleteNullProperties. + Changed: Room.AutoCleanUp can also be set from room options flag. + Internal: EnterRoomParams and OpJoinRoom now use a JoinMode (replacing EnterRoomParams.CreateIfNotExists and EnterRoomParams.RejoinOnly). + Fixed: Unity-specific CustomTypes.cs to actually only compile for Unity. + Updated: EncryptionMode.DatagramEncryptionGCMRandomSequence (12) with .DatagramEncryptionGCM in the LoadBalancingClient. + Added: Room.SetExpectedUsers() to let the server know who's also coming (or no longer coming). + +Version 4.1.4.8 (30. November 2020) + Added: Conditional compilation in methods which are only for UNITY_WEBGL and UNITY_XBOXONE. The code needed to compile for any platform, even though it should not run anywhere else. + Added: Support for UNITY_GAMECORE. + Added: Parameter checks for GetGameList (and PUN GetCustomRoomList). The operation is not sent unless the parameters are OK. + Added: SupportLogger.OnDestroy to be removed from callback targets. + Added: RoomOptions.SuppressPlayerInfo. It can be used to skip join and leave events as well as properties broadcasts in rooms. + +Version 4.1.4.7 (25. November 2020) + Fixed: It was possible to trigger multiple calls of Authenticate by calling ConnectToRegionMaster(region) multiple times while being connected to the Name Server. + Changed: AuthenticationValues.ToString() to expose less data while showing which values are set. + +Version 4.1.4.6 (17. November 2020) + Added: Unity-specific types will now be registered for de/serialization automatically (in Unity projects) using CustomTypesUnity (in LoadBalancingClient constructor). + Note: The Player class needs to reference the current room to deserialize, so it is not a serializable type in the Realtime API (but in PUN). Send the Player.ActorNumber instead and the receiver looks up the ActorNumber in the room. + Changed: The client will now call disconnect if any operation response has a ReturnCode == ErrorCode.OperationLimitReached. The resulting OnDisconnect callback gets the new DisconnectCause.DisconnectByOperationLimit value. + Added: DisconnectCause.DisconnectByDisconnectMessage. If the server has a "low level" reason to disconnect a client, it can now send a Disconnect Message with some debug info. The LoadBalancingClient will log this message as error and disconnect. When this gets used will be added to the docs. + Changed: The BroadcastProperties parameter is now always sent to the Game Server, no matter if there are properties. This fixes a recent issue where UserIds were not broadcast in rooms, if no other player properties were used (see v4.1.4.5 changes). + Changed: UseAlternativeUdpPorts is replaced by ServerPortOverrides, which allow configuration of ports per server (including using no override). + Changed: UseAlternativeUdpPorts is obsolete and no longer used. + Changed: LoadBalancingClient.NameServerPortOverride is now named NameServerPortInAppSettings, which is closer to what it resembles. It is overwritten by the ServerPortOverrides if the nameserver port is > 0 there. + Added: Struct PhotonPortDefinition. + Added: ReplacePortWithAlternative method to wrap up the replacement as per our address rules. + Changed: When the client does not connect initially and EnableProtocolFallback is enabled, the ServerPortOverrides are reset and the fallback protocol will use the default ports for the Name Server (defined per protocol). + Changed: ReconnectAndRejoin() no longer affects the value IsUsingNameServer. This is only about reconnecting. + Changed: ReconnectAndRejoin() was logging error-level messages for expected situations. Now, there are only warnings in the logs. You can simply check the return value, which is false on error (then you should connect again, as usual). + Internal: The pool type for paramDictionaryPool, which is used in OpRaiseEvent. It is now a ParameterDictionary, which will wrap some value-types into pooled objects. This helps avoid some memory allocation. + Internal: ParameterCode.Secret is now .Token to match the server naming. + Changed: Logging level when OpRaiseEvent fails due to leaving a room. It reports as INFO level, when leaving or disconnecting. + Added: Error log for Op Authenticate, if the client does not have a token to authenticate on a Master or Game Server. That token comes from the Name Server and should be automatically present and used. Note: The client will send the auth but may fail due to missing token. + Changed: LoadBalancingClient.Disconnect() now checks if the client was just created or is disconnecting already. Those cases won't trigger a callback, so there is no surplus attempt to disconnect the peer. Also, the State does not change. An INFO level debug message helps detect those cases. + +Version 4.1.4.5 (02. September 2020) + Added: Unity-only ConnectionHandler.StaticReset() to allow entering playmode without domain reload. + Added: ErrorCode definition for OperationLimitReached (32743). The client will become unable to call any further operations (to safeguard the room/server) and get disconnected soon after. Currently used for SetProperties only. + Fixed: Region pinging for the case that none of the regions answered anything. Then, all region results caused a callback. + Added: Support for rooms that suppress room-events. + Added: Field bool Room.SuppressRoomEvents to allow checking if room events are suppressed. + Changed: If room events are suppressed, the callbacks OnCreatedRoom() and OnJoinedRoom() are now called by the operation response (not waiting for the suppressed events). + Renamed: Room.SetRoomFlags() to InternalCacheRoomFlags(). + Changed: When entering a room, the local players NickName property (255) is not sent if NullOrEmpty. + Changed: LoadBalancingApi should not use Unity.Debug unconditionally. + Updated: AuthenticationValues reference slightly. Better wording. + Updated: Token setter to be protected internal. Only needs to be set by Photon LB API. + Fixed: Csproject files for Chat API and LoadBalancing API. The two projects now import the dll based on the current target framework (dynamic). + +Version 4.1.4.4 (6. July 2020) + Fixed: AppSettings.CopyTo method. It was not copying the new value EnableProtocolFallback yet. + Fixed: The date of version 4.1.4.3 in this changelog. + Updated: Error handling in PingWindowsStore. + +Version 4.1.4.3 (24. June 2020) + Added: Check that the Dev Region override is in the list of available regions (from Name Server). If not, the first available region is being used. + Changed: RegionPinger.Start() now attempts to use a ThreadPool WorkerItem to ping individual regions. Only if that fails, a separate managed Thread is used. This should help avoid running into Thread limits (if any). Builds for NETFX_CORE don't use this. + Changed: Error handling in PingMono. SocketExceptions were not handled entirely. + Changed: PhotonPingClasses is no longer used. It's empty and can be removed. + Changed: Handling of event LobbyStats in case of LoadBalancingPeer.UseByteArraySlicePoolForEvents. This relates to a new option in the PhotonPeer to use pooled memory (wrapped byte[] basically) when incoming events only contain a byte[]. See changes-library.txt and API reference. + Added: Initial puzzle pieces for WSS Proxy support. This is not yet funtional. To actually use the proxy settings, a special WebSocket implementation is needed. + Changed: The AppSettings.Port value is now also usable when connecting to a Name Server initially. This allows custom ports on a (custom) Name Server. + Added: Various details to the SupportLogger output. + Changed: Callback OnCreatedRoom() is now also triggered by the event Join. This is the same trigger as for JoinOrCreateRoom (if that created a new room). + Added: Player.HasRejoined value. This is set for the local and remote players and can help define the workflow on ReJoin. + Added: LoadBalancingClient.EnableProtocolFallback. If enabled, the client will try another protocol if the initial connect to the Name Server fails. + Added: AppSettings.EnableProtocolFallback with a default of true. Used in ConnectUsingSettings to set the client's value accordingly. + Internal: Added setting the LoadBalancingClient.Server in Connect and other places, so it should be accurate. + Added: Checks for connections on WebGL and Xbox One. Settings that can be corrected (to match the platform's requirements) are corrected with a log note. An Exception is thrown, if the settings can't be corrected automatically. This means Connect methods may throw an Exception in some cases, which are to be fixed during development time. + +Version 4.1.4.2 (8. May 2020 - rev5519) + Fixed: EventLeave handling. The IsInactive property is to false before doing the OnPlayerLeftRoom callback. + Note: Use Player.IsInactive to know the 'reason' for the callback. + +Version 4.1.4.0 (27. April 2020 rev5469) + Fixed: When connecting directly to a Master Server (self hosted), the serialization protocol 1.6 is used (not the detault 1.8). This was changed accidentally in v4.1.3.0 (and thus PUN 2.17). + Added: Connection state check in CheckIfOpCanBeSent() to fail early if an op can't be sent. + Updated: WebRPC handling and added an example to the doc of OnWebRpcResponse. + Added: Logging of OnJoinRoomFailed to SupportLogger. + Changed: StripKeysWithNullValues to reuse a list of key with null-values. This causes less allocations and garbage to clean. As a downside, the method now runs only for one thread (even for distinct IDictionary instances). This should not be a problem for the expected use case. + Changed: The LoadBalancingClient.OnStatusChanged will handle StatusCode.SendError as disconnect due to Exception. Log level INFO should log the inner exception when sending. + Fixed: Cleanup of the RoomReference for the local player object on disconnect. This prevents issues when setting properties, after joining and leaving a room (back on Master Server). + Internal: LoadBalancingClient.ExpectedProtocol is now a nullable property with private setter. It's used internally (only) to switch to the target transport protocol when Authmode AuthOnceWss is "done". + Fixed: EventLeave handling. When a player gets removed from the room, the IsInactive property must be set to false before doing the OnPlayerLeftRoom callback. Use Player.IsInactive to know the 'reason' for the callback. + +Version 4.1.3.0 (23.03.2020 rev5394) + Changed: Trying to set empty custom properties Hashtable will fail (return false) and log error. + Changed: In online mode, trying to set properties while not joined to a room will fail (return false) and log error. Caching local player properties could be allowed though. + Changed: Player.InternalCacheProperties is now "protected internal" and no longer "public". + Changed: LoadBalancingClient.OpSetPropertiesOfRoom is now "protected internal" and no longer "public". Use LoadBalancingClient.OpSetCustomPropertiesOfRoom or Room.SetCustomProperties. + Changed: StatusCode.EncryptionFailedToEstablish will cause disconnection with DisconnectCause.ExceptionOnConnect. + Changed: Fix for Unity cloud build context to prevent sanitization of server settings, it's not needed and for some reason doesn't detect the current server settings. + Changed: AppSettings. The NonSerialized attribute is now only used in Unity builds. + Changed: With the updated Photon library (v4.1.3.0), the encryption can be set to true on any connection, including WSS. It should not be used conditionally for Auth. + Changed: GetPingImplementation() new sets a default PhotonPingImplementation for UNITY_WEBGL, NETFX_CORE and regular Mono/.Net. + Internal: New datagram encryption mode DatagramEncryptionGCMRandomSequence (value 12). To be used later on. + Internal: The SocketWebTcp.SerializationProtocol is now selected by the PhotonSocket with the Peer's current value. It no longer needs to be set. + +Version 4.1.2.20 (12. December 2019 - rev5296) + Added: New callback IErrorInfoCallback.OnErrorInfo when the client receives an ErrorInfo event from the server. + Changed: RegionPinger use a singleton MonoBehaviourEmpty for coroutine ping in WebGL in Unity. + Added: LoadBalancingClient.SerializationProtocol property to get or set the binary protocol version. Use this always instead of setting it via LoadBalancingPeer.SerializationProtocolType. + Added: LoadBalancingClient.ConnectUsingSettings(AppSettings appSettings). This allows Best Region connect, setting a custom name server and much more. + Changed: Connect() is now ConnectToMasterServer(). Unlike ConnectUsingSettings(), this requires some settings to be done on the client. + Added: Return parameter for all methods that set properties on the server. + Note: Room.SetCustomProperties returns bool. If you did override this, your project will have errors, make sure to fix the return type. + Changed: Failed Authentication will no longer call the OnDisconnected callback twice. This should better align with expectations. + Internal: Pinging regions via coroutine (when Threads are unavailable) now uses only one GameObject for all pinging. Version 4.1.2.19 (12. November 2019 - rev5266) Fixed: The ExpectedProtocol is now also set for Authmode "AuthOnce" for ConnectToNameServer and ConnectToRegionMaster. @@ -15,7 +157,6 @@ Version 4.1.2.19 (12. November 2019 - rev5266) Added: LoadBalancingClient.OpJoinRandomOrCreateRoom. This can be used to create a room, should random matchmaking fail. This helps avoid race conditons where players can't find one another. Added: Extra null-check in handling of event leave. - Version 4.1.2.17 (9. August 2019 - rev5188) Changed: SupportLogger. Traffic stats are enabled by default. The PhotonHandler no longer has to enable this. Added: Min/max ping to logged statistics. SupportLogger.TrackValues is invoked to keep track of min/max ping for each connection. @@ -63,6 +204,9 @@ Version 4.1.2.11 (15. April 2019 - rev5043) Version 4.1.2.10 (11. March 2019 - rev5023) Changed: The cached "best region" is cleared whenever a region's pinging finishes. This fixes a potential issue when the BestRegion value is used before the pinging is done. Then, you end up with a wrong selection. + Changed: PhotonPing now reuses the Socket per region. + Changed: The RegionHandler now checks #if PING_VIA_COROUTINE to use a coroutine instead of a thread (per region). This is for WebGL exports from Unity. + Changed: The SupportLogger now uses a Stopwatch to log the time (not depending on Unity's APIs). Version 4.1.2.1 (31. July 2018 - rev4787) Changed: OnStateChangeAction is now named StateChanged and provides a "previous state" value. State changes only trigger the event-call when the value actually changes. diff --git a/Assets/Plugins.meta b/Assets/Plugins.meta index e5f6568..2d4b6f6 100644 --- a/Assets/Plugins.meta +++ b/Assets/Plugins.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e846af837ee794330b97f96592254488 +guid: d07b0e5404378af4192f2482f455e208 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scenes.meta b/Assets/Scenes.meta new file mode 100644 index 0000000..2b3bdc5 --- /dev/null +++ b/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c1fb1508cf0f2d4db00abce761a2416 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity new file mode 100644 index 0000000..d7548dd --- /dev/null +++ b/Assets/Scenes/SampleScene.unity @@ -0,0 +1,259 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 705507994} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &705507993 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 705507995} + - component: {fileID: 705507994} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &705507994 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 1 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &705507995 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_GateFitMode: 2 + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup.meta b/Assets/Scenes/SampleScene.unity.meta similarity index 74% rename from Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup.meta rename to Assets/Scenes/SampleScene.unity.meta index bdc71dc..952bd1e 100644 --- a/Assets/Photon/PhotonBolt/assemblies/bolt.user.dll.backup.meta +++ b/Assets/Scenes/SampleScene.unity.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8c0f868f5979f477884ca6b5c6b2f9b4 +guid: 9fc0d4010bbf28b4594072e72b8655ab DefaultImporter: externalObjects: {} userData: diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index eb98d31..cf57a37 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -585,7 +585,7 @@ PlayerSettings: webGLThreadsSupport: 0 webGLWasmStreaming: 0 scriptingDefineSymbols: - 1: UNITY_POST_PROCESSING_STACK_V2;BOLT_CLOUD + 1: UNITY_POST_PROCESSING_STACK_V2;BOLT_CLOUD;BOLT_1_3_OR_NEWER 4: UNITY_POST_PROCESSING_STACK_V2 7: UNITY_POST_PROCESSING_STACK_V2 13: UNITY_POST_PROCESSING_STACK_V2