mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
feat: KCP Transport (https://github.com/vis2k/kcp2k) (#2381)
This commit is contained in:
parent
88e160a5f7
commit
0c2ad96061
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.4366757, g: 0.48427194, b: 0.5645252, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.43667564, g: 0.48427147, b: 0.56452364, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -1830,12 +1830,12 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 0
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 1661834280}
|
||||
transport: {fileID: 0}
|
||||
networkAddress: localhost
|
||||
maxConnections: 4
|
||||
disconnectInactiveConnections: 0
|
||||
@ -1871,7 +1871,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1661834277}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -1898,10 +1898,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &1661834281
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.44657868, g: 0.49641263, b: 0.57481706, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -155,7 +155,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 249891953}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -182,10 +182,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &249891956
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -200,12 +204,12 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 0
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 249891955}
|
||||
transport: {fileID: 0}
|
||||
networkAddress: localhost
|
||||
maxConnections: 16
|
||||
disconnectInactiveConnections: 0
|
||||
|
@ -309,7 +309,7 @@ MonoBehaviour:
|
||||
- {fileID: 449802645721213856, guid: 30b8f251d03d84284b70601e691d474f, type: 3}
|
||||
spawnPrefab: {fileID: 449802645721213856, guid: 30b8f251d03d84284b70601e691d474f,
|
||||
type: 3}
|
||||
spawnAmount: 4000
|
||||
spawnAmount: 1000
|
||||
interleave: 1
|
||||
--- !u!114 &1282001521
|
||||
MonoBehaviour:
|
||||
@ -320,7 +320,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1282001517}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -347,12 +347,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
serverMaxReceivesPerTick: 10000
|
||||
clientMaxMessageSize: 16384
|
||||
clientMaxReceivesPerTick: 1000
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 0
|
||||
SendWindowSize: 512
|
||||
ReceiveWindowSize: 512
|
||||
debugGUI: 1
|
||||
--- !u!1 &2054208274
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.44657868, g: 0.49641263, b: 0.57481706, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -2895,7 +2895,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 1783103026}
|
||||
- component: {fileID: 1783103025}
|
||||
- component: {fileID: 1783103024}
|
||||
- component: {fileID: 1783103023}
|
||||
m_Layer: 0
|
||||
m_Name: NetworkManager
|
||||
m_TagString: Untagged
|
||||
@ -2903,7 +2903,7 @@ GameObject:
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1783103024
|
||||
--- !u!114 &1783103023
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@ -2912,7 +2912,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1783103022}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -2939,10 +2939,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &1783103025
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -2957,12 +2961,12 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 1783103024}
|
||||
transport: {fileID: 1783103023}
|
||||
networkAddress: localhost
|
||||
maxConnections: 4
|
||||
disconnectInactiveConnections: 0
|
||||
|
@ -12,7 +12,7 @@ GameObject:
|
||||
- component: {fileID: 4798169800353248833}
|
||||
- component: {fileID: 5399210850297115757}
|
||||
- component: {fileID: 1442807832621757098}
|
||||
- component: {fileID: 4798169800353248834}
|
||||
- component: {fileID: 7877660282335013212}
|
||||
m_Layer: 0
|
||||
m_Name: NetworkManagerPong
|
||||
m_TagString: Untagged
|
||||
@ -51,8 +51,6 @@ MonoBehaviour:
|
||||
_onServerListUpdated:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.Cloud.ServerListEvent, Mirror.Cloud, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!114 &5399210850297115757
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -65,6 +63,8 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 1f6e5d5acb5879f45a2235ae0f44dc92, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
manager: {fileID: 0}
|
||||
connector: {fileID: 0}
|
||||
gameName: Pong Game
|
||||
--- !u!114 &1442807832621757098
|
||||
MonoBehaviour:
|
||||
@ -80,12 +80,12 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene: Assets/Mirror/Examples/Cloud/PongWithListServer/Scenes/ListServerLobbyScenePong.unity
|
||||
onlineScene: Assets/Mirror/Examples/Cloud/PongWithListServer/Scenes/PongGameScene.unity
|
||||
transport: {fileID: 4798169800353248834}
|
||||
transport: {fileID: 7877660282335013212}
|
||||
networkAddress: localhost
|
||||
maxConnections: 2
|
||||
disconnectInactiveConnections: 0
|
||||
@ -97,7 +97,7 @@ MonoBehaviour:
|
||||
playerSpawnMethod: 1
|
||||
spawnPrefabs:
|
||||
- {fileID: 1080679924113744, guid: a4b57f17790d9634ea5fd0fe80b214fd, type: 3}
|
||||
--- !u!114 &4798169800353248834
|
||||
--- !u!114 &7877660282335013212
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@ -106,50 +106,38 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 4798169800353248846}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnClientDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ClientDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnServerConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
OnServerDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ServerDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventIntException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
serverMaxReceivesPerTick: 10000
|
||||
clientMaxMessageSize: 16384
|
||||
clientMaxReceivesPerTick: 1000
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
|
@ -13,7 +13,6 @@ GameObject:
|
||||
- component: {fileID: 5399210850297115757}
|
||||
- component: {fileID: 5256484632236059241}
|
||||
- component: {fileID: 1442807832621757098}
|
||||
- component: {fileID: 4798169800353248834}
|
||||
m_Layer: 0
|
||||
m_Name: TanksNetworkManager
|
||||
m_TagString: Untagged
|
||||
@ -52,8 +51,6 @@ MonoBehaviour:
|
||||
_onServerListUpdated:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.Cloud.ServerListEvent, Mirror.Cloud, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
--- !u!114 &5399210850297115757
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -66,6 +63,8 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 1f6e5d5acb5879f45a2235ae0f44dc92, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
manager: {fileID: 0}
|
||||
connector: {fileID: 0}
|
||||
gameName: Tanks Game
|
||||
--- !u!114 &5256484632236059241
|
||||
MonoBehaviour:
|
||||
@ -93,12 +92,12 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene: Assets/Mirror/Examples/Cloud/TanksWithListServer/Scenes/ListServerLobbySceneTanks.unity
|
||||
onlineScene: Assets/Mirror/Examples/Tanks/Scenes/Scene.unity
|
||||
transport: {fileID: 4798169800353248834}
|
||||
transport: {fileID: 0}
|
||||
networkAddress: localhost
|
||||
maxConnections: 4
|
||||
disconnectInactiveConnections: 0
|
||||
@ -110,59 +109,3 @@ MonoBehaviour:
|
||||
playerSpawnMethod: 1
|
||||
spawnPrefabs:
|
||||
- {fileID: 5890560936853567077, guid: b7dd46dbf38c643f09e206f9fa4be008, type: 3}
|
||||
--- !u!114 &4798169800353248834
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4798169800353248846}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnClientDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ClientDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnServerConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
OnServerDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ServerDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventIntException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
serverMaxReceivesPerTick: 10000
|
||||
clientMaxMessageSize: 16384
|
||||
clientMaxReceivesPerTick: 1000
|
||||
|
@ -451,6 +451,11 @@ PrefabInstance:
|
||||
propertyPath: m_SizeDelta.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4971607475644947932, guid: e16e442bbd8d4434cb606afd72bcd08b,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 0.000091552734
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4971607476029058370, guid: e16e442bbd8d4434cb606afd72bcd08b,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
@ -521,6 +526,11 @@ PrefabInstance:
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4971607476873278848, guid: e16e442bbd8d4434cb606afd72bcd08b,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4971607476965432301, guid: e16e442bbd8d4434cb606afd72bcd08b,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
|
@ -395,7 +395,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1556883243}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -422,10 +422,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &1556883245
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -440,7 +444,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
|
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 690741348}
|
||||
m_IndirectSpecularColor: {r: 0.4366757, g: 0.48427194, b: 0.5645252, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.43667564, g: 0.48427147, b: 0.56452364, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -54,7 +54,7 @@ LightmapSettings:
|
||||
m_EnableBakedLightmaps: 0
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
serializedVersion: 10
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
@ -62,7 +62,6 @@ LightmapSettings:
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
@ -77,16 +76,10 @@ 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_PVREnvironmentMIS: 0
|
||||
m_PVRFilteringMode: 2
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
@ -94,8 +87,7 @@ LightmapSettings:
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_ShowResolutionOverlay: 1
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_UseShadowmask: 1
|
||||
--- !u!196 &4
|
||||
@ -158,10 +150,9 @@ Camera:
|
||||
m_ClearFlags: 1
|
||||
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_GateFitMode: 2
|
||||
m_FocalLength: 50
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
@ -213,8 +204,8 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 69965670}
|
||||
- component: {fileID: 69965669}
|
||||
- component: {fileID: 69965668}
|
||||
- component: {fileID: 69965667}
|
||||
- component: {fileID: 69965668}
|
||||
m_Layer: 0
|
||||
m_Name: Network
|
||||
m_TagString: Untagged
|
||||
@ -246,7 +237,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 69965666}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -273,12 +264,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
serverMaxReceivesPerTick: 10000
|
||||
clientMaxMessageSize: 16384
|
||||
clientMaxReceivesPerTick: 1000
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &69965669
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -293,7 +286,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 0
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
@ -480,13 +473,12 @@ Light:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 690741347}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 9
|
||||
serializedVersion: 8
|
||||
m_Type: 1
|
||||
m_Color: {r: 0.990566, g: 0.9496818, b: 0.82702917, a: 1}
|
||||
m_Intensity: 1
|
||||
m_Range: 10
|
||||
m_SpotAngle: 30
|
||||
m_InnerSpotAngle: 21.80208
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
@ -496,24 +488,6 @@ Light:
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_CullingMatrixOverride:
|
||||
e00: 1
|
||||
e01: 0
|
||||
e02: 0
|
||||
e03: 0
|
||||
e10: 0
|
||||
e11: 1
|
||||
e12: 0
|
||||
e13: 0
|
||||
e20: 0
|
||||
e21: 0
|
||||
e22: 1
|
||||
e23: 0
|
||||
e30: 0
|
||||
e31: 0
|
||||
e32: 0
|
||||
e33: 1
|
||||
m_UseCullingMatrixOverride: 0
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
@ -521,15 +495,12 @@ Light:
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingLayerMask: 1
|
||||
m_Lightmapping: 4
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_UseBoundingSphereOverride: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
--- !u!4 &690741349
|
||||
|
@ -872,7 +872,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
@ -900,7 +900,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1886246549}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -927,7 +927,11 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
|
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.44657868, g: 0.49641263, b: 0.57481706, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -214,8 +214,8 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 492096636}
|
||||
- component: {fileID: 492096635}
|
||||
- component: {fileID: 492096634}
|
||||
- component: {fileID: 492096637}
|
||||
- component: {fileID: 492096634}
|
||||
m_Layer: 0
|
||||
m_Name: NetworkManager
|
||||
m_TagString: Untagged
|
||||
@ -232,53 +232,41 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 492096633}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnClientDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ClientDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnServerConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
OnServerDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.ServerDataReceivedEvent, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventIntException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
serverMaxReceivesPerTick: 10000
|
||||
clientMaxMessageSize: 16384
|
||||
clientMaxReceivesPerTick: 1000
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &492096635
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -293,7 +281,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
@ -394,8 +382,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
@ -881,8 +867,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
@ -955,8 +939,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 24
|
||||
@ -1034,8 +1016,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 24
|
||||
@ -1296,8 +1276,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 24
|
||||
@ -1378,8 +1356,6 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
|
@ -222,7 +222,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 2008127829}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
@ -249,10 +249,14 @@ MonoBehaviour:
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
serverMaxMessageSize: 16384
|
||||
clientMaxMessageSize: 16384
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!114 &2008127831
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -267,7 +271,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene: Assets/Mirror/Examples/Room/Scenes/OfflineScene.unity
|
||||
@ -290,7 +294,7 @@ MonoBehaviour:
|
||||
type: 3}
|
||||
RoomScene: Assets/Mirror/Examples/Room/Scenes/RoomScene.unity
|
||||
GameplayScene: Assets/Mirror/Examples/Room/Scenes/OnlineScene.unity
|
||||
allPlayersReady: 0
|
||||
_allPlayersReady: 0
|
||||
roomSlots: []
|
||||
--- !u!4 &2008127832
|
||||
Transform:
|
||||
|
@ -443,14 +443,17 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
dontDestroyOnLoad: 1
|
||||
runInBackground: 1
|
||||
startOnHeadless: 1
|
||||
serverTickRate: 30
|
||||
autoStartServerBuild: 1
|
||||
showDebugMessages: 0
|
||||
serverTickRate: 30
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 1282001521}
|
||||
networkAddress: localhost
|
||||
maxConnections: 4
|
||||
disconnectInactiveConnections: 0
|
||||
disconnectInactiveTimeout: 60
|
||||
authenticator: {fileID: 0}
|
||||
playerPrefab: {fileID: 1916082411674582, guid: 6f43bf5488a7443d19ab2a83c6b91f35,
|
||||
type: 3}
|
||||
autoCreatePlayer: 1
|
||||
@ -466,49 +469,41 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 1282001517}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7424c1070fad4ba2a7a96b02fbeb4bb, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
OnClientConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnClientDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventByteArray, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnClientDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine.CoreModule, Version=0.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
OnServerConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
OnServerDataReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventIntByteArray, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventIntException, Mirror, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
OnServerDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: Mirror.UnityEventInt, Mirror, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
port: 7777
|
||||
Port: 7777
|
||||
NoDelay: 1
|
||||
Interval: 10
|
||||
FastResend: 0
|
||||
CongestionWindow: 1
|
||||
SendWindowSize: 128
|
||||
ReceiveWindowSize: 128
|
||||
debugGUI: 0
|
||||
--- !u!1 &1458789072
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -7,7 +7,7 @@
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Serialization;
|
||||
using kcp2k;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
@ -204,7 +205,7 @@ public virtual void OnValidate()
|
||||
transport = GetComponent<Transport>();
|
||||
if (transport == null)
|
||||
{
|
||||
transport = gameObject.AddComponent<TelepathyTransport>();
|
||||
transport = gameObject.AddComponent<KcpTransport>();
|
||||
logger.Log("NetworkManager: added default Transport because there was none yet.");
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
|
8
Assets/Mirror/Runtime/Transport/KCP.meta
Normal file
8
Assets/Mirror/Runtime/Transport/KCP.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 953bb5ec5ab2346a092f58061e01ba65
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Mirror/Runtime/Transport/KCP/MirrorTransport.meta
Normal file
8
Assets/Mirror/Runtime/Transport/KCP/MirrorTransport.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bdb797750d0a490684410110bf48192
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,172 @@
|
||||
#if MIRROR
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public class KcpTransport : Transport
|
||||
{
|
||||
// scheme used by this transport
|
||||
public const string Scheme = "kcp";
|
||||
|
||||
// common
|
||||
[Header("Transport Configuration")]
|
||||
public ushort Port = 7777;
|
||||
[Tooltip("NoDelay is recommended to reduce latency. This also scales better without buffers getting full.")]
|
||||
public bool NoDelay = true;
|
||||
[Tooltip("KCP internal update interval. 100ms is KCP default, but a lower interval is recommended to minimize latency and to scale to more networked entities.")]
|
||||
public uint Interval = 10;
|
||||
[Header("Advanced")]
|
||||
[Tooltip("KCP fastresend parameter. Faster resend for the cost of higher bandwidth.")]
|
||||
public int FastResend = 0;
|
||||
[Tooltip("KCP congestion window can be disabled. This is necessary to Mirror 10k Benchmark. Disable this for high scale games if connections get chocked regularly.")]
|
||||
public bool CongestionWindow = true; // KCP 'NoCongestionWindow' is false by default. here we negate it for ease of use.
|
||||
[Tooltip("KCP window size can be modified to support higher loads. For example, Mirror Benchmark requires 128 for 4k monsters, 256 for 10k monsters (if CongestionWindow is disabled.)")]
|
||||
public uint SendWindowSize = 128; //Kcp.WND_SND; 32 by default. 128 is better for 4k Benchmark etc.
|
||||
[Tooltip("KCP window size can be modified to support higher loads. For example, Mirror Benchmark requires 128 for 4k monsters, 256 for 10k monsters (if CongestionWindow is disabled.)")]
|
||||
public uint ReceiveWindowSize = Kcp.WND_RCV;
|
||||
|
||||
// server & client
|
||||
KcpServer server;
|
||||
KcpClient client;
|
||||
|
||||
// debugging
|
||||
[Header("Debug")]
|
||||
public bool debugGUI;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// TODO simplify after converting Mirror Transport events to Action
|
||||
client = new KcpClient(
|
||||
() => OnClientConnected.Invoke(),
|
||||
(message) => OnClientDataReceived.Invoke(message, Channels.DefaultReliable),
|
||||
() => OnClientDisconnected.Invoke()
|
||||
);
|
||||
// TODO simplify after converting Mirror Transport events to Action
|
||||
server = new KcpServer(
|
||||
(connectionId) => OnServerConnected.Invoke(connectionId),
|
||||
(connectionId, message) => OnServerDataReceived.Invoke(connectionId, message, Channels.DefaultReliable),
|
||||
(connectionId) => OnServerDisconnected.Invoke(connectionId),
|
||||
NoDelay,
|
||||
Interval,
|
||||
FastResend,
|
||||
CongestionWindow,
|
||||
SendWindowSize,
|
||||
ReceiveWindowSize
|
||||
);
|
||||
Debug.Log("KcpTransport initialized!");
|
||||
}
|
||||
|
||||
// all except WebGL
|
||||
public override bool Available() =>
|
||||
Application.platform != RuntimePlatform.WebGLPlayer;
|
||||
|
||||
// client
|
||||
public override bool ClientConnected() => client.connected;
|
||||
public override void ClientConnect(string address)
|
||||
{
|
||||
client.Connect(address, Port, NoDelay, Interval, FastResend, CongestionWindow, SendWindowSize, ReceiveWindowSize);
|
||||
}
|
||||
public override void ClientSend(int channelId, ArraySegment<byte> segment)
|
||||
{
|
||||
client.Send(segment);
|
||||
}
|
||||
public override void ClientDisconnect() => client.Disconnect();
|
||||
|
||||
// IMPORTANT: set script execution order to >1000 to call Transport's
|
||||
// LateUpdate after all others. Fixes race condition where
|
||||
// e.g. in uSurvival Transport would apply Cmds before
|
||||
// ShoulderRotation.LateUpdate, resulting in projectile
|
||||
// spawns at the point before shoulder rotation.
|
||||
public void LateUpdate()
|
||||
{
|
||||
// note: we need to check enabled in case we set it to false
|
||||
// when LateUpdate already started.
|
||||
// (https://github.com/vis2k/Mirror/pull/379)
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
server.Tick();
|
||||
client.Tick();
|
||||
}
|
||||
|
||||
// server
|
||||
public override Uri ServerUri()
|
||||
{
|
||||
UriBuilder builder = new UriBuilder();
|
||||
builder.Scheme = Scheme;
|
||||
builder.Host = Dns.GetHostName();
|
||||
builder.Port = Port;
|
||||
return builder.Uri;
|
||||
}
|
||||
public override bool ServerActive() => server.IsActive();
|
||||
public override void ServerStart() => server.Start(Port);
|
||||
public override void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment)
|
||||
{
|
||||
server.Send(connectionId, segment);
|
||||
}
|
||||
public override bool ServerDisconnect(int connectionId)
|
||||
{
|
||||
server.Disconnect(connectionId);
|
||||
return true;
|
||||
}
|
||||
public override string ServerGetClientAddress(int connectionId) => server.GetClientAddress(connectionId);
|
||||
public override void ServerStop() => server.Stop();
|
||||
|
||||
// common
|
||||
public override void Shutdown() {}
|
||||
|
||||
// MTU
|
||||
public override int GetMaxPacketSize(int channelId = Channels.DefaultReliable) => Kcp.MTU_DEF;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "KCP";
|
||||
}
|
||||
|
||||
int GetTotalSendQueue() =>
|
||||
server.connections.Values.Sum(conn => conn.kcp.snd_queue.Count);
|
||||
int GetTotalReceiveQueue() =>
|
||||
server.connections.Values.Sum(conn => conn.kcp.rcv_queue.Count);
|
||||
int GetTotalSendBuffer() =>
|
||||
server.connections.Values.Sum(conn => conn.kcp.snd_buf.Count);
|
||||
int GetTotalReceiveBuffer() =>
|
||||
server.connections.Values.Sum(conn => conn.kcp.rcv_buf.Count);
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (!debugGUI) return;
|
||||
|
||||
GUILayout.BeginArea(new Rect(5, 100, 300, 300));
|
||||
|
||||
if (ServerActive())
|
||||
{
|
||||
GUILayout.BeginVertical("Box");
|
||||
GUILayout.Label("SERVER");
|
||||
GUILayout.Label(" connections: " + server.connections.Count);
|
||||
GUILayout.Label(" SendQueue: " + GetTotalSendQueue());
|
||||
GUILayout.Label(" ReceiveQueue: " + GetTotalReceiveQueue());
|
||||
GUILayout.Label(" SendBuffer: " + GetTotalSendBuffer());
|
||||
GUILayout.Label(" ReceiveBuffer: " + GetTotalReceiveBuffer());
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
if (ClientConnected())
|
||||
{
|
||||
GUILayout.BeginVertical("Box");
|
||||
GUILayout.Label("CLIENT");
|
||||
GUILayout.Label(" SendQueue: " + client.connection.kcp.snd_queue.Count);
|
||||
GUILayout.Label(" ReceiveQueue: " + client.connection.kcp.rcv_queue.Count);
|
||||
GUILayout.Label(" SendBuffer: " + client.connection.kcp.snd_buf.Count);
|
||||
GUILayout.Label(" ReceiveBuffer: " + client.connection.kcp.rcv_buf.Count);
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b0fecffa3f624585964b0d0eb21b18e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k.meta
Normal file
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71a1c8e8c022d4731a481c1808f37e5d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
24
Assets/Mirror/Runtime/Transport/KCP/kcp2k/LICENSE
Executable file
24
Assets/Mirror/Runtime/Transport/KCP/kcp2k/LICENSE
Executable file
@ -0,0 +1,24 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 limpo1989
|
||||
Copyright (c) 2020 Paul Pacheco
|
||||
Copyright (c) 2020 Lymdun
|
||||
Copyright (c) 2020 vis2k
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
7
Assets/Mirror/Runtime/Transport/KCP/kcp2k/LICENSE.meta
Normal file
7
Assets/Mirror/Runtime/Transport/KCP/kcp2k/LICENSE.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a3e8369060cf4e94ac117603de47aa6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
9
Assets/Mirror/Runtime/Transport/KCP/kcp2k/VERSION
Executable file
9
Assets/Mirror/Runtime/Transport/KCP/kcp2k/VERSION
Executable file
@ -0,0 +1,9 @@
|
||||
V1.1
|
||||
- high level cleanup, fixes, improvements
|
||||
|
||||
V1.0
|
||||
- Kcp.cs now mirrors original Kcp.c behaviour
|
||||
(this fixes dozens of bugs)
|
||||
|
||||
V0.1
|
||||
- initial kcp-csharp based version
|
7
Assets/Mirror/Runtime/Transport/KCP/kcp2k/VERSION.meta
Normal file
7
Assets/Mirror/Runtime/Transport/KCP/kcp2k/VERSION.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed3f2cf1bbf1b4d53a6f2c103d311f71
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel.meta
Normal file
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a54d18b954cb4407a28b633fc32ea6d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,95 @@
|
||||
// kcp client logic abstracted into a class.
|
||||
// for use in Mirror, DOTSNET, testing, etc.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public class KcpClient
|
||||
{
|
||||
// events
|
||||
public Action OnConnected;
|
||||
public Action<ArraySegment<byte>> OnData;
|
||||
public Action OnDisconnected;
|
||||
|
||||
// state
|
||||
public KcpClientConnection connection;
|
||||
public bool connected;
|
||||
|
||||
public KcpClient(Action OnConnected, Action<ArraySegment<byte>> OnData, Action OnDisconnected)
|
||||
{
|
||||
this.OnConnected = OnConnected;
|
||||
this.OnData = OnData;
|
||||
this.OnDisconnected = OnDisconnected;
|
||||
}
|
||||
|
||||
public void Connect(string address, ushort port, bool noDelay, uint interval, int fastResend = 0, bool congestionWindow = true, uint sendWindowSize = Kcp.WND_SND, uint receiveWindowSize = Kcp.WND_RCV)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
Debug.LogWarning("KCP: client already connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
connection = new KcpClientConnection();
|
||||
|
||||
// setup events
|
||||
connection.OnAuthenticated = () =>
|
||||
{
|
||||
Debug.Log($"KCP: OnClientConnected");
|
||||
connected = true;
|
||||
OnConnected.Invoke();
|
||||
};
|
||||
connection.OnData = (message) =>
|
||||
{
|
||||
//Debug.Log($"KCP: OnClientData({BitConverter.ToString(message.Array, message.Offset, message.Count)})");
|
||||
OnData.Invoke(message);
|
||||
};
|
||||
connection.OnDisconnected = () =>
|
||||
{
|
||||
Debug.Log($"KCP: OnClientDisconnected");
|
||||
connected = false;
|
||||
connection = null;
|
||||
OnDisconnected.Invoke();
|
||||
};
|
||||
|
||||
// connect
|
||||
connection.Connect(address, port, noDelay, interval, fastResend, congestionWindow, sendWindowSize, receiveWindowSize);
|
||||
}
|
||||
|
||||
public void Send(ArraySegment<byte> segment)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
connection.Send(segment);
|
||||
}
|
||||
else Debug.LogWarning("KCP: can't send because client not connected!");
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
// only if connected
|
||||
// otherwise we end up in a deadlock because of an open Mirror bug:
|
||||
// https://github.com/vis2k/Mirror/issues/2353
|
||||
if (connected)
|
||||
{
|
||||
// call Disconnect and let the connection handle it.
|
||||
// DO NOT set it to null yet. it needs to be updated a few more
|
||||
// times first. let the connection handle it!
|
||||
connection?.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
// tick client connection
|
||||
if (connection != null)
|
||||
{
|
||||
// recv on socket first
|
||||
connection.RawReceive();
|
||||
// then update
|
||||
connection.Tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aa069a28ed24fedb533c102d9742b36
|
||||
timeCreated: 1603786960
|
@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public class KcpClientConnection : KcpConnection
|
||||
{
|
||||
readonly byte[] buffer = new byte[1500];
|
||||
|
||||
public void Connect(string host, ushort port, bool noDelay, uint interval = Kcp.INTERVAL, int fastResend = 0, bool congestionWindow = true, uint sendWindowSize = Kcp.WND_SND, uint receiveWindowSize = Kcp.WND_RCV)
|
||||
{
|
||||
Debug.Log($"KcpClient: connect to {host}:{port}");
|
||||
IPAddress[] ipAddress = Dns.GetHostAddresses(host);
|
||||
if (ipAddress.Length < 1)
|
||||
throw new SocketException((int)SocketError.HostNotFound);
|
||||
|
||||
remoteEndpoint = new IPEndPoint(ipAddress[0], port);
|
||||
socket = new Socket(remoteEndpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
|
||||
socket.Connect(remoteEndpoint);
|
||||
SetupKcp(noDelay, interval, fastResend, congestionWindow, sendWindowSize, receiveWindowSize);
|
||||
|
||||
// client should send handshake to server as very first message
|
||||
SendHandshake();
|
||||
|
||||
RawReceive();
|
||||
}
|
||||
|
||||
// call from transport update
|
||||
public void RawReceive()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (socket != null)
|
||||
{
|
||||
while (socket.Poll(0, SelectMode.SelectRead))
|
||||
{
|
||||
int msgLength = socket.ReceiveFrom(buffer, ref remoteEndpoint);
|
||||
//Debug.Log($"KCP: client raw recv {msgLength} bytes = {BitConverter.ToString(buffer, 0, msgLength)}");
|
||||
RawInput(buffer, msgLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this is fine, the socket might have been closed in the other end
|
||||
catch (SocketException) {}
|
||||
}
|
||||
|
||||
protected override void Dispose()
|
||||
{
|
||||
socket.Close();
|
||||
socket = null;
|
||||
}
|
||||
|
||||
protected override void RawSend(byte[] data, int length)
|
||||
{
|
||||
socket.Send(data, length, SocketFlags.None);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96512e74aa8214a6faa8a412a7a07877
|
||||
timeCreated: 1602601237
|
@ -0,0 +1,360 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
enum KcpState { Connected, Authenticated, Disconnected }
|
||||
|
||||
public abstract class KcpConnection
|
||||
{
|
||||
protected Socket socket;
|
||||
protected EndPoint remoteEndpoint;
|
||||
internal Kcp kcp;
|
||||
|
||||
// kcp can have several different states, let's use a state machine
|
||||
KcpState state = KcpState.Disconnected;
|
||||
|
||||
public Action OnAuthenticated;
|
||||
public Action<ArraySegment<byte>> OnData;
|
||||
public Action OnDisconnected;
|
||||
|
||||
// If we don't receive anything these many milliseconds
|
||||
// then consider us disconnected
|
||||
public const int TIMEOUT = 10000;
|
||||
uint lastReceiveTime;
|
||||
|
||||
// internal time.
|
||||
// StopWatch offers ElapsedMilliSeconds and should be more precise than
|
||||
// Unity's time.deltaTime over long periods.
|
||||
readonly Stopwatch refTime = new Stopwatch();
|
||||
|
||||
// recv buffer to avoid allocations
|
||||
byte[] buffer = new byte[Kcp.MTU_DEF];
|
||||
|
||||
internal static readonly ArraySegment<byte> Hello = new ArraySegment<byte>(new byte[] { 0 });
|
||||
static readonly ArraySegment<byte> Goodbye = new ArraySegment<byte>(new byte[] { 1 });
|
||||
static readonly ArraySegment<byte> Ping = new ArraySegment<byte>(new byte[] { 2 });
|
||||
|
||||
// send a ping occasionally so we don't time out on the other end.
|
||||
// for example, creating a character in an MMO could easily take a
|
||||
// minute of no data being sent. which doesn't mean we want to time out.
|
||||
// same goes for slow paced card games etc.
|
||||
public const int PING_INTERVAL = 1000;
|
||||
uint lastPingTime;
|
||||
|
||||
// if we send more than kcp can handle, we will get ever growing
|
||||
// send/recv buffers and queues and minutes of latency.
|
||||
// => if a connection can't keep up, it should be disconnected instead
|
||||
// to protect the server under heavy load, and because there is no
|
||||
// point in growing to gigabytes of memory or minutes of latency!
|
||||
// => 2k isn't enough. we reach 2k when spawning 4k monsters at once
|
||||
// easily, but it does recover over time.
|
||||
// => 10k seems safe.
|
||||
//
|
||||
// note: we have a ChokeConnectionAutoDisconnects test for this too!
|
||||
internal const int QueueDisconnectThreshold = 10000;
|
||||
|
||||
// NoDelay, interval, window size are the most important configurations.
|
||||
// let's force require the parameters so we don't forget it anywhere.
|
||||
protected void SetupKcp(bool noDelay, uint interval = Kcp.INTERVAL, int fastResend = 0, bool congestionWindow = true, uint sendWindowSize = Kcp.WND_SND, uint receiveWindowSize = Kcp.WND_RCV)
|
||||
{
|
||||
kcp = new Kcp(0, RawSend);
|
||||
// set nodelay.
|
||||
// note that kcp uses 'nocwnd' internally so we negate the parameter
|
||||
kcp.SetNoDelay(noDelay ? 1u : 0u, interval, fastResend, !congestionWindow);
|
||||
kcp.SetWindowSize(sendWindowSize, receiveWindowSize);
|
||||
refTime.Start();
|
||||
state = KcpState.Connected;
|
||||
|
||||
Tick();
|
||||
}
|
||||
|
||||
void HandleTimeout(uint time)
|
||||
{
|
||||
// note: we are also sending a ping regularly, so timeout should
|
||||
// only ever happen if the connection is truly gone.
|
||||
if (time >= lastReceiveTime + TIMEOUT)
|
||||
{
|
||||
Debug.LogWarning($"KCP: Connection timed out after {TIMEOUT}ms. Disconnecting.");
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void HandleDeadLink()
|
||||
{
|
||||
// kcp has 'dead_link' detection. might as well use it.
|
||||
if (kcp.state == -1)
|
||||
{
|
||||
Debug.LogWarning("KCP Connection dead_link detected. Disconnecting.");
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// send a ping occasionally in order to not time out on the other end.
|
||||
void HandlePing(uint time)
|
||||
{
|
||||
// enough time elapsed since last ping?
|
||||
if (time >= lastPingTime + PING_INTERVAL)
|
||||
{
|
||||
// ping again and reset time
|
||||
//Debug.Log("KCP: sending ping...");
|
||||
Send(Ping);
|
||||
lastPingTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleChoked()
|
||||
{
|
||||
// disconnect connections that can't process the load.
|
||||
// see QueueSizeDisconnect comments.
|
||||
int total = kcp.rcv_queue.Count + kcp.snd_queue.Count +
|
||||
kcp.rcv_buf.Count + kcp.snd_buf.Count;
|
||||
if (total >= QueueDisconnectThreshold)
|
||||
{
|
||||
Debug.LogWarning($"KCP: disconnecting connection because it can't process data fast enough.\n" +
|
||||
$"Queue total {total}>{QueueDisconnectThreshold}. rcv_queue={kcp.rcv_queue.Count} snd_queue={kcp.snd_queue.Count} rcv_buf={kcp.rcv_buf.Count} snd_buf={kcp.snd_buf.Count}\n" +
|
||||
$"* Try to Enable NoDelay, decrease INTERVAL, disable Congestion Window (= enable NOCWND!), increase SEND/RECV WINDOW or compress data.\n" +
|
||||
$"* Or perhaps the network is simply too slow on our end, or on the other end.\n");
|
||||
|
||||
// let's clear all pending sends before disconnting with 'Bye'.
|
||||
// otherwise a single Flush in Disconnect() won't be enough to
|
||||
// flush thousands of messages to finally deliver 'Bye'.
|
||||
// this is just faster and more robust.
|
||||
kcp.snd_queue.Clear();
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// reads the next message from connection.
|
||||
bool ReceiveNext(out ArraySegment<byte> message)
|
||||
{
|
||||
// read only one message
|
||||
int msgSize = kcp.PeekSize();
|
||||
if (msgSize > 0)
|
||||
{
|
||||
// only allow receiving up to MaxMessageSize sized messages.
|
||||
// otherwise we would get BlockCopy ArgumentException anyway.
|
||||
if (msgSize <= Kcp.MTU_DEF)
|
||||
{
|
||||
int received = kcp.Receive(buffer, msgSize);
|
||||
if (received >= 0)
|
||||
{
|
||||
message = new ArraySegment<byte>(buffer, 0, msgSize);
|
||||
lastReceiveTime = (uint)refTime.ElapsedMilliseconds;
|
||||
|
||||
// return false if it was a ping message. true otherwise.
|
||||
if (Utils.SegmentsEqual(message, Ping))
|
||||
{
|
||||
//Debug.Log("KCP: received ping.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if receive failed, close everything
|
||||
Debug.LogWarning($"Receive failed with error={received}. closing connection.");
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
// we don't allow sending messages > Max, so this must be an
|
||||
// attacker. let's disconnect to avoid allocation attacks etc.
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"KCP: possible allocation attack for msgSize {msgSize} > max {Kcp.MTU_DEF}. Disconnecting the connection.");
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TickConnected(uint time)
|
||||
{
|
||||
// detect common events & ping
|
||||
HandleTimeout(time);
|
||||
HandleDeadLink();
|
||||
HandlePing(time);
|
||||
HandleChoked();
|
||||
|
||||
kcp.Update(time);
|
||||
|
||||
// any message received?
|
||||
if (ReceiveNext(out ArraySegment<byte> message))
|
||||
{
|
||||
// handshake message?
|
||||
if (Utils.SegmentsEqual(message, Hello))
|
||||
{
|
||||
Debug.Log("KCP: received handshake");
|
||||
state = KcpState.Authenticated;
|
||||
OnAuthenticated?.Invoke();
|
||||
}
|
||||
// otherwise it's random data from the internet, not
|
||||
// from a legitimate player. disconnect.
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("KCP: received random data before handshake. Disconnecting the connection.");
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TickAuthenticated(uint time)
|
||||
{
|
||||
// detect common events & ping
|
||||
HandleTimeout(time);
|
||||
HandleDeadLink();
|
||||
HandlePing(time);
|
||||
HandleChoked();
|
||||
|
||||
kcp.Update(time);
|
||||
|
||||
// process all received messages
|
||||
while (ReceiveNext(out ArraySegment<byte> message))
|
||||
{
|
||||
// disconnect message?
|
||||
if (Utils.SegmentsEqual(message, Goodbye))
|
||||
{
|
||||
Debug.Log("KCP: received disconnect message");
|
||||
Disconnect();
|
||||
break;
|
||||
}
|
||||
// otherwise regular message
|
||||
else
|
||||
{
|
||||
// only accept regular messages
|
||||
//Debug.LogWarning($"Kcp recv msg: {BitConverter.ToString(buffer, 0, msgSize)}");
|
||||
OnData?.Invoke(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
uint time = (uint)refTime.ElapsedMilliseconds;
|
||||
|
||||
try
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case KcpState.Connected:
|
||||
{
|
||||
TickConnected(time);
|
||||
break;
|
||||
}
|
||||
case KcpState.Authenticated:
|
||||
{
|
||||
TickAuthenticated(time);
|
||||
break;
|
||||
}
|
||||
case KcpState.Disconnected:
|
||||
{
|
||||
// do nothing while disconnected
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException exception)
|
||||
{
|
||||
// this is ok, the connection was closed
|
||||
Debug.Log($"KCP Connection: Disconnecting because {exception}. This is fine.");
|
||||
Disconnect();
|
||||
}
|
||||
catch (ObjectDisposedException exception)
|
||||
{
|
||||
// fine, socket was closed
|
||||
Debug.Log($"KCP Connection: Disconnecting because {exception}. This is fine.");
|
||||
Disconnect();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// unexpected
|
||||
Debug.LogException(ex);
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void RawInput(byte[] buffer, int msgLength)
|
||||
{
|
||||
int input = kcp.Input(buffer, msgLength);
|
||||
if (input != 0)
|
||||
{
|
||||
Debug.LogWarning($"Input failed with error={input} for buffer with length={msgLength}");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void RawSend(byte[] data, int length);
|
||||
|
||||
public void Send(ArraySegment<byte> data)
|
||||
{
|
||||
// only allow sending up to MaxMessageSize sized messages.
|
||||
// other end won't process bigger messages anyway.
|
||||
if (data.Count <= Kcp.MTU_DEF)
|
||||
{
|
||||
int sent = kcp.Send(data.Array, data.Offset, data.Count);
|
||||
if (sent < 0)
|
||||
{
|
||||
Debug.LogWarning($"Send failed with error={sent} for segment with length={data.Count}");
|
||||
}
|
||||
}
|
||||
else Debug.LogError($"Failed to send message of size {data.Count} because it's larger than MaxMessageSize={Kcp.MTU_DEF}");
|
||||
}
|
||||
|
||||
// server & client need to send handshake at different times, so we need
|
||||
// to expose the function.
|
||||
// * client should send it immediately.
|
||||
// * server should send it as reply to client's handshake, not before
|
||||
// (server should not reply to random internet messages with handshake)
|
||||
public void SendHandshake()
|
||||
{
|
||||
Debug.Log("KcpConnection: sending Handshake to other end!");
|
||||
Send(Hello);
|
||||
}
|
||||
|
||||
protected virtual void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
// disconnect this connection
|
||||
public void Disconnect()
|
||||
{
|
||||
// only if not disconnected yet
|
||||
if (state == KcpState.Disconnected)
|
||||
return;
|
||||
|
||||
// send a disconnect message
|
||||
if (socket.Connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
Send(Goodbye);
|
||||
kcp.Flush();
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
// this is ok, the connection was already closed
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// this is normal when we stop the server
|
||||
// the socket is stopped so we can't send anything anymore
|
||||
// to the clients
|
||||
|
||||
// the clients will eventually timeout and realize they
|
||||
// were disconnected
|
||||
}
|
||||
}
|
||||
|
||||
// set as Disconnected, call event
|
||||
Debug.Log("KCP Connection: Disconnected.");
|
||||
state = KcpState.Disconnected;
|
||||
OnDisconnected?.Invoke();
|
||||
}
|
||||
|
||||
// get remote endpoint
|
||||
public EndPoint GetRemoteEndPoint() => remoteEndpoint;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3915c7c62b72d4dc2a9e4e76c94fc484
|
||||
timeCreated: 1602600432
|
229
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpServer.cs
Normal file
229
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpServer.cs
Normal file
@ -0,0 +1,229 @@
|
||||
// kcp server logic abstracted into a class.
|
||||
// for use in Mirror, DOTSNET, testing, etc.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public class KcpServer
|
||||
{
|
||||
// events
|
||||
public Action<int> OnConnected;
|
||||
public Action<int, ArraySegment<byte>> OnData;
|
||||
public Action<int> OnDisconnected;
|
||||
|
||||
// configuration
|
||||
// NoDelay is recommended to reduce latency. This also scales better
|
||||
// without buffers getting full.
|
||||
public bool NoDelay;
|
||||
// KCP internal update interval. 100ms is KCP default, but a lower
|
||||
// interval is recommended to minimize latency and to scale to more
|
||||
// networked entities.
|
||||
public uint Interval;
|
||||
// KCP fastresend parameter. Faster resend for the cost of higher
|
||||
// bandwidth.
|
||||
public int FastResend;
|
||||
// KCP 'NoCongestionWindow' is false by default. here we negate it for
|
||||
// ease of use. This can be disabled for high scale games if connections
|
||||
// choke regularly.
|
||||
public bool CongestionWindow;
|
||||
// KCP window size can be modified to support higher loads.
|
||||
// for example, Mirror Benchmark requires:
|
||||
// 128, 128 for 4k monsters
|
||||
// 512, 512 for 10k monsters
|
||||
// 8192, 8192 for 20k monsters
|
||||
public uint SendWindowSize;
|
||||
public uint ReceiveWindowSize;
|
||||
|
||||
// state
|
||||
Socket socket;
|
||||
EndPoint newClientEP = new IPEndPoint(IPAddress.IPv6Any, 0);
|
||||
readonly byte[] buffer = new byte[Kcp.MTU_DEF];
|
||||
|
||||
// connections <connectionId, connection> where connectionId is EndPoint.GetHashCode
|
||||
public Dictionary<int, KcpServerConnection> connections = new Dictionary<int, KcpServerConnection>();
|
||||
|
||||
public KcpServer(Action<int> OnConnected,
|
||||
Action<int, ArraySegment<byte>> OnData,
|
||||
Action<int> OnDisconnected,
|
||||
bool NoDelay,
|
||||
uint Interval,
|
||||
int FastResend = 0,
|
||||
bool CongestionWindow = true,
|
||||
uint SendWindowSize = Kcp.WND_SND,
|
||||
uint ReceiveWindowSize = Kcp.WND_RCV)
|
||||
{
|
||||
this.OnConnected = OnConnected;
|
||||
this.OnData = OnData;
|
||||
this.OnDisconnected = OnDisconnected;
|
||||
this.NoDelay = NoDelay;
|
||||
this.Interval = Interval;
|
||||
this.FastResend = FastResend;
|
||||
this.CongestionWindow = CongestionWindow;
|
||||
this.SendWindowSize = SendWindowSize;
|
||||
this.ReceiveWindowSize = ReceiveWindowSize;
|
||||
}
|
||||
|
||||
public bool IsActive() => socket != null;
|
||||
|
||||
public void Start(ushort port)
|
||||
{
|
||||
// only start once
|
||||
if (socket != null)
|
||||
{
|
||||
Debug.LogWarning("KCP: server already started!");
|
||||
}
|
||||
|
||||
// listen
|
||||
socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
|
||||
socket.DualMode = true;
|
||||
socket.Bind(new IPEndPoint(IPAddress.IPv6Any, port));
|
||||
}
|
||||
|
||||
public void Send(int connectionId, ArraySegment<byte> segment)
|
||||
{
|
||||
if (connections.TryGetValue(connectionId, out KcpServerConnection connection))
|
||||
{
|
||||
connection.Send(segment);
|
||||
}
|
||||
}
|
||||
public void Disconnect(int connectionId)
|
||||
{
|
||||
if (connections.TryGetValue(connectionId, out KcpServerConnection connection))
|
||||
{
|
||||
connection.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetClientAddress(int connectionId)
|
||||
{
|
||||
if (connections.TryGetValue(connectionId, out KcpServerConnection connection))
|
||||
{
|
||||
return (connection.GetRemoteEndPoint() as IPEndPoint).Address.ToString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
HashSet<int> connectionsToRemove = new HashSet<int>();
|
||||
public void Tick()
|
||||
{
|
||||
while (socket != null && socket.Poll(0, SelectMode.SelectRead))
|
||||
{
|
||||
int msgLength = socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP);
|
||||
//Debug.Log($"KCP: server raw recv {msgLength} bytes = {BitConverter.ToString(buffer, 0, msgLength)}");
|
||||
|
||||
// calculate connectionId from endpoint
|
||||
int connectionId = newClientEP.GetHashCode();
|
||||
|
||||
// is this a new connection?
|
||||
if (!connections.TryGetValue(connectionId, out KcpServerConnection connection))
|
||||
{
|
||||
// create a new KcpConnection
|
||||
connection = new KcpServerConnection(socket, newClientEP, NoDelay, Interval, FastResend, CongestionWindow, SendWindowSize, ReceiveWindowSize);
|
||||
|
||||
// DO NOT add to connections yet. only if the first message
|
||||
// is actually the kcp handshake. otherwise it's either:
|
||||
// * random data from the internet
|
||||
// * or from a client connection that we just disconnected
|
||||
// but that hasn't realized it yet, still sending data
|
||||
// from last session that we should absolutely ignore.
|
||||
//
|
||||
//
|
||||
// TODO this allocates a new KcpConnection for each new
|
||||
// internet connection. not ideal, but C# UDP Receive
|
||||
// already allocated anyway.
|
||||
//
|
||||
// expecting a MAGIC byte[] would work, but sending the raw
|
||||
// UDP message without kcp's reliability will have low
|
||||
// probability of being received.
|
||||
//
|
||||
// for now, this is fine.
|
||||
|
||||
// setup authenticated event that also adds to connections
|
||||
connection.OnAuthenticated = () =>
|
||||
{
|
||||
// only send handshake to client AFTER we received his
|
||||
// handshake in OnAuthenticated.
|
||||
// we don't want to reply to random internet messages
|
||||
// with handshakes each time.
|
||||
connection.SendHandshake();
|
||||
|
||||
// add to connections dict after being authenticated.
|
||||
connections.Add(connectionId, connection);
|
||||
Debug.Log($"KCP: server added connection({connectionId}): {newClientEP}");
|
||||
|
||||
// setup Data + Disconnected events only AFTER the
|
||||
// handshake. we don't want to fire OnServerDisconnected
|
||||
// every time we receive invalid random data from the
|
||||
// internet.
|
||||
|
||||
// setup data event
|
||||
connection.OnData = (message) =>
|
||||
{
|
||||
// call mirror event
|
||||
//Debug.Log($"KCP: OnServerDataReceived({connectionId}, {BitConverter.ToString(message.Array, message.Offset, message.Count)})");
|
||||
OnData.Invoke(connectionId, message);
|
||||
};
|
||||
|
||||
// setup disconnected event
|
||||
connection.OnDisconnected = () =>
|
||||
{
|
||||
// flag for removal
|
||||
// (can't remove directly because connection is updated
|
||||
// and event is called while iterating all connections)
|
||||
connectionsToRemove.Add(connectionId);
|
||||
|
||||
// call mirror event
|
||||
Debug.Log($"KCP: OnServerDisconnected({connectionId})");
|
||||
OnDisconnected.Invoke(connectionId);
|
||||
};
|
||||
|
||||
// finally, call mirror OnConnected event
|
||||
Debug.Log($"KCP: OnServerConnected({connectionId})");
|
||||
OnConnected.Invoke(connectionId);
|
||||
};
|
||||
|
||||
// now input the message & tick
|
||||
// connected event was set up.
|
||||
// tick will process the first message and adds the
|
||||
// connection if it was the handshake.
|
||||
connection.RawInput(buffer, msgLength);
|
||||
connection.Tick();
|
||||
|
||||
// again, do not add to connections.
|
||||
// if the first message wasn't the kcp handshake then
|
||||
// connection will simply be garbage collected.
|
||||
}
|
||||
// existing connection: simply input the message into kcp
|
||||
else
|
||||
{
|
||||
connection.RawInput(buffer, msgLength);
|
||||
}
|
||||
}
|
||||
|
||||
// tick all server connections
|
||||
foreach (KcpServerConnection connection in connections.Values)
|
||||
{
|
||||
connection.Tick();
|
||||
}
|
||||
|
||||
// remove disconnected connections
|
||||
// (can't do it in connection.OnDisconnected because Tick is called
|
||||
// while iterating connections)
|
||||
foreach (int connectionId in connectionsToRemove)
|
||||
{
|
||||
connections.Remove(connectionId);
|
||||
}
|
||||
connectionsToRemove.Clear();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
socket?.Close();
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9759159c6589494a9037f5e130a867ed
|
||||
timeCreated: 1603787747
|
@ -0,0 +1,20 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public class KcpServerConnection : KcpConnection
|
||||
{
|
||||
public KcpServerConnection(Socket socket, EndPoint remoteEndpoint, bool noDelay, uint interval = Kcp.INTERVAL, int fastResend = 0, bool congestionWindow = true, uint sendWindowSize = Kcp.WND_SND, uint receiveWindowSize = Kcp.WND_RCV)
|
||||
{
|
||||
this.socket = socket;
|
||||
this.remoteEndpoint = remoteEndpoint;
|
||||
SetupKcp(noDelay, interval, fastResend, congestionWindow, sendWindowSize, receiveWindowSize);
|
||||
}
|
||||
|
||||
protected override void RawSend(byte[] data, int length)
|
||||
{
|
||||
socket.SendTo(data, 0, length, SocketFlags.None, remoteEndpoint);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80a9b1ce9a6f14abeb32bfa9921d097b
|
||||
timeCreated: 1602601483
|
23
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/Utils.cs
Normal file
23
Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/Utils.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public static partial class Utils
|
||||
{
|
||||
// ArraySegment content comparison without Linq
|
||||
public static unsafe bool SegmentsEqual(ArraySegment<byte> a, ArraySegment<byte> b)
|
||||
{
|
||||
if (a.Count == b.Count)
|
||||
{
|
||||
fixed (byte* aPtr = &a.Array[a.Offset],
|
||||
bPtr = &b.Array[b.Offset])
|
||||
{
|
||||
return UnsafeUtility.MemCmp(aPtr, bPtr, a.Count) == 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3a2f1efc7864cb2b01af9d99470613a
|
||||
timeCreated: 1603833478
|
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp.meta
Normal file
8
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cafb8851a0084f3e94a580c207b3923
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("kcp2k.Tests")]
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aec6a15ac7bd43129317ea1f01f19782
|
||||
timeCreated: 1602665988
|
1025
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Kcp.cs
Executable file
1025
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Kcp.cs
Executable file
File diff suppressed because it is too large
Load Diff
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Kcp.cs.meta
Executable file
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Kcp.cs.meta
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a59b1cae10a334faf807432ab472f212
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
81
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Segment.cs
Executable file
81
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Segment.cs
Executable file
@ -0,0 +1,81 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
// KCP Segment Definition
|
||||
internal class Segment
|
||||
{
|
||||
internal uint conv; // conversation
|
||||
internal uint cmd; // command, e.g. Kcp.CMD_ACK etc.
|
||||
internal uint frg; // fragment
|
||||
internal uint wnd; // window
|
||||
internal uint ts; // timestamp
|
||||
internal uint sn; // serial number
|
||||
internal uint una;
|
||||
internal uint resendts; // resend timestamp
|
||||
internal int rto;
|
||||
internal uint fastack;
|
||||
internal uint xmit;
|
||||
// we need a auto scaling byte[] with a WriteBytes function.
|
||||
// MemoryStream does that perfectly, no need to reinvent the wheel.
|
||||
// note: no need to pool it, because Segment is already pooled.
|
||||
internal MemoryStream data = new MemoryStream();
|
||||
|
||||
// pool ////////////////////////////////////////////////////////////////
|
||||
internal static readonly Stack<Segment> Pool = new Stack<Segment>(32);
|
||||
|
||||
public static Segment Take()
|
||||
{
|
||||
if (Pool.Count > 0)
|
||||
{
|
||||
Segment seg = Pool.Pop();
|
||||
return seg;
|
||||
}
|
||||
return new Segment();
|
||||
}
|
||||
|
||||
public static void Return(Segment seg)
|
||||
{
|
||||
seg.Reset();
|
||||
Pool.Push(seg);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ikcp_encode_seg
|
||||
// encode a segment into buffer
|
||||
internal int Encode(byte[] ptr, int offset)
|
||||
{
|
||||
int offset_ = offset;
|
||||
offset += Utils.Encode32U(ptr, offset, conv);
|
||||
offset += Utils.Encode8u(ptr, offset, (byte)cmd);
|
||||
offset += Utils.Encode8u(ptr, offset, (byte)frg);
|
||||
offset += Utils.Encode16U(ptr, offset, (ushort)wnd);
|
||||
offset += Utils.Encode32U(ptr, offset, ts);
|
||||
offset += Utils.Encode32U(ptr, offset, sn);
|
||||
offset += Utils.Encode32U(ptr, offset, una);
|
||||
offset += Utils.Encode32U(ptr, offset, (uint)data.Position);
|
||||
|
||||
return offset - offset_;
|
||||
}
|
||||
|
||||
// reset to return a fresh segment to the pool
|
||||
internal void Reset()
|
||||
{
|
||||
conv = 0;
|
||||
cmd = 0;
|
||||
frg = 0;
|
||||
wnd = 0;
|
||||
ts = 0;
|
||||
sn = 0;
|
||||
una = 0;
|
||||
rto = 0;
|
||||
xmit = 0;
|
||||
resendts = 0;
|
||||
fastack = 0;
|
||||
|
||||
// keep buffer for next pool usage, but reset length (= bytes written)
|
||||
data.SetLength(0);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Segment.cs.meta
Executable file
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Segment.cs.meta
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc58706a05dd3442c8fde858d5266855
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
68
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Utils.cs
Executable file
68
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Utils.cs
Executable file
@ -0,0 +1,68 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace kcp2k
|
||||
{
|
||||
public static partial class Utils
|
||||
{
|
||||
// encode 8 bits unsigned int
|
||||
public static int Encode8u(byte[] p, int offset, byte c)
|
||||
{
|
||||
p[0 + offset] = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// decode 8 bits unsigned int
|
||||
public static int Decode8u(byte[] p, int offset, ref byte c)
|
||||
{
|
||||
c = p[0 + offset];
|
||||
return 1;
|
||||
}
|
||||
|
||||
// encode 16 bits unsigned int (lsb)
|
||||
public static int Encode16U(byte[] p, int offset, ushort w)
|
||||
{
|
||||
p[0 + offset] = (byte)(w >> 0);
|
||||
p[1 + offset] = (byte)(w >> 8);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// decode 16 bits unsigned int (lsb)
|
||||
public static int Decode16U(byte[] p, int offset, ref ushort c)
|
||||
{
|
||||
ushort result = 0;
|
||||
result |= p[0 + offset];
|
||||
result |= (ushort)(p[1 + offset] << 8);
|
||||
c = result;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// encode 32 bits unsigned int (lsb)
|
||||
public static int Encode32U(byte[] p, int offset, uint l)
|
||||
{
|
||||
p[0 + offset] = (byte)(l >> 0);
|
||||
p[1 + offset] = (byte)(l >> 8);
|
||||
p[2 + offset] = (byte)(l >> 16);
|
||||
p[3 + offset] = (byte)(l >> 24);
|
||||
return 4;
|
||||
}
|
||||
|
||||
// decode 32 bits unsigned int (lsb)
|
||||
public static int Decode32U(byte[] p, int offset, ref uint c)
|
||||
{
|
||||
uint result = 0;
|
||||
result |= p[0 + offset];
|
||||
result |= (uint)(p[1 + offset] << 8);
|
||||
result |= (uint)(p[2 + offset] << 16);
|
||||
result |= (uint)(p[3 + offset] << 24);
|
||||
c = result;
|
||||
return 4;
|
||||
}
|
||||
|
||||
// timediff was a macro in original Kcp. let's inline it if possible.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int TimeDiff(uint later, uint earlier)
|
||||
{
|
||||
return (int)(later - earlier);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Utils.cs.meta
Executable file
11
Assets/Mirror/Runtime/Transport/KCP/kcp2k/kcp/Utils.cs.meta
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef959eb716205bd48b050f010a9a35ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
273
Packages/packages-lock.json
Normal file
273
Packages/packages-lock.json
Normal file
@ -0,0 +1,273 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.package-manager-ui": {
|
||||
"version": "2.0.13",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework.performance": {
|
||||
"version": "0.1.50-preview",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.textmeshpro": {
|
||||
"version": "1.4.1",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.modules.ai": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.animation": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.assetbundle": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.audio": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.cloth": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.director": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.animation": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.imageconversion": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.imgui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.jsonserialize": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.particlesystem": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.physics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.physics2d": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.screencapture": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.subsystems": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.terrain": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.terrainphysics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.terrain": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.tilemap": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics2d": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.ui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.uielements": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.uielementsnative": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.uielementsnative": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.umbra": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.unityanalytics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequest": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestassetbundle": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestaudio": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequesttexture": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestwww": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestaudio": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.vehicles": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.video": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.vr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.xr": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.wind": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.xr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.subsystems": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
UserSettings/EditorUserSettings.asset
Normal file
BIN
UserSettings/EditorUserSettings.asset
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user