├── CubesMultiplayerDemoClient
├── .gitignore
├── Assets
│ ├── Materials
│ │ ├── Floor.mat
│ │ └── Player.mat
│ ├── Prefabs
│ │ ├── Floor.prefab
│ │ ├── NetPlayer.prefab
│ │ └── Player.prefab
│ ├── Scenes
│ │ └── SampleScene.unity
│ ├── Scripts
│ │ ├── LiteNetLib
│ │ │ ├── INetEventListener.cs
│ │ │ ├── NatPunchModule.cs
│ │ │ ├── NetConstants.cs
│ │ │ ├── NetDebug.cs
│ │ │ ├── NetEndPoint.cs
│ │ │ ├── NetManager.cs
│ │ │ ├── NetPacket.cs
│ │ │ ├── NetPacketPool.cs
│ │ │ ├── NetPeer.cs
│ │ │ ├── NetPeerCollection.cs
│ │ │ ├── NetSocket.cs
│ │ │ ├── NetStatistics.cs
│ │ │ ├── NetThread.cs
│ │ │ ├── NetUtils.cs
│ │ │ ├── ReliableChannel.cs
│ │ │ ├── SequencedChannel.cs
│ │ │ ├── SimpleChannel.cs
│ │ │ └── Utils
│ │ │ │ ├── FastBitConverter.cs
│ │ │ │ ├── NetDataReader.cs
│ │ │ │ ├── NetDataWriter.cs
│ │ │ │ └── NetSerializer.cs
│ │ ├── NetPlayer.cs
│ │ ├── Network.cs
│ │ └── Player.cs
│ └── Shared.dll
├── Packages
│ └── manifest.json
└── ProjectSettings
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── NetworkManager.asset
│ ├── Physics2DSettings.asset
│ ├── PresetManager.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ └── UnityConnectSettings.asset
├── CubesMultiplayerDemoServer
├── .gitignore
├── CubesMultiplayerDemoServer.sln
└── src
│ ├── Server
│ ├── NetworkPlayer.cs
│ ├── Program.cs
│ └── Server.csproj
│ └── Shared
│ ├── Enums
│ └── NetworkTags.cs
│ └── Shared.csproj
├── README.md
└── example.gif
/CubesMultiplayerDemoClient/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 | .vs/
9 |
10 | # Build results
11 | [Dd]ebug/
12 | [Dd]ebugPublic/
13 | [Rr]elease/
14 | [Rr]eleases/
15 | x64/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | #NUNIT
29 | *.VisualState.xml
30 | TestResult.xml
31 |
32 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # Visual Studio 2015/2017 cache/options directory
85 | .vs/
86 | # Uncomment if you have tasks that create the project's static files in wwwroot
87 | #wwwroot/
88 |
89 | # Visual Studio 2017 auto generated files
90 | Generated\ Files/
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding addin-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | ## TODO: Comment the next line if you want to checkin your
137 | ## web deploy settings but do note that will include unencrypted
138 | ## passwords
139 | *.pubxml
140 |
141 | # NuGet Packages Directory
142 | packages/*
143 | ## TODO: If the tool you use requires repositories.config
144 | ## uncomment the next line
145 | #!packages/repositories.config
146 |
147 | # Enable "build/" folder in the NuGet Packages folder since
148 | # NuGet packages use it for MSBuild targets.
149 | # This line needs to be after the ignore of the build folder
150 | # (and the packages folder if the line above has been uncommented)
151 | !packages/build/
152 |
153 | # Windows Azure Build Output
154 | csx/
155 | *.build.csdef
156 |
157 | # Windows Store app package directory
158 | AppPackages/
159 |
160 | # Others
161 | sql/
162 | *.Cache
163 | ClientBin/
164 | [Ss]tyle[Cc]op.*
165 | ~$*
166 | *~
167 | *.dbmdl
168 | *.dbproj.schemaview
169 | *.pfx
170 | *.publishsettings
171 | node_modules/
172 |
173 | # RIA/Silverlight projects
174 | Generated_Code/
175 |
176 | # Backup & report files from converting an old project file
177 | # to a newer Visual Studio version. Backup files are not needed,
178 | # because we have git ;-)
179 | _UpgradeReport_Files/
180 | Backup*/
181 | UpgradeLog*.XML
182 | UpgradeLog*.htm
183 |
184 | # SQL Server files
185 | *.mdf
186 | *.ldf
187 |
188 | # Business Intelligence projects
189 | *.rdl.data
190 | *.bim.layout
191 | *.bim_*.settings
192 |
193 | # Microsoft Fakes
194 | FakesAssemblies/
195 |
196 | git_stats/*
197 |
198 | *.ncrunchproject
199 | StyleCop.Cache
200 | bin
201 | obj
202 |
203 |
204 | # UNITY
205 |
206 | [Ll]ibrary/
207 | [Tt]emp/
208 | [Oo]bj/
209 | [Bb]uild/
210 | [Bb]uilds/
211 | Assets/AssetStoreTools*
212 |
213 | # Visual Studio cache directory
214 | .vs/
215 |
216 | # Autogenerated VS/MD/Consulo solution and project files
217 | ExportedObj/
218 | .consulo/
219 | *.csproj
220 | *.unityproj
221 | *.sln
222 | *.suo
223 | *.tmp
224 | *.user
225 | *.userprefs
226 | *.pidb
227 | *.booproj
228 | *.svd
229 | *.pdb
230 | *.opendb
231 |
232 | # Unity3D generated meta files
233 | *.pidb.meta
234 | *.pdb.meta
235 |
236 | # Unity3D Generated File On Crash Reports
237 | sysinfo.txt
238 |
239 | # Builds
240 | *.apk
241 | *.unitypackage
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Materials/Floor.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_CorrespondingSourceObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Floor
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords:
12 | m_LightmapFlags: 4
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 0.5
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0.15419188, g: 0.5188679, b: 0.25857887, a: 1}
76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
77 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Materials/Player.mat:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!21 &2100000
4 | Material:
5 | serializedVersion: 6
6 | m_ObjectHideFlags: 0
7 | m_CorrespondingSourceObject: {fileID: 0}
8 | m_PrefabInternal: {fileID: 0}
9 | m_Name: Player
10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
11 | m_ShaderKeywords:
12 | m_LightmapFlags: 4
13 | m_EnableInstancingVariants: 0
14 | m_DoubleSidedGI: 0
15 | m_CustomRenderQueue: -1
16 | stringTagMap: {}
17 | disabledShaderPasses: []
18 | m_SavedProperties:
19 | serializedVersion: 3
20 | m_TexEnvs:
21 | - _BumpMap:
22 | m_Texture: {fileID: 0}
23 | m_Scale: {x: 1, y: 1}
24 | m_Offset: {x: 0, y: 0}
25 | - _DetailAlbedoMap:
26 | m_Texture: {fileID: 0}
27 | m_Scale: {x: 1, y: 1}
28 | m_Offset: {x: 0, y: 0}
29 | - _DetailMask:
30 | m_Texture: {fileID: 0}
31 | m_Scale: {x: 1, y: 1}
32 | m_Offset: {x: 0, y: 0}
33 | - _DetailNormalMap:
34 | m_Texture: {fileID: 0}
35 | m_Scale: {x: 1, y: 1}
36 | m_Offset: {x: 0, y: 0}
37 | - _EmissionMap:
38 | m_Texture: {fileID: 0}
39 | m_Scale: {x: 1, y: 1}
40 | m_Offset: {x: 0, y: 0}
41 | - _MainTex:
42 | m_Texture: {fileID: 0}
43 | m_Scale: {x: 1, y: 1}
44 | m_Offset: {x: 0, y: 0}
45 | - _MetallicGlossMap:
46 | m_Texture: {fileID: 0}
47 | m_Scale: {x: 1, y: 1}
48 | m_Offset: {x: 0, y: 0}
49 | - _OcclusionMap:
50 | m_Texture: {fileID: 0}
51 | m_Scale: {x: 1, y: 1}
52 | m_Offset: {x: 0, y: 0}
53 | - _ParallaxMap:
54 | m_Texture: {fileID: 0}
55 | m_Scale: {x: 1, y: 1}
56 | m_Offset: {x: 0, y: 0}
57 | m_Floats:
58 | - _BumpScale: 1
59 | - _Cutoff: 0.5
60 | - _DetailNormalMapScale: 1
61 | - _DstBlend: 0
62 | - _GlossMapScale: 1
63 | - _Glossiness: 0.5
64 | - _GlossyReflections: 1
65 | - _Metallic: 0
66 | - _Mode: 0
67 | - _OcclusionStrength: 1
68 | - _Parallax: 0.02
69 | - _SmoothnessTextureChannel: 0
70 | - _SpecularHighlights: 1
71 | - _SrcBlend: 1
72 | - _UVSec: 0
73 | - _ZWrite: 1
74 | m_Colors:
75 | - _Color: {r: 0.6886792, g: 0.48402455, b: 0.48402455, a: 1}
76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
77 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Prefabs/Floor.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1001 &100100000
4 | Prefab:
5 | m_ObjectHideFlags: 1
6 | serializedVersion: 2
7 | m_Modification:
8 | m_TransformParent: {fileID: 0}
9 | m_Modifications: []
10 | m_RemovedComponents: []
11 | m_SourcePrefab: {fileID: 0}
12 | m_RootGameObject: {fileID: 1010506836010290}
13 | m_IsPrefabAsset: 1
14 | --- !u!1 &1010340096941446
15 | GameObject:
16 | m_ObjectHideFlags: 0
17 | m_CorrespondingSourceObject: {fileID: 0}
18 | m_PrefabInternal: {fileID: 100100000}
19 | serializedVersion: 6
20 | m_Component:
21 | - component: {fileID: 4573927177739748}
22 | - component: {fileID: 33662256303880736}
23 | - component: {fileID: 23774172063303014}
24 | - component: {fileID: 65787851039163106}
25 | - component: {fileID: 65087800184519950}
26 | m_Layer: 0
27 | m_Name: Bord (2)
28 | m_TagString: Untagged
29 | m_Icon: {fileID: 0}
30 | m_NavMeshLayer: 0
31 | m_StaticEditorFlags: 0
32 | m_IsActive: 1
33 | --- !u!1 &1010506836010290
34 | GameObject:
35 | m_ObjectHideFlags: 0
36 | m_CorrespondingSourceObject: {fileID: 0}
37 | m_PrefabInternal: {fileID: 100100000}
38 | serializedVersion: 6
39 | m_Component:
40 | - component: {fileID: 4284712273699304}
41 | - component: {fileID: 33929017365551490}
42 | - component: {fileID: 23038515933329936}
43 | - component: {fileID: 64689253414403800}
44 | - component: {fileID: 65805571091712842}
45 | m_Layer: 0
46 | m_Name: Floor
47 | m_TagString: Untagged
48 | m_Icon: {fileID: 0}
49 | m_NavMeshLayer: 0
50 | m_StaticEditorFlags: 0
51 | m_IsActive: 1
52 | --- !u!1 &1665137963937560
53 | GameObject:
54 | m_ObjectHideFlags: 0
55 | m_CorrespondingSourceObject: {fileID: 0}
56 | m_PrefabInternal: {fileID: 100100000}
57 | serializedVersion: 6
58 | m_Component:
59 | - component: {fileID: 4615528866575254}
60 | - component: {fileID: 33862078007593612}
61 | - component: {fileID: 23523361689677772}
62 | - component: {fileID: 65803275033776586}
63 | - component: {fileID: 65631375037955232}
64 | m_Layer: 0
65 | m_Name: Bord (3)
66 | m_TagString: Untagged
67 | m_Icon: {fileID: 0}
68 | m_NavMeshLayer: 0
69 | m_StaticEditorFlags: 0
70 | m_IsActive: 1
71 | --- !u!1 &1872367868043456
72 | GameObject:
73 | m_ObjectHideFlags: 0
74 | m_CorrespondingSourceObject: {fileID: 0}
75 | m_PrefabInternal: {fileID: 100100000}
76 | serializedVersion: 6
77 | m_Component:
78 | - component: {fileID: 4738313961880710}
79 | - component: {fileID: 33896680748480580}
80 | - component: {fileID: 23011519681391014}
81 | - component: {fileID: 65059584660200156}
82 | - component: {fileID: 65590949987065842}
83 | - component: {fileID: 65627854145120356}
84 | m_Layer: 0
85 | m_Name: Bord
86 | m_TagString: Untagged
87 | m_Icon: {fileID: 0}
88 | m_NavMeshLayer: 0
89 | m_StaticEditorFlags: 0
90 | m_IsActive: 1
91 | --- !u!1 &1950511125725858
92 | GameObject:
93 | m_ObjectHideFlags: 0
94 | m_CorrespondingSourceObject: {fileID: 0}
95 | m_PrefabInternal: {fileID: 100100000}
96 | serializedVersion: 6
97 | m_Component:
98 | - component: {fileID: 4752335114122484}
99 | - component: {fileID: 33462836363037428}
100 | - component: {fileID: 23458528837225990}
101 | - component: {fileID: 65076807166802294}
102 | - component: {fileID: 65114910231564214}
103 | m_Layer: 0
104 | m_Name: Bord (1)
105 | m_TagString: Untagged
106 | m_Icon: {fileID: 0}
107 | m_NavMeshLayer: 0
108 | m_StaticEditorFlags: 0
109 | m_IsActive: 1
110 | --- !u!4 &4284712273699304
111 | Transform:
112 | m_ObjectHideFlags: 1
113 | m_CorrespondingSourceObject: {fileID: 0}
114 | m_PrefabInternal: {fileID: 100100000}
115 | m_GameObject: {fileID: 1010506836010290}
116 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
117 | m_LocalPosition: {x: 0, y: 0, z: 0}
118 | m_LocalScale: {x: 2, y: 1, z: 2}
119 | m_Children:
120 | - {fileID: 4738313961880710}
121 | - {fileID: 4752335114122484}
122 | - {fileID: 4573927177739748}
123 | - {fileID: 4615528866575254}
124 | m_Father: {fileID: 0}
125 | m_RootOrder: 0
126 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
127 | --- !u!4 &4573927177739748
128 | Transform:
129 | m_ObjectHideFlags: 1
130 | m_CorrespondingSourceObject: {fileID: 0}
131 | m_PrefabInternal: {fileID: 100100000}
132 | m_GameObject: {fileID: 1010340096941446}
133 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
134 | m_LocalPosition: {x: -0.02, y: 0, z: -5.08}
135 | m_LocalScale: {x: 10.4656, y: 1, z: 0.32958338}
136 | m_Children: []
137 | m_Father: {fileID: 4284712273699304}
138 | m_RootOrder: 2
139 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
140 | --- !u!4 &4615528866575254
141 | Transform:
142 | m_ObjectHideFlags: 1
143 | m_CorrespondingSourceObject: {fileID: 0}
144 | m_PrefabInternal: {fileID: 100100000}
145 | m_GameObject: {fileID: 1665137963937560}
146 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
147 | m_LocalPosition: {x: -0.02, y: 0, z: 4.834}
148 | m_LocalScale: {x: 10.4656, y: 1, z: 0.329585}
149 | m_Children: []
150 | m_Father: {fileID: 4284712273699304}
151 | m_RootOrder: 3
152 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
153 | --- !u!4 &4738313961880710
154 | Transform:
155 | m_ObjectHideFlags: 1
156 | m_CorrespondingSourceObject: {fileID: 0}
157 | m_PrefabInternal: {fileID: 100100000}
158 | m_GameObject: {fileID: 1872367868043456}
159 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
160 | m_LocalPosition: {x: -5.13, y: 0, z: 0}
161 | m_LocalScale: {x: 0.37416, y: 1, z: 9.9901}
162 | m_Children: []
163 | m_Father: {fileID: 4284712273699304}
164 | m_RootOrder: 0
165 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
166 | --- !u!4 &4752335114122484
167 | Transform:
168 | m_ObjectHideFlags: 1
169 | m_CorrespondingSourceObject: {fileID: 0}
170 | m_PrefabInternal: {fileID: 100100000}
171 | m_GameObject: {fileID: 1950511125725858}
172 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
173 | m_LocalPosition: {x: 5.07, y: 0, z: 0}
174 | m_LocalScale: {x: 0.37416, y: 1, z: 9.9901}
175 | m_Children: []
176 | m_Father: {fileID: 4284712273699304}
177 | m_RootOrder: 1
178 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
179 | --- !u!23 &23011519681391014
180 | MeshRenderer:
181 | m_ObjectHideFlags: 1
182 | m_CorrespondingSourceObject: {fileID: 0}
183 | m_PrefabInternal: {fileID: 100100000}
184 | m_GameObject: {fileID: 1872367868043456}
185 | m_Enabled: 1
186 | m_CastShadows: 1
187 | m_ReceiveShadows: 1
188 | m_DynamicOccludee: 1
189 | m_MotionVectors: 1
190 | m_LightProbeUsage: 1
191 | m_ReflectionProbeUsage: 1
192 | m_RenderingLayerMask: 4294967295
193 | m_Materials:
194 | - {fileID: 2100000, guid: ab2a7968eac24a4468126b30e7c9293b, type: 2}
195 | m_StaticBatchInfo:
196 | firstSubMesh: 0
197 | subMeshCount: 0
198 | m_StaticBatchRoot: {fileID: 0}
199 | m_ProbeAnchor: {fileID: 0}
200 | m_LightProbeVolumeOverride: {fileID: 0}
201 | m_ScaleInLightmap: 1
202 | m_PreserveUVs: 0
203 | m_IgnoreNormalsForChartDetection: 0
204 | m_ImportantGI: 0
205 | m_StitchLightmapSeams: 0
206 | m_SelectedEditorRenderState: 3
207 | m_MinimumChartSize: 4
208 | m_AutoUVMaxDistance: 0.5
209 | m_AutoUVMaxAngle: 89
210 | m_LightmapParameters: {fileID: 0}
211 | m_SortingLayerID: 0
212 | m_SortingLayer: 0
213 | m_SortingOrder: 0
214 | --- !u!23 &23038515933329936
215 | MeshRenderer:
216 | m_ObjectHideFlags: 1
217 | m_CorrespondingSourceObject: {fileID: 0}
218 | m_PrefabInternal: {fileID: 100100000}
219 | m_GameObject: {fileID: 1010506836010290}
220 | m_Enabled: 1
221 | m_CastShadows: 1
222 | m_ReceiveShadows: 1
223 | m_DynamicOccludee: 1
224 | m_MotionVectors: 1
225 | m_LightProbeUsage: 1
226 | m_ReflectionProbeUsage: 1
227 | m_RenderingLayerMask: 4294967295
228 | m_Materials:
229 | - {fileID: 2100000, guid: ab2a7968eac24a4468126b30e7c9293b, type: 2}
230 | m_StaticBatchInfo:
231 | firstSubMesh: 0
232 | subMeshCount: 0
233 | m_StaticBatchRoot: {fileID: 0}
234 | m_ProbeAnchor: {fileID: 0}
235 | m_LightProbeVolumeOverride: {fileID: 0}
236 | m_ScaleInLightmap: 1
237 | m_PreserveUVs: 0
238 | m_IgnoreNormalsForChartDetection: 0
239 | m_ImportantGI: 0
240 | m_StitchLightmapSeams: 0
241 | m_SelectedEditorRenderState: 3
242 | m_MinimumChartSize: 4
243 | m_AutoUVMaxDistance: 0.5
244 | m_AutoUVMaxAngle: 89
245 | m_LightmapParameters: {fileID: 0}
246 | m_SortingLayerID: 0
247 | m_SortingLayer: 0
248 | m_SortingOrder: 0
249 | --- !u!23 &23458528837225990
250 | MeshRenderer:
251 | m_ObjectHideFlags: 1
252 | m_CorrespondingSourceObject: {fileID: 0}
253 | m_PrefabInternal: {fileID: 100100000}
254 | m_GameObject: {fileID: 1950511125725858}
255 | m_Enabled: 1
256 | m_CastShadows: 1
257 | m_ReceiveShadows: 1
258 | m_DynamicOccludee: 1
259 | m_MotionVectors: 1
260 | m_LightProbeUsage: 1
261 | m_ReflectionProbeUsage: 1
262 | m_RenderingLayerMask: 4294967295
263 | m_Materials:
264 | - {fileID: 2100000, guid: ab2a7968eac24a4468126b30e7c9293b, type: 2}
265 | m_StaticBatchInfo:
266 | firstSubMesh: 0
267 | subMeshCount: 0
268 | m_StaticBatchRoot: {fileID: 0}
269 | m_ProbeAnchor: {fileID: 0}
270 | m_LightProbeVolumeOverride: {fileID: 0}
271 | m_ScaleInLightmap: 1
272 | m_PreserveUVs: 0
273 | m_IgnoreNormalsForChartDetection: 0
274 | m_ImportantGI: 0
275 | m_StitchLightmapSeams: 0
276 | m_SelectedEditorRenderState: 3
277 | m_MinimumChartSize: 4
278 | m_AutoUVMaxDistance: 0.5
279 | m_AutoUVMaxAngle: 89
280 | m_LightmapParameters: {fileID: 0}
281 | m_SortingLayerID: 0
282 | m_SortingLayer: 0
283 | m_SortingOrder: 0
284 | --- !u!23 &23523361689677772
285 | MeshRenderer:
286 | m_ObjectHideFlags: 1
287 | m_CorrespondingSourceObject: {fileID: 0}
288 | m_PrefabInternal: {fileID: 100100000}
289 | m_GameObject: {fileID: 1665137963937560}
290 | m_Enabled: 1
291 | m_CastShadows: 1
292 | m_ReceiveShadows: 1
293 | m_DynamicOccludee: 1
294 | m_MotionVectors: 1
295 | m_LightProbeUsage: 1
296 | m_ReflectionProbeUsage: 1
297 | m_RenderingLayerMask: 4294967295
298 | m_Materials:
299 | - {fileID: 2100000, guid: ab2a7968eac24a4468126b30e7c9293b, type: 2}
300 | m_StaticBatchInfo:
301 | firstSubMesh: 0
302 | subMeshCount: 0
303 | m_StaticBatchRoot: {fileID: 0}
304 | m_ProbeAnchor: {fileID: 0}
305 | m_LightProbeVolumeOverride: {fileID: 0}
306 | m_ScaleInLightmap: 1
307 | m_PreserveUVs: 0
308 | m_IgnoreNormalsForChartDetection: 0
309 | m_ImportantGI: 0
310 | m_StitchLightmapSeams: 0
311 | m_SelectedEditorRenderState: 3
312 | m_MinimumChartSize: 4
313 | m_AutoUVMaxDistance: 0.5
314 | m_AutoUVMaxAngle: 89
315 | m_LightmapParameters: {fileID: 0}
316 | m_SortingLayerID: 0
317 | m_SortingLayer: 0
318 | m_SortingOrder: 0
319 | --- !u!23 &23774172063303014
320 | MeshRenderer:
321 | m_ObjectHideFlags: 1
322 | m_CorrespondingSourceObject: {fileID: 0}
323 | m_PrefabInternal: {fileID: 100100000}
324 | m_GameObject: {fileID: 1010340096941446}
325 | m_Enabled: 1
326 | m_CastShadows: 1
327 | m_ReceiveShadows: 1
328 | m_DynamicOccludee: 1
329 | m_MotionVectors: 1
330 | m_LightProbeUsage: 1
331 | m_ReflectionProbeUsage: 1
332 | m_RenderingLayerMask: 4294967295
333 | m_Materials:
334 | - {fileID: 2100000, guid: ab2a7968eac24a4468126b30e7c9293b, type: 2}
335 | m_StaticBatchInfo:
336 | firstSubMesh: 0
337 | subMeshCount: 0
338 | m_StaticBatchRoot: {fileID: 0}
339 | m_ProbeAnchor: {fileID: 0}
340 | m_LightProbeVolumeOverride: {fileID: 0}
341 | m_ScaleInLightmap: 1
342 | m_PreserveUVs: 0
343 | m_IgnoreNormalsForChartDetection: 0
344 | m_ImportantGI: 0
345 | m_StitchLightmapSeams: 0
346 | m_SelectedEditorRenderState: 3
347 | m_MinimumChartSize: 4
348 | m_AutoUVMaxDistance: 0.5
349 | m_AutoUVMaxAngle: 89
350 | m_LightmapParameters: {fileID: 0}
351 | m_SortingLayerID: 0
352 | m_SortingLayer: 0
353 | m_SortingOrder: 0
354 | --- !u!33 &33462836363037428
355 | MeshFilter:
356 | m_ObjectHideFlags: 1
357 | m_CorrespondingSourceObject: {fileID: 0}
358 | m_PrefabInternal: {fileID: 100100000}
359 | m_GameObject: {fileID: 1950511125725858}
360 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
361 | --- !u!33 &33662256303880736
362 | MeshFilter:
363 | m_ObjectHideFlags: 1
364 | m_CorrespondingSourceObject: {fileID: 0}
365 | m_PrefabInternal: {fileID: 100100000}
366 | m_GameObject: {fileID: 1010340096941446}
367 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
368 | --- !u!33 &33862078007593612
369 | MeshFilter:
370 | m_ObjectHideFlags: 1
371 | m_CorrespondingSourceObject: {fileID: 0}
372 | m_PrefabInternal: {fileID: 100100000}
373 | m_GameObject: {fileID: 1665137963937560}
374 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
375 | --- !u!33 &33896680748480580
376 | MeshFilter:
377 | m_ObjectHideFlags: 1
378 | m_CorrespondingSourceObject: {fileID: 0}
379 | m_PrefabInternal: {fileID: 100100000}
380 | m_GameObject: {fileID: 1872367868043456}
381 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
382 | --- !u!33 &33929017365551490
383 | MeshFilter:
384 | m_ObjectHideFlags: 1
385 | m_CorrespondingSourceObject: {fileID: 0}
386 | m_PrefabInternal: {fileID: 100100000}
387 | m_GameObject: {fileID: 1010506836010290}
388 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
389 | --- !u!64 &64689253414403800
390 | MeshCollider:
391 | m_ObjectHideFlags: 1
392 | m_CorrespondingSourceObject: {fileID: 0}
393 | m_PrefabInternal: {fileID: 100100000}
394 | m_GameObject: {fileID: 1010506836010290}
395 | m_Material: {fileID: 0}
396 | m_IsTrigger: 0
397 | m_Enabled: 1
398 | serializedVersion: 3
399 | m_Convex: 0
400 | m_CookingOptions: 14
401 | m_SkinWidth: 0.01
402 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
403 | --- !u!65 &65059584660200156
404 | BoxCollider:
405 | m_ObjectHideFlags: 1
406 | m_CorrespondingSourceObject: {fileID: 0}
407 | m_PrefabInternal: {fileID: 100100000}
408 | m_GameObject: {fileID: 1872367868043456}
409 | m_Material: {fileID: 0}
410 | m_IsTrigger: 0
411 | m_Enabled: 1
412 | serializedVersion: 2
413 | m_Size: {x: 1, y: 1, z: 1}
414 | m_Center: {x: 0, y: 0, z: 0}
415 | --- !u!65 &65076807166802294
416 | BoxCollider:
417 | m_ObjectHideFlags: 1
418 | m_CorrespondingSourceObject: {fileID: 0}
419 | m_PrefabInternal: {fileID: 100100000}
420 | m_GameObject: {fileID: 1950511125725858}
421 | m_Material: {fileID: 0}
422 | m_IsTrigger: 0
423 | m_Enabled: 1
424 | serializedVersion: 2
425 | m_Size: {x: 1, y: 1, z: 1}
426 | m_Center: {x: 0, y: 0, z: 0}
427 | --- !u!65 &65087800184519950
428 | BoxCollider:
429 | m_ObjectHideFlags: 1
430 | m_CorrespondingSourceObject: {fileID: 0}
431 | m_PrefabInternal: {fileID: 100100000}
432 | m_GameObject: {fileID: 1010340096941446}
433 | m_Material: {fileID: 0}
434 | m_IsTrigger: 0
435 | m_Enabled: 1
436 | serializedVersion: 2
437 | m_Size: {x: 1, y: 1, z: 1}
438 | m_Center: {x: 0, y: 0, z: 0}
439 | --- !u!65 &65114910231564214
440 | BoxCollider:
441 | m_ObjectHideFlags: 1
442 | m_CorrespondingSourceObject: {fileID: 0}
443 | m_PrefabInternal: {fileID: 100100000}
444 | m_GameObject: {fileID: 1950511125725858}
445 | m_Material: {fileID: 0}
446 | m_IsTrigger: 0
447 | m_Enabled: 1
448 | serializedVersion: 2
449 | m_Size: {x: 1.0000001, y: 1, z: 1}
450 | m_Center: {x: 0, y: 0, z: 0}
451 | --- !u!65 &65590949987065842
452 | BoxCollider:
453 | m_ObjectHideFlags: 1
454 | m_CorrespondingSourceObject: {fileID: 0}
455 | m_PrefabInternal: {fileID: 100100000}
456 | m_GameObject: {fileID: 1872367868043456}
457 | m_Material: {fileID: 0}
458 | m_IsTrigger: 0
459 | m_Enabled: 1
460 | serializedVersion: 2
461 | m_Size: {x: 1.0000001, y: 1, z: 1}
462 | m_Center: {x: 0, y: 0, z: 0}
463 | --- !u!65 &65627854145120356
464 | BoxCollider:
465 | m_ObjectHideFlags: 1
466 | m_CorrespondingSourceObject: {fileID: 0}
467 | m_PrefabInternal: {fileID: 100100000}
468 | m_GameObject: {fileID: 1872367868043456}
469 | m_Material: {fileID: 0}
470 | m_IsTrigger: 0
471 | m_Enabled: 1
472 | serializedVersion: 2
473 | m_Size: {x: 1.0000001, y: 1, z: 1}
474 | m_Center: {x: 0, y: 0, z: 0}
475 | --- !u!65 &65631375037955232
476 | BoxCollider:
477 | m_ObjectHideFlags: 1
478 | m_CorrespondingSourceObject: {fileID: 0}
479 | m_PrefabInternal: {fileID: 100100000}
480 | m_GameObject: {fileID: 1665137963937560}
481 | m_Material: {fileID: 0}
482 | m_IsTrigger: 0
483 | m_Enabled: 1
484 | serializedVersion: 2
485 | m_Size: {x: 1, y: 1, z: 1}
486 | m_Center: {x: 0, y: 0, z: 0}
487 | --- !u!65 &65787851039163106
488 | BoxCollider:
489 | m_ObjectHideFlags: 1
490 | m_CorrespondingSourceObject: {fileID: 0}
491 | m_PrefabInternal: {fileID: 100100000}
492 | m_GameObject: {fileID: 1010340096941446}
493 | m_Material: {fileID: 0}
494 | m_IsTrigger: 0
495 | m_Enabled: 1
496 | serializedVersion: 2
497 | m_Size: {x: 1, y: 1, z: 1}
498 | m_Center: {x: 0, y: 0, z: 0}
499 | --- !u!65 &65803275033776586
500 | BoxCollider:
501 | m_ObjectHideFlags: 1
502 | m_CorrespondingSourceObject: {fileID: 0}
503 | m_PrefabInternal: {fileID: 100100000}
504 | m_GameObject: {fileID: 1665137963937560}
505 | m_Material: {fileID: 0}
506 | m_IsTrigger: 0
507 | m_Enabled: 1
508 | serializedVersion: 2
509 | m_Size: {x: 1, y: 1, z: 1}
510 | m_Center: {x: 0, y: 0, z: 0}
511 | --- !u!65 &65805571091712842
512 | BoxCollider:
513 | m_ObjectHideFlags: 1
514 | m_CorrespondingSourceObject: {fileID: 0}
515 | m_PrefabInternal: {fileID: 100100000}
516 | m_GameObject: {fileID: 1010506836010290}
517 | m_Material: {fileID: 0}
518 | m_IsTrigger: 0
519 | m_Enabled: 1
520 | serializedVersion: 2
521 | m_Size: {x: 10, y: 2.220446e-16, z: 10}
522 | m_Center: {x: 0, y: 0, z: 0}
523 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Prefabs/NetPlayer.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1001 &100100000
4 | Prefab:
5 | m_ObjectHideFlags: 1
6 | serializedVersion: 2
7 | m_Modification:
8 | m_TransformParent: {fileID: 0}
9 | m_Modifications: []
10 | m_RemovedComponents: []
11 | m_SourcePrefab: {fileID: 0}
12 | m_RootGameObject: {fileID: 1907576282027438}
13 | m_IsPrefabAsset: 1
14 | --- !u!1 &1907576282027438
15 | GameObject:
16 | m_ObjectHideFlags: 0
17 | m_CorrespondingSourceObject: {fileID: 0}
18 | m_PrefabInternal: {fileID: 100100000}
19 | serializedVersion: 6
20 | m_Component:
21 | - component: {fileID: 4322976432850648}
22 | - component: {fileID: 33329529089019516}
23 | - component: {fileID: 23544497273986068}
24 | - component: {fileID: 65867865545197592}
25 | - component: {fileID: 54098693686471628}
26 | - component: {fileID: 114598850161925216}
27 | m_Layer: 0
28 | m_Name: NetPlayer
29 | m_TagString: Untagged
30 | m_Icon: {fileID: 0}
31 | m_NavMeshLayer: 0
32 | m_StaticEditorFlags: 0
33 | m_IsActive: 1
34 | --- !u!4 &4322976432850648
35 | Transform:
36 | m_ObjectHideFlags: 1
37 | m_CorrespondingSourceObject: {fileID: 0}
38 | m_PrefabInternal: {fileID: 100100000}
39 | m_GameObject: {fileID: 1907576282027438}
40 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
41 | m_LocalPosition: {x: 0.27323237, y: 2.47, z: 1.9536208}
42 | m_LocalScale: {x: 1, y: 1, z: 1}
43 | m_Children: []
44 | m_Father: {fileID: 0}
45 | m_RootOrder: 0
46 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
47 | --- !u!23 &23544497273986068
48 | MeshRenderer:
49 | m_ObjectHideFlags: 1
50 | m_CorrespondingSourceObject: {fileID: 0}
51 | m_PrefabInternal: {fileID: 100100000}
52 | m_GameObject: {fileID: 1907576282027438}
53 | m_Enabled: 1
54 | m_CastShadows: 1
55 | m_ReceiveShadows: 1
56 | m_DynamicOccludee: 1
57 | m_MotionVectors: 1
58 | m_LightProbeUsage: 1
59 | m_ReflectionProbeUsage: 1
60 | m_RenderingLayerMask: 4294967295
61 | m_Materials:
62 | - {fileID: 2100000, guid: e6bbc5330ae4aa749901f0d8e039adab, type: 2}
63 | m_StaticBatchInfo:
64 | firstSubMesh: 0
65 | subMeshCount: 0
66 | m_StaticBatchRoot: {fileID: 0}
67 | m_ProbeAnchor: {fileID: 0}
68 | m_LightProbeVolumeOverride: {fileID: 0}
69 | m_ScaleInLightmap: 1
70 | m_PreserveUVs: 0
71 | m_IgnoreNormalsForChartDetection: 0
72 | m_ImportantGI: 0
73 | m_StitchLightmapSeams: 0
74 | m_SelectedEditorRenderState: 3
75 | m_MinimumChartSize: 4
76 | m_AutoUVMaxDistance: 0.5
77 | m_AutoUVMaxAngle: 89
78 | m_LightmapParameters: {fileID: 0}
79 | m_SortingLayerID: 0
80 | m_SortingLayer: 0
81 | m_SortingOrder: 0
82 | --- !u!33 &33329529089019516
83 | MeshFilter:
84 | m_ObjectHideFlags: 1
85 | m_CorrespondingSourceObject: {fileID: 0}
86 | m_PrefabInternal: {fileID: 100100000}
87 | m_GameObject: {fileID: 1907576282027438}
88 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
89 | --- !u!54 &54098693686471628
90 | Rigidbody:
91 | m_ObjectHideFlags: 1
92 | m_CorrespondingSourceObject: {fileID: 0}
93 | m_PrefabInternal: {fileID: 100100000}
94 | m_GameObject: {fileID: 1907576282027438}
95 | serializedVersion: 2
96 | m_Mass: 1
97 | m_Drag: 1
98 | m_AngularDrag: 0.05
99 | m_UseGravity: 1
100 | m_IsKinematic: 0
101 | m_Interpolate: 0
102 | m_Constraints: 112
103 | m_CollisionDetection: 0
104 | --- !u!65 &65867865545197592
105 | BoxCollider:
106 | m_ObjectHideFlags: 1
107 | m_CorrespondingSourceObject: {fileID: 0}
108 | m_PrefabInternal: {fileID: 100100000}
109 | m_GameObject: {fileID: 1907576282027438}
110 | m_Material: {fileID: 0}
111 | m_IsTrigger: 0
112 | m_Enabled: 1
113 | serializedVersion: 2
114 | m_Size: {x: 1, y: 1, z: 1}
115 | m_Center: {x: 0, y: 0, z: 0}
116 | --- !u!114 &114598850161925216
117 | MonoBehaviour:
118 | m_ObjectHideFlags: 1
119 | m_CorrespondingSourceObject: {fileID: 0}
120 | m_PrefabInternal: {fileID: 100100000}
121 | m_GameObject: {fileID: 1907576282027438}
122 | m_Enabled: 1
123 | m_EditorHideFlags: 0
124 | m_Script: {fileID: 11500000, guid: f2cc146edb8065b408f3ab3d31f1577b, type: 3}
125 | m_Name:
126 | m_EditorClassIdentifier:
127 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Prefabs/Player.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1001 &100100000
4 | Prefab:
5 | m_ObjectHideFlags: 1
6 | serializedVersion: 2
7 | m_Modification:
8 | m_TransformParent: {fileID: 0}
9 | m_Modifications: []
10 | m_RemovedComponents: []
11 | m_SourcePrefab: {fileID: 0}
12 | m_RootGameObject: {fileID: 1414922606614572}
13 | m_IsPrefabAsset: 1
14 | --- !u!1 &1414922606614572
15 | GameObject:
16 | m_ObjectHideFlags: 0
17 | m_CorrespondingSourceObject: {fileID: 0}
18 | m_PrefabInternal: {fileID: 100100000}
19 | serializedVersion: 6
20 | m_Component:
21 | - component: {fileID: 4162407942446692}
22 | - component: {fileID: 33732225074929884}
23 | - component: {fileID: 23026479571434842}
24 | - component: {fileID: 65628339607062204}
25 | - component: {fileID: 114350425359523364}
26 | - component: {fileID: 54463104736367640}
27 | m_Layer: 0
28 | m_Name: Player
29 | m_TagString: Untagged
30 | m_Icon: {fileID: 0}
31 | m_NavMeshLayer: 0
32 | m_StaticEditorFlags: 0
33 | m_IsActive: 1
34 | --- !u!4 &4162407942446692
35 | Transform:
36 | m_ObjectHideFlags: 1
37 | m_CorrespondingSourceObject: {fileID: 0}
38 | m_PrefabInternal: {fileID: 100100000}
39 | m_GameObject: {fileID: 1414922606614572}
40 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
41 | m_LocalPosition: {x: 0.27323237, y: 0.58, z: 1.9536208}
42 | m_LocalScale: {x: 1, y: 1, z: 1}
43 | m_Children: []
44 | m_Father: {fileID: 0}
45 | m_RootOrder: 0
46 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
47 | --- !u!23 &23026479571434842
48 | MeshRenderer:
49 | m_ObjectHideFlags: 1
50 | m_CorrespondingSourceObject: {fileID: 0}
51 | m_PrefabInternal: {fileID: 100100000}
52 | m_GameObject: {fileID: 1414922606614572}
53 | m_Enabled: 1
54 | m_CastShadows: 1
55 | m_ReceiveShadows: 1
56 | m_DynamicOccludee: 1
57 | m_MotionVectors: 1
58 | m_LightProbeUsage: 1
59 | m_ReflectionProbeUsage: 1
60 | m_RenderingLayerMask: 4294967295
61 | m_Materials:
62 | - {fileID: 2100000, guid: e6bbc5330ae4aa749901f0d8e039adab, type: 2}
63 | m_StaticBatchInfo:
64 | firstSubMesh: 0
65 | subMeshCount: 0
66 | m_StaticBatchRoot: {fileID: 0}
67 | m_ProbeAnchor: {fileID: 0}
68 | m_LightProbeVolumeOverride: {fileID: 0}
69 | m_ScaleInLightmap: 1
70 | m_PreserveUVs: 0
71 | m_IgnoreNormalsForChartDetection: 0
72 | m_ImportantGI: 0
73 | m_StitchLightmapSeams: 0
74 | m_SelectedEditorRenderState: 3
75 | m_MinimumChartSize: 4
76 | m_AutoUVMaxDistance: 0.5
77 | m_AutoUVMaxAngle: 89
78 | m_LightmapParameters: {fileID: 0}
79 | m_SortingLayerID: 0
80 | m_SortingLayer: 0
81 | m_SortingOrder: 0
82 | --- !u!33 &33732225074929884
83 | MeshFilter:
84 | m_ObjectHideFlags: 1
85 | m_CorrespondingSourceObject: {fileID: 0}
86 | m_PrefabInternal: {fileID: 100100000}
87 | m_GameObject: {fileID: 1414922606614572}
88 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
89 | --- !u!54 &54463104736367640
90 | Rigidbody:
91 | m_ObjectHideFlags: 1
92 | m_CorrespondingSourceObject: {fileID: 0}
93 | m_PrefabInternal: {fileID: 100100000}
94 | m_GameObject: {fileID: 1414922606614572}
95 | serializedVersion: 2
96 | m_Mass: 1
97 | m_Drag: 20
98 | m_AngularDrag: 0.05
99 | m_UseGravity: 1
100 | m_IsKinematic: 0
101 | m_Interpolate: 0
102 | m_Constraints: 112
103 | m_CollisionDetection: 0
104 | --- !u!65 &65628339607062204
105 | BoxCollider:
106 | m_ObjectHideFlags: 1
107 | m_CorrespondingSourceObject: {fileID: 0}
108 | m_PrefabInternal: {fileID: 100100000}
109 | m_GameObject: {fileID: 1414922606614572}
110 | m_Material: {fileID: 0}
111 | m_IsTrigger: 0
112 | m_Enabled: 1
113 | serializedVersion: 2
114 | m_Size: {x: 1, y: 1, z: 1}
115 | m_Center: {x: 0, y: 0, z: 0}
116 | --- !u!114 &114350425359523364
117 | MonoBehaviour:
118 | m_ObjectHideFlags: 1
119 | m_CorrespondingSourceObject: {fileID: 0}
120 | m_PrefabInternal: {fileID: 100100000}
121 | m_GameObject: {fileID: 1414922606614572}
122 | m_Enabled: 1
123 | m_EditorHideFlags: 0
124 | m_Script: {fileID: 11500000, guid: f2cc146edb8065b408f3ab3d31f1577b, type: 3}
125 | m_Name:
126 | m_EditorClassIdentifier:
127 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scenes/SampleScene.unity:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!29 &1
4 | OcclusionCullingSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_OcclusionBakeSettings:
8 | smallestOccluder: 5
9 | smallestHole: 0.25
10 | backfaceThreshold: 100
11 | m_SceneGUID: 00000000000000000000000000000000
12 | m_OcclusionCullingData: {fileID: 0}
13 | --- !u!104 &2
14 | RenderSettings:
15 | m_ObjectHideFlags: 0
16 | serializedVersion: 9
17 | m_Fog: 0
18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
19 | m_FogMode: 3
20 | m_FogDensity: 0.01
21 | m_LinearFogStart: 0
22 | m_LinearFogEnd: 300
23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
26 | m_AmbientIntensity: 1
27 | m_AmbientMode: 0
28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
30 | m_HaloStrength: 0.5
31 | m_FlareStrength: 1
32 | m_FlareFadeSpeed: 3
33 | m_HaloTexture: {fileID: 0}
34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
35 | m_DefaultReflectionMode: 0
36 | m_DefaultReflectionResolution: 128
37 | m_ReflectionBounces: 1
38 | m_ReflectionIntensity: 1
39 | m_CustomReflection: {fileID: 0}
40 | m_Sun: {fileID: 0}
41 | m_IndirectSpecularColor: {r: 0.44657844, g: 0.49641222, b: 0.57481694, a: 1}
42 | m_UseRadianceAmbientProbe: 0
43 | --- !u!157 &3
44 | LightmapSettings:
45 | m_ObjectHideFlags: 0
46 | serializedVersion: 11
47 | m_GIWorkflowMode: 0
48 | m_GISettings:
49 | serializedVersion: 2
50 | m_BounceScale: 1
51 | m_IndirectOutputScale: 1
52 | m_AlbedoBoost: 1
53 | m_TemporalCoherenceThreshold: 1
54 | m_EnvironmentLightingMode: 0
55 | m_EnableBakedLightmaps: 1
56 | m_EnableRealtimeLightmaps: 0
57 | m_LightmapEditorSettings:
58 | serializedVersion: 10
59 | m_Resolution: 2
60 | m_BakeResolution: 10
61 | m_AtlasSize: 512
62 | m_AO: 0
63 | m_AOMaxDistance: 1
64 | m_CompAOExponent: 1
65 | m_CompAOExponentDirect: 0
66 | m_Padding: 2
67 | m_LightmapParameters: {fileID: 0}
68 | m_LightmapsBakeMode: 1
69 | m_TextureCompression: 1
70 | m_FinalGather: 0
71 | m_FinalGatherFiltering: 1
72 | m_FinalGatherRayCount: 256
73 | m_ReflectionCompression: 2
74 | m_MixedBakeMode: 2
75 | m_BakeBackend: 1
76 | m_PVRSampling: 1
77 | m_PVRDirectSampleCount: 32
78 | m_PVRSampleCount: 256
79 | m_PVRBounces: 2
80 | m_PVRFilterTypeDirect: 0
81 | m_PVRFilterTypeIndirect: 0
82 | m_PVRFilterTypeAO: 0
83 | m_PVRFilteringMode: 1
84 | m_PVRCulling: 1
85 | m_PVRFilteringGaussRadiusDirect: 1
86 | m_PVRFilteringGaussRadiusIndirect: 5
87 | m_PVRFilteringGaussRadiusAO: 2
88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5
89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2
90 | m_PVRFilteringAtrousPositionSigmaAO: 1
91 | m_ShowResolutionOverlay: 1
92 | m_LightingDataAsset: {fileID: 0}
93 | m_UseShadowmask: 1
94 | --- !u!196 &4
95 | NavMeshSettings:
96 | serializedVersion: 2
97 | m_ObjectHideFlags: 0
98 | m_BuildSettings:
99 | serializedVersion: 2
100 | agentTypeID: 0
101 | agentRadius: 0.5
102 | agentHeight: 2
103 | agentSlope: 45
104 | agentClimb: 0.4
105 | ledgeDropHeight: 0
106 | maxJumpAcrossDistance: 0
107 | minRegionArea: 2
108 | manualCellSize: 0
109 | cellSize: 0.16666667
110 | manualTileSize: 0
111 | tileSize: 256
112 | accuratePlacement: 0
113 | debug:
114 | m_Flags: 0
115 | m_NavMeshData: {fileID: 0}
116 | --- !u!1 &170076733
117 | GameObject:
118 | m_ObjectHideFlags: 0
119 | m_CorrespondingSourceObject: {fileID: 0}
120 | m_PrefabInternal: {fileID: 0}
121 | serializedVersion: 6
122 | m_Component:
123 | - component: {fileID: 170076735}
124 | - component: {fileID: 170076734}
125 | m_Layer: 0
126 | m_Name: Directional Light
127 | m_TagString: Untagged
128 | m_Icon: {fileID: 0}
129 | m_NavMeshLayer: 0
130 | m_StaticEditorFlags: 0
131 | m_IsActive: 1
132 | --- !u!108 &170076734
133 | Light:
134 | m_ObjectHideFlags: 0
135 | m_CorrespondingSourceObject: {fileID: 0}
136 | m_PrefabInternal: {fileID: 0}
137 | m_GameObject: {fileID: 170076733}
138 | m_Enabled: 1
139 | serializedVersion: 8
140 | m_Type: 1
141 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
142 | m_Intensity: 1
143 | m_Range: 10
144 | m_SpotAngle: 30
145 | m_CookieSize: 10
146 | m_Shadows:
147 | m_Type: 2
148 | m_Resolution: -1
149 | m_CustomResolution: -1
150 | m_Strength: 1
151 | m_Bias: 0.05
152 | m_NormalBias: 0.4
153 | m_NearPlane: 0.2
154 | m_Cookie: {fileID: 0}
155 | m_DrawHalo: 0
156 | m_Flare: {fileID: 0}
157 | m_RenderMode: 0
158 | m_CullingMask:
159 | serializedVersion: 2
160 | m_Bits: 4294967295
161 | m_Lightmapping: 1
162 | m_LightShadowCasterMode: 0
163 | m_AreaSize: {x: 1, y: 1}
164 | m_BounceIntensity: 1
165 | m_ColorTemperature: 6570
166 | m_UseColorTemperature: 0
167 | m_ShadowRadius: 0
168 | m_ShadowAngle: 0
169 | --- !u!4 &170076735
170 | Transform:
171 | m_ObjectHideFlags: 0
172 | m_CorrespondingSourceObject: {fileID: 0}
173 | m_PrefabInternal: {fileID: 0}
174 | m_GameObject: {fileID: 170076733}
175 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
176 | m_LocalPosition: {x: 0, y: 3, z: 0}
177 | m_LocalScale: {x: 1, y: 1, z: 1}
178 | m_Children: []
179 | m_Father: {fileID: 0}
180 | m_RootOrder: 1
181 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
182 | --- !u!1 &534669902
183 | GameObject:
184 | m_ObjectHideFlags: 0
185 | m_CorrespondingSourceObject: {fileID: 0}
186 | m_PrefabInternal: {fileID: 0}
187 | serializedVersion: 6
188 | m_Component:
189 | - component: {fileID: 534669905}
190 | - component: {fileID: 534669904}
191 | - component: {fileID: 534669903}
192 | m_Layer: 0
193 | m_Name: Main Camera
194 | m_TagString: Untagged
195 | m_Icon: {fileID: 0}
196 | m_NavMeshLayer: 0
197 | m_StaticEditorFlags: 0
198 | m_IsActive: 1
199 | --- !u!81 &534669903
200 | AudioListener:
201 | m_ObjectHideFlags: 0
202 | m_CorrespondingSourceObject: {fileID: 0}
203 | m_PrefabInternal: {fileID: 0}
204 | m_GameObject: {fileID: 534669902}
205 | m_Enabled: 1
206 | --- !u!20 &534669904
207 | Camera:
208 | m_ObjectHideFlags: 0
209 | m_CorrespondingSourceObject: {fileID: 0}
210 | m_PrefabInternal: {fileID: 0}
211 | m_GameObject: {fileID: 534669902}
212 | m_Enabled: 1
213 | serializedVersion: 2
214 | m_ClearFlags: 1
215 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
216 | m_projectionMatrixMode: 1
217 | m_SensorSize: {x: 36, y: 24}
218 | m_LensShift: {x: 0, y: 0}
219 | m_FocalLength: 50
220 | m_NormalizedViewPortRect:
221 | serializedVersion: 2
222 | x: 0
223 | y: 0
224 | width: 1
225 | height: 1
226 | near clip plane: 0.3
227 | far clip plane: 1000
228 | field of view: 60
229 | orthographic: 0
230 | orthographic size: 5
231 | m_Depth: -1
232 | m_CullingMask:
233 | serializedVersion: 2
234 | m_Bits: 4294967295
235 | m_RenderingPath: -1
236 | m_TargetTexture: {fileID: 0}
237 | m_TargetDisplay: 0
238 | m_TargetEye: 3
239 | m_HDR: 1
240 | m_AllowMSAA: 1
241 | m_AllowDynamicResolution: 0
242 | m_ForceIntoRT: 0
243 | m_OcclusionCulling: 1
244 | m_StereoConvergence: 10
245 | m_StereoSeparation: 0.022
246 | --- !u!4 &534669905
247 | Transform:
248 | m_ObjectHideFlags: 0
249 | m_CorrespondingSourceObject: {fileID: 0}
250 | m_PrefabInternal: {fileID: 0}
251 | m_GameObject: {fileID: 534669902}
252 | m_LocalRotation: {x: -0.31295317, y: 0.007690475, z: -0.0025340617, w: -0.9497341}
253 | m_LocalPosition: {x: -0.55480546, y: 8.812106, z: -14.104752}
254 | m_LocalScale: {x: 1, y: 1, z: 1}
255 | m_Children: []
256 | m_Father: {fileID: 0}
257 | m_RootOrder: 0
258 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
259 | --- !u!1001 &682273211
260 | Prefab:
261 | m_ObjectHideFlags: 0
262 | serializedVersion: 2
263 | m_Modification:
264 | m_TransformParent: {fileID: 0}
265 | m_Modifications:
266 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
267 | propertyPath: m_LocalPosition.x
268 | value: 0.27323237
269 | objectReference: {fileID: 0}
270 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
271 | propertyPath: m_LocalPosition.y
272 | value: 2.47
273 | objectReference: {fileID: 0}
274 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
275 | propertyPath: m_LocalPosition.z
276 | value: 1.9536208
277 | objectReference: {fileID: 0}
278 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
279 | propertyPath: m_LocalRotation.x
280 | value: 0
281 | objectReference: {fileID: 0}
282 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
283 | propertyPath: m_LocalRotation.y
284 | value: 0
285 | objectReference: {fileID: 0}
286 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
287 | propertyPath: m_LocalRotation.z
288 | value: 0
289 | objectReference: {fileID: 0}
290 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
291 | propertyPath: m_LocalRotation.w
292 | value: 1
293 | objectReference: {fileID: 0}
294 | - target: {fileID: 4322976432850648, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
295 | propertyPath: m_RootOrder
296 | value: 3
297 | objectReference: {fileID: 0}
298 | - target: {fileID: 1907576282027438, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
299 | propertyPath: m_Name
300 | value: Player
301 | objectReference: {fileID: 0}
302 | - target: {fileID: 54098693686471628, guid: c732c2a27348837429ae048c52fc4ff5,
303 | type: 2}
304 | propertyPath: m_Mass
305 | value: 1
306 | objectReference: {fileID: 0}
307 | - target: {fileID: 54098693686471628, guid: c732c2a27348837429ae048c52fc4ff5,
308 | type: 2}
309 | propertyPath: m_Drag
310 | value: 1
311 | objectReference: {fileID: 0}
312 | m_RemovedComponents: []
313 | m_SourcePrefab: {fileID: 100100000, guid: c732c2a27348837429ae048c52fc4ff5, type: 2}
314 | m_IsPrefabAsset: 0
315 | --- !u!1001 &832715669
316 | Prefab:
317 | m_ObjectHideFlags: 0
318 | serializedVersion: 2
319 | m_Modification:
320 | m_TransformParent: {fileID: 0}
321 | m_Modifications:
322 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
323 | propertyPath: m_LocalPosition.x
324 | value: 0
325 | objectReference: {fileID: 0}
326 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
327 | propertyPath: m_LocalPosition.y
328 | value: 0
329 | objectReference: {fileID: 0}
330 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
331 | propertyPath: m_LocalPosition.z
332 | value: 0
333 | objectReference: {fileID: 0}
334 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
335 | propertyPath: m_LocalRotation.x
336 | value: 0
337 | objectReference: {fileID: 0}
338 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
339 | propertyPath: m_LocalRotation.y
340 | value: 0
341 | objectReference: {fileID: 0}
342 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
343 | propertyPath: m_LocalRotation.z
344 | value: 0
345 | objectReference: {fileID: 0}
346 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
347 | propertyPath: m_LocalRotation.w
348 | value: 1
349 | objectReference: {fileID: 0}
350 | - target: {fileID: 4284712273699304, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
351 | propertyPath: m_RootOrder
352 | value: 2
353 | objectReference: {fileID: 0}
354 | m_RemovedComponents: []
355 | m_SourcePrefab: {fileID: 100100000, guid: 329a3e36b25332c4b9ace67af047f460, type: 2}
356 | m_IsPrefabAsset: 0
357 | --- !u!1 &1234116709 stripped
358 | GameObject:
359 | m_CorrespondingSourceObject: {fileID: 1907576282027438, guid: c732c2a27348837429ae048c52fc4ff5,
360 | type: 2}
361 | m_PrefabInternal: {fileID: 682273211}
362 | --- !u!114 &1234116710
363 | MonoBehaviour:
364 | m_ObjectHideFlags: 0
365 | m_CorrespondingSourceObject: {fileID: 0}
366 | m_PrefabInternal: {fileID: 0}
367 | m_GameObject: {fileID: 1234116709}
368 | m_Enabled: 1
369 | m_EditorHideFlags: 0
370 | m_Script: {fileID: 11500000, guid: f2cc146edb8065b408f3ab3d31f1577b, type: 3}
371 | m_Name:
372 | m_EditorClassIdentifier:
373 | --- !u!1 &1828230971
374 | GameObject:
375 | m_ObjectHideFlags: 0
376 | m_CorrespondingSourceObject: {fileID: 0}
377 | m_PrefabInternal: {fileID: 0}
378 | serializedVersion: 6
379 | m_Component:
380 | - component: {fileID: 1828230973}
381 | - component: {fileID: 1828230972}
382 | m_Layer: 0
383 | m_Name: Network
384 | m_TagString: Untagged
385 | m_Icon: {fileID: 0}
386 | m_NavMeshLayer: 0
387 | m_StaticEditorFlags: 0
388 | m_IsActive: 1
389 | --- !u!114 &1828230972
390 | MonoBehaviour:
391 | m_ObjectHideFlags: 0
392 | m_CorrespondingSourceObject: {fileID: 0}
393 | m_PrefabInternal: {fileID: 0}
394 | m_GameObject: {fileID: 1828230971}
395 | m_Enabled: 1
396 | m_EditorHideFlags: 0
397 | m_Script: {fileID: 11500000, guid: bed6be86f8dc24d41b4a64911ff1e288, type: 3}
398 | m_Name:
399 | m_EditorClassIdentifier:
400 | player: {fileID: 1234116710}
401 | netPlayerPrefab: {fileID: 1907576282027438, guid: c732c2a27348837429ae048c52fc4ff5,
402 | type: 2}
403 | --- !u!4 &1828230973
404 | Transform:
405 | m_ObjectHideFlags: 0
406 | m_CorrespondingSourceObject: {fileID: 0}
407 | m_PrefabInternal: {fileID: 0}
408 | m_GameObject: {fileID: 1828230971}
409 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
410 | m_LocalPosition: {x: -0.582959, y: 7.234597, z: -11.971174}
411 | m_LocalScale: {x: 1, y: 1, z: 1}
412 | m_Children: []
413 | m_Father: {fileID: 0}
414 | m_RootOrder: 4
415 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
416 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/INetEventListener.cs:
--------------------------------------------------------------------------------
1 | using LiteNetLib.Utils;
2 |
3 | namespace LiteNetLib
4 | {
5 | ///
6 | /// Type of message that you receive in OnNetworkReceiveUnconnected event
7 | ///
8 | public enum UnconnectedMessageType
9 | {
10 | Default,
11 | DiscoveryRequest,
12 | DiscoveryResponse
13 | }
14 |
15 | ///
16 | /// Disconnect reason that you receive in OnPeerDisconnected event
17 | ///
18 | public enum DisconnectReason
19 | {
20 | SocketReceiveError,
21 | ConnectionFailed,
22 | Timeout,
23 | SocketSendError,
24 | RemoteConnectionClose,
25 | DisconnectPeerCalled
26 | }
27 |
28 | ///
29 | /// Additional information about disconnection
30 | ///
31 | public struct DisconnectInfo
32 | {
33 | ///
34 | /// Additional info why peer disconnected
35 | ///
36 | public DisconnectReason Reason;
37 |
38 | ///
39 | /// Error code (if reason is SocketSendError or SocketReceiveError)
40 | ///
41 | public int SocketErrorCode;
42 |
43 | ///
44 | /// Additional data that can be accessed (only if reason is RemoteConnectionClose)
45 | ///
46 | public NetDataReader AdditionalData;
47 | }
48 |
49 | public interface INetEventListener
50 | {
51 | ///
52 | /// New remote peer connected to host, or client connected to remote host
53 | ///
54 | /// Connected peer object
55 | void OnPeerConnected(NetPeer peer);
56 |
57 | ///
58 | /// Peer disconnected
59 | ///
60 | /// disconnected peer
61 | /// additional info about reason, errorCode or data received with disconnect message
62 | void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
63 |
64 | ///
65 | /// Network error (on send or receive)
66 | ///
67 | /// From endPoint (can be null)
68 | /// Socket error code
69 | void OnNetworkError(NetEndPoint endPoint, int socketErrorCode);
70 |
71 | ///
72 | /// Received some data
73 | ///
74 | /// From peer
75 | /// DataReader containing all received data
76 | void OnNetworkReceive(NetPeer peer, NetDataReader reader);
77 |
78 | ///
79 | /// Received unconnected message
80 | ///
81 | /// From address (IP and Port)
82 | /// Message data
83 | /// Message type (simple, discovery request or responce)
84 | void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader, UnconnectedMessageType messageType);
85 |
86 | ///
87 | /// Latency information updated
88 | ///
89 | /// Peer with updated latency
90 | /// latency value in milliseconds
91 | void OnNetworkLatencyUpdate(NetPeer peer, int latency);
92 | }
93 |
94 | public class EventBasedNetListener : INetEventListener
95 | {
96 | public delegate void OnPeerConnected(NetPeer peer);
97 | public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
98 | public delegate void OnNetworkError(NetEndPoint endPoint, int socketErrorCode);
99 | public delegate void OnNetworkReceive(NetPeer peer, NetDataReader reader);
100 | public delegate void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader, UnconnectedMessageType messageType);
101 | public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency);
102 |
103 | public event OnPeerConnected PeerConnectedEvent;
104 | public event OnPeerDisconnected PeerDisconnectedEvent;
105 | public event OnNetworkError NetworkErrorEvent;
106 | public event OnNetworkReceive NetworkReceiveEvent;
107 | public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent;
108 | public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent;
109 |
110 | void INetEventListener.OnPeerConnected(NetPeer peer)
111 | {
112 | if (PeerConnectedEvent != null)
113 | PeerConnectedEvent(peer);
114 | }
115 |
116 | void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
117 | {
118 | if (PeerDisconnectedEvent != null)
119 | PeerDisconnectedEvent(peer, disconnectInfo);
120 | }
121 |
122 | void INetEventListener.OnNetworkError(NetEndPoint endPoint, int socketErrorCode)
123 | {
124 | if (NetworkErrorEvent != null)
125 | NetworkErrorEvent(endPoint, socketErrorCode);
126 | }
127 |
128 | void INetEventListener.OnNetworkReceive(NetPeer peer, NetDataReader reader)
129 | {
130 | if (NetworkReceiveEvent != null)
131 | NetworkReceiveEvent(peer, reader);
132 | }
133 |
134 | void INetEventListener.OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader, UnconnectedMessageType messageType)
135 | {
136 | if (NetworkReceiveUnconnectedEvent != null)
137 | NetworkReceiveUnconnectedEvent(remoteEndPoint, reader, messageType);
138 | }
139 |
140 | void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency)
141 | {
142 | if (NetworkLatencyUpdateEvent != null)
143 | NetworkLatencyUpdateEvent(peer, latency);
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NatPunchModule.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using LiteNetLib.Utils;
4 |
5 | //Some code parts taken from lidgren-network-gen3
6 | namespace LiteNetLib
7 | {
8 | public interface INatPunchListener
9 | {
10 | void OnNatIntroductionRequest(NetEndPoint localEndPoint, NetEndPoint remoteEndPoint, string token);
11 | void OnNatIntroductionSuccess(NetEndPoint targetEndPoint, string token);
12 | }
13 |
14 | public class EventBasedNatPunchListener : INatPunchListener
15 | {
16 | public delegate void OnNatIntroductionRequest(NetEndPoint localEndPoint, NetEndPoint remoteEndPoint, string token);
17 | public delegate void OnNatIntroductionSuccess(NetEndPoint targetEndPoint, string token);
18 |
19 | public event OnNatIntroductionRequest NatIntroductionRequest;
20 | public event OnNatIntroductionSuccess NatIntroductionSuccess;
21 |
22 | void INatPunchListener.OnNatIntroductionRequest(NetEndPoint localEndPoint, NetEndPoint remoteEndPoint, string token)
23 | {
24 | if(NatIntroductionRequest != null)
25 | NatIntroductionRequest(localEndPoint, remoteEndPoint, token);
26 | }
27 |
28 | void INatPunchListener.OnNatIntroductionSuccess(NetEndPoint targetEndPoint, string token)
29 | {
30 | if (NatIntroductionSuccess != null)
31 | NatIntroductionSuccess(targetEndPoint, token);
32 | }
33 | }
34 |
35 | ///
36 | /// Module for UDP NAT Hole punching operations. Can be accessed from NetManager
37 | ///
38 | public sealed class NatPunchModule
39 | {
40 | struct RequestEventData
41 | {
42 | public NetEndPoint LocalEndPoint;
43 | public NetEndPoint RemoteEndPoint;
44 | public string Token;
45 | }
46 |
47 | struct SuccessEventData
48 | {
49 | public NetEndPoint TargetEndPoint;
50 | public string Token;
51 | }
52 |
53 | private readonly NetManager _netBase;
54 | private readonly Queue _requestEvents;
55 | private readonly Queue _successEvents;
56 | private const byte HostByte = 1;
57 | private const byte ClientByte = 0;
58 | public const int MaxTokenLength = 256;
59 |
60 | private INatPunchListener _natPunchListener;
61 |
62 | internal NatPunchModule(NetManager netBase)
63 | {
64 | _netBase = netBase;
65 | _requestEvents = new Queue();
66 | _successEvents = new Queue();
67 | }
68 |
69 | public void Init(INatPunchListener listener)
70 | {
71 | _natPunchListener = listener;
72 | }
73 |
74 | public void NatIntroduce(
75 | NetEndPoint hostInternal,
76 | NetEndPoint hostExternal,
77 | NetEndPoint clientInternal,
78 | NetEndPoint clientExternal,
79 | string additionalInfo)
80 | {
81 | NetDataWriter dw = new NetDataWriter();
82 |
83 | //First packet (server)
84 | //send to client
85 | dw.Put(ClientByte);
86 | dw.Put(hostInternal);
87 | dw.Put(hostExternal);
88 | dw.Put(additionalInfo, MaxTokenLength);
89 |
90 | var packet = _netBase.PacketPool.GetWithData(PacketProperty.NatIntroduction, dw);
91 | _netBase.SendRawAndRecycle(packet, clientExternal);
92 |
93 | //Second packet (client)
94 | //send to server
95 | dw.Reset();
96 | dw.Put(HostByte);
97 | dw.Put(clientInternal);
98 | dw.Put(clientExternal);
99 | dw.Put(additionalInfo, MaxTokenLength);
100 |
101 | packet = _netBase.PacketPool.GetWithData(PacketProperty.NatIntroduction, dw);
102 | _netBase.SendRawAndRecycle(packet, hostExternal);
103 | }
104 |
105 | public void PollEvents()
106 | {
107 | if (_natPunchListener == null)
108 | return;
109 | lock (_successEvents)
110 | {
111 | while (_successEvents.Count > 0)
112 | {
113 | var evt = _successEvents.Dequeue();
114 | _natPunchListener.OnNatIntroductionSuccess(evt.TargetEndPoint, evt.Token);
115 | }
116 | }
117 | lock (_requestEvents)
118 | {
119 | while (_requestEvents.Count > 0)
120 | {
121 | var evt = _requestEvents.Dequeue();
122 | _natPunchListener.OnNatIntroductionRequest(evt.LocalEndPoint, evt.RemoteEndPoint, evt.Token);
123 | }
124 | }
125 | }
126 |
127 | public void SendNatIntroduceRequest(NetEndPoint masterServerEndPoint, string additionalInfo)
128 | {
129 | if (!_netBase.IsRunning)
130 | return;
131 |
132 | //prepare outgoing data
133 | NetDataWriter dw = new NetDataWriter();
134 | string networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv4);
135 | if (string.IsNullOrEmpty(networkIp))
136 | {
137 | networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv6);
138 | }
139 | int networkPort = _netBase.LocalPort;
140 | NetEndPoint localEndPoint = new NetEndPoint(networkIp, networkPort);
141 | dw.Put(localEndPoint);
142 | dw.Put(additionalInfo, MaxTokenLength);
143 |
144 | //prepare packet
145 | var packet = _netBase.PacketPool.GetWithData(PacketProperty.NatIntroductionRequest, dw);
146 | _netBase.SendRawAndRecycle(packet, masterServerEndPoint);
147 | }
148 |
149 | private void HandleNatPunch(NetEndPoint senderEndPoint, NetDataReader dr)
150 | {
151 | byte fromHostByte = dr.GetByte();
152 | if (fromHostByte != HostByte && fromHostByte != ClientByte)
153 | {
154 | //garbage
155 | return;
156 | }
157 |
158 | //Read info
159 | string additionalInfo = dr.GetString(MaxTokenLength);
160 | NetUtils.DebugWrite(ConsoleColor.Green, "[NAT] punch received from {0} - additional info: {1}", senderEndPoint, additionalInfo);
161 |
162 | //Release punch success to client; enabling him to Connect() to msg.Sender if token is ok
163 | lock (_successEvents)
164 | {
165 | _successEvents.Enqueue(new SuccessEventData { TargetEndPoint = senderEndPoint, Token = additionalInfo });
166 | }
167 | }
168 |
169 | private void HandleNatIntroduction(NetDataReader dr)
170 | {
171 | // read intro
172 | byte hostByte = dr.GetByte();
173 | NetEndPoint remoteInternal = dr.GetNetEndPoint();
174 | NetEndPoint remoteExternal = dr.GetNetEndPoint();
175 | string token = dr.GetString(MaxTokenLength);
176 |
177 | NetUtils.DebugWrite(ConsoleColor.Cyan, "[NAT] introduction received; we are designated " + (hostByte == HostByte ? "host" : "client"));
178 | NetDataWriter writer = new NetDataWriter();
179 |
180 | // send internal punch
181 | writer.Put(hostByte);
182 | writer.Put(token);
183 | var packet = _netBase.PacketPool.GetWithData(PacketProperty.NatPunchMessage, writer);
184 | _netBase.SendRawAndRecycle(packet, remoteInternal);
185 | NetUtils.DebugWrite(ConsoleColor.Cyan, "[NAT] internal punch sent to " + remoteInternal);
186 |
187 | // send external punch
188 | writer.Reset();
189 | writer.Put(hostByte);
190 | writer.Put(token);
191 | packet = _netBase.PacketPool.GetWithData(PacketProperty.NatPunchMessage, writer);
192 | _netBase.SendRawAndRecycle(packet, remoteExternal);
193 | NetUtils.DebugWrite(ConsoleColor.Cyan, "[NAT] external punch sent to " + remoteExternal);
194 | }
195 |
196 | private void HandleNatIntroductionRequest(NetEndPoint senderEndPoint, NetDataReader dr)
197 | {
198 | NetEndPoint localEp = dr.GetNetEndPoint();
199 | string token = dr.GetString(MaxTokenLength);
200 | lock (_requestEvents)
201 | {
202 | _requestEvents.Enqueue(new RequestEventData
203 | {
204 | LocalEndPoint = localEp,
205 | RemoteEndPoint = senderEndPoint,
206 | Token = token
207 | });
208 | }
209 | }
210 |
211 | internal void ProcessMessage(NetEndPoint senderEndPoint, NetPacket packet)
212 | {
213 | var dr = new NetDataReader(packet.RawData, NetConstants.HeaderSize, packet.Size);
214 | switch (packet.Property)
215 | {
216 | case PacketProperty.NatIntroductionRequest:
217 | //We got request and must introduce
218 | HandleNatIntroductionRequest(senderEndPoint, dr);
219 | break;
220 | case PacketProperty.NatIntroduction:
221 | //We got introduce and must punch
222 | HandleNatIntroduction(dr);
223 | break;
224 | case PacketProperty.NatPunchMessage:
225 | //We got punch and can connect
226 | HandleNatPunch(senderEndPoint, dr);
227 | break;
228 | }
229 | }
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetConstants.cs:
--------------------------------------------------------------------------------
1 | namespace LiteNetLib
2 | {
3 | ///
4 | /// Sending method type
5 | ///
6 | public enum SendOptions
7 | {
8 | ///
9 | /// Unreliable. Packets can be dropped, duplicated or arrive without order
10 | ///
11 | Unreliable,
12 |
13 | ///
14 | /// Reliable. All packets will be sent and received, but without order
15 | ///
16 | ReliableUnordered,
17 |
18 | ///
19 | /// Unreliable. Packets can be dropped, but never duplicated and arrive in order
20 | ///
21 | Sequenced,
22 |
23 | ///
24 | /// Reliable and ordered. All packets will be sent and received in order
25 | ///
26 | ReliableOrdered
27 | }
28 |
29 | ///
30 | /// Network constants. Can be tuned from sources for your purposes.
31 | ///
32 | public static class NetConstants
33 | {
34 | //can be tuned
35 | public const int DefaultWindowSize = 64;
36 | public const int SocketBufferSize = 1024 * 1024; //1mb
37 | public const int SocketTTL = 255;
38 |
39 | public const int HeaderSize = 1;
40 | public const int SequencedHeaderSize = 3;
41 | public const int FragmentHeaderSize = 6;
42 | public const ushort MaxSequence = 32768;
43 | public const ushort HalfMaxSequence = MaxSequence / 2;
44 | public const int MinPacketSize = 576 - MaxUdpHeaderSize;
45 | public const int MinPacketDataSize = MinPacketSize - HeaderSize;
46 | public const int MinSequencedPacketDataSize = MinPacketSize - SequencedHeaderSize;
47 |
48 | //internal
49 | internal const string MulticastGroupIPv4 = "224.0.0.1";
50 | internal const string MulticastGroupIPv6 = "FF02:0:0:0:0:0:0:1";
51 |
52 | //protocol
53 | internal const int ProtocolId = 1;
54 | internal const int MaxUdpHeaderSize = 68;
55 | internal const int PacketSizeLimit = ushort.MaxValue - MaxUdpHeaderSize;
56 | internal const int RequestConnectIdIndex = 5;
57 | internal const int AcceptConnectIdIndex = 1;
58 |
59 | internal static readonly int[] PossibleMtu =
60 | {
61 | 576 - MaxUdpHeaderSize, //Internet Path MTU for X.25 (RFC 879)
62 | 1492 - MaxUdpHeaderSize, //Ethernet with LLC and SNAP, PPPoE (RFC 1042)
63 | 1500 - MaxUdpHeaderSize, //Ethernet II (RFC 1191)
64 | 4352 - MaxUdpHeaderSize, //FDDI
65 | 4464 - MaxUdpHeaderSize, //Token ring
66 | 7981 - MaxUdpHeaderSize //WLAN
67 | };
68 |
69 | internal static int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1];
70 |
71 | //peer specific
72 | public const int FlowUpdateTime = 1000;
73 | public const int FlowIncreaseThreshold = 4;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetDebug.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LiteNetLib
4 | {
5 | ///
6 | /// Interface to implement for your own logger
7 | ///
8 | public interface INetLogger
9 | {
10 | void WriteNet(ConsoleColor color, string str, params object[] args);
11 | }
12 |
13 | ///
14 | /// Static class for defining your own LiteNetLib logger instead of Console.WriteLine
15 | /// or Debug.Log if compiled with UNITY flag
16 | ///
17 | public static class NetDebug
18 | {
19 | public static INetLogger Logger = null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetEndPoint.cs:
--------------------------------------------------------------------------------
1 | #if !WINRT || UNITY_EDITOR
2 | using System;
3 | using System.Net;
4 | using System.Net.Sockets;
5 |
6 | namespace LiteNetLib
7 | {
8 | ///
9 | /// Network End Point. Contains ip address and port
10 | ///
11 | public sealed class NetEndPoint
12 | {
13 | public string Host { get { return EndPoint.Address.ToString(); } }
14 | public int Port { get { return EndPoint.Port; } }
15 |
16 | internal readonly IPEndPoint EndPoint;
17 |
18 | internal NetEndPoint(IPEndPoint ipEndPoint)
19 | {
20 | EndPoint = ipEndPoint;
21 | }
22 |
23 | public override bool Equals(object obj)
24 | {
25 | if (!(obj is NetEndPoint))
26 | {
27 | return false;
28 | }
29 | return EndPoint.Equals(((NetEndPoint)obj).EndPoint);
30 | }
31 |
32 | public override string ToString()
33 | {
34 | return EndPoint.ToString();
35 | }
36 |
37 | public override int GetHashCode()
38 | {
39 | return EndPoint.GetHashCode();
40 | }
41 |
42 | public NetEndPoint(string hostStr, int port)
43 | {
44 | IPAddress ipAddress;
45 | if (!IPAddress.TryParse(hostStr, out ipAddress))
46 | {
47 | if (NetSocket.IPv6Support)
48 | {
49 | if (hostStr == "localhost")
50 | {
51 | ipAddress = IPAddress.IPv6Loopback;
52 | }
53 | else
54 | {
55 | ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetworkV6);
56 | }
57 | }
58 | if (ipAddress == null)
59 | {
60 | ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetwork);
61 | }
62 | }
63 | if (ipAddress == null)
64 | {
65 | throw new Exception("Invalid address: " + hostStr);
66 | }
67 | EndPoint = new IPEndPoint(ipAddress, port);
68 | }
69 |
70 | private IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily)
71 | {
72 | #if NETCORE
73 | var hostTask = Dns.GetHostEntryAsync(hostStr);
74 | hostTask.Wait();
75 | var host = hostTask.Result;
76 | #else
77 | var host = Dns.GetHostEntry(hostStr);
78 | #endif
79 | foreach (IPAddress ip in host.AddressList)
80 | {
81 | if (ip.AddressFamily == addressFamily)
82 | {
83 | return ip;
84 | }
85 | }
86 | return null;
87 | }
88 |
89 | internal long GetId()
90 | {
91 | byte[] addr = EndPoint.Address.GetAddressBytes();
92 | long id = 0;
93 |
94 | if (addr.Length == 4) //IPv4
95 | {
96 | id = addr[0];
97 | id |= (long)addr[1] << 8;
98 | id |= (long)addr[2] << 16;
99 | id |= (long)addr[3] << 24;
100 | id |= (long)EndPoint.Port << 32;
101 | }
102 | else if (addr.Length == 16) //IPv6
103 | {
104 | id = addr[0] ^ addr[8];
105 | id |= (long)(addr[1] ^ addr[9]) << 8;
106 | id |= (long)(addr[2] ^ addr[10]) << 16;
107 |
108 |
109 | id |= (long)(addr[3] ^ addr[11]) << 24;
110 | id |= (long)(addr[4] ^ addr[12]) << 32;
111 | id |= (long)(addr[5] ^ addr[13]) << 40;
112 | id |= (long)(addr[6] ^ addr[14]) << 48;
113 | id |= (long)(Port ^ addr[7] ^ addr[15]) << 56;
114 | }
115 |
116 | return id;
117 | }
118 | }
119 | }
120 | #else
121 | using System;
122 | using Windows.Networking;
123 | using Windows.Networking.Sockets;
124 |
125 | namespace LiteNetLib
126 | {
127 | public sealed class NetEndPoint
128 | {
129 | public string Host { get { return HostName.DisplayName; } }
130 | public int Port { get; private set; }
131 | internal readonly HostName HostName;
132 | internal readonly string PortStr;
133 |
134 | internal NetEndPoint(int port)
135 | {
136 | HostName = null;
137 | PortStr = port.ToString();
138 | Port = port;
139 | }
140 |
141 | public override bool Equals(object obj)
142 | {
143 | if (!(obj is NetEndPoint))
144 | {
145 | return false;
146 | }
147 | NetEndPoint other = (NetEndPoint) obj;
148 | return HostName.IsEqual(other.HostName) && PortStr.Equals(other.PortStr);
149 | }
150 |
151 | public override int GetHashCode()
152 | {
153 | return HostName.CanonicalName.GetHashCode() ^ PortStr.GetHashCode();
154 | }
155 |
156 | internal long GetId()
157 | {
158 | //Check locals
159 | if (HostName == null)
160 | {
161 | return ParseIpToId("0.0.0.0");
162 | }
163 |
164 | if (HostName.DisplayName == "localhost")
165 | {
166 | return ParseIpToId("127.0.0.1");
167 | }
168 |
169 | //Check remote
170 | string hostIp = string.Empty;
171 | var task = DatagramSocket.GetEndpointPairsAsync(HostName, "0").AsTask();
172 | task.Wait();
173 |
174 | //IPv4
175 | foreach (var endpointPair in task.Result)
176 | {
177 | hostIp = endpointPair.RemoteHostName.CanonicalName;
178 | if (endpointPair.RemoteHostName.Type == HostNameType.Ipv4)
179 | {
180 | return ParseIpToId(hostIp);
181 | }
182 | }
183 |
184 | //Else
185 | return hostIp.GetHashCode() ^ Port;
186 | }
187 |
188 | private long ParseIpToId(string hostIp)
189 | {
190 | long id = 0;
191 | string[] ip = hostIp.Split('.');
192 | id |= long.Parse(ip[0]);
193 | id |= long.Parse(ip[1]) << 8;
194 | id |= long.Parse(ip[2]) << 16;
195 | id |= long.Parse(ip[3]) << 24;
196 | id |= (long)Port << 32;
197 | return id;
198 | }
199 |
200 | public override string ToString()
201 | {
202 | return HostName.CanonicalName + ":" + PortStr;
203 | }
204 |
205 | public NetEndPoint(string hostName, int port)
206 | {
207 | var task = DatagramSocket.GetEndpointPairsAsync(new HostName(hostName), port.ToString()).AsTask();
208 | task.Wait();
209 | HostName = task.Result[0].RemoteHostName;
210 | Port = port;
211 | PortStr = port.ToString();
212 | }
213 |
214 | internal NetEndPoint(HostName hostName, string port)
215 | {
216 | HostName = hostName;
217 | Port = int.Parse(port);
218 | PortStr = port;
219 | }
220 | }
221 | }
222 | #endif
223 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetPacket.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LiteNetLib.Utils;
3 |
4 | namespace LiteNetLib
5 | {
6 | internal enum PacketProperty : byte
7 | {
8 | Unreliable, //0
9 | Reliable, //1
10 | Sequenced, //2
11 | ReliableOrdered, //3
12 | AckReliable, //4
13 | AckReliableOrdered, //5
14 | Ping, //6
15 | Pong, //7
16 | ConnectRequest, //8
17 | ConnectAccept, //9
18 | Disconnect, //10
19 | UnconnectedMessage, //11
20 | NatIntroductionRequest, //12
21 | NatIntroduction, //13
22 | NatPunchMessage, //14
23 | MtuCheck, //15
24 | MtuOk, //16
25 | DiscoveryRequest, //17
26 | DiscoveryResponse, //18
27 | Merged //19
28 | }
29 |
30 | internal sealed class NetPacket
31 | {
32 | private const int LastProperty = 19;
33 |
34 | //Header
35 | public PacketProperty Property
36 | {
37 | get { return (PacketProperty)(RawData[0] & 0x7F); }
38 | set { RawData[0] = (byte)((RawData[0] & 0x80) | ((byte)value & 0x7F)); }
39 | }
40 |
41 | public ushort Sequence
42 | {
43 | get { return BitConverter.ToUInt16(RawData, 1); }
44 | set { FastBitConverter.GetBytes(RawData, 1, value); }
45 | }
46 |
47 | public bool IsFragmented
48 | {
49 | get { return (RawData[0] & 0x80) != 0; }
50 | set
51 | {
52 | if (value)
53 | RawData[0] |= 0x80; //set first bit
54 | else
55 | RawData[0] &= 0x7F; //unset first bit
56 | }
57 | }
58 |
59 | public ushort FragmentId
60 | {
61 | get { return BitConverter.ToUInt16(RawData, 3); }
62 | set { FastBitConverter.GetBytes(RawData, 3, value); }
63 | }
64 |
65 | public ushort FragmentPart
66 | {
67 | get { return BitConverter.ToUInt16(RawData, 5); }
68 | set { FastBitConverter.GetBytes(RawData, 5, value); }
69 | }
70 |
71 | public ushort FragmentsTotal
72 | {
73 | get { return BitConverter.ToUInt16(RawData, 7); }
74 | set { FastBitConverter.GetBytes(RawData, 7, value); }
75 | }
76 |
77 | //Data
78 | public byte[] RawData;
79 | public int Size;
80 |
81 | public NetPacket(int size)
82 | {
83 | RawData = new byte[size];
84 | Size = 0;
85 | }
86 |
87 | public bool Realloc(int toSize)
88 | {
89 | if (RawData.Length < toSize)
90 | {
91 | RawData = new byte[toSize];
92 | return true;
93 | }
94 | return false;
95 | }
96 |
97 | public static bool GetPacketProperty(byte[] data, out PacketProperty property)
98 | {
99 | byte properyByte = (byte)(data[0] & 0x7F);
100 | if (properyByte > LastProperty)
101 | {
102 | property = PacketProperty.Unreliable;
103 | return false;
104 | }
105 | property = (PacketProperty)properyByte;
106 | return true;
107 | }
108 |
109 | public static int GetHeaderSize(PacketProperty property)
110 | {
111 | switch (property)
112 | {
113 | case PacketProperty.ReliableOrdered:
114 | case PacketProperty.Reliable:
115 | case PacketProperty.Sequenced:
116 | case PacketProperty.Ping:
117 | case PacketProperty.Pong:
118 | case PacketProperty.AckReliable:
119 | case PacketProperty.AckReliableOrdered:
120 | return NetConstants.SequencedHeaderSize;
121 | default:
122 | return NetConstants.HeaderSize;
123 | }
124 | }
125 |
126 | public int GetHeaderSize()
127 | {
128 | return GetHeaderSize(Property);
129 | }
130 |
131 | public byte[] GetPacketData()
132 | {
133 | int headerSize = GetHeaderSize(Property);
134 | int dataSize = Size - headerSize;
135 | byte[] data = new byte[dataSize];
136 | Buffer.BlockCopy(RawData, headerSize, data, 0, dataSize);
137 | return data;
138 | }
139 |
140 | public bool IsClientData()
141 | {
142 | var property = Property;
143 | return property == PacketProperty.Reliable ||
144 | property == PacketProperty.ReliableOrdered ||
145 | property == PacketProperty.Unreliable ||
146 | property == PacketProperty.Sequenced;
147 | }
148 |
149 | //Packet contstructor from byte array
150 | public bool FromBytes(byte[] data, int start, int packetSize)
151 | {
152 | //Reading property
153 | byte property = (byte)(data[start] & 0x7F);
154 | bool fragmented = (data[start] & 0x80) != 0;
155 | int headerSize = GetHeaderSize((PacketProperty) property);
156 |
157 | if (property > LastProperty ||
158 | packetSize > NetConstants.PacketSizeLimit ||
159 | packetSize < headerSize ||
160 | (fragmented && packetSize < headerSize + NetConstants.FragmentHeaderSize))
161 | {
162 | return false;
163 | }
164 |
165 | Buffer.BlockCopy(data, start, RawData, 0, packetSize);
166 | Size = packetSize;
167 | return true;
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetPacketPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using LiteNetLib.Utils;
4 |
5 | namespace LiteNetLib
6 | {
7 | internal class NetPacketPool
8 | {
9 | private const int PoolLimit = 1000;
10 | private readonly Stack _pool;
11 |
12 | public NetPacketPool()
13 | {
14 | _pool = new Stack();
15 | }
16 |
17 | public NetPacket GetWithData(PacketProperty property, NetDataWriter writer)
18 | {
19 | var packet = Get(property, writer.Length);
20 | Buffer.BlockCopy(writer.Data, 0, packet.RawData, NetPacket.GetHeaderSize(property), writer.Length);
21 | return packet;
22 | }
23 |
24 | public NetPacket GetWithData(PacketProperty property, byte[] data, int start, int length)
25 | {
26 | var packet = Get(property, length);
27 | Buffer.BlockCopy(data, start, packet.RawData, NetPacket.GetHeaderSize(property), length);
28 | return packet;
29 | }
30 |
31 | private NetPacket GetPacket(int size, bool clear)
32 | {
33 | NetPacket packet = null;
34 | if (size <= NetConstants.MaxPacketSize)
35 | {
36 | lock (_pool)
37 | {
38 | if (_pool.Count > 0)
39 | {
40 | packet = _pool.Pop();
41 | }
42 | }
43 | }
44 | if (packet == null)
45 | {
46 | //allocate new packet
47 | packet = new NetPacket(size);
48 | }
49 | else
50 | {
51 | //reallocate packet data if packet not fits
52 | if (!packet.Realloc(size) && clear)
53 | {
54 | //clear in not reallocated
55 | Array.Clear(packet.RawData, 0, size);
56 | }
57 | }
58 | return packet;
59 | }
60 |
61 | //Get packet just for read
62 | public NetPacket GetAndRead(byte[] data, int start, int count)
63 | {
64 | NetPacket packet = GetPacket(count, false);
65 | if (!packet.FromBytes(data, start, count))
66 | {
67 | Recycle(packet);
68 | return null;
69 | }
70 | return packet;
71 | }
72 |
73 | //Get packet with size
74 | public NetPacket Get(PacketProperty property, int size)
75 | {
76 | size += NetPacket.GetHeaderSize(property);
77 | NetPacket packet = GetPacket(size, true);
78 | packet.Property = property;
79 | packet.Size = size;
80 | return packet;
81 | }
82 |
83 | public void Recycle(NetPacket packet)
84 | {
85 | if (packet.Size > NetConstants.MaxPacketSize || _pool.Count > PoolLimit)
86 | {
87 | //Dont pool big packets. Save memory
88 | return;
89 | }
90 |
91 | //Clean fragmented flag
92 | packet.IsFragmented = false;
93 | lock (_pool)
94 | {
95 | _pool.Push(packet);
96 | }
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetPeerCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace LiteNetLib
5 | {
6 | internal sealed class NetPeerCollection
7 | {
8 | private readonly Dictionary _peersDict;
9 | private readonly NetPeer[] _peersArray;
10 | private int _count;
11 |
12 | public int Count
13 | {
14 | get { return _count; }
15 | }
16 |
17 | public NetPeer this[int index]
18 | {
19 | get { return _peersArray[index]; }
20 | }
21 |
22 | public NetPeerCollection(int maxPeers)
23 | {
24 | _peersArray = new NetPeer[maxPeers];
25 | _peersDict = new Dictionary();
26 | }
27 |
28 | public bool TryGetValue(NetEndPoint endPoint, out NetPeer peer)
29 | {
30 | return _peersDict.TryGetValue(endPoint, out peer);
31 | }
32 |
33 | public void Clear()
34 | {
35 | Array.Clear(_peersArray, 0, _count);
36 | _peersDict.Clear();
37 | _count = 0;
38 | }
39 |
40 | public void Add(NetEndPoint endPoint, NetPeer peer)
41 | {
42 | _peersArray[_count] = peer;
43 | _peersDict.Add(endPoint, peer);
44 | _count++;
45 | }
46 |
47 | public bool ContainsAddress(NetEndPoint endPoint)
48 | {
49 | return _peersDict.ContainsKey(endPoint);
50 | }
51 |
52 | public NetPeer[] ToArray()
53 | {
54 | NetPeer[] result = new NetPeer[_count];
55 | Array.Copy(_peersArray, 0, result, 0, _count);
56 | return result;
57 | }
58 |
59 | public void RemoveAt(int idx)
60 | {
61 | _peersDict.Remove(_peersArray[idx].EndPoint);
62 | _peersArray[idx] = _peersArray[_count - 1];
63 | _peersArray[_count - 1] = null;
64 | _count--;
65 | }
66 |
67 | public void Remove(NetEndPoint endPoint)
68 | {
69 | for (int i = 0; i < _count; i++)
70 | {
71 | if (_peersArray[i].EndPoint.Equals(endPoint))
72 | {
73 | RemoveAt(i);
74 | break;
75 | }
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetSocket.cs:
--------------------------------------------------------------------------------
1 | #if !WINRT || UNITY_EDITOR
2 | using System;
3 | using System.Net;
4 | using System.Net.Sockets;
5 | using System.Threading;
6 |
7 | namespace LiteNetLib
8 | {
9 | internal sealed class NetSocket
10 | {
11 | private Socket _udpSocketv4;
12 | private Socket _udpSocketv6;
13 | private int _port;
14 | private Thread _threadv4;
15 | private Thread _threadv6;
16 | private bool _running;
17 | private readonly NetManager.OnMessageReceived _onMessageReceived;
18 |
19 | private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse (NetConstants.MulticastGroupIPv6);
20 | internal static readonly bool IPv6Support;
21 | private const int SocketReceivePollTime = 100000;
22 | private const int SocketSendPollTime = 5000;
23 |
24 | public int LocalPort
25 | {
26 | get { return _port; }
27 | }
28 |
29 | static NetSocket()
30 | {
31 | #if UNITY
32 | IPv6Support = Socket.SupportsIPv6;
33 | #else
34 | IPv6Support = Socket.OSSupportsIPv6;
35 | #endif
36 | }
37 |
38 | public NetSocket(NetManager.OnMessageReceived onMessageReceived)
39 | {
40 | _onMessageReceived = onMessageReceived;
41 | }
42 |
43 | private void ReceiveLogic(object state)
44 | {
45 | Socket socket = (Socket)state;
46 | EndPoint bufferEndPoint = new IPEndPoint(socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0);
47 | NetEndPoint bufferNetEndPoint = new NetEndPoint((IPEndPoint)bufferEndPoint);
48 | byte[] receiveBuffer = new byte[NetConstants.PacketSizeLimit];
49 |
50 | while (_running)
51 | {
52 | //wait for data
53 | if (!socket.Poll(SocketReceivePollTime, SelectMode.SelectRead))
54 | {
55 | continue;
56 | }
57 |
58 | int result;
59 |
60 | //Reading data
61 | try
62 | {
63 | result = socket.ReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref bufferEndPoint);
64 | if (!bufferNetEndPoint.EndPoint.Equals(bufferEndPoint))
65 | {
66 | bufferNetEndPoint = new NetEndPoint((IPEndPoint)bufferEndPoint);
67 | }
68 | }
69 | catch (SocketException ex)
70 | {
71 | if (ex.SocketErrorCode == SocketError.ConnectionReset ||
72 | ex.SocketErrorCode == SocketError.MessageSize)
73 | {
74 | //10040 - message too long
75 | //10054 - remote close (not error)
76 | //Just UDP
77 | NetUtils.DebugWrite(ConsoleColor.DarkRed, "[R] Ingored error: {0} - {1}", (int)ex.SocketErrorCode, ex.ToString() );
78 | continue;
79 | }
80 | NetUtils.DebugWriteError("[R]Error code: {0} - {1}", (int)ex.SocketErrorCode, ex.ToString());
81 | _onMessageReceived(null, 0, (int)ex.SocketErrorCode, bufferNetEndPoint);
82 | continue;
83 | }
84 |
85 | //All ok!
86 | NetUtils.DebugWrite(ConsoleColor.Blue, "[R]Recieved data from {0}, result: {1}", bufferNetEndPoint.ToString(), result);
87 | _onMessageReceived(receiveBuffer, result, 0, bufferNetEndPoint);
88 | }
89 | }
90 |
91 | public bool Bind(int port, bool reuseAddress)
92 | {
93 | _udpSocketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
94 | _udpSocketv4.Blocking = false;
95 | _udpSocketv4.ReceiveBufferSize = NetConstants.SocketBufferSize;
96 | _udpSocketv4.SendBufferSize = NetConstants.SocketBufferSize;
97 | _udpSocketv4.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, NetConstants.SocketTTL);
98 | if(reuseAddress)
99 | _udpSocketv4.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
100 | #if !NETCORE
101 | _udpSocketv4.DontFragment = true;
102 | #endif
103 |
104 | try
105 | {
106 | _udpSocketv4.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
107 | }
108 | catch (SocketException e)
109 | {
110 | NetUtils.DebugWriteError("Broadcast error: {0}", e.ToString());
111 | }
112 |
113 | if (!BindSocket(_udpSocketv4, new IPEndPoint(IPAddress.Any, port)))
114 | {
115 | return false;
116 | }
117 | _port = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port;
118 | _running = true;
119 | _threadv4 = new Thread(ReceiveLogic);
120 | _threadv4.Name = "SocketThreadv4(" + _port + ")";
121 | _threadv4.IsBackground = true;
122 | _threadv4.Start(_udpSocketv4);
123 |
124 | //Check IPv6 support
125 | if (!IPv6Support)
126 | return true;
127 |
128 | _udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
129 | _udpSocketv6.Blocking = false;
130 | _udpSocketv6.ReceiveBufferSize = NetConstants.SocketBufferSize;
131 | _udpSocketv6.SendBufferSize = NetConstants.SocketBufferSize;
132 | if (reuseAddress)
133 | _udpSocketv6.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
134 |
135 | //Use one port for two sockets
136 | if (BindSocket(_udpSocketv6, new IPEndPoint(IPAddress.IPv6Any, _port)))
137 | {
138 | try
139 | {
140 | #if !ENABLE_IL2CPP
141 | _udpSocketv6.SetSocketOption(
142 | SocketOptionLevel.IPv6,
143 | SocketOptionName.AddMembership,
144 | new IPv6MulticastOption(MulticastAddressV6));
145 | #endif
146 | }
147 | catch(Exception)
148 | {
149 | // Unity3d throws exception - ignored
150 | }
151 |
152 | _threadv6 = new Thread(ReceiveLogic);
153 | _threadv6.Name = "SocketThreadv6(" + _port + ")";
154 | _threadv6.IsBackground = true;
155 | _threadv6.Start(_udpSocketv6);
156 | }
157 |
158 | return true;
159 | }
160 |
161 | private bool BindSocket(Socket socket, IPEndPoint ep)
162 | {
163 | try
164 | {
165 | socket.Bind(ep);
166 | NetUtils.DebugWrite(ConsoleColor.Blue, "[B]Succesfully binded to port: {0}", ((IPEndPoint)socket.LocalEndPoint).Port);
167 | }
168 | catch (SocketException ex)
169 | {
170 | NetUtils.DebugWriteError("[B]Bind exception: {0}", ex.ToString());
171 | //TODO: very temporary hack for iOS (Unity3D)
172 | if (ex.SocketErrorCode == SocketError.AddressFamilyNotSupported)
173 | {
174 | return true;
175 | }
176 | return false;
177 | }
178 | return true;
179 | }
180 |
181 | public bool SendBroadcast(byte[] data, int offset, int size, int port)
182 | {
183 | try
184 | {
185 | int result = _udpSocketv4.SendTo(data, offset, size, SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, port));
186 | if (result <= 0)
187 | return false;
188 | if (IPv6Support)
189 | {
190 | result = _udpSocketv6.SendTo(data, offset, size, SocketFlags.None, new IPEndPoint(MulticastAddressV6, port));
191 | if (result <= 0)
192 | return false;
193 | }
194 | }
195 | catch (Exception ex)
196 | {
197 | NetUtils.DebugWriteError("[S][MCAST]" + ex);
198 | return false;
199 | }
200 | return true;
201 | }
202 |
203 | public int SendTo(byte[] data, int offset, int size, NetEndPoint remoteEndPoint, ref int errorCode)
204 | {
205 | try
206 | {
207 | int result = 0;
208 | if (remoteEndPoint.EndPoint.AddressFamily == AddressFamily.InterNetwork)
209 | {
210 | if (!_udpSocketv4.Poll(SocketSendPollTime, SelectMode.SelectWrite))
211 | return -1;
212 | result = _udpSocketv4.SendTo(data, offset, size, SocketFlags.None, remoteEndPoint.EndPoint);
213 | }
214 | else if(IPv6Support)
215 | {
216 | if (!_udpSocketv6.Poll(SocketSendPollTime, SelectMode.SelectWrite))
217 | return -1;
218 | result = _udpSocketv6.SendTo(data, offset, size, SocketFlags.None, remoteEndPoint.EndPoint);
219 | }
220 |
221 | NetUtils.DebugWrite(ConsoleColor.Blue, "[S]Send packet to {0}, result: {1}", remoteEndPoint.EndPoint, result);
222 | return result;
223 | }
224 | catch (SocketException ex)
225 | {
226 | if (ex.SocketErrorCode != SocketError.MessageSize)
227 | {
228 | NetUtils.DebugWriteError("[S]" + ex);
229 | }
230 |
231 | errorCode = (int)ex.SocketErrorCode;
232 | return -1;
233 | }
234 | catch (Exception ex)
235 | {
236 | NetUtils.DebugWriteError("[S]" + ex);
237 | return -1;
238 | }
239 | }
240 |
241 | private void CloseSocket(Socket s)
242 | {
243 | #if NETCORE
244 | s.Dispose();
245 | #else
246 | s.Close();
247 | #endif
248 | }
249 |
250 | public void Close()
251 | {
252 | _running = false;
253 |
254 | //Close IPv4
255 | if (Thread.CurrentThread != _threadv4)
256 | {
257 | _threadv4.Join();
258 | }
259 | _threadv4 = null;
260 | if (_udpSocketv4 != null)
261 | {
262 | CloseSocket(_udpSocketv4);
263 | _udpSocketv4 = null;
264 | }
265 |
266 | //No ipv6
267 | if (_udpSocketv6 == null)
268 | return;
269 |
270 | //Close IPv6
271 | if (Thread.CurrentThread != _threadv6)
272 | {
273 | _threadv6.Join();
274 | }
275 | _threadv6 = null;
276 | if (_udpSocketv6 != null)
277 | {
278 | CloseSocket(_udpSocketv6);
279 | _udpSocketv6 = null;
280 | }
281 | }
282 | }
283 | }
284 | #else
285 | using System;
286 | using System.Collections.Generic;
287 | using System.IO;
288 | using System.Runtime.InteropServices.WindowsRuntime;
289 | using System.Threading;
290 | using System.Threading.Tasks;
291 | using Windows.Networking;
292 | using Windows.Networking.Sockets;
293 | using Windows.Storage.Streams;
294 |
295 | namespace LiteNetLib
296 | {
297 | internal sealed class NetSocket
298 | {
299 | private DatagramSocket _datagramSocket;
300 | private readonly Dictionary _peers = new Dictionary();
301 | private readonly NetManager.OnMessageReceived _onMessageReceived;
302 | private readonly byte[] _byteBuffer = new byte[NetConstants.PacketSizeLimit];
303 | private readonly IBuffer _buffer;
304 | private NetEndPoint _bufferEndPoint;
305 | private int _port;
306 | private static readonly HostName BroadcastAddress = new HostName("255.255.255.255");
307 | private static readonly HostName MulticastAddressV6 = new HostName(NetConstants.MulticastGroupIPv6);
308 |
309 | public int LocalPort
310 | {
311 | get { return _port; }
312 | }
313 |
314 | public NetSocket(NetManager.OnMessageReceived onMessageReceived)
315 | {
316 | _onMessageReceived = onMessageReceived;
317 | _buffer = _byteBuffer.AsBuffer();
318 | }
319 |
320 | private void OnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
321 | {
322 | var result = args.GetDataStream().ReadAsync(_buffer, _buffer.Capacity, InputStreamOptions.None).AsTask().Result;
323 | int length = (int)result.Length;
324 | if (length <= 0)
325 | return;
326 |
327 | if (_bufferEndPoint == null ||
328 | !_bufferEndPoint.HostName.IsEqual(args.RemoteAddress) ||
329 | !_bufferEndPoint.PortStr.Equals(args.RemotePort))
330 | {
331 | _bufferEndPoint = new NetEndPoint(args.RemoteAddress, args.RemotePort);
332 | }
333 | _onMessageReceived(_byteBuffer, length, 0, _bufferEndPoint);
334 | }
335 |
336 | public bool Bind(int port, bool reuseAddress)
337 | {
338 | _datagramSocket = new DatagramSocket();
339 | _datagramSocket.Control.InboundBufferSizeInBytes = NetConstants.SocketBufferSize;
340 | _datagramSocket.Control.DontFragment = true;
341 | _datagramSocket.Control.OutboundUnicastHopLimit = NetConstants.SocketTTL;
342 | _datagramSocket.MessageReceived += OnMessageReceived;
343 |
344 | try
345 | {
346 | _datagramSocket.BindServiceNameAsync(port.ToString()).AsTask().Wait();
347 | _datagramSocket.JoinMulticastGroup(MulticastAddressV6);
348 | _port = int.Parse(_datagramSocket.Information.LocalPort);
349 | }
350 | catch (Exception ex)
351 | {
352 | NetUtils.DebugWriteError("[B]Bind exception: {0}", ex.ToString());
353 | return false;
354 | }
355 | return true;
356 | }
357 |
358 | public bool SendBroadcast(byte[] data, int offset, int size, int port)
359 | {
360 | var portString = port.ToString();
361 | try
362 | {
363 | var outputStream =
364 | _datagramSocket.GetOutputStreamAsync(BroadcastAddress, portString)
365 | .AsTask()
366 | .Result;
367 | var writer = outputStream.AsStreamForWrite();
368 | writer.Write(data, offset, size);
369 | writer.Flush();
370 |
371 | outputStream =
372 | _datagramSocket.GetOutputStreamAsync(MulticastAddressV6, portString)
373 | .AsTask()
374 | .Result;
375 | writer = outputStream.AsStreamForWrite();
376 | writer.Write(data, offset, size);
377 | writer.Flush();
378 | }
379 | catch (Exception ex)
380 | {
381 | NetUtils.DebugWriteError("[S][MCAST]" + ex);
382 | return false;
383 | }
384 | return true;
385 | }
386 |
387 | public int SendTo(byte[] data, int offset, int length, NetEndPoint remoteEndPoint, ref int errorCode)
388 | {
389 | Task task = null;
390 | try
391 | {
392 | IOutputStream writer;
393 | if (!_peers.TryGetValue(remoteEndPoint, out writer))
394 | {
395 | writer =
396 | _datagramSocket.GetOutputStreamAsync(remoteEndPoint.HostName, remoteEndPoint.PortStr)
397 | .AsTask()
398 | .Result;
399 | _peers.Add(remoteEndPoint, writer);
400 | }
401 |
402 | task = writer.WriteAsync(data.AsBuffer(offset, length)).AsTask();
403 | return (int)task.Result;
404 | }
405 | catch (Exception ex)
406 | {
407 | if (task?.Exception?.InnerExceptions != null)
408 | {
409 | ex = task.Exception.InnerException;
410 | }
411 | var errorStatus = SocketError.GetStatus(ex.HResult);
412 | switch (errorStatus)
413 | {
414 | case SocketErrorStatus.MessageTooLong:
415 | errorCode = 10040;
416 | break;
417 | default:
418 | errorCode = (int)errorStatus;
419 | NetUtils.DebugWriteError("[S " + errorStatus + "(" + errorCode + ")]" + ex);
420 | break;
421 | }
422 |
423 | return -1;
424 | }
425 | }
426 |
427 | internal void RemovePeer(NetEndPoint ep)
428 | {
429 | _peers.Remove(ep);
430 | }
431 |
432 | public void Close()
433 | {
434 | _datagramSocket.Dispose();
435 | _datagramSocket = null;
436 | ClearPeers();
437 | }
438 |
439 | internal void ClearPeers()
440 | {
441 | _peers.Clear();
442 | }
443 | }
444 | }
445 | #endif
446 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetStatistics.cs:
--------------------------------------------------------------------------------
1 | namespace LiteNetLib
2 | {
3 | public sealed class NetStatistics
4 | {
5 | public ulong PacketsSent;
6 | public ulong PacketsReceived;
7 | public ulong BytesSent;
8 | public ulong BytesReceived;
9 | public ulong PacketLoss;
10 | public ulong PacketLossPercent
11 | {
12 | get
13 | {
14 | if (PacketsSent == 0)
15 | {
16 | return 0;
17 | }
18 |
19 | return PacketLoss * 100 / PacketsSent;
20 | }
21 | }
22 |
23 | public override string ToString()
24 | {
25 | return
26 | string.Format(
27 | "BytesReceived: {0}\nPacketsReceived: {1}\nBytesSent: {2}\nPacketsSent: {3}\nPacketLoss: {4}\nPacketLossPercent: {5}\n",
28 | BytesReceived,
29 | PacketsReceived,
30 | BytesSent,
31 | PacketsSent,
32 | PacketLoss,
33 | PacketLossPercent);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetThread.cs:
--------------------------------------------------------------------------------
1 | #if WINRT && !UNITY_EDITOR
2 | #define USE_WINRT
3 | #endif
4 |
5 | using System;
6 | using System.Threading;
7 |
8 | #if USE_WINRT
9 | using Windows.Foundation;
10 | using Windows.System.Threading;
11 | using Windows.System.Threading.Core;
12 | #endif
13 |
14 | namespace LiteNetLib
15 | {
16 | internal sealed class NetThread
17 | {
18 | #if USE_WINRT
19 | private readonly ManualResetEvent _updateWaiter = new ManualResetEvent(false);
20 | private readonly ManualResetEvent _joinWaiter = new ManualResetEvent(false);
21 | #else
22 | private Thread _thread;
23 | #endif
24 |
25 | private readonly Action _callback;
26 |
27 | public int SleepTime;
28 | private volatile bool _running;
29 | private readonly string _name;
30 |
31 | public bool IsRunning
32 | {
33 | get { return _running; }
34 | }
35 |
36 | public NetThread(string name, int sleepTime, Action callback)
37 | {
38 | _callback = callback;
39 | SleepTime = sleepTime;
40 | _name = name;
41 | }
42 |
43 | public void Sleep(int msec)
44 | {
45 | #if USE_WINRT
46 | _updateWaiter.WaitOne(msec);
47 | #else
48 | Thread.Sleep(msec);
49 | #endif
50 | }
51 |
52 | public void Start()
53 | {
54 | if (_running)
55 | return;
56 | _running = true;
57 | #if USE_WINRT
58 | var thread = new PreallocatedWorkItem(ThreadLogic, WorkItemPriority.Normal, WorkItemOptions.TimeSliced);
59 | thread.RunAsync().AsTask();
60 | #else
61 | _thread = new Thread(ThreadLogic)
62 | {
63 | Name = _name,
64 | IsBackground = true
65 | };
66 | _thread.Start();
67 | #endif
68 | }
69 |
70 | public void Stop()
71 | {
72 | if (!_running)
73 | return;
74 | _running = false;
75 |
76 | #if USE_WINRT
77 | _joinWaiter.WaitOne();
78 | #else
79 | _thread.Join();
80 | #endif
81 | }
82 |
83 | #if USE_WINRT
84 | private void ThreadLogic(IAsyncAction action)
85 | {
86 | while (_running)
87 | {
88 | _callback();
89 | _updateWaiter.WaitOne(SleepTime);
90 | }
91 | _joinWaiter.Set();
92 | }
93 | #else
94 | private void ThreadLogic()
95 | {
96 | while (_running)
97 | {
98 | _callback();
99 | Thread.Sleep(SleepTime);
100 | }
101 | }
102 | #endif
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/NetUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | #if WINRT && !UNITY_EDITOR
5 | using Windows.Networking;
6 | using Windows.Networking.Connectivity;
7 | #else
8 | using System.Net;
9 | using System.Net.Sockets;
10 | using System.Net.NetworkInformation;
11 | #endif
12 |
13 | namespace LiteNetLib
14 | {
15 | #if WINRT && !UNITY_EDITOR
16 | public enum ConsoleColor
17 | {
18 | Gray,
19 | Yellow,
20 | Cyan,
21 | DarkCyan,
22 | DarkGreen,
23 | Blue,
24 | DarkRed,
25 | Red,
26 | Green,
27 | DarkYellow
28 | }
29 | #endif
30 |
31 | ///
32 | /// Address type that you want to receive from NetUtils.GetLocalIp method
33 | ///
34 | [Flags]
35 | public enum LocalAddrType
36 | {
37 | IPv4 = 1,
38 | IPv6 = 2,
39 | All = 3
40 | }
41 |
42 | ///
43 | /// Some specific network utilities
44 | ///
45 | public static class NetUtils
46 | {
47 | ///
48 | /// Request time from NTP server and calls callback (if success)
49 | ///
50 | /// NTP Server address
51 | /// port
52 | /// callback (called from other thread!)
53 | public static void RequestTimeFromNTP(string ntpServerAddress, int port, Action onRequestComplete)
54 | {
55 | NetSocket socket = null;
56 | var ntpEndPoint = new NetEndPoint(ntpServerAddress, port);
57 |
58 | NetManager.OnMessageReceived onReceive = (data, length, code, point) =>
59 | {
60 | if (!point.Equals(ntpEndPoint) || length < 48)
61 | {
62 | return;
63 | }
64 | socket.Close();
65 |
66 | ulong intPart = (ulong)data[40] << 24 | (ulong)data[41] << 16 | (ulong)data[42] << 8 | (ulong)data[43];
67 | ulong fractPart = (ulong)data[44] << 24 | (ulong)data[45] << 16 | (ulong)data[46] << 8 | (ulong)data[47];
68 | var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
69 | onRequestComplete(new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((long) milliseconds));
70 | };
71 |
72 | //Create and start socket
73 | socket = new NetSocket(onReceive);
74 | socket.Bind(0, false);
75 |
76 | //Send request
77 | int errorCode = 0;
78 | var sendData = new byte[48];
79 | sendData[0] = 0x1B;
80 | var sendCount = socket.SendTo(sendData, 0, sendData.Length, ntpEndPoint, ref errorCode);
81 | if (errorCode != 0 || sendCount != sendData.Length)
82 | {
83 | onRequestComplete(null);
84 | }
85 | }
86 |
87 | ///
88 | /// Get all local ip addresses
89 | ///
90 | /// type of address (IPv4, IPv6 or both)
91 | /// List with all local ip adresses
92 | public static List GetLocalIpList(LocalAddrType addrType)
93 | {
94 | List targetList = new List();
95 | GetLocalIpList(targetList, addrType);
96 | return targetList;
97 | }
98 |
99 | ///
100 | /// Get all local ip addresses (non alloc version)
101 | ///
102 | /// result list
103 | /// type of address (IPv4, IPv6 or both)
104 | public static void GetLocalIpList(List targetList, LocalAddrType addrType)
105 | {
106 | bool ipv4 = (addrType & LocalAddrType.IPv4) == LocalAddrType.IPv4;
107 | bool ipv6 = (addrType & LocalAddrType.IPv6) == LocalAddrType.IPv6;
108 | #if WINRT && !UNITY_EDITOR
109 | foreach (HostName localHostName in NetworkInformation.GetHostNames())
110 | {
111 | if (localHostName.IPInformation != null &&
112 | ((ipv4 && localHostName.Type == HostNameType.Ipv4) ||
113 | (ipv6 && localHostName.Type == HostNameType.Ipv6)))
114 | {
115 | targetList.Add(localHostName.ToString());
116 | }
117 | }
118 | #else
119 | try
120 | {
121 | foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
122 | {
123 | //Skip loopback and disabled network interfaces
124 | if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback ||
125 | ni.OperationalStatus != OperationalStatus.Up)
126 | continue;
127 |
128 | var ipProps = ni.GetIPProperties();
129 |
130 | //Skip address without gateway
131 | if (ipProps.GatewayAddresses.Count == 0)
132 | continue;
133 |
134 | foreach (UnicastIPAddressInformation ip in ipProps.UnicastAddresses)
135 | {
136 | var address = ip.Address;
137 | if ((ipv4 && address.AddressFamily == AddressFamily.InterNetwork) ||
138 | (ipv6 && address.AddressFamily == AddressFamily.InterNetworkV6))
139 | targetList.Add(address.ToString());
140 | }
141 | }
142 | }
143 | catch
144 | {
145 | //ignored
146 | }
147 |
148 | //Fallback mode (unity android)
149 | if (targetList.Count == 0)
150 | {
151 | #if NETCORE
152 | var hostTask = Dns.GetHostEntryAsync(Dns.GetHostName());
153 | hostTask.Wait();
154 | var host = hostTask.Result;
155 | #else
156 | var host = Dns.GetHostEntry(Dns.GetHostName());
157 | #endif
158 | foreach (IPAddress ip in host.AddressList)
159 | {
160 | if((ipv4 && ip.AddressFamily == AddressFamily.InterNetwork) ||
161 | (ipv6 && ip.AddressFamily == AddressFamily.InterNetworkV6))
162 | targetList.Add(ip.ToString());
163 | }
164 | }
165 | #endif
166 | if (targetList.Count == 0)
167 | {
168 | if(ipv4)
169 | targetList.Add("127.0.0.1");
170 | if(ipv6)
171 | targetList.Add("::1");
172 | }
173 | }
174 |
175 | private static readonly List IpList = new List();
176 | ///
177 | /// Get first detected local ip address
178 | ///
179 | /// type of address (IPv4, IPv6 or both)
180 | /// IP address if available. Else - string.Empty
181 | public static string GetLocalIp(LocalAddrType addrType)
182 | {
183 | lock (IpList)
184 | {
185 | IpList.Clear();
186 | GetLocalIpList(IpList, addrType);
187 | return IpList.Count == 0 ? string.Empty : IpList[0];
188 | }
189 | }
190 |
191 | // ===========================================
192 | // Internal and debug log related stuff
193 | // ===========================================
194 | internal static void PrintInterfaceInfos()
195 | {
196 | #if !WINRT || UNITY_EDITOR
197 | DebugWriteForce(ConsoleColor.Green, "IPv6Support: {0}", NetSocket.IPv6Support);
198 | try
199 | {
200 | foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
201 | {
202 | foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
203 | {
204 | if (ip.Address.AddressFamily == AddressFamily.InterNetwork ||
205 | ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
206 | {
207 | DebugWriteForce(
208 | ConsoleColor.Green,
209 | "Interface: {0}, Type: {1}, Ip: {2}, OpStatus: {3}",
210 | ni.Name,
211 | ni.NetworkInterfaceType.ToString(),
212 | ip.Address.ToString(),
213 | ni.OperationalStatus.ToString());
214 | }
215 | }
216 | }
217 | }
218 | catch (Exception e)
219 | {
220 | DebugWriteForce(ConsoleColor.Red, "Error while getting interface infos: {0}", e.ToString());
221 | }
222 | #endif
223 | }
224 |
225 | internal static int RelativeSequenceNumber(int number, int expected)
226 | {
227 | return (number - expected + NetConstants.MaxSequence + NetConstants.HalfMaxSequence) % NetConstants.MaxSequence - NetConstants.HalfMaxSequence;
228 | }
229 |
230 | private static readonly object DebugLogLock = new object();
231 | private static void DebugWriteLogic(ConsoleColor color, string str, params object[] args)
232 | {
233 | lock (DebugLogLock)
234 | {
235 |
236 | if (NetDebug.Logger == null)
237 | {
238 | #if UNITY
239 | UnityEngine.Debug.Log(string.Format(str, args));
240 | #elif WINRT
241 | Debug.WriteLine(str, args);
242 | #else
243 | //Console.ForegroundColor = color;
244 | Console.WriteLine(str, args);
245 | //Console.ForegroundColor = ConsoleColor.Gray;
246 | #endif
247 | }
248 | else
249 | {
250 | NetDebug.Logger.WriteNet(color, str, args);
251 | }
252 | }
253 | }
254 |
255 | [Conditional("DEBUG_MESSAGES")]
256 | internal static void DebugWrite(string str, params object[] args)
257 | {
258 | DebugWriteLogic(ConsoleColor.DarkGreen, str, args);
259 | }
260 |
261 | [Conditional("DEBUG_MESSAGES")]
262 | internal static void DebugWrite(ConsoleColor color, string str, params object[] args)
263 | {
264 | DebugWriteLogic(color, str, args);
265 | }
266 |
267 | [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")]
268 | internal static void DebugWriteForce(ConsoleColor color, string str, params object[] args)
269 | {
270 | DebugWriteLogic(color, str, args);
271 | }
272 |
273 | [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")]
274 | internal static void DebugWriteError(string str, params object[] args)
275 | {
276 | DebugWriteLogic(ConsoleColor.Red, str, args);
277 | }
278 | }
279 | }
280 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/ReliableChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 |
5 | namespace LiteNetLib
6 | {
7 | internal sealed class ReliableChannel
8 | {
9 | private sealed class PendingPacket
10 | {
11 | public NetPacket Packet;
12 | public DateTime? TimeStamp;
13 | public PendingPacket Next;
14 | public PendingPacket Prev;
15 |
16 | public void Clear()
17 | {
18 | if (Prev != null)
19 | {
20 | Prev.Next = Next;
21 | }
22 | if (Next != null)
23 | {
24 | Next.Prev = Prev;
25 | }
26 | Prev = null;
27 | Next = null;
28 | Packet = null;
29 | TimeStamp = null;
30 | }
31 | }
32 |
33 | private readonly Queue _outgoingPackets;
34 | private readonly bool[] _outgoingAcks; //for send acks
35 | private readonly PendingPacket[] _pendingPackets; //for unacked packets and duplicates
36 | private readonly NetPacket[] _receivedPackets; //for order
37 | private readonly bool[] _earlyReceived; //for unordered
38 | private PendingPacket _headPendingPacket;
39 |
40 | private int _localSeqence;
41 | private int _remoteSequence;
42 | private int _localWindowStart;
43 | private int _remoteWindowStart;
44 |
45 | private readonly NetPeer _peer;
46 | private bool _mustSendAcks;
47 |
48 | private readonly bool _ordered;
49 | private readonly int _windowSize;
50 | private const int BitsInByte = 8;
51 |
52 | public int PacketsInQueue
53 | {
54 | get { return _outgoingPackets.Count; }
55 | }
56 |
57 | public ReliableChannel(NetPeer peer, bool ordered)
58 | {
59 | _windowSize = NetConstants.DefaultWindowSize;
60 | _peer = peer;
61 | _ordered = ordered;
62 |
63 | _outgoingPackets = new Queue(_windowSize);
64 |
65 | _outgoingAcks = new bool[_windowSize];
66 | _pendingPackets = new PendingPacket[_windowSize];
67 | for (int i = 0; i < _pendingPackets.Length; i++)
68 | {
69 | _pendingPackets[i] = new PendingPacket();
70 | }
71 |
72 | if (_ordered)
73 | _receivedPackets = new NetPacket[_windowSize];
74 | else
75 | _earlyReceived = new bool[_windowSize];
76 |
77 | _localWindowStart = 0;
78 | _localSeqence = 0;
79 | _remoteSequence = 0;
80 | _remoteWindowStart = 0;
81 | }
82 |
83 | //ProcessAck in packet
84 | public void ProcessAck(NetPacket packet)
85 | {
86 | int validPacketSize = (_windowSize - 1) / BitsInByte + 1 + NetConstants.SequencedHeaderSize;
87 | if (packet.Size != validPacketSize)
88 | {
89 | NetUtils.DebugWrite("[PA]Invalid acks packet size");
90 | return;
91 | }
92 |
93 | ushort ackWindowStart = packet.Sequence;
94 | if (ackWindowStart > NetConstants.MaxSequence)
95 | {
96 | NetUtils.DebugWrite("[PA]Bad window start");
97 | return;
98 | }
99 |
100 | //check relevance
101 | if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
102 | {
103 | NetUtils.DebugWrite("[PA]Old acks");
104 | return;
105 | }
106 |
107 | byte[] acksData = packet.RawData;
108 | NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
109 | int startByte = NetConstants.SequencedHeaderSize;
110 |
111 | Monitor.Enter(_pendingPackets);
112 | for (int i = 0; i < _windowSize; i++)
113 | {
114 | int ackSequence = (ackWindowStart + i) % NetConstants.MaxSequence;
115 | if (NetUtils.RelativeSequenceNumber(ackSequence, _localWindowStart) < 0)
116 | {
117 | //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP OLD: " + ackSequence);
118 | //Skip old ack
119 | continue;
120 | }
121 |
122 | int currentByte = startByte + i / BitsInByte;
123 | int currentBit = i % BitsInByte;
124 |
125 | if ((acksData[currentByte] & (1 << currentBit)) == 0)
126 | {
127 | #if STATS_ENABLED || DEBUG
128 | if(_pendingPackets[ackSequence % _windowSize].TimeStamp.HasValue)
129 | _peer.Statistics.PacketLoss++;
130 | #endif
131 | //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP FALSE: " + ackSequence);
132 | //Skip false ack
133 | continue;
134 | }
135 |
136 | if (ackSequence == _localWindowStart)
137 | {
138 | //Move window
139 | _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence;
140 | }
141 |
142 | PendingPacket pendingPacket = _pendingPackets[ackSequence % _windowSize];
143 | if (pendingPacket.Packet != null)
144 | {
145 | if (pendingPacket == _headPendingPacket)
146 | {
147 | _headPendingPacket = _headPendingPacket.Prev;
148 | }
149 | _peer.Recycle(pendingPacket.Packet);
150 | pendingPacket.Clear();
151 | NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", ackSequence);
152 | }
153 | else
154 | {
155 | NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - false", ackSequence);
156 | }
157 | }
158 | Monitor.Exit(_pendingPackets);
159 | }
160 |
161 | public void AddToQueue(NetPacket packet)
162 | {
163 | Monitor.Enter(_outgoingPackets);
164 | _outgoingPackets.Enqueue(packet);
165 | Monitor.Exit(_outgoingPackets);
166 | }
167 |
168 | public void SendNextPackets()
169 | {
170 | //check sending acks
171 | DateTime currentTime = DateTime.UtcNow;
172 | Monitor.Enter(_pendingPackets);
173 | //get packets from queue
174 | Monitor.Enter(_outgoingPackets);
175 | while (_outgoingPackets.Count > 0)
176 | {
177 | int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart);
178 | if (relate < _windowSize)
179 | {
180 | PendingPacket pendingPacket = _pendingPackets[_localSeqence % _windowSize];
181 | pendingPacket.Packet = _outgoingPackets.Dequeue();
182 | pendingPacket.Packet.Sequence = (ushort) _localSeqence;
183 | if (_headPendingPacket != null)
184 | {
185 | _headPendingPacket.Next = pendingPacket;
186 | pendingPacket.Prev = _headPendingPacket;
187 | }
188 | _headPendingPacket = pendingPacket;
189 | _localSeqence = (_localSeqence + 1) % NetConstants.MaxSequence;
190 | }
191 | else //Queue filled
192 | {
193 | break;
194 | }
195 | }
196 | Monitor.Exit(_outgoingPackets);
197 |
198 | //if no pending packets return
199 | if (_headPendingPacket == null)
200 | {
201 | Monitor.Exit(_pendingPackets);
202 | return;
203 | }
204 | //send
205 | PendingPacket currentPacket = _headPendingPacket;
206 | do
207 | {
208 | if (currentPacket.TimeStamp.HasValue) //check send time
209 | {
210 | double packetHoldTime = (currentTime - currentPacket.TimeStamp.Value).TotalMilliseconds;
211 | if (packetHoldTime < _peer.ResendDelay)
212 | {
213 | continue;
214 | }
215 | NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, _peer.ResendDelay);
216 | }
217 |
218 | currentPacket.TimeStamp = currentTime;
219 | _peer.SendRawData(currentPacket.Packet);
220 | } while ((currentPacket = currentPacket.Prev) != null);
221 | Monitor.Exit(_pendingPackets);
222 | }
223 |
224 | public void SendAcks()
225 | {
226 | if (!_mustSendAcks)
227 | return;
228 | _mustSendAcks = false;
229 |
230 | NetUtils.DebugWrite("[RR]SendAcks");
231 |
232 | //Init packet
233 | int bytesCount = (_windowSize - 1) / BitsInByte + 1;
234 | PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable;
235 | var acksPacket = _peer.GetPacketFromPool(property, bytesCount);
236 |
237 | //For quick access
238 | byte[] data = acksPacket.RawData; //window start + acks size
239 |
240 | //Put window start
241 | Monitor.Enter(_outgoingAcks);
242 | acksPacket.Sequence = (ushort)_remoteWindowStart;
243 |
244 | //Put acks
245 | int startAckIndex = _remoteWindowStart % _windowSize;
246 | int currentAckIndex = startAckIndex;
247 | int currentBit = 0;
248 | int currentByte = NetConstants.SequencedHeaderSize;
249 | do
250 | {
251 | if (_outgoingAcks[currentAckIndex])
252 | {
253 | data[currentByte] |= (byte)(1 << currentBit);
254 | }
255 |
256 | currentBit++;
257 | if (currentBit == BitsInByte)
258 | {
259 | currentByte++;
260 | currentBit = 0;
261 | }
262 | currentAckIndex = (currentAckIndex + 1) % _windowSize;
263 | } while (currentAckIndex != startAckIndex);
264 | Monitor.Exit(_outgoingAcks);
265 |
266 | _peer.SendRawData(acksPacket);
267 | _peer.Recycle(acksPacket);
268 | }
269 |
270 | //Process incoming packet
271 | public void ProcessPacket(NetPacket packet)
272 | {
273 | if (packet.Sequence >= NetConstants.MaxSequence)
274 | {
275 | NetUtils.DebugWrite("[RR]Bad sequence");
276 | return;
277 | }
278 |
279 | int relate = NetUtils.RelativeSequenceNumber(packet.Sequence, _remoteWindowStart);
280 | int relateSeq = NetUtils.RelativeSequenceNumber(packet.Sequence, _remoteSequence);
281 |
282 | if (relateSeq > _windowSize)
283 | {
284 | NetUtils.DebugWrite("[RR]Bad sequence");
285 | return;
286 | }
287 |
288 | //Drop bad packets
289 | if(relate < 0)
290 | {
291 | //Too old packet doesn't ack
292 | NetUtils.DebugWrite("[RR]ReliableInOrder too old");
293 | return;
294 | }
295 | if (relate >= _windowSize * 2)
296 | {
297 | //Some very new packet
298 | NetUtils.DebugWrite("[RR]ReliableInOrder too new");
299 | return;
300 | }
301 |
302 | //If very new - move window
303 | Monitor.Enter(_outgoingAcks);
304 | if (relate >= _windowSize)
305 | {
306 | //New window position
307 | int newWindowStart = (_remoteWindowStart + relate - _windowSize + 1) % NetConstants.MaxSequence;
308 |
309 | //Clean old data
310 | while (_remoteWindowStart != newWindowStart)
311 | {
312 | _outgoingAcks[_remoteWindowStart % _windowSize] = false;
313 | _remoteWindowStart = (_remoteWindowStart + 1) % NetConstants.MaxSequence;
314 | }
315 | }
316 |
317 | //Final stage - process valid packet
318 | //trigger acks send
319 | _mustSendAcks = true;
320 |
321 | if (_outgoingAcks[packet.Sequence % _windowSize])
322 | {
323 | NetUtils.DebugWrite("[RR]ReliableInOrder duplicate");
324 | Monitor.Exit(_outgoingAcks);
325 | return;
326 | }
327 |
328 | //save ack
329 | _outgoingAcks[packet.Sequence % _windowSize] = true;
330 | Monitor.Exit(_outgoingAcks);
331 |
332 | //detailed check
333 | if (packet.Sequence == _remoteSequence)
334 | {
335 | NetUtils.DebugWrite("[RR]ReliableInOrder packet succes");
336 | _peer.AddIncomingPacket(packet);
337 | _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence;
338 |
339 | if (_ordered)
340 | {
341 | NetPacket p;
342 | while ( (p = _receivedPackets[_remoteSequence % _windowSize]) != null)
343 | {
344 | //process holded packet
345 | _receivedPackets[_remoteSequence % _windowSize] = null;
346 | _peer.AddIncomingPacket(p);
347 | _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence;
348 | }
349 | }
350 | else
351 | {
352 | while (_earlyReceived[_remoteSequence % _windowSize])
353 | {
354 | //process early packet
355 | _earlyReceived[_remoteSequence % _windowSize] = false;
356 | _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence;
357 | }
358 | }
359 |
360 | return;
361 | }
362 |
363 | //holded packet
364 | if (_ordered)
365 | {
366 | _receivedPackets[packet.Sequence % _windowSize] = packet;
367 | }
368 | else
369 | {
370 | _earlyReceived[packet.Sequence % _windowSize] = true;
371 | _peer.AddIncomingPacket(packet);
372 | }
373 | }
374 | }
375 | }
376 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/SequencedChannel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace LiteNetLib
4 | {
5 | internal sealed class SequencedChannel
6 | {
7 | private int _localSequence;
8 | private int _remoteSequence;
9 | private readonly Queue _outgoingPackets;
10 | private readonly NetPeer _peer;
11 |
12 | public SequencedChannel(NetPeer peer)
13 | {
14 | _outgoingPackets = new Queue();
15 | _peer = peer;
16 | }
17 |
18 | public void AddToQueue(NetPacket packet)
19 | {
20 | lock (_outgoingPackets)
21 | {
22 | _outgoingPackets.Enqueue(packet);
23 | }
24 | }
25 |
26 | public void SendNextPackets()
27 | {
28 | lock (_outgoingPackets)
29 | {
30 | while (_outgoingPackets.Count > 0)
31 | {
32 | NetPacket packet = _outgoingPackets.Dequeue();
33 | _localSequence = (_localSequence + 1) % NetConstants.MaxSequence;
34 | packet.Sequence = (ushort)_localSequence;
35 | _peer.SendRawData(packet);
36 | _peer.Recycle(packet);
37 | }
38 | }
39 | }
40 |
41 | public void ProcessPacket(NetPacket packet)
42 | {
43 | if (packet.Sequence < NetConstants.MaxSequence &&
44 | NetUtils.RelativeSequenceNumber(packet.Sequence, _remoteSequence) > 0)
45 | {
46 | _remoteSequence = packet.Sequence;
47 | _peer.AddIncomingPacket(packet);
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/SimpleChannel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace LiteNetLib
4 | {
5 | internal sealed class SimpleChannel
6 | {
7 | private readonly Queue _outgoingPackets;
8 | private readonly NetPeer _peer;
9 |
10 | public SimpleChannel(NetPeer peer)
11 | {
12 | _outgoingPackets = new Queue();
13 | _peer = peer;
14 | }
15 |
16 | public void AddToQueue(NetPacket packet)
17 | {
18 | lock (_outgoingPackets)
19 | {
20 | _outgoingPackets.Enqueue(packet);
21 | }
22 | }
23 |
24 | public bool SendNextPackets()
25 | {
26 | NetPacket packet;
27 | lock (_outgoingPackets)
28 | {
29 | while (_outgoingPackets.Count > 0)
30 | {
31 | packet = _outgoingPackets.Dequeue();
32 | _peer.SendRawData(packet);
33 | _peer.Recycle(packet);
34 | }
35 | }
36 | return true;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/Utils/FastBitConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace LiteNetLib.Utils
4 | {
5 | public static class FastBitConverter
6 | {
7 | [StructLayout(LayoutKind.Explicit)]
8 | private struct ConverterHelperDouble
9 | {
10 | [FieldOffset(0)]
11 | public ulong Along;
12 |
13 | [FieldOffset(0)]
14 | public double Adouble;
15 | }
16 |
17 | [StructLayout(LayoutKind.Explicit)]
18 | private struct ConverterHelperFloat
19 | {
20 | [FieldOffset(0)]
21 | public int Aint;
22 |
23 | [FieldOffset(0)]
24 | public float Afloat;
25 | }
26 |
27 | private static void WriteLittleEndian(byte[] buffer, int offset, ulong data)
28 | {
29 | #if BIGENDIAN
30 | buffer[offset + 7] = (byte)(data);
31 | buffer[offset + 6] = (byte)(data >> 8);
32 | buffer[offset + 5] = (byte)(data >> 16);
33 | buffer[offset + 4] = (byte)(data >> 24);
34 | buffer[offset + 3] = (byte)(data >> 32);
35 | buffer[offset + 2] = (byte)(data >> 40);
36 | buffer[offset + 1] = (byte)(data >> 48);
37 | buffer[offset ] = (byte)(data >> 56);
38 | #else
39 | buffer[offset] = (byte)(data);
40 | buffer[offset + 1] = (byte)(data >> 8);
41 | buffer[offset + 2] = (byte)(data >> 16);
42 | buffer[offset + 3] = (byte)(data >> 24);
43 | buffer[offset + 4] = (byte)(data >> 32);
44 | buffer[offset + 5] = (byte)(data >> 40);
45 | buffer[offset + 6] = (byte)(data >> 48);
46 | buffer[offset + 7] = (byte)(data >> 56);
47 | #endif
48 | }
49 |
50 | private static void WriteLittleEndian(byte[] buffer, int offset, int data)
51 | {
52 | #if BIGENDIAN
53 | buffer[offset + 3] = (byte)(data);
54 | buffer[offset + 2] = (byte)(data >> 8);
55 | buffer[offset + 1] = (byte)(data >> 16);
56 | buffer[offset ] = (byte)(data >> 24);
57 | #else
58 | buffer[offset] = (byte)(data);
59 | buffer[offset + 1] = (byte)(data >> 8);
60 | buffer[offset + 2] = (byte)(data >> 16);
61 | buffer[offset + 3] = (byte)(data >> 24);
62 | #endif
63 | }
64 |
65 | public static void WriteLittleEndian(byte[] buffer, int offset, short data)
66 | {
67 | #if BIGENDIAN
68 | buffer[offset + 1] = (byte)(data);
69 | buffer[offset ] = (byte)(data >> 8);
70 | #else
71 | buffer[offset] = (byte)(data);
72 | buffer[offset + 1] = (byte)(data >> 8);
73 | #endif
74 | }
75 |
76 | public static void GetBytes(byte[] bytes, int startIndex, double value)
77 | {
78 | ConverterHelperDouble ch = new ConverterHelperDouble { Adouble = value };
79 | WriteLittleEndian(bytes, startIndex, ch.Along);
80 | }
81 |
82 | public static void GetBytes(byte[] bytes, int startIndex, float value)
83 | {
84 | ConverterHelperFloat ch = new ConverterHelperFloat { Afloat = value };
85 | WriteLittleEndian(bytes, startIndex, ch.Aint);
86 | }
87 |
88 | public static void GetBytes(byte[] bytes, int startIndex, short value)
89 | {
90 | WriteLittleEndian(bytes, startIndex, value);
91 | }
92 |
93 | public static void GetBytes(byte[] bytes, int startIndex, ushort value)
94 | {
95 | WriteLittleEndian(bytes, startIndex, (short)value);
96 | }
97 |
98 | public static void GetBytes(byte[] bytes, int startIndex, int value)
99 | {
100 | WriteLittleEndian(bytes, startIndex, value);
101 | }
102 |
103 | public static void GetBytes(byte[] bytes, int startIndex, uint value)
104 | {
105 | WriteLittleEndian(bytes, startIndex, (int)value);
106 | }
107 |
108 | public static void GetBytes(byte[] bytes, int startIndex, long value)
109 | {
110 | WriteLittleEndian(bytes, startIndex, (ulong)value);
111 | }
112 |
113 | public static void GetBytes(byte[] bytes, int startIndex, ulong value)
114 | {
115 | WriteLittleEndian(bytes, startIndex, value);
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/Utils/NetDataReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace LiteNetLib.Utils
5 | {
6 | public class NetDataReader
7 | {
8 | protected byte[] _data;
9 | protected int _position;
10 | protected int _dataSize;
11 |
12 | public byte[] Data
13 | {
14 | get { return _data; }
15 | }
16 |
17 | public int Position
18 | {
19 | get { return _position; }
20 | }
21 |
22 | public bool EndOfData
23 | {
24 | get { return _position == _dataSize; }
25 | }
26 |
27 | public int AvailableBytes
28 | {
29 | get { return _dataSize - _position; }
30 | }
31 |
32 | public void SetSource(NetDataWriter dataWriter)
33 | {
34 | _data = dataWriter.Data;
35 | _position = 0;
36 | _dataSize = dataWriter.Length;
37 | }
38 |
39 | public void SetSource(byte[] source)
40 | {
41 | _data = source;
42 | _position = 0;
43 | _dataSize = source.Length;
44 | }
45 |
46 | public void SetSource(byte[] source, int offset)
47 | {
48 | _data = source;
49 | _position = offset;
50 | _dataSize = source.Length;
51 | }
52 |
53 | public void SetSource(byte[] source, int offset, int dataSize)
54 | {
55 | _data = source;
56 | _position = offset;
57 | _dataSize = dataSize;
58 | }
59 |
60 | ///
61 | /// Clone NetDataReader without data copy (usable for OnReceive)
62 | ///
63 | /// new NetDataReader instance
64 | public NetDataReader Clone()
65 | {
66 | return new NetDataReader(_data, _position, _dataSize);
67 | }
68 |
69 | public NetDataReader()
70 | {
71 |
72 | }
73 |
74 | public NetDataReader(byte[] source)
75 | {
76 | SetSource(source);
77 | }
78 |
79 | public NetDataReader(byte[] source, int offset)
80 | {
81 | SetSource(source, offset);
82 | }
83 |
84 | public NetDataReader(byte[] source, int offset, int maxSize)
85 | {
86 | SetSource(source, offset, maxSize);
87 | }
88 |
89 | #region GetMethods
90 | public NetEndPoint GetNetEndPoint()
91 | {
92 | string host = GetString(1000);
93 | int port = GetInt();
94 | return new NetEndPoint(host, port);
95 | }
96 |
97 | public byte GetByte()
98 | {
99 | byte res = _data[_position];
100 | _position += 1;
101 | return res;
102 | }
103 |
104 | public sbyte GetSByte()
105 | {
106 | var b = (sbyte)_data[_position];
107 | _position++;
108 | return b;
109 | }
110 |
111 | public bool[] GetBoolArray()
112 | {
113 | ushort size = BitConverter.ToUInt16(_data, _position);
114 | _position += 2;
115 | var arr = new bool[size];
116 | for (int i = 0; i < size; i++)
117 | {
118 | arr[i] = GetBool();
119 | }
120 | return arr;
121 | }
122 |
123 | public ushort[] GetUShortArray()
124 | {
125 | ushort size = BitConverter.ToUInt16(_data, _position);
126 | _position += 2;
127 | var arr = new ushort[size];
128 | for (int i = 0; i < size; i++)
129 | {
130 | arr[i] = GetUShort();
131 | }
132 | return arr;
133 | }
134 |
135 | public short[] GetShortArray()
136 | {
137 | ushort size = BitConverter.ToUInt16(_data, _position);
138 | _position += 2;
139 | var arr = new short[size];
140 | for (int i = 0; i < size; i++)
141 | {
142 | arr[i] = GetShort();
143 | }
144 | return arr;
145 | }
146 |
147 | public long[] GetLongArray()
148 | {
149 | ushort size = BitConverter.ToUInt16(_data, _position);
150 | _position += 2;
151 | var arr = new long[size];
152 | for (int i = 0; i < size; i++)
153 | {
154 | arr[i] = GetLong();
155 | }
156 | return arr;
157 | }
158 |
159 | public ulong[] GetULongArray()
160 | {
161 | ushort size = BitConverter.ToUInt16(_data, _position);
162 | _position += 2;
163 | var arr = new ulong[size];
164 | for (int i = 0; i < size; i++)
165 | {
166 | arr[i] = GetULong();
167 | }
168 | return arr;
169 | }
170 |
171 | public int[] GetIntArray()
172 | {
173 | ushort size = BitConverter.ToUInt16(_data, _position);
174 | _position += 2;
175 | var arr = new int[size];
176 | for (int i = 0; i < size; i++)
177 | {
178 | arr[i] = GetInt();
179 | }
180 | return arr;
181 | }
182 |
183 | public uint[] GetUIntArray()
184 | {
185 | ushort size = BitConverter.ToUInt16(_data, _position);
186 | _position += 2;
187 | var arr = new uint[size];
188 | for (int i = 0; i < size; i++)
189 | {
190 | arr[i] = GetUInt();
191 | }
192 | return arr;
193 | }
194 |
195 | public float[] GetFloatArray()
196 | {
197 | ushort size = BitConverter.ToUInt16(_data, _position);
198 | _position += 2;
199 | var arr = new float[size];
200 | for (int i = 0; i < size; i++)
201 | {
202 | arr[i] = GetFloat();
203 | }
204 | return arr;
205 | }
206 |
207 | public double[] GetDoubleArray()
208 | {
209 | ushort size = BitConverter.ToUInt16(_data, _position);
210 | _position += 2;
211 | var arr = new double[size];
212 | for (int i = 0; i < size; i++)
213 | {
214 | arr[i] = GetDouble();
215 | }
216 | return arr;
217 | }
218 |
219 | public string[] GetStringArray(int maxLength)
220 | {
221 | ushort size = BitConverter.ToUInt16(_data, _position);
222 | _position += 2;
223 | var arr = new string[size];
224 | for (int i = 0; i < size; i++)
225 | {
226 | arr[i] = GetString(maxLength);
227 | }
228 | return arr;
229 | }
230 |
231 | public bool GetBool()
232 | {
233 | bool res = _data[_position] > 0;
234 | _position += 1;
235 | return res;
236 | }
237 |
238 | public char GetChar()
239 | {
240 | char result = BitConverter.ToChar(_data, _position);
241 | _position += 2;
242 | return result;
243 | }
244 |
245 | public ushort GetUShort()
246 | {
247 | ushort result = BitConverter.ToUInt16(_data, _position);
248 | _position += 2;
249 | return result;
250 | }
251 |
252 | public short GetShort()
253 | {
254 | short result = BitConverter.ToInt16(_data, _position);
255 | _position += 2;
256 | return result;
257 | }
258 |
259 | public long GetLong()
260 | {
261 | long result = BitConverter.ToInt64(_data, _position);
262 | _position += 8;
263 | return result;
264 | }
265 |
266 | public ulong GetULong()
267 | {
268 | ulong result = BitConverter.ToUInt64(_data, _position);
269 | _position += 8;
270 | return result;
271 | }
272 |
273 | public int GetInt()
274 | {
275 | int result = BitConverter.ToInt32(_data, _position);
276 | _position += 4;
277 | return result;
278 | }
279 |
280 | public uint GetUInt()
281 | {
282 | uint result = BitConverter.ToUInt32(_data, _position);
283 | _position += 4;
284 | return result;
285 | }
286 |
287 | public float GetFloat()
288 | {
289 | float result = BitConverter.ToSingle(_data, _position);
290 | _position += 4;
291 | return result;
292 | }
293 |
294 | public double GetDouble()
295 | {
296 | double result = BitConverter.ToDouble(_data, _position);
297 | _position += 8;
298 | return result;
299 | }
300 |
301 | public string GetString(int maxLength)
302 | {
303 | int bytesCount = GetInt();
304 | if (bytesCount <= 0 || bytesCount > maxLength*2)
305 | {
306 | return string.Empty;
307 | }
308 |
309 | int charCount = Encoding.UTF8.GetCharCount(_data, _position, bytesCount);
310 | if (charCount > maxLength)
311 | {
312 | return string.Empty;
313 | }
314 |
315 | string result = Encoding.UTF8.GetString(_data, _position, bytesCount);
316 | _position += bytesCount;
317 | return result;
318 | }
319 |
320 | public string GetString()
321 | {
322 | int bytesCount = GetInt();
323 | if (bytesCount <= 0)
324 | {
325 | return string.Empty;
326 | }
327 |
328 | string result = Encoding.UTF8.GetString(_data, _position, bytesCount);
329 | _position += bytesCount;
330 | return result;
331 | }
332 |
333 | public byte[] GetRemainingBytes()
334 | {
335 | byte[] outgoingData = new byte[AvailableBytes];
336 | Buffer.BlockCopy(_data, _position, outgoingData, 0, AvailableBytes);
337 | _position = _data.Length;
338 | return outgoingData;
339 | }
340 |
341 | public void GetRemainingBytes(byte[] destination)
342 | {
343 | Buffer.BlockCopy(_data, _position, destination, 0, AvailableBytes);
344 | _position = _data.Length;
345 | }
346 |
347 | public void GetBytes(byte[] destination, int lenght)
348 | {
349 | Buffer.BlockCopy(_data, _position, destination, 0, lenght);
350 | _position += lenght;
351 | }
352 |
353 | public byte[] GetBytesWithLength()
354 | {
355 | int length = GetInt();
356 | byte[] outgoingData = new byte[length];
357 | Buffer.BlockCopy(_data, _position, outgoingData, 0, length);
358 | _position += length;
359 | return outgoingData;
360 | }
361 | #endregion
362 |
363 | #region PeekMethods
364 |
365 | public byte PeekByte()
366 | {
367 | return _data[_position];
368 | }
369 |
370 | public sbyte PeekSByte()
371 | {
372 | return (sbyte)_data[_position];
373 | }
374 |
375 | public bool PeekBool()
376 | {
377 | return _data[_position] > 0;
378 | }
379 |
380 | public char PeekChar()
381 | {
382 | return BitConverter.ToChar(_data, _position);
383 | }
384 |
385 | public ushort PeekUShort()
386 | {
387 | return BitConverter.ToUInt16(_data, _position);
388 | }
389 |
390 | public short PeekShort()
391 | {
392 | return BitConverter.ToInt16(_data, _position);
393 | }
394 |
395 | public long PeekLong()
396 | {
397 | return BitConverter.ToInt64(_data, _position);
398 | }
399 |
400 | public ulong PeekULong()
401 | {
402 | return BitConverter.ToUInt64(_data, _position);
403 | }
404 |
405 | public int PeekInt()
406 | {
407 | return BitConverter.ToInt32(_data, _position);
408 | }
409 |
410 | public uint PeekUInt()
411 | {
412 | return BitConverter.ToUInt32(_data, _position);
413 | }
414 |
415 | public float PeekFloat()
416 | {
417 | return BitConverter.ToSingle(_data, _position);
418 | }
419 |
420 | public double PeekDouble()
421 | {
422 | return BitConverter.ToDouble(_data, _position);
423 | }
424 |
425 | public string PeekString(int maxLength)
426 | {
427 | int bytesCount = BitConverter.ToInt32(_data, _position);
428 | if (bytesCount <= 0 || bytesCount > maxLength * 2)
429 | {
430 | return string.Empty;
431 | }
432 |
433 | int charCount = Encoding.UTF8.GetCharCount(_data, _position + 4, bytesCount);
434 | if (charCount > maxLength)
435 | {
436 | return string.Empty;
437 | }
438 |
439 | string result = Encoding.UTF8.GetString(_data, _position + 4, bytesCount);
440 | return result;
441 | }
442 |
443 | public string PeekString()
444 | {
445 | int bytesCount = BitConverter.ToInt32(_data, _position);
446 | if (bytesCount <= 0)
447 | {
448 | return string.Empty;
449 | }
450 |
451 | string result = Encoding.UTF8.GetString(_data, _position + 4, bytesCount);
452 | return result;
453 | }
454 | #endregion
455 |
456 | public void Clear()
457 | {
458 | _position = 0;
459 | _dataSize = 0;
460 | _data = null;
461 | }
462 | }
463 | }
464 |
465 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/LiteNetLib/Utils/NetDataWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace LiteNetLib.Utils
5 | {
6 | public class NetDataWriter
7 | {
8 | protected byte[] _data;
9 | protected int _position;
10 |
11 | private int _maxLength;
12 | private readonly bool _autoResize;
13 |
14 | public NetDataWriter()
15 | {
16 | _maxLength = 64;
17 | _data = new byte[_maxLength];
18 | _autoResize = true;
19 | }
20 |
21 | public NetDataWriter(bool autoResize)
22 | {
23 | _maxLength = 64;
24 | _data = new byte[_maxLength];
25 | _autoResize = autoResize;
26 | }
27 |
28 | public NetDataWriter(bool autoResize, int initialSize)
29 | {
30 | _maxLength = initialSize;
31 | _data = new byte[_maxLength];
32 | _autoResize = autoResize;
33 | }
34 |
35 | public void ResizeIfNeed(int newSize)
36 | {
37 | if (_maxLength < newSize)
38 | {
39 | while (_maxLength < newSize)
40 | {
41 | _maxLength *= 2;
42 | }
43 | Array.Resize(ref _data, _maxLength);
44 | }
45 | }
46 |
47 | public void Reset(int size)
48 | {
49 | ResizeIfNeed(size);
50 | _position = 0;
51 | }
52 |
53 | public void Reset()
54 | {
55 | _position = 0;
56 | }
57 |
58 | public byte[] CopyData()
59 | {
60 | byte[] resultData = new byte[_position];
61 | Buffer.BlockCopy(_data, 0, resultData, 0, _position);
62 | return resultData;
63 | }
64 |
65 | public byte[] Data
66 | {
67 | get { return _data; }
68 | }
69 |
70 | public int Length
71 | {
72 | get { return _position; }
73 | }
74 |
75 | public void Put(float value)
76 | {
77 | if (_autoResize)
78 | ResizeIfNeed(_position + 4);
79 | FastBitConverter.GetBytes(_data, _position, value);
80 | _position += 4;
81 | }
82 |
83 | public void Put(double value)
84 | {
85 | if (_autoResize)
86 | ResizeIfNeed(_position + 8);
87 | FastBitConverter.GetBytes(_data, _position, value);
88 | _position += 8;
89 | }
90 |
91 | public void Put(long value)
92 | {
93 | if (_autoResize)
94 | ResizeIfNeed(_position + 8);
95 | FastBitConverter.GetBytes(_data, _position, value);
96 | _position += 8;
97 | }
98 |
99 | public void Put(ulong value)
100 | {
101 | if (_autoResize)
102 | ResizeIfNeed(_position + 8);
103 | FastBitConverter.GetBytes(_data, _position, value);
104 | _position += 8;
105 | }
106 |
107 | public void Put(int value)
108 | {
109 | if (_autoResize)
110 | ResizeIfNeed(_position + 4);
111 | FastBitConverter.GetBytes(_data, _position, value);
112 | _position += 4;
113 | }
114 |
115 | public void Put(uint value)
116 | {
117 | if (_autoResize)
118 | ResizeIfNeed(_position + 4);
119 | FastBitConverter.GetBytes(_data, _position, value);
120 | _position += 4;
121 | }
122 |
123 | public void Put(char value)
124 | {
125 | if (_autoResize)
126 | ResizeIfNeed(_position + 2);
127 | FastBitConverter.GetBytes(_data, _position, value);
128 | _position += 2;
129 | }
130 |
131 | public void Put(ushort value)
132 | {
133 | if (_autoResize)
134 | ResizeIfNeed(_position + 2);
135 | FastBitConverter.GetBytes(_data, _position, value);
136 | _position += 2;
137 | }
138 |
139 | public void Put(short value)
140 | {
141 | if (_autoResize)
142 | ResizeIfNeed(_position + 2);
143 | FastBitConverter.GetBytes(_data, _position, value);
144 | _position += 2;
145 | }
146 |
147 | public void Put(sbyte value)
148 | {
149 | if (_autoResize)
150 | ResizeIfNeed(_position + 1);
151 | _data[_position] = (byte)value;
152 | _position++;
153 | }
154 |
155 | public void Put(byte value)
156 | {
157 | if (_autoResize)
158 | ResizeIfNeed(_position + 1);
159 | _data[_position] = value;
160 | _position++;
161 | }
162 |
163 | public void Put(byte[] data, int offset, int length)
164 | {
165 | if (_autoResize)
166 | ResizeIfNeed(_position + length);
167 | Buffer.BlockCopy(data, offset, _data, _position, length);
168 | _position += length;
169 | }
170 |
171 | public void Put(byte[] data)
172 | {
173 | if (_autoResize)
174 | ResizeIfNeed(_position + data.Length);
175 | Buffer.BlockCopy(data, 0, _data, _position, data.Length);
176 | _position += data.Length;
177 | }
178 |
179 | public void PutBytesWithLength(byte[] data, int offset, int length)
180 | {
181 | if (_autoResize)
182 | ResizeIfNeed(_position + length + 4);
183 | FastBitConverter.GetBytes(_data, _position, length);
184 | Buffer.BlockCopy(data, offset, _data, _position + 4, length);
185 | _position += length + 4;
186 | }
187 |
188 | public void PutBytesWithLength(byte[] data)
189 | {
190 | if (_autoResize)
191 | ResizeIfNeed(_position + data.Length + 4);
192 | FastBitConverter.GetBytes(_data, _position, data.Length);
193 | Buffer.BlockCopy(data, 0, _data, _position + 4, data.Length);
194 | _position += data.Length + 4;
195 | }
196 |
197 | public void Put(bool value)
198 | {
199 | if (_autoResize)
200 | ResizeIfNeed(_position + 1);
201 | _data[_position] = (byte)(value ? 1 : 0);
202 | _position++;
203 | }
204 |
205 | public void PutArray(float[] value)
206 | {
207 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
208 | if (_autoResize)
209 | ResizeIfNeed(_position + len * 4 + 2);
210 | Put(len);
211 | for (int i = 0; i < len; i++)
212 | {
213 | Put(value[i]);
214 | }
215 | }
216 |
217 | public void PutArray(double[] value)
218 | {
219 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
220 | if (_autoResize)
221 | ResizeIfNeed(_position + len * 8 + 2);
222 | Put(len);
223 | for (int i = 0; i < len; i++)
224 | {
225 | Put(value[i]);
226 | }
227 | }
228 |
229 | public void PutArray(long[] value)
230 | {
231 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
232 | if (_autoResize)
233 | ResizeIfNeed(_position + len * 8 + 2);
234 | Put(len);
235 | for (int i = 0; i < len; i++)
236 | {
237 | Put(value[i]);
238 | }
239 | }
240 |
241 | public void PutArray(ulong[] value)
242 | {
243 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
244 | if (_autoResize)
245 | ResizeIfNeed(_position + len * 8 + 2);
246 | Put(len);
247 | for (int i = 0; i < len; i++)
248 | {
249 | Put(value[i]);
250 | }
251 | }
252 |
253 | public void PutArray(int[] value)
254 | {
255 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
256 | if (_autoResize)
257 | ResizeIfNeed(_position + len * 4 + 2);
258 | Put(len);
259 | for (int i = 0; i < len; i++)
260 | {
261 | Put(value[i]);
262 | }
263 | }
264 |
265 | public void PutArray(uint[] value)
266 | {
267 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
268 | if (_autoResize)
269 | ResizeIfNeed(_position + len * 4 + 2);
270 | Put(len);
271 | for (int i = 0; i < len; i++)
272 | {
273 | Put(value[i]);
274 | }
275 | }
276 |
277 | public void PutArray(ushort[] value)
278 | {
279 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
280 | if (_autoResize)
281 | ResizeIfNeed(_position + len * 2 + 2);
282 | Put(len);
283 | for (int i = 0; i < len; i++)
284 | {
285 | Put(value[i]);
286 | }
287 | }
288 |
289 | public void PutArray(short[] value)
290 | {
291 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
292 | if (_autoResize)
293 | ResizeIfNeed(_position + len * 2 + 2);
294 | Put(len);
295 | for (int i = 0; i < len; i++)
296 | {
297 | Put(value[i]);
298 | }
299 | }
300 |
301 | public void PutArray(bool[] value)
302 | {
303 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
304 | if (_autoResize)
305 | ResizeIfNeed(_position + len + 2);
306 | Put(len);
307 | for (int i = 0; i < len; i++)
308 | {
309 | Put(value[i]);
310 | }
311 | }
312 |
313 | public void PutArray(string[] value)
314 | {
315 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
316 | Put(len);
317 | for (int i = 0; i < len; i++)
318 | {
319 | Put(value[i]);
320 | }
321 | }
322 |
323 | public void PutArray(string[] value, int maxLength)
324 | {
325 | ushort len = value == null ? (ushort)0 : (ushort)value.Length;
326 | Put(len);
327 | for (int i = 0; i < len; i++)
328 | {
329 | Put(value[i], maxLength);
330 | }
331 | }
332 |
333 | public void Put(NetEndPoint endPoint)
334 | {
335 | Put(endPoint.Host);
336 | Put(endPoint.Port);
337 | }
338 |
339 | public void Put(string value)
340 | {
341 | if (string.IsNullOrEmpty(value))
342 | {
343 | Put(0);
344 | return;
345 | }
346 |
347 | //put bytes count
348 | int bytesCount = Encoding.UTF8.GetByteCount(value);
349 | if (_autoResize)
350 | ResizeIfNeed(_position + bytesCount + 4);
351 | Put(bytesCount);
352 |
353 | //put string
354 | Encoding.UTF8.GetBytes(value, 0, value.Length, _data, _position);
355 | _position += bytesCount;
356 | }
357 |
358 | public void Put(string value, int maxLength)
359 | {
360 | if (string.IsNullOrEmpty(value))
361 | {
362 | Put(0);
363 | return;
364 | }
365 |
366 | int length = value.Length > maxLength ? maxLength : value.Length;
367 | //calculate max count
368 | int bytesCount = Encoding.UTF8.GetByteCount(value);
369 | if (_autoResize)
370 | ResizeIfNeed(_position + bytesCount + 4);
371 |
372 | //put bytes count
373 | Put(bytesCount);
374 |
375 | //put string
376 | Encoding.UTF8.GetBytes(value, 0, length, _data, _position);
377 |
378 | _position += bytesCount;
379 | }
380 | }
381 | }
382 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/NetPlayer.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Assets.Scripts
4 | {
5 | public class NetPlayer
6 | {
7 | public float X { get; set; }
8 | public float Y { get; set; }
9 | public float Z { get; set; }
10 |
11 | public GameObject GameObject { get; set; }
12 | public bool GameObjectAdded { get; set; }
13 |
14 | public NetPlayer()
15 | {
16 | GameObjectAdded = false;
17 | }
18 |
19 | public Vector3 Position => new Vector3(X, Y, Z);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/Network.cs:
--------------------------------------------------------------------------------
1 | using Assets.Scripts;
2 | using LiteNetLib;
3 | using LiteNetLib.Utils;
4 | using Shared.Enums;
5 | using System.Collections.Generic;
6 | using UnityEngine;
7 |
8 | public class Network : MonoBehaviour, INetEventListener {
9 |
10 | public Player player;
11 | private Vector3 lastNetworkedPosition = Vector3.zero;
12 |
13 | private float lastDistance = 0.0f;
14 | const float MIN_DISTANCE_TO_SEND_POSITION = 0.01f;
15 |
16 | private NetDataWriter dataWriter;
17 | private NetManager clientNetManager;
18 | private NetPeer serverPeer;
19 |
20 | public GameObject netPlayerPrefab;
21 | private Dictionary netPlayersDictionary;
22 |
23 | // Use this for initialization
24 | void Start()
25 | {
26 | netPlayersDictionary = new Dictionary();
27 | dataWriter = new NetDataWriter();
28 | clientNetManager = new NetManager(this, "game");
29 |
30 | if (clientNetManager.Start())
31 | {
32 | clientNetManager.Connect("localhost", 15000);
33 | Debug.Log("Client net manager started!");
34 | }
35 | else
36 | Debug.LogError("Could not start client net manager!");
37 |
38 | }
39 |
40 | private void FixedUpdate()
41 | {
42 | if (clientNetManager != null)
43 | if (clientNetManager.IsRunning)
44 | {
45 | clientNetManager.PollEvents();
46 |
47 | lastDistance = Vector3.Distance(lastNetworkedPosition, player.transform.position);
48 | if(lastDistance >= MIN_DISTANCE_TO_SEND_POSITION)
49 | {
50 | dataWriter.Reset();
51 |
52 | dataWriter.Put((int)NetworkTags.PlayerPosition);
53 | dataWriter.Put(player.transform.position.x);
54 | dataWriter.Put(player.transform.position.y);
55 | dataWriter.Put(player.transform.position.z);
56 |
57 | serverPeer.Send(dataWriter, SendOptions.Sequenced);
58 |
59 | lastNetworkedPosition = player.transform.position;
60 | }
61 | }
62 |
63 | foreach (var player in netPlayersDictionary)
64 | {
65 | if (!player.Value.GameObjectAdded)
66 | {
67 | player.Value.GameObjectAdded = true;
68 | player.Value.GameObject = Instantiate(netPlayerPrefab, player.Value.Position, Quaternion.identity);
69 | }
70 | else
71 | player.Value.GameObject.transform.position = player.Value.Position;
72 | }
73 | }
74 |
75 | private void OnApplicationQuit()
76 | {
77 | if (clientNetManager != null)
78 | if (clientNetManager.IsRunning)
79 | clientNetManager.Stop();
80 | }
81 |
82 | public void OnNetworkLatencyUpdate(NetPeer peer, int latency) { }
83 |
84 | public void OnNetworkReceive(NetPeer peer, NetDataReader reader)
85 | {
86 | if (reader.Data == null)
87 | return;
88 |
89 | Debug.Log($"OnNetworkReceive: {reader.Data.Length}");
90 |
91 | if (reader.Data.Length >= 4)
92 | {
93 | NetworkTags networkTag = (NetworkTags)reader.GetInt();
94 | if (networkTag == NetworkTags.PlayerPositionsArray)
95 | {
96 | int lengthArr = (reader.Data.Length - 4) / (sizeof(long) + sizeof(float) * 3);
97 |
98 | Debug.Log("Got positions array data num : " + lengthArr);
99 |
100 | for (int i = 0; i < lengthArr; i++)
101 | {
102 | long playerid = reader.GetLong();
103 |
104 | if (!netPlayersDictionary.ContainsKey(playerid))
105 | netPlayersDictionary.Add(playerid, new NetPlayer());
106 |
107 | netPlayersDictionary[playerid].X = reader.GetFloat();
108 | netPlayersDictionary[playerid].Y = reader.GetFloat();
109 | netPlayersDictionary[playerid].Z = reader.GetFloat();
110 | }
111 | }
112 | }
113 | }
114 |
115 | public void OnPeerConnected(NetPeer peer)
116 | {
117 | serverPeer = peer;
118 | Debug.Log($"OnPeerConnected: {peer.EndPoint.Host} : {peer.EndPoint.Port}");
119 | }
120 |
121 | public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
122 | {
123 | Debug.Log($"OnPeerConnected: {peer.EndPoint.Host} : {peer.EndPoint.Port} Reason: {disconnectInfo.Reason.ToString()}");
124 | }
125 |
126 | public void OnNetworkError(NetEndPoint endPoint, int socketErrorCode)
127 | {
128 | Debug.LogError($"OnNetworkError: {socketErrorCode}");
129 | }
130 |
131 | public void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader, UnconnectedMessageType messageType)
132 | {
133 | Debug.Log($"OnNetworkReceive: {reader.Data.Length}");
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Scripts/Player.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | public class Player : MonoBehaviour {
4 |
5 | private readonly float moveSpeed = 5f;
6 |
7 | // Use this for initialization
8 | void Start () {
9 |
10 | }
11 |
12 | // Update is called once per frame
13 | void Update () {
14 | float vertical = Input.GetAxis("Vertical");
15 | float horizontal = Input.GetAxis("Horizontal");
16 |
17 | transform.Translate(moveSpeed * Input.GetAxis("Horizontal") * Time.deltaTime, 0f, moveSpeed * Input.GetAxis("Vertical") * Time.deltaTime);
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Assets/Shared.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MUN1Z/CubesMultiplayerDemoUnityLiteNetLib/d29387ded18b1353409c03fe7cd53ded6106f789/CubesMultiplayerDemoClient/Assets/Shared.dll
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/Packages/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "com.unity.ads": "2.0.8",
4 | "com.unity.analytics": "2.0.16",
5 | "com.unity.package-manager-ui": "1.9.11",
6 | "com.unity.purchasing": "2.0.3",
7 | "com.unity.textmeshpro": "1.2.4",
8 | "com.unity.modules.ai": "1.0.0",
9 | "com.unity.modules.animation": "1.0.0",
10 | "com.unity.modules.assetbundle": "1.0.0",
11 | "com.unity.modules.audio": "1.0.0",
12 | "com.unity.modules.cloth": "1.0.0",
13 | "com.unity.modules.director": "1.0.0",
14 | "com.unity.modules.imageconversion": "1.0.0",
15 | "com.unity.modules.imgui": "1.0.0",
16 | "com.unity.modules.jsonserialize": "1.0.0",
17 | "com.unity.modules.particlesystem": "1.0.0",
18 | "com.unity.modules.physics": "1.0.0",
19 | "com.unity.modules.physics2d": "1.0.0",
20 | "com.unity.modules.screencapture": "1.0.0",
21 | "com.unity.modules.terrain": "1.0.0",
22 | "com.unity.modules.terrainphysics": "1.0.0",
23 | "com.unity.modules.tilemap": "1.0.0",
24 | "com.unity.modules.ui": "1.0.0",
25 | "com.unity.modules.uielements": "1.0.0",
26 | "com.unity.modules.umbra": "1.0.0",
27 | "com.unity.modules.unityanalytics": "1.0.0",
28 | "com.unity.modules.unitywebrequest": "1.0.0",
29 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
30 | "com.unity.modules.unitywebrequestaudio": "1.0.0",
31 | "com.unity.modules.unitywebrequesttexture": "1.0.0",
32 | "com.unity.modules.unitywebrequestwww": "1.0.0",
33 | "com.unity.modules.vehicles": "1.0.0",
34 | "com.unity.modules.video": "1.0.0",
35 | "com.unity.modules.vr": "1.0.0",
36 | "com.unity.modules.wind": "1.0.0",
37 | "com.unity.modules.xr": "1.0.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!11 &1
4 | AudioManager:
5 | m_ObjectHideFlags: 0
6 | m_Volume: 1
7 | Rolloff Scale: 1
8 | Doppler Factor: 1
9 | Default Speaker Mode: 2
10 | m_SampleRate: 0
11 | m_DSPBufferSize: 1024
12 | m_VirtualVoiceCount: 512
13 | m_RealVoiceCount: 32
14 | m_SpatializerPlugin:
15 | m_AmbisonicDecoderPlugin:
16 | m_DisableAudio: 0
17 | m_VirtualizeEffects: 1
18 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!236 &1
4 | ClusterInputManager:
5 | m_ObjectHideFlags: 0
6 | m_Inputs: []
7 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!55 &1
4 | PhysicsManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_Gravity: {x: 0, y: -9.81, z: 0}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_BounceThreshold: 2
10 | m_SleepThreshold: 0.005
11 | m_DefaultContactOffset: 0.01
12 | m_DefaultSolverIterations: 6
13 | m_DefaultSolverVelocityIterations: 1
14 | m_QueriesHitBackfaces: 0
15 | m_QueriesHitTriggers: 1
16 | m_EnableAdaptiveForce: 0
17 | m_ClothInterCollisionDistance: 0
18 | m_ClothInterCollisionStiffness: 0
19 | m_ContactsGeneration: 1
20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
21 | m_AutoSimulation: 1
22 | m_AutoSyncTransforms: 1
23 | m_ClothInterCollisionSettingsToggle: 0
24 | m_ContactPairsMode: 0
25 | m_BroadphaseType: 0
26 | m_WorldBounds:
27 | m_Center: {x: 0, y: 0, z: 0}
28 | m_Extent: {x: 250, y: 250, z: 250}
29 | m_WorldSubdivisions: 8
30 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1045 &1
4 | EditorBuildSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Scenes:
8 | - enabled: 1
9 | path: Assets/Scenes/SampleScene.unity
10 | guid: 99c9720ab356a0642a771bea13969a05
11 | m_configObjects: {}
12 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!159 &1
4 | EditorSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_ExternalVersionControlSupport: Visible Meta Files
8 | m_SerializationMode: 2
9 | m_LineEndingsForNewScripts: 2
10 | m_DefaultBehaviorMode: 0
11 | m_SpritePackerMode: 0
12 | m_SpritePackerPaddingPower: 1
13 | m_EtcTextureCompressorBehavior: 1
14 | m_EtcTextureFastCompressor: 1
15 | m_EtcTextureNormalCompressor: 2
16 | m_EtcTextureBestCompressor: 4
17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd
18 | m_ProjectGenerationRootNamespace:
19 | m_UserGeneratedProjectSuffix:
20 | m_CollabEditorSettings:
21 | inProgressEnabled: 1
22 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!30 &1
4 | GraphicsSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 12
7 | m_Deferred:
8 | m_Mode: 1
9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
10 | m_DeferredReflections:
11 | m_Mode: 1
12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
13 | m_ScreenSpaceShadows:
14 | m_Mode: 1
15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
16 | m_LegacyDeferred:
17 | m_Mode: 1
18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
19 | m_DepthNormals:
20 | m_Mode: 1
21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
22 | m_MotionVectors:
23 | m_Mode: 1
24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
25 | m_LightHalo:
26 | m_Mode: 1
27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
28 | m_LensFlare:
29 | m_Mode: 1
30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
31 | m_AlwaysIncludedShaders:
32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
38 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
39 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
40 | m_PreloadedShaders: []
41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
42 | type: 0}
43 | m_CustomRenderPipeline: {fileID: 0}
44 | m_TransparencySortMode: 0
45 | m_TransparencySortAxis: {x: 0, y: 0, z: 1}
46 | m_DefaultRenderingPath: 1
47 | m_DefaultMobileRenderingPath: 1
48 | m_TierSettings: []
49 | m_LightmapStripping: 0
50 | m_FogStripping: 0
51 | m_InstancingStripping: 0
52 | m_LightmapKeepPlain: 1
53 | m_LightmapKeepDirCombined: 1
54 | m_LightmapKeepDynamicPlain: 1
55 | m_LightmapKeepDynamicDirCombined: 1
56 | m_LightmapKeepShadowMask: 1
57 | m_LightmapKeepSubtractive: 1
58 | m_FogKeepLinear: 1
59 | m_FogKeepExp: 1
60 | m_FogKeepExp2: 1
61 | m_AlbedoSwatchInfos: []
62 | m_LightsUseLinearIntensity: 0
63 | m_LightsUseColorTemperature: 0
64 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!13 &1
4 | InputManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Axes:
8 | - serializedVersion: 3
9 | m_Name: Horizontal
10 | descriptiveName:
11 | descriptiveNegativeName:
12 | negativeButton: left
13 | positiveButton: right
14 | altNegativeButton: a
15 | altPositiveButton: d
16 | gravity: 3
17 | dead: 0.001
18 | sensitivity: 3
19 | snap: 1
20 | invert: 0
21 | type: 0
22 | axis: 0
23 | joyNum: 0
24 | - serializedVersion: 3
25 | m_Name: Vertical
26 | descriptiveName:
27 | descriptiveNegativeName:
28 | negativeButton: down
29 | positiveButton: up
30 | altNegativeButton: s
31 | altPositiveButton: w
32 | gravity: 3
33 | dead: 0.001
34 | sensitivity: 3
35 | snap: 1
36 | invert: 0
37 | type: 0
38 | axis: 0
39 | joyNum: 0
40 | - serializedVersion: 3
41 | m_Name: Fire1
42 | descriptiveName:
43 | descriptiveNegativeName:
44 | negativeButton:
45 | positiveButton: left ctrl
46 | altNegativeButton:
47 | altPositiveButton: mouse 0
48 | gravity: 1000
49 | dead: 0.001
50 | sensitivity: 1000
51 | snap: 0
52 | invert: 0
53 | type: 0
54 | axis: 0
55 | joyNum: 0
56 | - serializedVersion: 3
57 | m_Name: Fire2
58 | descriptiveName:
59 | descriptiveNegativeName:
60 | negativeButton:
61 | positiveButton: left alt
62 | altNegativeButton:
63 | altPositiveButton: mouse 1
64 | gravity: 1000
65 | dead: 0.001
66 | sensitivity: 1000
67 | snap: 0
68 | invert: 0
69 | type: 0
70 | axis: 0
71 | joyNum: 0
72 | - serializedVersion: 3
73 | m_Name: Fire3
74 | descriptiveName:
75 | descriptiveNegativeName:
76 | negativeButton:
77 | positiveButton: left shift
78 | altNegativeButton:
79 | altPositiveButton: mouse 2
80 | gravity: 1000
81 | dead: 0.001
82 | sensitivity: 1000
83 | snap: 0
84 | invert: 0
85 | type: 0
86 | axis: 0
87 | joyNum: 0
88 | - serializedVersion: 3
89 | m_Name: Jump
90 | descriptiveName:
91 | descriptiveNegativeName:
92 | negativeButton:
93 | positiveButton: space
94 | altNegativeButton:
95 | altPositiveButton:
96 | gravity: 1000
97 | dead: 0.001
98 | sensitivity: 1000
99 | snap: 0
100 | invert: 0
101 | type: 0
102 | axis: 0
103 | joyNum: 0
104 | - serializedVersion: 3
105 | m_Name: Mouse X
106 | descriptiveName:
107 | descriptiveNegativeName:
108 | negativeButton:
109 | positiveButton:
110 | altNegativeButton:
111 | altPositiveButton:
112 | gravity: 0
113 | dead: 0
114 | sensitivity: 0.1
115 | snap: 0
116 | invert: 0
117 | type: 1
118 | axis: 0
119 | joyNum: 0
120 | - serializedVersion: 3
121 | m_Name: Mouse Y
122 | descriptiveName:
123 | descriptiveNegativeName:
124 | negativeButton:
125 | positiveButton:
126 | altNegativeButton:
127 | altPositiveButton:
128 | gravity: 0
129 | dead: 0
130 | sensitivity: 0.1
131 | snap: 0
132 | invert: 0
133 | type: 1
134 | axis: 1
135 | joyNum: 0
136 | - serializedVersion: 3
137 | m_Name: Mouse ScrollWheel
138 | descriptiveName:
139 | descriptiveNegativeName:
140 | negativeButton:
141 | positiveButton:
142 | altNegativeButton:
143 | altPositiveButton:
144 | gravity: 0
145 | dead: 0
146 | sensitivity: 0.1
147 | snap: 0
148 | invert: 0
149 | type: 1
150 | axis: 2
151 | joyNum: 0
152 | - serializedVersion: 3
153 | m_Name: Horizontal
154 | descriptiveName:
155 | descriptiveNegativeName:
156 | negativeButton:
157 | positiveButton:
158 | altNegativeButton:
159 | altPositiveButton:
160 | gravity: 0
161 | dead: 0.19
162 | sensitivity: 1
163 | snap: 0
164 | invert: 0
165 | type: 2
166 | axis: 0
167 | joyNum: 0
168 | - serializedVersion: 3
169 | m_Name: Vertical
170 | descriptiveName:
171 | descriptiveNegativeName:
172 | negativeButton:
173 | positiveButton:
174 | altNegativeButton:
175 | altPositiveButton:
176 | gravity: 0
177 | dead: 0.19
178 | sensitivity: 1
179 | snap: 0
180 | invert: 1
181 | type: 2
182 | axis: 1
183 | joyNum: 0
184 | - serializedVersion: 3
185 | m_Name: Fire1
186 | descriptiveName:
187 | descriptiveNegativeName:
188 | negativeButton:
189 | positiveButton: joystick button 0
190 | altNegativeButton:
191 | altPositiveButton:
192 | gravity: 1000
193 | dead: 0.001
194 | sensitivity: 1000
195 | snap: 0
196 | invert: 0
197 | type: 0
198 | axis: 0
199 | joyNum: 0
200 | - serializedVersion: 3
201 | m_Name: Fire2
202 | descriptiveName:
203 | descriptiveNegativeName:
204 | negativeButton:
205 | positiveButton: joystick button 1
206 | altNegativeButton:
207 | altPositiveButton:
208 | gravity: 1000
209 | dead: 0.001
210 | sensitivity: 1000
211 | snap: 0
212 | invert: 0
213 | type: 0
214 | axis: 0
215 | joyNum: 0
216 | - serializedVersion: 3
217 | m_Name: Fire3
218 | descriptiveName:
219 | descriptiveNegativeName:
220 | negativeButton:
221 | positiveButton: joystick button 2
222 | altNegativeButton:
223 | altPositiveButton:
224 | gravity: 1000
225 | dead: 0.001
226 | sensitivity: 1000
227 | snap: 0
228 | invert: 0
229 | type: 0
230 | axis: 0
231 | joyNum: 0
232 | - serializedVersion: 3
233 | m_Name: Jump
234 | descriptiveName:
235 | descriptiveNegativeName:
236 | negativeButton:
237 | positiveButton: joystick button 3
238 | altNegativeButton:
239 | altPositiveButton:
240 | gravity: 1000
241 | dead: 0.001
242 | sensitivity: 1000
243 | snap: 0
244 | invert: 0
245 | type: 0
246 | axis: 0
247 | joyNum: 0
248 | - serializedVersion: 3
249 | m_Name: Submit
250 | descriptiveName:
251 | descriptiveNegativeName:
252 | negativeButton:
253 | positiveButton: return
254 | altNegativeButton:
255 | altPositiveButton: joystick button 0
256 | gravity: 1000
257 | dead: 0.001
258 | sensitivity: 1000
259 | snap: 0
260 | invert: 0
261 | type: 0
262 | axis: 0
263 | joyNum: 0
264 | - serializedVersion: 3
265 | m_Name: Submit
266 | descriptiveName:
267 | descriptiveNegativeName:
268 | negativeButton:
269 | positiveButton: enter
270 | altNegativeButton:
271 | altPositiveButton: space
272 | gravity: 1000
273 | dead: 0.001
274 | sensitivity: 1000
275 | snap: 0
276 | invert: 0
277 | type: 0
278 | axis: 0
279 | joyNum: 0
280 | - serializedVersion: 3
281 | m_Name: Cancel
282 | descriptiveName:
283 | descriptiveNegativeName:
284 | negativeButton:
285 | positiveButton: escape
286 | altNegativeButton:
287 | altPositiveButton: joystick button 1
288 | gravity: 1000
289 | dead: 0.001
290 | sensitivity: 1000
291 | snap: 0
292 | invert: 0
293 | type: 0
294 | axis: 0
295 | joyNum: 0
296 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!126 &1
4 | NavMeshProjectSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | areas:
8 | - name: Walkable
9 | cost: 1
10 | - name: Not Walkable
11 | cost: 1
12 | - name: Jump
13 | cost: 2
14 | - name:
15 | cost: 1
16 | - name:
17 | cost: 1
18 | - name:
19 | cost: 1
20 | - name:
21 | cost: 1
22 | - name:
23 | cost: 1
24 | - name:
25 | cost: 1
26 | - name:
27 | cost: 1
28 | - name:
29 | cost: 1
30 | - name:
31 | cost: 1
32 | - name:
33 | cost: 1
34 | - name:
35 | cost: 1
36 | - name:
37 | cost: 1
38 | - name:
39 | cost: 1
40 | - name:
41 | cost: 1
42 | - name:
43 | cost: 1
44 | - name:
45 | cost: 1
46 | - name:
47 | cost: 1
48 | - name:
49 | cost: 1
50 | - name:
51 | cost: 1
52 | - name:
53 | cost: 1
54 | - name:
55 | cost: 1
56 | - name:
57 | cost: 1
58 | - name:
59 | cost: 1
60 | - name:
61 | cost: 1
62 | - name:
63 | cost: 1
64 | - name:
65 | cost: 1
66 | - name:
67 | cost: 1
68 | - name:
69 | cost: 1
70 | - name:
71 | cost: 1
72 | m_LastAgentTypeID: -887442657
73 | m_Settings:
74 | - serializedVersion: 2
75 | agentTypeID: 0
76 | agentRadius: 0.5
77 | agentHeight: 2
78 | agentSlope: 45
79 | agentClimb: 0.75
80 | ledgeDropHeight: 0
81 | maxJumpAcrossDistance: 0
82 | minRegionArea: 2
83 | manualCellSize: 0
84 | cellSize: 0.16666667
85 | manualTileSize: 0
86 | tileSize: 256
87 | accuratePlacement: 0
88 | debug:
89 | m_Flags: 0
90 | m_SettingNames:
91 | - Humanoid
92 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!149 &1
4 | NetworkManager:
5 | m_ObjectHideFlags: 0
6 | m_DebugLevel: 0
7 | m_Sendrate: 15
8 | m_AssetToPrefab: {}
9 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!19 &1
4 | Physics2DSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 3
7 | m_Gravity: {x: 0, y: -9.81}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_VelocityIterations: 8
10 | m_PositionIterations: 3
11 | m_VelocityThreshold: 1
12 | m_MaxLinearCorrection: 0.2
13 | m_MaxAngularCorrection: 8
14 | m_MaxTranslationSpeed: 100
15 | m_MaxRotationSpeed: 360
16 | m_BaumgarteScale: 0.2
17 | m_BaumgarteTimeOfImpactScale: 0.75
18 | m_TimeToSleep: 0.5
19 | m_LinearSleepTolerance: 0.01
20 | m_AngularSleepTolerance: 2
21 | m_DefaultContactOffset: 0.01
22 | m_AutoSimulation: 1
23 | m_QueriesHitTriggers: 1
24 | m_QueriesStartInColliders: 1
25 | m_ChangeStopsCallbacks: 0
26 | m_CallbacksOnDisable: 1
27 | m_AutoSyncTransforms: 1
28 | m_AlwaysShowColliders: 0
29 | m_ShowColliderSleep: 1
30 | m_ShowColliderContacts: 0
31 | m_ShowColliderAABB: 0
32 | m_ContactArrowScale: 0.2
33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
38 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/PresetManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1386491679 &1
4 | PresetManager:
5 | m_ObjectHideFlags: 0
6 | m_DefaultList:
7 | - type:
8 | m_NativeTypeID: 108
9 | m_ManagedTypePPtr: {fileID: 0}
10 | m_ManagedTypeFallback:
11 | defaultPresets:
12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea,
13 | type: 2}
14 | - type:
15 | m_NativeTypeID: 1020
16 | m_ManagedTypePPtr: {fileID: 0}
17 | m_ManagedTypeFallback:
18 | defaultPresets:
19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6,
20 | type: 2}
21 | - type:
22 | m_NativeTypeID: 1006
23 | m_ManagedTypePPtr: {fileID: 0}
24 | m_ManagedTypeFallback:
25 | defaultPresets:
26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9,
27 | type: 2}
28 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 2018.2.7f1
2 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!47 &1
4 | QualitySettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 5
7 | m_CurrentQuality: 4
8 | m_QualitySettings:
9 | - serializedVersion: 2
10 | name: Very Low
11 | pixelLightCount: 0
12 | shadows: 0
13 | shadowResolution: 0
14 | shadowProjection: 1
15 | shadowCascades: 1
16 | shadowDistance: 15
17 | shadowNearPlaneOffset: 3
18 | shadowCascade2Split: 0.33333334
19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
20 | shadowmaskMode: 0
21 | blendWeights: 1
22 | textureQuality: 1
23 | anisotropicTextures: 0
24 | antiAliasing: 0
25 | softParticles: 0
26 | softVegetation: 0
27 | realtimeReflectionProbes: 0
28 | billboardsFaceCameraPosition: 0
29 | vSyncCount: 0
30 | lodBias: 0.3
31 | maximumLODLevel: 0
32 | particleRaycastBudget: 4
33 | asyncUploadTimeSlice: 2
34 | asyncUploadBufferSize: 4
35 | resolutionScalingFixedDPIFactor: 1
36 | excludedTargetPlatforms: []
37 | - serializedVersion: 2
38 | name: Low
39 | pixelLightCount: 0
40 | shadows: 0
41 | shadowResolution: 0
42 | shadowProjection: 1
43 | shadowCascades: 1
44 | shadowDistance: 20
45 | shadowNearPlaneOffset: 3
46 | shadowCascade2Split: 0.33333334
47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
48 | shadowmaskMode: 0
49 | blendWeights: 2
50 | textureQuality: 0
51 | anisotropicTextures: 0
52 | antiAliasing: 0
53 | softParticles: 0
54 | softVegetation: 0
55 | realtimeReflectionProbes: 0
56 | billboardsFaceCameraPosition: 0
57 | vSyncCount: 0
58 | lodBias: 0.4
59 | maximumLODLevel: 0
60 | particleRaycastBudget: 16
61 | asyncUploadTimeSlice: 2
62 | asyncUploadBufferSize: 4
63 | resolutionScalingFixedDPIFactor: 1
64 | excludedTargetPlatforms: []
65 | - serializedVersion: 2
66 | name: Medium
67 | pixelLightCount: 1
68 | shadows: 1
69 | shadowResolution: 0
70 | shadowProjection: 1
71 | shadowCascades: 1
72 | shadowDistance: 20
73 | shadowNearPlaneOffset: 3
74 | shadowCascade2Split: 0.33333334
75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
76 | shadowmaskMode: 0
77 | blendWeights: 2
78 | textureQuality: 0
79 | anisotropicTextures: 1
80 | antiAliasing: 0
81 | softParticles: 0
82 | softVegetation: 0
83 | realtimeReflectionProbes: 0
84 | billboardsFaceCameraPosition: 0
85 | vSyncCount: 1
86 | lodBias: 0.7
87 | maximumLODLevel: 0
88 | particleRaycastBudget: 64
89 | asyncUploadTimeSlice: 2
90 | asyncUploadBufferSize: 4
91 | resolutionScalingFixedDPIFactor: 1
92 | excludedTargetPlatforms: []
93 | - serializedVersion: 2
94 | name: High
95 | pixelLightCount: 2
96 | shadows: 2
97 | shadowResolution: 1
98 | shadowProjection: 1
99 | shadowCascades: 2
100 | shadowDistance: 40
101 | shadowNearPlaneOffset: 3
102 | shadowCascade2Split: 0.33333334
103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
104 | shadowmaskMode: 1
105 | blendWeights: 2
106 | textureQuality: 0
107 | anisotropicTextures: 1
108 | antiAliasing: 2
109 | softParticles: 0
110 | softVegetation: 1
111 | realtimeReflectionProbes: 1
112 | billboardsFaceCameraPosition: 1
113 | vSyncCount: 1
114 | lodBias: 1
115 | maximumLODLevel: 0
116 | particleRaycastBudget: 256
117 | asyncUploadTimeSlice: 2
118 | asyncUploadBufferSize: 4
119 | resolutionScalingFixedDPIFactor: 1
120 | excludedTargetPlatforms: []
121 | - serializedVersion: 2
122 | name: Very High
123 | pixelLightCount: 3
124 | shadows: 2
125 | shadowResolution: 2
126 | shadowProjection: 1
127 | shadowCascades: 2
128 | shadowDistance: 40
129 | shadowNearPlaneOffset: 3
130 | shadowCascade2Split: 0.33333334
131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
132 | shadowmaskMode: 1
133 | blendWeights: 4
134 | textureQuality: 0
135 | anisotropicTextures: 1
136 | antiAliasing: 4
137 | softParticles: 1
138 | softVegetation: 1
139 | realtimeReflectionProbes: 1
140 | billboardsFaceCameraPosition: 1
141 | vSyncCount: 1
142 | lodBias: 1.5
143 | maximumLODLevel: 0
144 | particleRaycastBudget: 1024
145 | asyncUploadTimeSlice: 2
146 | asyncUploadBufferSize: 4
147 | resolutionScalingFixedDPIFactor: 1
148 | excludedTargetPlatforms: []
149 | - serializedVersion: 2
150 | name: Ultra
151 | pixelLightCount: 4
152 | shadows: 2
153 | shadowResolution: 2
154 | shadowProjection: 1
155 | shadowCascades: 4
156 | shadowDistance: 150
157 | shadowNearPlaneOffset: 3
158 | shadowCascade2Split: 0.33333334
159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
160 | shadowmaskMode: 1
161 | blendWeights: 4
162 | textureQuality: 0
163 | anisotropicTextures: 1
164 | antiAliasing: 4
165 | softParticles: 1
166 | softVegetation: 1
167 | realtimeReflectionProbes: 1
168 | billboardsFaceCameraPosition: 1
169 | vSyncCount: 1
170 | lodBias: 2
171 | maximumLODLevel: 0
172 | particleRaycastBudget: 4096
173 | asyncUploadTimeSlice: 2
174 | asyncUploadBufferSize: 4
175 | resolutionScalingFixedDPIFactor: 1
176 | excludedTargetPlatforms: []
177 | m_PerPlatformDefaultQuality:
178 | Android: 2
179 | Nintendo 3DS: 5
180 | Nintendo Switch: 5
181 | PS4: 5
182 | PSP2: 2
183 | Standalone: 5
184 | Tizen: 2
185 | WebGL: 3
186 | WiiU: 5
187 | Windows Store Apps: 5
188 | XboxOne: 5
189 | iPhone: 2
190 | tvOS: 2
191 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!78 &1
4 | TagManager:
5 | serializedVersion: 2
6 | tags: []
7 | layers:
8 | - Default
9 | - TransparentFX
10 | - Ignore Raycast
11 | -
12 | - Water
13 | - UI
14 | -
15 | -
16 | - PostProcessing
17 | -
18 | -
19 | -
20 | -
21 | -
22 | -
23 | -
24 | -
25 | -
26 | -
27 | -
28 | -
29 | -
30 | -
31 | -
32 | -
33 | -
34 | -
35 | -
36 | -
37 | -
38 | -
39 | -
40 | m_SortingLayers:
41 | - name: Default
42 | uniqueID: 0
43 | locked: 0
44 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!5 &1
4 | TimeManager:
5 | m_ObjectHideFlags: 0
6 | Fixed Timestep: 0.02
7 | Maximum Allowed Timestep: 0.1
8 | m_TimeScale: 1
9 | Maximum Particle Timestep: 0.03
10 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoClient/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!310 &1
4 | UnityConnectSettings:
5 | m_ObjectHideFlags: 0
6 | m_Enabled: 1
7 | m_TestMode: 0
8 | m_TestEventUrl:
9 | m_TestConfigUrl:
10 | m_TestInitMode: 0
11 | CrashReportingSettings:
12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes
13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate
14 | m_Enabled: 0
15 | m_CaptureEditorExceptions: 1
16 | UnityPurchasingSettings:
17 | m_Enabled: 0
18 | m_TestMode: 0
19 | UnityAnalyticsSettings:
20 | m_Enabled: 1
21 | m_InitializeOnStartup: 1
22 | m_TestMode: 0
23 | m_TestEventUrl:
24 | m_TestConfigUrl:
25 | UnityAdsSettings:
26 | m_Enabled: 0
27 | m_InitializeOnStartup: 1
28 | m_TestMode: 0
29 | m_IosGameId:
30 | m_AndroidGameId:
31 | m_GameIds: {}
32 | m_GameId:
33 | PerformanceReportingSettings:
34 | m_Enabled: 0
35 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 | .vs/
9 |
10 | # Build results
11 | [Dd]ebug/
12 | [Dd]ebugPublic/
13 | [Rr]elease/
14 | [Rr]eleases/
15 | x64/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | #NUNIT
29 | *.VisualState.xml
30 | TestResult.xml
31 |
32 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # Visual Studio 2015/2017 cache/options directory
85 | .vs/
86 | # Uncomment if you have tasks that create the project's static files in wwwroot
87 | #wwwroot/
88 |
89 | # Visual Studio 2017 auto generated files
90 | Generated\ Files/
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding addin-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | ## TODO: Comment the next line if you want to checkin your
137 | ## web deploy settings but do note that will include unencrypted
138 | ## passwords
139 | *.pubxml
140 |
141 | # NuGet Packages Directory
142 | packages/*
143 | ## TODO: If the tool you use requires repositories.config
144 | ## uncomment the next line
145 | #!packages/repositories.config
146 |
147 | # Enable "build/" folder in the NuGet Packages folder since
148 | # NuGet packages use it for MSBuild targets.
149 | # This line needs to be after the ignore of the build folder
150 | # (and the packages folder if the line above has been uncommented)
151 | !packages/build/
152 |
153 | # Windows Azure Build Output
154 | csx/
155 | *.build.csdef
156 |
157 | # Windows Store app package directory
158 | AppPackages/
159 |
160 | # Others
161 | sql/
162 | *.Cache
163 | ClientBin/
164 | [Ss]tyle[Cc]op.*
165 | ~$*
166 | *~
167 | *.dbmdl
168 | *.dbproj.schemaview
169 | *.pfx
170 | *.publishsettings
171 | node_modules/
172 |
173 | # RIA/Silverlight projects
174 | Generated_Code/
175 |
176 | # Backup & report files from converting an old project file
177 | # to a newer Visual Studio version. Backup files are not needed,
178 | # because we have git ;-)
179 | _UpgradeReport_Files/
180 | Backup*/
181 | UpgradeLog*.XML
182 | UpgradeLog*.htm
183 |
184 | # SQL Server files
185 | *.mdf
186 | *.ldf
187 |
188 | # Business Intelligence projects
189 | *.rdl.data
190 | *.bim.layout
191 | *.bim_*.settings
192 |
193 | # Microsoft Fakes
194 | FakesAssemblies/
195 |
196 | git_stats/*
197 |
198 | *.ncrunchproject
199 | StyleCop.Cache
200 | bin
201 | obj
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/CubesMultiplayerDemoServer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2041
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "src\Server\Server.csproj", "{B02FC5BC-4A7E-4994-9074-B4D8C54FE907}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "src\Shared\Shared.csproj", "{FC144ED3-D224-4FE7-92EB-44013C0A5005}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {B02FC5BC-4A7E-4994-9074-B4D8C54FE907}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {B02FC5BC-4A7E-4994-9074-B4D8C54FE907}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {B02FC5BC-4A7E-4994-9074-B4D8C54FE907}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {B02FC5BC-4A7E-4994-9074-B4D8C54FE907}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {FC144ED3-D224-4FE7-92EB-44013C0A5005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {FC144ED3-D224-4FE7-92EB-44013C0A5005}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {FC144ED3-D224-4FE7-92EB-44013C0A5005}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {FC144ED3-D224-4FE7-92EB-44013C0A5005}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {3D63F82C-2719-4B5C-AF4C-E60EFCADBAFC}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/src/Server/NetworkPlayer.cs:
--------------------------------------------------------------------------------
1 | using LiteNetLib;
2 |
3 | namespace Server
4 | {
5 | public class NetworkPlayer
6 | {
7 | public float X { get; set; }
8 | public float Y { get; set; }
9 | public float Z { get; set; }
10 |
11 | public NetPeer NetPeer { get; set; }
12 | public bool Moved { get; set; }
13 |
14 |
15 | public NetworkPlayer(NetPeer peer)
16 | {
17 | NetPeer = peer;
18 |
19 | X = 0.0f;
20 | Y = 0.0f;
21 | Z = 0.0f;
22 |
23 | Moved = false;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/src/Server/Program.cs:
--------------------------------------------------------------------------------
1 | using LiteNetLib;
2 | using LiteNetLib.Utils;
3 | using Shared.Enums;
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Server
8 | {
9 | class Program : INetEventListener
10 | {
11 | NetDataWriter dataWriter;
12 | private NetManager serverNetManager;
13 |
14 | private Dictionary networkPlayersDictionary;
15 |
16 | public void Run()
17 | {
18 | try
19 | {
20 | dataWriter = new NetDataWriter();
21 | networkPlayersDictionary = new Dictionary();
22 |
23 | serverNetManager = new NetManager(this, 100, "game");
24 | if (serverNetManager.Start(15000))
25 | Console.WriteLine("Server started listening on port 15000");
26 | else
27 | {
28 | Console.WriteLine("Server cold not start!");
29 | return;
30 | }
31 |
32 | while (serverNetManager.IsRunning)
33 | {
34 | serverNetManager.PollEvents();
35 |
36 | SendPlayerPositions();
37 |
38 | System.Threading.Thread.Sleep(15);
39 | }
40 | }
41 | catch (Exception ex)
42 | {
43 | Console.WriteLine($"Error: {ex.Message}");
44 | }
45 | }
46 |
47 | static void Main(string[] args)
48 | {
49 | Program program = new Program();
50 | program.Run();
51 |
52 | Console.ReadKey();
53 | }
54 |
55 | public void SendPlayerPositions()
56 | {
57 | try
58 | {
59 | Dictionary sendPosDict = new Dictionary(networkPlayersDictionary);
60 |
61 | foreach (var sendToPlayer in sendPosDict)
62 | {
63 | if (sendToPlayer.Value == null)
64 | continue;
65 |
66 | dataWriter.Reset();
67 | dataWriter.Put((int)NetworkTags.PlayerPositionsArray);
68 |
69 | int amountPlayersMoved = 0;
70 |
71 | foreach (var posPlayers in sendPosDict)
72 | {
73 | if (sendToPlayer.Key == posPlayers.Key)
74 | continue;
75 |
76 | if (!posPlayers.Value.Moved)
77 | continue;
78 |
79 | dataWriter.Put(posPlayers.Key);
80 |
81 | dataWriter.Put(posPlayers.Value.X);
82 | dataWriter.Put(posPlayers.Value.Y);
83 | dataWriter.Put(posPlayers.Value.Z);
84 |
85 | amountPlayersMoved++;
86 | }
87 |
88 | if (amountPlayersMoved > 0)
89 | sendToPlayer.Value.NetPeer.Send(dataWriter, SendOptions.Sequenced);
90 | }
91 |
92 | foreach (var player in networkPlayersDictionary)
93 | player.Value.Moved = false;
94 | }
95 | catch (Exception ex)
96 | {
97 | Console.WriteLine($"Error: {ex.Message}");
98 | }
99 | }
100 |
101 | public void OnPeerConnected(NetPeer peer)
102 | {
103 | try
104 | {
105 | Console.WriteLine($"OnPeerConnected: {peer.EndPoint.Host} : {peer.EndPoint.Port}");
106 |
107 | NetDataWriter netDataWriter = new NetDataWriter();
108 | netDataWriter.Reset();
109 | netDataWriter.Put((int)NetworkTags.PlayerPositionsArray);
110 | foreach (var p in networkPlayersDictionary)
111 | {
112 | netDataWriter.Put(p.Key);
113 |
114 | netDataWriter.Put(p.Value.X);
115 | netDataWriter.Put(p.Value.Y);
116 | netDataWriter.Put(p.Value.Z);
117 | }
118 |
119 | peer.Send(netDataWriter, SendOptions.ReliableOrdered);
120 |
121 | if (!networkPlayersDictionary.ContainsKey(peer.ConnectId))
122 | networkPlayersDictionary.Add(peer.ConnectId, new NetworkPlayer(peer));
123 |
124 | networkPlayersDictionary[peer.ConnectId].Moved = true;
125 | }
126 | catch (Exception ex)
127 | {
128 | Console.WriteLine($"Error: {ex.Message}");
129 | }
130 | }
131 |
132 | public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
133 | {
134 | try
135 | {
136 | Console.WriteLine($"OnPeerConnected: {peer.EndPoint.Host} : {peer.EndPoint.Port} Reason: {disconnectInfo.Reason.ToString()}");
137 |
138 | if (networkPlayersDictionary.ContainsKey(peer.ConnectId))
139 | networkPlayersDictionary.Remove(peer.ConnectId);
140 | }
141 | catch(Exception ex)
142 | {
143 | Console.WriteLine($"Error: {ex.Message}");
144 | }
145 | }
146 |
147 | public void OnNetworkError(NetEndPoint endPoint, int socketErrorCode)
148 | {
149 | try
150 | {
151 | Console.WriteLine($"OnNetworkError: {socketErrorCode}");
152 | }
153 | catch (Exception ex)
154 | {
155 | Console.WriteLine($"Error: {ex.Message}");
156 | }
157 | }
158 |
159 | public void OnNetworkReceive(NetPeer peer, NetDataReader reader)
160 | {
161 | try
162 | {
163 | if (reader.Data == null)
164 | return;
165 |
166 | NetworkTags networkTag = (NetworkTags)reader.GetInt();
167 | if (networkTag == NetworkTags.PlayerPosition)
168 | {
169 | float x = reader.GetFloat();
170 | float y = reader.GetFloat();
171 | float z = reader.GetFloat();
172 |
173 | Console.WriteLine($"Got position packet : {x} | {y} | {z}");
174 |
175 | networkPlayersDictionary[peer.ConnectId].X = x;
176 | networkPlayersDictionary[peer.ConnectId].Y = y;
177 | networkPlayersDictionary[peer.ConnectId].Z = z;
178 |
179 | networkPlayersDictionary[peer.ConnectId].Moved = true;
180 | }
181 | }
182 | catch (Exception ex)
183 | {
184 | Console.WriteLine($"Error: {ex.Message}");
185 | }
186 | }
187 |
188 | public void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader, UnconnectedMessageType messageType)
189 | {
190 | try
191 | {
192 | Console.WriteLine($"OnNetworkReceiveUnconnected");
193 | }
194 | catch (Exception ex)
195 | {
196 | Console.WriteLine($"Error: {ex.Message}");
197 | }
198 | }
199 |
200 | public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
201 | {
202 | try { }
203 | catch (Exception ex)
204 | {
205 | Console.WriteLine($"Error: {ex.Message}");
206 | }
207 | }
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/src/Server/Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/src/Shared/Enums/NetworkTags.cs:
--------------------------------------------------------------------------------
1 | namespace Shared.Enums
2 | {
3 | public enum NetworkTags
4 | {
5 | PlayerPosition,
6 | PlayerPositionsArray
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/CubesMultiplayerDemoServer/src/Shared/Shared.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | Example of multiplayer game using unity 2018, .net core, .net standard and LiteLibNet (https://github.com/RevenantX/LiteNetLib).
4 |
5 |
--------------------------------------------------------------------------------
/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MUN1Z/CubesMultiplayerDemoUnityLiteNetLib/d29387ded18b1353409c03fe7cd53ded6106f789/example.gif
--------------------------------------------------------------------------------