├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── issue_template.md ├── .gitignore ├── LICENSE.txt ├── LNL.png ├── LNL.svg ├── LibSample ├── AesEncryptLayer.cs ├── AesEncryptionTest.cs ├── BroadcastTest.cs ├── EchoMessagesTest.cs ├── GithubSample.cs ├── HolePunchServerTest.cs ├── IExample.cs ├── LibSample.csproj ├── NtpTest.cs ├── PacketProcessorExample.cs ├── Program.cs ├── SerializerBenchmark.cs └── SpeedBench.cs ├── LiteNetLib.Tests ├── CRC32LayerTest.cs ├── CommunicationTest.cs ├── LiteNetLib.Tests.csproj ├── NetSerializerTest.cs ├── ReaderWriterSimpleDataTest.cs └── TestUtility │ └── NetManagerStack.cs ├── LiteNetLib.Trim.Dummy ├── LiteNetLib.Trim.Dummy.csproj └── Program.cs ├── LiteNetLib.sln ├── LiteNetLib ├── BaseChannel.cs ├── ConnectionRequest.cs ├── INetEventListener.cs ├── InternalPackets.cs ├── Layers │ ├── Crc32cLayer.cs │ ├── PacketLayerBase.cs │ └── XorEncryptLayer.cs ├── LiteNetLib.asmdef ├── LiteNetLib.csproj ├── NatPunchModule.cs ├── NativeSocket.cs ├── NetConstants.cs ├── NetDebug.cs ├── NetManager.HashSet.cs ├── NetManager.PacketPool.cs ├── NetManager.Socket.cs ├── NetManager.cs ├── NetPacket.cs ├── NetPeer.cs ├── NetStatistics.cs ├── NetUtils.cs ├── PausedSocketFix.cs ├── PooledPacket.cs ├── ReliableChannel.cs ├── SequencedChannel.cs ├── Trimming.cs ├── Utils │ ├── CRC32C.cs │ ├── FastBitConverter.cs │ ├── INetSerializable.cs │ ├── NetDataReader.cs │ ├── NetDataWriter.cs │ ├── NetPacketProcessor.cs │ ├── NetSerializer.cs │ ├── NtpPacket.cs │ ├── NtpRequest.cs │ └── Preserve.cs └── package.json ├── LiteNetLibSampleUnity ├── .gitignore ├── Assets │ ├── GameClient.cs │ ├── GameClient.cs.meta │ ├── GameServer.cs │ ├── GameServer.cs.meta │ ├── MainScene.unity │ ├── MainScene.unity.meta │ ├── Resources.meta │ └── Resources │ │ ├── BillingMode.json │ │ └── BillingMode.json.meta ├── Packages │ ├── manifest.json │ └── packages-lock.json ├── ProjectSettings │ ├── AudioManager.asset │ ├── ClusterInputManager.asset │ ├── DynamicsManager.asset │ ├── EditorBuildSettings.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── MemorySettings.asset │ ├── NavMeshAreas.asset │ ├── NetworkManager.asset │ ├── PackageManagerSettings.asset │ ├── Physics2DSettings.asset │ ├── PresetManager.asset │ ├── ProjectSettings.asset │ ├── ProjectVersion.txt │ ├── QualitySettings.asset │ ├── TagManager.asset │ ├── TimeManager.asset │ ├── UnityConnectSettings.asset │ ├── VFXManager.asset │ └── VersionControlSettings.asset └── UserSettings │ ├── EditorUserSettings.asset │ ├── Layouts │ ├── CurrentMaximizeLayout.dwlt │ └── default-2022.dwlt │ └── Search.settings ├── README.md ├── appveyor.yml ├── docfx_project ├── .gitignore ├── api │ ├── .gitignore │ └── index.md ├── articles │ ├── netserializerusage.md │ └── toc.yml ├── docfx.json ├── filterConfig.yml ├── index.md └── toc.yml ├── docs ├── api │ ├── LiteNetLib.ConnectionRequest.html │ ├── LiteNetLib.ConnectionRequestType.html │ ├── LiteNetLib.ConnectionState.html │ ├── LiteNetLib.DeliveryMethod.html │ ├── LiteNetLib.DisconnectInfo.html │ ├── LiteNetLib.DisconnectReason.html │ ├── LiteNetLib.EventBasedNatPunchListener.html │ ├── LiteNetLib.EventBasedNetListener.html │ ├── LiteNetLib.IDeliveryEventListener.html │ ├── LiteNetLib.INatPunchListener.html │ ├── LiteNetLib.INetEventListener.html │ ├── LiteNetLib.INetLogger.html │ ├── LiteNetLib.INtpEventListener.html │ ├── LiteNetLib.IPeerAddressChangedListener.html │ ├── LiteNetLib.IPv6Mode.html │ ├── LiteNetLib.InvalidPacketException.html │ ├── LiteNetLib.Layers.Crc32cLayer.html │ ├── LiteNetLib.Layers.PacketLayerBase.html │ ├── LiteNetLib.Layers.XorEncryptLayer.html │ ├── LiteNetLib.Layers.html │ ├── LiteNetLib.LocalAddrType.html │ ├── LiteNetLib.NatAddressType.html │ ├── LiteNetLib.NatPunchModule.html │ ├── LiteNetLib.NetConstants.html │ ├── LiteNetLib.NetDebug.html │ ├── LiteNetLib.NetLogLevel.html │ ├── LiteNetLib.NetManager.NetPeerEnumerator.html │ ├── LiteNetLib.NetManager.html │ ├── LiteNetLib.NetPacketReader.html │ ├── LiteNetLib.NetPeer.html │ ├── LiteNetLib.NetStatistics.html │ ├── LiteNetLib.NetUtils.html │ ├── LiteNetLib.PooledPacket.html │ ├── LiteNetLib.TooBigPacketException.html │ ├── LiteNetLib.UnconnectedMessageType.html │ ├── LiteNetLib.Utils.CRC32C.html │ ├── LiteNetLib.Utils.FastBitConverter.html │ ├── LiteNetLib.Utils.INetSerializable.html │ ├── LiteNetLib.Utils.InvalidTypeException.html │ ├── LiteNetLib.Utils.NetDataReader.html │ ├── LiteNetLib.Utils.NetDataWriter.html │ ├── LiteNetLib.Utils.NetPacketProcessor.html │ ├── LiteNetLib.Utils.NetSerializer.html │ ├── LiteNetLib.Utils.NtpLeapIndicator.html │ ├── LiteNetLib.Utils.NtpMode.html │ ├── LiteNetLib.Utils.NtpPacket.html │ ├── LiteNetLib.Utils.NtpRequest.html │ ├── LiteNetLib.Utils.ParseException.html │ ├── LiteNetLib.Utils.PreserveAttribute.html │ ├── LiteNetLib.Utils.html │ ├── LiteNetLib.html │ ├── index.html │ ├── toc.html │ └── toc.json ├── articles │ ├── netserializerusage.html │ ├── toc.html │ └── toc.json ├── favicon.ico ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── index.html ├── logo.svg ├── manifest.json ├── search-stopwords.json ├── styles │ ├── docfx.css │ ├── docfx.js │ ├── docfx.vendor.css │ ├── docfx.vendor.js │ ├── docfx.vendor.min.css │ ├── docfx.vendor.min.css.map │ ├── docfx.vendor.min.js │ ├── docfx.vendor.min.js.map │ ├── glyphicons-halflings-regular-ACNUA6UY.ttf │ ├── glyphicons-halflings-regular-JOUF32XT.woff │ ├── glyphicons-halflings-regular-PIHUWCJO.eot │ ├── glyphicons-halflings-regular-QXYEM3FU.svg │ ├── glyphicons-halflings-regular-W4DYDFZM.woff2 │ ├── lunr.js │ ├── lunr.min.js │ ├── main.css │ ├── main.js │ ├── search-worker.js │ ├── search-worker.min.js │ └── search-worker.min.js.map ├── toc.html ├── toc.json └── xrefmap.yml └── update_docs.bat /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | 7 | [*.cs] 8 | charset = utf-8-bom 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | # IDE0032: Use auto property 12 | dotnet_style_prefer_auto_properties = true:none 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.paypal.com/donate/?business=G9PDX5KLGKBA2&no_recurring=0¤cy_code=USD'] 13 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | Information about bug or feature 2 | 3 | ```csharp 4 | //Some c# code if needed 5 | netPeer.Connect("192.168.0.1", 9050); 6 | ``` 7 | 8 | **Library version**: [commit id (9f2a1d1a8244510d9ec502cc002bfdddba666d09) or release version (0.7.7.1)] 9 | 10 | **Framework**: [Mono, Unity, dotnetcore, .NET Framework] 11 | 12 | **OS**: [Linux, Windows, etc] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Standrart 2 | .DS_Store 3 | .dist 4 | 5 | # MongoDB 6 | app 7 | bin 8 | db 9 | node_modules 10 | 11 | 12 | ## Ignore Visual Studio temporary files, build results, and 13 | ## files generated by popular Visual Studio add-ons. 14 | 15 | # User-specific files 16 | *.suo 17 | *.user 18 | *.userosscache 19 | *.sln.docstates 20 | 21 | # User-specific files (MonoDevelop/Xamarin Studio) 22 | *.userprefs 23 | 24 | # Build results 25 | [Dd]ebug/ 26 | [Dd]ebugPublic/ 27 | [Rr]elease/ 28 | [Rr]eleases/ 29 | x64/ 30 | x86/ 31 | build/ 32 | bld/ 33 | [Bb]in/ 34 | [Oo]bj/ 35 | 36 | # Visual Studio 2015 cache/options directory 37 | .vs/ 38 | 39 | # MSTest test Results 40 | [Tt]est[Rr]esult*/ 41 | [Bb]uild[Ll]og.* 42 | 43 | # NUNIT 44 | *.VisualState.xml 45 | TestResult.xml 46 | 47 | # Build Results of an ATL Project 48 | [Dd]ebugPS/ 49 | [Rr]eleasePS/ 50 | dlldata.c 51 | 52 | # DNX 53 | project.lock.json 54 | artifacts/ 55 | 56 | *_i.c 57 | *_p.c 58 | *_i.h 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.svclog 79 | *.scc 80 | 81 | # Chutzpah Test files 82 | _Chutzpah* 83 | 84 | # Visual C++ cache files 85 | ipch/ 86 | *.aps 87 | *.ncb 88 | *.opensdf 89 | *.sdf 90 | *.cachefile 91 | 92 | # Visual Studio profiler 93 | *.psess 94 | *.vsp 95 | *.vspx 96 | 97 | # TFS 2012 Local Workspace 98 | $tf/ 99 | 100 | # Guidance Automation Toolkit 101 | *.gpState 102 | 103 | # ReSharper is a .NET coding add-in 104 | _ReSharper*/ 105 | *.[Rr]e[Ss]harper 106 | *.DotSettings.user 107 | 108 | # JustCode is a .NET coding add-in 109 | .JustCode 110 | 111 | # TeamCity is a build add-in 112 | _TeamCity* 113 | 114 | # DotCover is a Code Coverage Tool 115 | *.dotCover 116 | 117 | # NCrunch 118 | _NCrunch_* 119 | .*crunch*.local.xml 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | ## TODO: Comment the next line if you want to checkin your 148 | ## web deploy settings but do note that will include unencrypted 149 | ## passwords 150 | #*.pubxml 151 | 152 | *.publishproj 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | 163 | !LiteNetLibSampleUnity/Packages/* 164 | 165 | # Windows Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | [Ss]tyle[Cc]op.* 181 | ~$* 182 | *~ 183 | *.dbmdl 184 | *.dbproj.schemaview 185 | *.pfx 186 | *.publishsettings 187 | node_modules/ 188 | orleans.codegen.cs 189 | 190 | # RIA/Silverlight projects 191 | Generated_Code/ 192 | 193 | # Backup & report files from converting an old project file 194 | # to a newer Visual Studio version. Backup files are not needed, 195 | # because we have git ;-) 196 | _UpgradeReport_Files/ 197 | Backup*/ 198 | UpgradeLog*.XML 199 | UpgradeLog*.htm 200 | 201 | # SQL Server files 202 | *.mdf 203 | *.ldf 204 | 205 | # Business Intelligence projects 206 | *.rdl.data 207 | *.bim.layout 208 | *.bim_*.settings 209 | 210 | # Microsoft Fakes 211 | FakesAssemblies/ 212 | 213 | # Node.js Tools for Visual Studio 214 | .ntvs_analysis.dat 215 | 216 | # Visual Studio 6 build log 217 | *.plg 218 | 219 | # Visual Studio 6 workspace options file 220 | *.opt 221 | 222 | # LightSwitch generated files 223 | GeneratedArtifacts/ 224 | _Pvt_Extensions/ 225 | ModelManifest.xml 226 | 227 | # Rider 228 | .idea/ 229 | *.sln.iml 230 | **/*.vscode -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ruslan Pyrch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LNL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/LNL.png -------------------------------------------------------------------------------- /LNL.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LibSample/AesEncryptLayer.cs: -------------------------------------------------------------------------------- 1 | using LiteNetLib.Layers; 2 | using System; 3 | using System.Net; 4 | using System.Security.Cryptography; 5 | 6 | namespace LibSample 7 | { 8 | /// 9 | /// Uses AES encryption in CBC mode. Make sure you handle your key properly. 10 | /// GCHandle.Alloc(key, GCHandleType.Pinned) to avoid your key being moved around different memory segments. 11 | /// ZeroMemory(gch.AddrOfPinnedObject(), key.Length); to erase it when you are done. 12 | /// Speed varies greatly depending on hardware encryption support. 13 | /// Why encrypt: http://ithare.com/udp-for-games-security-encryption-and-ddos-protection/ 14 | /// 15 | public class AesEncryptLayer : PacketLayerBase 16 | { 17 | public const int KeySize = 256; 18 | public const int BlockSize = 128; 19 | public const int KeySizeInBytes = KeySize / 8; 20 | public const int BlockSizeInBytes = BlockSize / 8; 21 | 22 | private readonly Aes _aes; 23 | private ICryptoTransform _encryptor; 24 | private byte[] cipherBuffer = new byte[1500]; //Max possible UDP packet size 25 | private ICryptoTransform _decryptor; 26 | private byte[] ivBuffer = new byte[BlockSizeInBytes]; 27 | 28 | /// 29 | /// Should be safe against eavesdropping, but is vulnerable to tampering 30 | /// Needs a HMAC on top of the encrypted content to be fully safe 31 | /// 32 | /// 33 | /// 34 | public AesEncryptLayer(byte[] key) : base(BlockSizeInBytes * 2) 35 | { 36 | if (key.Length != KeySizeInBytes) throw new NotSupportedException("EncryptLayer only supports keysize " + KeySize); 37 | 38 | //Switch this with AesGCM for better performance, requires .NET Core 3.0 or Standard 2.1 39 | _aes = Aes.Create(); 40 | _aes.KeySize = KeySize; 41 | _aes.BlockSize = BlockSize; 42 | _aes.Key = key; 43 | _aes.Mode = CipherMode.CBC; 44 | _aes.Padding = PaddingMode.PKCS7; 45 | 46 | _encryptor = _aes.CreateEncryptor(); 47 | _decryptor = _aes.CreateDecryptor(); 48 | } 49 | 50 | public override void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int length) 51 | { 52 | //Can't copy directly to _aes.IV. It won't work for some reason. 53 | Buffer.BlockCopy(data, 0, ivBuffer, 0, ivBuffer.Length); 54 | //_aes.IV = ivBuffer; 55 | _decryptor = _aes.CreateDecryptor(_aes.Key, ivBuffer); 56 | 57 | //int currentRead = ivBuffer.Length; 58 | //int currentWrite = 0; 59 | 60 | //TransformBlocks(_decryptor, data, length, ref currentRead, ref currentWrite); 61 | byte[] lastBytes = _decryptor.TransformFinalBlock(data, BlockSizeInBytes, length - BlockSizeInBytes); 62 | 63 | data = lastBytes; 64 | length = lastBytes.Length; 65 | } 66 | 67 | public override void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) 68 | { 69 | //Some Unity platforms may need these (and will be slower + generate garbage) 70 | if (!_encryptor.CanReuseTransform) 71 | { 72 | _aes.GenerateIV(); 73 | _encryptor = _aes.CreateEncryptor(); 74 | } 75 | 76 | //Copy IV in plaintext to output, this is standard practice 77 | _aes.IV.CopyTo(cipherBuffer, 0); 78 | 79 | int currentRead = offset; 80 | int currentWrite = _aes.IV.Length; 81 | byte[] lastBytes = _encryptor.TransformFinalBlock(data, currentRead, length - offset); 82 | lastBytes.CopyTo(cipherBuffer, currentWrite); 83 | //TransformBlocks(_encryptor, data, length, ref currentRead, ref currentWrite); 84 | 85 | data = cipherBuffer; 86 | offset = 0; 87 | length = lastBytes.Length + BlockSizeInBytes; 88 | } 89 | 90 | private void TransformBlocks(ICryptoTransform transform, byte[] input, int inputLength, ref int currentRead, ref int currentWrite) 91 | { 92 | //This loop produces a invalid padding exception 93 | //I'm leaving it here as a start point in case others need support for 94 | //Platforms wheere !transfom.CanTransformMultipleBlocks 95 | if (!transform.CanTransformMultipleBlocks) 96 | { 97 | while (inputLength - currentRead > BlockSizeInBytes) 98 | { 99 | int encryptedCount = transform.TransformBlock(input, currentRead, BlockSizeInBytes, cipherBuffer, currentWrite); 100 | currentRead += encryptedCount; 101 | currentWrite += encryptedCount; 102 | } 103 | } 104 | 105 | byte[] lastBytes = transform.TransformFinalBlock(input, currentRead, inputLength - currentRead); 106 | lastBytes.CopyTo(cipherBuffer, currentWrite); 107 | currentWrite += lastBytes.Length; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /LibSample/AesEncryptionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | 7 | namespace LibSample 8 | { 9 | class AesEncryptionTest : IExample 10 | { 11 | public void Run() => AesLayerEncryptDecrypt(); 12 | 13 | private void AesLayerEncryptDecrypt() 14 | { 15 | IPEndPoint emptyEndPoint = null; 16 | 17 | var keyGen = RandomNumberGenerator.Create(); 18 | byte[] key = new byte[AesEncryptLayer.KeySizeInBytes]; 19 | keyGen.GetBytes(key); 20 | const string testData = "This text is long enough to need multiple blocks to encrypt"; 21 | 22 | var outboudLayer = new AesEncryptLayer(key); 23 | byte[] outbound = Encoding.ASCII.GetBytes(testData); 24 | int lengthOfPacket = outbound.Length; 25 | int start = 0; 26 | int length = outbound.Length; 27 | outboudLayer.ProcessOutBoundPacket(ref emptyEndPoint, ref outbound, ref start, ref length); 28 | 29 | int minLenth = lengthOfPacket + AesEncryptLayer.BlockSizeInBytes; 30 | int maxLength = lengthOfPacket + outboudLayer.ExtraPacketSizeForLayer; 31 | if (length < minLenth || length > maxLength) 32 | { 33 | throw new Exception("Packet length out of bounds"); 34 | } 35 | 36 | var inboundLayer = new AesEncryptLayer(key); 37 | //Copy array so we dont read and write to same array 38 | byte[] inboundData = new byte[outbound.Length]; 39 | outbound.CopyTo(inboundData, 0); 40 | inboundLayer.ProcessInboundPacket(ref emptyEndPoint, ref inboundData, ref length); 41 | 42 | Console.WriteLine(Encoding.ASCII.GetString(inboundData, 0, length)); 43 | byte[] expectedPlaintext = Encoding.ASCII.GetBytes(testData); 44 | 45 | var isEqualLength = expectedPlaintext.Length == length; 46 | var areContentEqual = expectedPlaintext.SequenceEqual(inboundData); 47 | if (isEqualLength && areContentEqual) 48 | { 49 | Console.WriteLine("Test complete"); 50 | } 51 | else 52 | { 53 | throw new Exception("Test failed, decrypted data not equal to original"); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LibSample/GithubSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using LiteNetLib; 4 | using LiteNetLib.Utils; 5 | 6 | namespace LibSample 7 | { 8 | class GithubSample 9 | { 10 | public void Server() 11 | { 12 | EventBasedNetListener listener = new EventBasedNetListener(); 13 | NetManager server = new NetManager(listener); 14 | server.Start(9050 /* port */); 15 | 16 | listener.ConnectionRequestEvent += request => 17 | { 18 | if(server.ConnectedPeersCount < 10 /* max connections */) 19 | request.AcceptIfKey("SomeConnectionKey"); 20 | else 21 | request.Reject(); 22 | }; 23 | 24 | listener.PeerConnectedEvent += peer => 25 | { 26 | Console.WriteLine("We got connection: {0}", peer); // Show peer ip 27 | NetDataWriter writer = new NetDataWriter(); // Create writer class 28 | writer.Put("Hello client!"); // Put some string 29 | peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability 30 | }; 31 | 32 | while (!Console.KeyAvailable) 33 | { 34 | server.PollEvents(); 35 | Thread.Sleep(15); 36 | } 37 | 38 | server.Stop(); 39 | } 40 | 41 | public void Client() 42 | { 43 | EventBasedNetListener listener = new EventBasedNetListener(); 44 | NetManager client = new NetManager(listener); 45 | client.Start(); 46 | client.Connect("localhost" /* host ip or name */, 9050 /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); 47 | listener.NetworkReceiveEvent += (fromPeer, dataReader, channel, deliveryMethod) => 48 | { 49 | Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); 50 | dataReader.Recycle(); 51 | }; 52 | 53 | while (!Console.KeyAvailable) 54 | { 55 | client.PollEvents(); 56 | Thread.Sleep(15); 57 | } 58 | 59 | client.Stop(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /LibSample/IExample.cs: -------------------------------------------------------------------------------- 1 | namespace LibSample 2 | { 3 | public interface IExample 4 | { 5 | void Run(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /LibSample/LibSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0;net7.0;net6.0 6 | net8.0;net7.0;net6.0;net471 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /LibSample/NtpTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using LiteNetLib; 4 | 5 | namespace LibSample 6 | { 7 | public class NtpTest : IExample 8 | { 9 | public void Run() 10 | { 11 | RequestNtpService("0.pool.ntp.org"); 12 | } 13 | 14 | private void RequestNtpService(string ntpService) 15 | { 16 | Console.WriteLine($"Request time from \"{ntpService}\" service"); 17 | var ntpComplete = false; 18 | EventBasedNetListener listener = new EventBasedNetListener(); 19 | listener.NtpResponseEvent += ntpPacket => 20 | { 21 | if (ntpPacket != null) 22 | Console.WriteLine("[MAIN] NTP time test offset: " + ntpPacket.CorrectionOffset); 23 | else 24 | Console.WriteLine("[MAIN] NTP time error"); 25 | ntpComplete = true; 26 | }; 27 | 28 | NetManager nm = new NetManager(listener); 29 | nm.Start(); 30 | nm.CreateNtpRequest(ntpService); 31 | 32 | while (!ntpComplete) 33 | { 34 | Thread.Yield(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LibSample/PacketProcessorExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using LiteNetLib; 5 | using LiteNetLib.Utils; 6 | 7 | namespace LibSample 8 | { 9 | struct CustomStruct : INetSerializable 10 | { 11 | public int X; 12 | public int Y; 13 | 14 | public void Serialize(NetDataWriter writer) 15 | { 16 | writer.Put(X); 17 | writer.Put(Y); 18 | } 19 | 20 | public void Deserialize(NetDataReader reader) 21 | { 22 | X = reader.GetInt(); 23 | Y = reader.GetInt(); 24 | } 25 | } 26 | 27 | class ArgumentsForLogin 28 | { 29 | public string UserId { get; set; } 30 | public string Password { get; set; } 31 | public int SomeInt { get; set; } 32 | public List SomeList { get; set; } 33 | } 34 | 35 | class PacketProcessorExample : IExample 36 | { 37 | private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); 38 | private NetManager _client; 39 | private NetManager _server; 40 | private NetDataWriter _writer = new NetDataWriter(); 41 | 42 | public void Run() 43 | { 44 | //setup netpacketprocessor 45 | _netPacketProcessor.RegisterNestedType(); 46 | _netPacketProcessor.SubscribeReusable(Method1); 47 | 48 | //setup events 49 | EventBasedNetListener clientListener = new EventBasedNetListener(); 50 | EventBasedNetListener serverListener = new EventBasedNetListener(); 51 | serverListener.ConnectionRequestEvent += request => 52 | { 53 | request.AcceptIfKey("key"); 54 | }; 55 | serverListener.NetworkReceiveEvent += 56 | (peer, reader, channel, method) => 57 | { 58 | _netPacketProcessor.ReadAllPackets(reader, peer); 59 | }; 60 | clientListener.PeerConnectedEvent += peer => 61 | { 62 | //send after connect 63 | var testList = new List 64 | { 65 | new CustomStruct {X = 1, Y = -1}, 66 | new CustomStruct {X = 5, Y = -28}, 67 | new CustomStruct {X = -114, Y = 65535} 68 | }; 69 | _writer.Reset(); 70 | _netPacketProcessor.Write(_writer, new ArgumentsForLogin { Password = "pass", SomeInt = 5, UserId = "someUser", SomeList = testList }); 71 | peer.Send(_writer, DeliveryMethod.ReliableOrdered); 72 | }; 73 | 74 | //start client/server 75 | _client = new NetManager(clientListener); 76 | _server = new NetManager(serverListener); 77 | _client.Start(); 78 | _server.Start(9050); 79 | _client.Connect("localhost", 9050, "key"); 80 | 81 | while (!Console.KeyAvailable) 82 | { 83 | _server.PollEvents(); 84 | _client.PollEvents(); 85 | Thread.Sleep(10); 86 | } 87 | _client.Stop(); 88 | _server.Stop(); 89 | } 90 | 91 | void Method1(ArgumentsForLogin args, NetPeer peer) 92 | { 93 | Console.WriteLine("Received: \n {0}\n {1}\n {2}", args.UserId, args.Password, args.SomeInt); 94 | Console.WriteLine("List count: " + args.SomeList.Count); 95 | for (int i = 0; i < args.SomeList.Count; i++) 96 | { 97 | Console.WriteLine($" X: {args.SomeList[i].X}, Y: {args.SomeList[i].Y}"); 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /LibSample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace LibSample 5 | { 6 | public static class Program 7 | { 8 | private static readonly IExample[] Examples = { 9 | new EchoMessagesTest(), 10 | new HolePunchServerTest(), 11 | new BroadcastTest(), 12 | new SerializerBenchmark(), 13 | new SpeedBench(), 14 | new PacketProcessorExample(), 15 | new AesEncryptionTest(), 16 | new NtpTest(), 17 | }; 18 | 19 | static void Main(string[] args) 20 | { 21 | AppendExampleMenu(MenuStringBuilder); 22 | WriteAndClean(MenuStringBuilder); 23 | 24 | do 25 | { 26 | Console.Write("Write command: "); 27 | var input = Console.ReadLine(); 28 | 29 | if (input != null) 30 | { 31 | var lcInput = input.ToLower(); 32 | 33 | if (lcInput == "help" || lcInput == "h") 34 | { 35 | AppendFullHelpMenu(MenuStringBuilder); 36 | WriteAndClean(MenuStringBuilder); 37 | continue; 38 | } 39 | 40 | if (lcInput == "quit" || lcInput == "exit" || lcInput == "q" || lcInput == "e") 41 | { 42 | break; 43 | } 44 | 45 | if (int.TryParse(input, out var optionKey)) 46 | { 47 | if (optionKey < 0 || optionKey >= Examples.Length) 48 | { 49 | PrintInvalidCommand(input); 50 | continue; 51 | } 52 | 53 | ((IExample)Activator.CreateInstance(Examples[optionKey].GetType())).Run(); 54 | } 55 | else 56 | { 57 | PrintInvalidCommand(input); 58 | } 59 | } 60 | else 61 | { 62 | PrintInvalidCommand(string.Empty); 63 | } 64 | } while (true); 65 | } 66 | 67 | private static void PrintInvalidCommand(string invalidInput) 68 | { 69 | AppendInvalidCommand(MenuStringBuilder, invalidInput); 70 | WriteAndClean(MenuStringBuilder); 71 | } 72 | 73 | private static readonly StringBuilder MenuStringBuilder = new StringBuilder(); 74 | 75 | private static void WriteAndClean(StringBuilder sb) 76 | { 77 | Console.WriteLine(sb.ToString()); 78 | sb.Clear(); 79 | } 80 | 81 | private static void AppendInvalidCommand(StringBuilder sb, string invalidInput) 82 | { 83 | sb.Append("Invalid input \""); 84 | sb.Append(string.IsNullOrWhiteSpace(invalidInput) ? "[Whitespace/Empty Line]" : invalidInput); 85 | sb.AppendLine("\" command. Write \"help\" command for more information."); 86 | } 87 | 88 | private static void AppendFullHelpMenu(StringBuilder sb) 89 | { 90 | sb.AppendLine(); 91 | sb.AppendLine("\"help/h\" - write helper text for this console menu."); 92 | sb.AppendLine("\"exit/e/quit/q\" - close app"); 93 | AppendExampleMenu(sb); 94 | sb.AppendLine(); 95 | } 96 | 97 | private static void AppendExampleMenu(StringBuilder sb) 98 | { 99 | for (var i = 0; i < Examples.Length; i++) 100 | { 101 | var example = Examples[i]; 102 | sb.AppendLine($"\"{i}\" - Example of {example.GetType().Name}"); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /LiteNetLib.Tests/CRC32LayerTest.cs: -------------------------------------------------------------------------------- 1 | using LiteNetLib.Layers; 2 | using LiteNetLib.Utils; 3 | using NUnit.Framework; 4 | using System; 5 | using System.Net; 6 | 7 | namespace LiteNetLib.Tests 8 | { 9 | [TestFixture] 10 | public class CRC32LayerTest 11 | { 12 | private Crc32cLayer _crc32Layer; 13 | private IPEndPoint _dummyEndpoint; 14 | 15 | [SetUp] 16 | public void Setup() 17 | { 18 | NetDebug.Logger = null; 19 | _crc32Layer = new Crc32cLayer(); 20 | _dummyEndpoint = new IPEndPoint(IPAddress.Loopback, 23456); 21 | } 22 | 23 | [Test] 24 | public void ReturnsDataWithoutChecksum() 25 | { 26 | byte[] packet = GetTestPacketWithCrc(); 27 | 28 | int length = packet.Length; 29 | _crc32Layer.ProcessInboundPacket(ref _dummyEndpoint, ref packet, ref length); 30 | 31 | Assert.AreEqual(packet.Length - CRC32C.ChecksumSize, length); 32 | } 33 | 34 | [Test] 35 | public void ReturnsNilCountForBadChecksum() 36 | { 37 | byte[] packet = GetTestPacketWithCrc(); 38 | 39 | //Fake a change to the data to cause data/crc missmatch 40 | packet[4] = 0; 41 | 42 | int length = packet.Length; 43 | _crc32Layer.ProcessInboundPacket(ref _dummyEndpoint, ref packet, ref length); 44 | 45 | Assert.AreEqual(0, length); 46 | } 47 | 48 | [Test] 49 | public void ReturnsNilCountForTooShortMessage() 50 | { 51 | byte[] packet = new byte[2]; 52 | 53 | int length = packet.Length; 54 | 55 | _crc32Layer.ProcessInboundPacket(ref _dummyEndpoint, ref packet, ref length); 56 | 57 | Assert.AreEqual(0, length); 58 | } 59 | 60 | [Test] 61 | public void CanSendAndReceiveSameMessage() 62 | { 63 | byte[] message = GetTestMessageBytes(); 64 | //Process outbound adds bytes, so we need a larger array 65 | byte[] package = new byte[message.Length + CRC32C.ChecksumSize]; 66 | 67 | Buffer.BlockCopy(message, 0, package, 0, message.Length); 68 | 69 | int offset = 0; 70 | int length = message.Length; 71 | _crc32Layer.ProcessOutBoundPacket(ref _dummyEndpoint, ref package, ref offset, ref length); 72 | _crc32Layer.ProcessInboundPacket(ref _dummyEndpoint, ref package, ref length); 73 | } 74 | 75 | private static byte[] GetTestPacketWithCrc() 76 | { 77 | byte[] testMsg = GetTestMessageBytes(); 78 | uint crc32 = CRC32C.Compute(testMsg, 0, testMsg.Length); 79 | 80 | byte[] packet = new byte[testMsg.Length + CRC32C.ChecksumSize]; 81 | Buffer.BlockCopy(testMsg, 0, packet, 0, testMsg.Length); 82 | FastBitConverter.GetBytes(packet, testMsg.Length, crc32); 83 | return packet; 84 | } 85 | 86 | private static byte[] GetTestMessageBytes() 87 | => System.Text.Encoding.ASCII.GetBytes("This is a test string with some length"); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /LiteNetLib.Tests/LiteNetLib.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Library 5 | net8.0;net7.0;net6.0; 6 | net8.0;net7.0;net6.0;net471 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /LiteNetLib.Tests/TestUtility/NetManagerStack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using LiteNetLib.Layers; 5 | using NUnit.Framework; 6 | 7 | namespace LiteNetLib.Tests.TestUtility 8 | { 9 | public class NetManagerStack : IDisposable 10 | { 11 | private struct NetContainer 12 | { 13 | public readonly NetManager Manager; 14 | public readonly EventBasedNetListener Listener; 15 | 16 | public NetContainer(NetManager netManager, EventBasedNetListener listener) 17 | { 18 | Manager = netManager; 19 | Listener = listener; 20 | } 21 | } 22 | 23 | private readonly string _appKey; 24 | private readonly int _serverPort; 25 | 26 | private readonly HashSet _clientIds = new HashSet(); 27 | private readonly HashSet _serverIds = new HashSet(); 28 | 29 | private readonly Dictionary _managers = 30 | new Dictionary(); 31 | 32 | public NetManagerStack(string appKey, int serverPort) 33 | { 34 | _appKey = appKey; 35 | _serverPort = serverPort; 36 | } 37 | 38 | public void ClientForeach(Action action) 39 | { 40 | foreach (var id in _clientIds) 41 | { 42 | var tuple = GetNetworkManager(id, true); 43 | action(id, tuple.Manager, tuple.Listener); 44 | } 45 | } 46 | 47 | public void ServerForeach(Action action) 48 | { 49 | foreach (var id in _clientIds) 50 | { 51 | var tuple = GetNetworkManager(id, false); 52 | action(id, tuple.Manager, tuple.Listener); 53 | } 54 | } 55 | 56 | public NetManager Client(ushort id) 57 | { 58 | _clientIds.Add(id); 59 | return GetNetworkManager(id, true).Manager; 60 | } 61 | 62 | public EventBasedNetListener ClientListener(ushort id) 63 | { 64 | _clientIds.Add(id); 65 | return GetNetworkManager(id, true).Listener; 66 | } 67 | 68 | public NetManager Server(ushort id) 69 | { 70 | _serverIds.Add(id); 71 | return GetNetworkManager(id, false).Manager; 72 | } 73 | 74 | public EventBasedNetListener ServerListener(ushort id) 75 | { 76 | _serverIds.Add(id); 77 | return GetNetworkManager(id, false).Listener; 78 | } 79 | 80 | public void Dispose() 81 | { 82 | foreach (var manager in _managers.Values.Select(v => v.Manager)) 83 | { 84 | manager.Stop(); 85 | } 86 | } 87 | 88 | private NetContainer GetNetworkManager(ushort id, bool isClient) 89 | { 90 | NetContainer container; 91 | if (id == 0) 92 | { 93 | Assert.Fail("Id cannot be 0"); 94 | } 95 | 96 | var key = isClient ? id : (uint) id << 16; 97 | if (!_managers.TryGetValue(key, out container)) 98 | { 99 | var listener = new EventBasedNetListener(); 100 | listener.ConnectionRequestEvent += request => 101 | { 102 | request.AcceptIfKey(_appKey); 103 | }; 104 | NetManager netManager = new NetManager(listener, new Crc32cLayer()); 105 | if (isClient) 106 | { 107 | if (!netManager.Start()) 108 | { 109 | Assert.Fail($"Client {id} start failed"); 110 | } 111 | } 112 | else 113 | { 114 | if (!netManager.Start(_serverPort)) 115 | { 116 | Assert.Fail($"Server {id} on port{_serverPort} start failed"); 117 | } 118 | } 119 | 120 | container = new NetContainer(netManager, listener); 121 | _managers[key] = container; 122 | } 123 | 124 | return container; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /LiteNetLib.Trim.Dummy/LiteNetLib.Trim.Dummy.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /LiteNetLib.Trim.Dummy/Program.cs: -------------------------------------------------------------------------------- 1 | // I'm a dummy for assembly trimming since the built-in analyzer isn't perfect yet. 2 | // Please build me with `dotnet publish -c Release -r win-x64` (or similar) and test for warnings. 3 | Console.WriteLine("Hello, World!"); 4 | -------------------------------------------------------------------------------- /LiteNetLib/BaseChannel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | 4 | namespace LiteNetLib 5 | { 6 | internal abstract class BaseChannel 7 | { 8 | protected readonly NetPeer Peer; 9 | protected readonly Queue OutgoingQueue = new Queue(NetConstants.DefaultWindowSize); 10 | private int _isAddedToPeerChannelSendQueue; 11 | 12 | public int PacketsInQueue => OutgoingQueue.Count; 13 | 14 | protected BaseChannel(NetPeer peer) 15 | { 16 | Peer = peer; 17 | } 18 | 19 | public void AddToQueue(NetPacket packet) 20 | { 21 | lock (OutgoingQueue) 22 | { 23 | OutgoingQueue.Enqueue(packet); 24 | } 25 | AddToPeerChannelSendQueue(); 26 | } 27 | 28 | protected void AddToPeerChannelSendQueue() 29 | { 30 | if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0) 31 | { 32 | Peer.AddToReliableChannelSendQueue(this); 33 | } 34 | } 35 | 36 | public bool SendAndCheckQueue() 37 | { 38 | bool hasPacketsToSend = SendNextPackets(); 39 | if (!hasPacketsToSend) 40 | Interlocked.Exchange(ref _isAddedToPeerChannelSendQueue, 0); 41 | 42 | return hasPacketsToSend; 43 | } 44 | 45 | protected abstract bool SendNextPackets(); 46 | public abstract bool ProcessPacket(NetPacket packet); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /LiteNetLib/ConnectionRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading; 3 | using LiteNetLib.Utils; 4 | 5 | namespace LiteNetLib 6 | { 7 | internal enum ConnectionRequestResult 8 | { 9 | None, 10 | Accept, 11 | Reject, 12 | RejectForce 13 | } 14 | 15 | public class ConnectionRequest 16 | { 17 | private readonly NetManager _listener; 18 | private int _used; 19 | 20 | public NetDataReader Data => InternalPacket.Data; 21 | 22 | internal ConnectionRequestResult Result { get; private set; } 23 | internal NetConnectRequestPacket InternalPacket; 24 | 25 | public readonly IPEndPoint RemoteEndPoint; 26 | 27 | internal void UpdateRequest(NetConnectRequestPacket connectRequest) 28 | { 29 | //old request 30 | if (connectRequest.ConnectionTime < InternalPacket.ConnectionTime) 31 | return; 32 | 33 | if (connectRequest.ConnectionTime == InternalPacket.ConnectionTime && 34 | connectRequest.ConnectionNumber == InternalPacket.ConnectionNumber) 35 | return; 36 | 37 | InternalPacket = connectRequest; 38 | } 39 | 40 | private bool TryActivate() 41 | { 42 | return Interlocked.CompareExchange(ref _used, 1, 0) == 0; 43 | } 44 | 45 | internal ConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket, NetManager listener) 46 | { 47 | InternalPacket = requestPacket; 48 | RemoteEndPoint = remoteEndPoint; 49 | _listener = listener; 50 | } 51 | 52 | public NetPeer AcceptIfKey(string key) 53 | { 54 | if (!TryActivate()) 55 | return null; 56 | try 57 | { 58 | if (Data.GetString() == key) 59 | Result = ConnectionRequestResult.Accept; 60 | } 61 | catch 62 | { 63 | NetDebug.WriteError("[AC] Invalid incoming data"); 64 | } 65 | if (Result == ConnectionRequestResult.Accept) 66 | return _listener.OnConnectionSolved(this, null, 0, 0); 67 | 68 | Result = ConnectionRequestResult.Reject; 69 | _listener.OnConnectionSolved(this, null, 0, 0); 70 | return null; 71 | } 72 | 73 | /// 74 | /// Accept connection and get new NetPeer as result 75 | /// 76 | /// Connected NetPeer 77 | public NetPeer Accept() 78 | { 79 | if (!TryActivate()) 80 | return null; 81 | Result = ConnectionRequestResult.Accept; 82 | return _listener.OnConnectionSolved(this, null, 0, 0); 83 | } 84 | 85 | public void Reject(byte[] rejectData, int start, int length, bool force) 86 | { 87 | if (!TryActivate()) 88 | return; 89 | Result = force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject; 90 | _listener.OnConnectionSolved(this, rejectData, start, length); 91 | } 92 | 93 | public void Reject(byte[] rejectData, int start, int length) 94 | { 95 | Reject(rejectData, start, length, false); 96 | } 97 | 98 | 99 | public void RejectForce(byte[] rejectData, int start, int length) 100 | { 101 | Reject(rejectData, start, length, true); 102 | } 103 | 104 | public void RejectForce() 105 | { 106 | Reject(null, 0, 0, true); 107 | } 108 | 109 | public void RejectForce(byte[] rejectData) 110 | { 111 | Reject(rejectData, 0, rejectData.Length, true); 112 | } 113 | 114 | public void RejectForce(NetDataWriter rejectData) 115 | { 116 | Reject(rejectData.Data, 0, rejectData.Length, true); 117 | } 118 | 119 | public void Reject() 120 | { 121 | Reject(null, 0, 0, false); 122 | } 123 | 124 | public void Reject(byte[] rejectData) 125 | { 126 | Reject(rejectData, 0, rejectData.Length, false); 127 | } 128 | 129 | public void Reject(NetDataWriter rejectData) 130 | { 131 | Reject(rejectData.Data, 0, rejectData.Length, false); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /LiteNetLib/InternalPackets.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using LiteNetLib.Utils; 4 | 5 | namespace LiteNetLib 6 | { 7 | internal sealed class NetConnectRequestPacket 8 | { 9 | public const int HeaderSize = 18; 10 | public readonly long ConnectionTime; 11 | public byte ConnectionNumber; 12 | public readonly byte[] TargetAddress; 13 | public readonly NetDataReader Data; 14 | public readonly int PeerId; 15 | 16 | private NetConnectRequestPacket(long connectionTime, byte connectionNumber, int localId, byte[] targetAddress, NetDataReader data) 17 | { 18 | ConnectionTime = connectionTime; 19 | ConnectionNumber = connectionNumber; 20 | TargetAddress = targetAddress; 21 | Data = data; 22 | PeerId = localId; 23 | } 24 | 25 | public static int GetProtocolId(NetPacket packet) 26 | { 27 | return BitConverter.ToInt32(packet.RawData, 1); 28 | } 29 | 30 | public static NetConnectRequestPacket FromData(NetPacket packet) 31 | { 32 | if (packet.ConnectionNumber >= NetConstants.MaxConnectionNumber) 33 | return null; 34 | 35 | //Getting connection time for peer 36 | long connectionTime = BitConverter.ToInt64(packet.RawData, 5); 37 | 38 | //Get peer id 39 | int peerId = BitConverter.ToInt32(packet.RawData, 13); 40 | 41 | //Get target address 42 | int addrSize = packet.RawData[HeaderSize-1]; 43 | if (addrSize != 16 && addrSize != 28) 44 | return null; 45 | byte[] addressBytes = new byte[addrSize]; 46 | Buffer.BlockCopy(packet.RawData, HeaderSize, addressBytes, 0, addrSize); 47 | 48 | // Read data and create request 49 | var reader = new NetDataReader(null, 0, 0); 50 | if (packet.Size > HeaderSize+addrSize) 51 | reader.SetSource(packet.RawData, HeaderSize + addrSize, packet.Size); 52 | 53 | return new NetConnectRequestPacket(connectionTime, packet.ConnectionNumber, peerId, addressBytes, reader); 54 | } 55 | 56 | public static NetPacket Make(NetDataWriter connectData, SocketAddress addressBytes, long connectTime, int localId) 57 | { 58 | //Make initial packet 59 | var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size); 60 | 61 | //Add data 62 | FastBitConverter.GetBytes(packet.RawData, 1, NetConstants.ProtocolId); 63 | FastBitConverter.GetBytes(packet.RawData, 5, connectTime); 64 | FastBitConverter.GetBytes(packet.RawData, 13, localId); 65 | packet.RawData[HeaderSize-1] = (byte)addressBytes.Size; 66 | for (int i = 0; i < addressBytes.Size; i++) 67 | packet.RawData[HeaderSize + i] = addressBytes[i]; 68 | Buffer.BlockCopy(connectData.Data, 0, packet.RawData, HeaderSize + addressBytes.Size, connectData.Length); 69 | return packet; 70 | } 71 | } 72 | 73 | internal sealed class NetConnectAcceptPacket 74 | { 75 | public const int Size = 15; 76 | public readonly long ConnectionTime; 77 | public readonly byte ConnectionNumber; 78 | public readonly int PeerId; 79 | public readonly bool PeerNetworkChanged; 80 | 81 | private NetConnectAcceptPacket(long connectionTime, byte connectionNumber, int peerId, bool peerNetworkChanged) 82 | { 83 | ConnectionTime = connectionTime; 84 | ConnectionNumber = connectionNumber; 85 | PeerId = peerId; 86 | PeerNetworkChanged = peerNetworkChanged; 87 | } 88 | 89 | public static NetConnectAcceptPacket FromData(NetPacket packet) 90 | { 91 | if (packet.Size != Size) 92 | return null; 93 | 94 | long connectionId = BitConverter.ToInt64(packet.RawData, 1); 95 | 96 | //check connect num 97 | byte connectionNumber = packet.RawData[9]; 98 | if (connectionNumber >= NetConstants.MaxConnectionNumber) 99 | return null; 100 | 101 | //check reused flag 102 | byte isReused = packet.RawData[10]; 103 | if (isReused > 1) 104 | return null; 105 | 106 | //get remote peer id 107 | int peerId = BitConverter.ToInt32(packet.RawData, 11); 108 | if (peerId < 0) 109 | return null; 110 | 111 | return new NetConnectAcceptPacket(connectionId, connectionNumber, peerId, isReused == 1); 112 | } 113 | 114 | public static NetPacket Make(long connectTime, byte connectNum, int localPeerId) 115 | { 116 | var packet = new NetPacket(PacketProperty.ConnectAccept, 0); 117 | FastBitConverter.GetBytes(packet.RawData, 1, connectTime); 118 | packet.RawData[9] = connectNum; 119 | FastBitConverter.GetBytes(packet.RawData, 11, localPeerId); 120 | return packet; 121 | } 122 | 123 | public static NetPacket MakeNetworkChanged(NetPeer peer) 124 | { 125 | var packet = new NetPacket(PacketProperty.PeerNotFound, Size-1); 126 | FastBitConverter.GetBytes(packet.RawData, 1, peer.ConnectTime); 127 | packet.RawData[9] = peer.ConnectionNum; 128 | packet.RawData[10] = 1; 129 | FastBitConverter.GetBytes(packet.RawData, 11, peer.RemoteId); 130 | return packet; 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /LiteNetLib/Layers/Crc32cLayer.cs: -------------------------------------------------------------------------------- 1 | using LiteNetLib.Utils; 2 | using System; 3 | using System.Net; 4 | 5 | namespace LiteNetLib.Layers 6 | { 7 | public sealed class Crc32cLayer : PacketLayerBase 8 | { 9 | public Crc32cLayer() : base(CRC32C.ChecksumSize) 10 | { 11 | 12 | } 13 | 14 | public override void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int length) 15 | { 16 | if (length < NetConstants.HeaderSize + CRC32C.ChecksumSize) 17 | { 18 | NetDebug.WriteError("[NM] DataReceived size: bad!"); 19 | //Set length to 0 to have netManager drop the packet. 20 | length = 0; 21 | return; 22 | } 23 | 24 | int checksumPoint = length - CRC32C.ChecksumSize; 25 | if (CRC32C.Compute(data, 0, checksumPoint) != BitConverter.ToUInt32(data, checksumPoint)) 26 | { 27 | NetDebug.Write("[NM] DataReceived checksum: bad!"); 28 | //Set length to 0 to have netManager drop the packet. 29 | length = 0; 30 | return; 31 | } 32 | length -= CRC32C.ChecksumSize; 33 | } 34 | 35 | public override void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) 36 | { 37 | FastBitConverter.GetBytes(data, length, CRC32C.Compute(data, offset, length)); 38 | length += CRC32C.ChecksumSize; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LiteNetLib/Layers/PacketLayerBase.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace LiteNetLib.Layers 4 | { 5 | public abstract class PacketLayerBase 6 | { 7 | public readonly int ExtraPacketSizeForLayer; 8 | 9 | protected PacketLayerBase(int extraPacketSizeForLayer) 10 | { 11 | ExtraPacketSizeForLayer = extraPacketSizeForLayer; 12 | } 13 | 14 | public abstract void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int length); 15 | public abstract void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LiteNetLib/Layers/XorEncryptLayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Text; 4 | 5 | namespace LiteNetLib.Layers 6 | { 7 | public class XorEncryptLayer : PacketLayerBase 8 | { 9 | private byte[] _byteKey; 10 | 11 | public XorEncryptLayer() : base(0) 12 | { 13 | 14 | } 15 | 16 | public XorEncryptLayer(byte[] key) : this() 17 | { 18 | SetKey(key); 19 | } 20 | 21 | public XorEncryptLayer(string key) : this() 22 | { 23 | SetKey(key); 24 | } 25 | 26 | public void SetKey(string key) 27 | { 28 | _byteKey = Encoding.UTF8.GetBytes(key); 29 | } 30 | 31 | public void SetKey(byte[] key) 32 | { 33 | if (_byteKey == null || _byteKey.Length != key.Length) 34 | _byteKey = new byte[key.Length]; 35 | Buffer.BlockCopy(key, 0, _byteKey, 0, key.Length); 36 | } 37 | 38 | public override void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int length) 39 | { 40 | if (_byteKey == null) 41 | return; 42 | for (int i = 0; i < length; i++) 43 | { 44 | data[i] = (byte)(data[i] ^ _byteKey[i % _byteKey.Length]); 45 | } 46 | } 47 | 48 | public override void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) 49 | { 50 | if (_byteKey == null) 51 | return; 52 | int cur = offset; 53 | for (int i = 0; i < length; i++, cur++) 54 | { 55 | data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /LiteNetLib/LiteNetLib.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LiteNetLib", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": true, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [], 12 | "noEngineReferences": false 13 | } -------------------------------------------------------------------------------- /LiteNetLib/LiteNetLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LiteNetLib 5 | LiteNetLib 6 | net8.0;net7.0;net6.0;netstandard2.1;netstandard2.0 7 | net8.0;net7.0;net6.0;netstandard2.1;netstandard2.0;net471 8 | true 9 | Library 10 | 7.3 11 | 12 | true 13 | 1701;1702;1705;1591 14 | 1.3.1 15 | Lite reliable UDP library for Mono and .NET 16 | true 17 | true 18 | 1.3.1 19 | 20 | 21 | 22 | TRACE;DEBUG 23 | 24 | 25 | 26 | TRACE 27 | 28 | 29 | 30 | true 31 | $(DefineConstants);LITENETLIB_UNSAFE 32 | udp reliable-udp network 33 | https://github.com/RevenantX/LiteNetLib/releases/tag/1.3.1 34 | git 35 | https://github.com/RevenantX/LiteNetLib 36 | https://github.com/RevenantX/LiteNetLib 37 | MIT 38 | True 39 | Ruslan Pyrch 40 | Copyright 2024 Ruslan Pyrch 41 | Lite reliable UDP library for .NET, Mono, and .NET Core 42 | LNL.png 43 | README.md 44 | net6.0;net7.0;net8.0;netstandard2.0;netstandard2.1;net471 45 | 46 | 47 | 48 | 49 | True 50 | \ 51 | 52 | 53 | True 54 | \ 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /LiteNetLib/NetConstants.cs: -------------------------------------------------------------------------------- 1 | namespace LiteNetLib 2 | { 3 | /// 4 | /// Sending method type 5 | /// 6 | public enum DeliveryMethod : byte 7 | { 8 | /// 9 | /// Unreliable. Packets can be dropped, can be duplicated, can arrive without order. 10 | /// 11 | Unreliable = 4, 12 | 13 | /// 14 | /// Reliable. Packets won't be dropped, won't be duplicated, can arrive without order. 15 | /// 16 | ReliableUnordered = 0, 17 | 18 | /// 19 | /// Unreliable. Packets can be dropped, won't be duplicated, will arrive in order. 20 | /// 21 | Sequenced = 1, 22 | 23 | /// 24 | /// Reliable and ordered. Packets won't be dropped, won't be duplicated, will arrive in order. 25 | /// 26 | ReliableOrdered = 2, 27 | 28 | /// 29 | /// Reliable only last packet. Packets can be dropped (except the last one), won't be duplicated, will arrive in order. 30 | /// Cannot be fragmented 31 | /// 32 | ReliableSequenced = 3 33 | } 34 | 35 | /// 36 | /// Network constants. Can be tuned from sources for your purposes. 37 | /// 38 | public static class NetConstants 39 | { 40 | //can be tuned 41 | public const int DefaultWindowSize = 64; 42 | public const int SocketBufferSize = 1024 * 1024; //1mb 43 | public const int SocketTTL = 255; 44 | 45 | public const int HeaderSize = 1; 46 | public const int ChanneledHeaderSize = 4; 47 | public const int FragmentHeaderSize = 6; 48 | public const int FragmentedHeaderTotalSize = ChanneledHeaderSize + FragmentHeaderSize; 49 | public const ushort MaxSequence = 32768; 50 | public const ushort HalfMaxSequence = MaxSequence / 2; 51 | 52 | //protocol 53 | internal const int ProtocolId = 13; 54 | internal const int MaxUdpHeaderSize = 68; 55 | internal const int ChannelTypeCount = 4; 56 | 57 | internal static readonly int[] PossibleMtu = 58 | { 59 | //576 - MaxUdpHeaderSize minimal (RFC 1191) 60 | 1024, //most games standard 61 | 1232 - MaxUdpHeaderSize, 62 | 1460 - MaxUdpHeaderSize, //google cloud 63 | 1472 - MaxUdpHeaderSize, //VPN 64 | 1492 - MaxUdpHeaderSize, //Ethernet with LLC and SNAP, PPPoE (RFC 1042) 65 | 1500 - MaxUdpHeaderSize //Ethernet II (RFC 1191) 66 | }; 67 | 68 | //Max possible single packet size 69 | public static readonly int InitialMtu = PossibleMtu[0]; 70 | public static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1]; 71 | public static readonly int MaxUnreliableDataSize = MaxPacketSize - HeaderSize; 72 | 73 | //peer specific 74 | public const byte MaxConnectionNumber = 4; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /LiteNetLib/NetDebug.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace LiteNetLib 5 | { 6 | public class InvalidPacketException : ArgumentException 7 | { 8 | public InvalidPacketException(string message) : base(message) 9 | { 10 | } 11 | } 12 | 13 | public class TooBigPacketException : InvalidPacketException 14 | { 15 | public TooBigPacketException(string message) : base(message) 16 | { 17 | } 18 | } 19 | 20 | public enum NetLogLevel 21 | { 22 | Warning, 23 | Error, 24 | Trace, 25 | Info 26 | } 27 | 28 | /// 29 | /// Interface to implement for your own logger 30 | /// 31 | public interface INetLogger 32 | { 33 | void WriteNet(NetLogLevel level, string str, params object[] args); 34 | } 35 | 36 | /// 37 | /// Static class for defining your own LiteNetLib logger instead of Console.WriteLine 38 | /// or Debug.Log if compiled with UNITY flag 39 | /// 40 | public static class NetDebug 41 | { 42 | public static INetLogger Logger = null; 43 | private static readonly object DebugLogLock = new object(); 44 | private static void WriteLogic(NetLogLevel logLevel, string str, params object[] args) 45 | { 46 | lock (DebugLogLock) 47 | { 48 | if (Logger == null) 49 | { 50 | #if UNITY_5_3_OR_NEWER 51 | UnityEngine.Debug.Log(string.Format(str, args)); 52 | #else 53 | Console.WriteLine(str, args); 54 | #endif 55 | } 56 | else 57 | { 58 | Logger.WriteNet(logLevel, str, args); 59 | } 60 | } 61 | } 62 | 63 | [Conditional("DEBUG_MESSAGES")] 64 | internal static void Write(string str) 65 | { 66 | WriteLogic(NetLogLevel.Trace, str); 67 | } 68 | 69 | [Conditional("DEBUG_MESSAGES")] 70 | internal static void Write(NetLogLevel level, string str) 71 | { 72 | WriteLogic(level, str); 73 | } 74 | 75 | [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] 76 | internal static void WriteForce(string str) 77 | { 78 | WriteLogic(NetLogLevel.Trace, str); 79 | } 80 | 81 | [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] 82 | internal static void WriteForce(NetLogLevel level, string str) 83 | { 84 | WriteLogic(level, str); 85 | } 86 | 87 | internal static void WriteError(string str) 88 | { 89 | WriteLogic(NetLogLevel.Error, str); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /LiteNetLib/NetManager.PacketPool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LiteNetLib 4 | { 5 | public partial class NetManager 6 | { 7 | private NetPacket _poolHead; 8 | private int _poolCount; 9 | private readonly object _poolLock = new object(); 10 | 11 | /// 12 | /// Maximum packet pool size (increase if you have tons of packets sending) 13 | /// 14 | public int PacketPoolSize = 1000; 15 | 16 | public int PoolCount => _poolCount; 17 | 18 | private NetPacket PoolGetWithData(PacketProperty property, byte[] data, int start, int length) 19 | { 20 | int headerSize = NetPacket.GetHeaderSize(property); 21 | NetPacket packet = PoolGetPacket(length + headerSize); 22 | packet.Property = property; 23 | Buffer.BlockCopy(data, start, packet.RawData, headerSize, length); 24 | return packet; 25 | } 26 | 27 | //Get packet with size 28 | private NetPacket PoolGetWithProperty(PacketProperty property, int size) 29 | { 30 | NetPacket packet = PoolGetPacket(size + NetPacket.GetHeaderSize(property)); 31 | packet.Property = property; 32 | return packet; 33 | } 34 | 35 | private NetPacket PoolGetWithProperty(PacketProperty property) 36 | { 37 | NetPacket packet = PoolGetPacket(NetPacket.GetHeaderSize(property)); 38 | packet.Property = property; 39 | return packet; 40 | } 41 | 42 | internal NetPacket PoolGetPacket(int size) 43 | { 44 | if (size > NetConstants.MaxPacketSize) 45 | return new NetPacket(size); 46 | 47 | NetPacket packet; 48 | lock (_poolLock) 49 | { 50 | packet = _poolHead; 51 | if (packet == null) 52 | return new NetPacket(size); 53 | 54 | _poolHead = _poolHead.Next; 55 | _poolCount--; 56 | } 57 | 58 | packet.Size = size; 59 | if (packet.RawData.Length < size) 60 | packet.RawData = new byte[size]; 61 | return packet; 62 | } 63 | 64 | internal void PoolRecycle(NetPacket packet) 65 | { 66 | if (packet.RawData.Length > NetConstants.MaxPacketSize || _poolCount >= PacketPoolSize) 67 | { 68 | //Don't pool big packets. Save memory 69 | return; 70 | } 71 | 72 | //Clean fragmented flag 73 | packet.RawData[0] = 0; 74 | lock (_poolLock) 75 | { 76 | packet.Next = _poolHead; 77 | _poolHead = packet; 78 | _poolCount++; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /LiteNetLib/NetPacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LiteNetLib.Utils; 3 | 4 | namespace LiteNetLib 5 | { 6 | internal enum PacketProperty : byte 7 | { 8 | Unreliable, 9 | Channeled, 10 | Ack, 11 | Ping, 12 | Pong, 13 | ConnectRequest, 14 | ConnectAccept, 15 | Disconnect, 16 | UnconnectedMessage, 17 | MtuCheck, 18 | MtuOk, 19 | Broadcast, 20 | Merged, 21 | ShutdownOk, 22 | PeerNotFound, 23 | InvalidProtocol, 24 | NatMessage, 25 | Empty 26 | } 27 | 28 | internal sealed class NetPacket 29 | { 30 | private static readonly int PropertiesCount = Enum.GetValues(typeof(PacketProperty)).Length; 31 | private static readonly int[] HeaderSizes; 32 | 33 | static NetPacket() 34 | { 35 | HeaderSizes = NetUtils.AllocatePinnedUninitializedArray(PropertiesCount); 36 | for (int i = 0; i < HeaderSizes.Length; i++) 37 | { 38 | switch ((PacketProperty)i) 39 | { 40 | case PacketProperty.Channeled: 41 | case PacketProperty.Ack: 42 | HeaderSizes[i] = NetConstants.ChanneledHeaderSize; 43 | break; 44 | case PacketProperty.Ping: 45 | HeaderSizes[i] = NetConstants.HeaderSize + 2; 46 | break; 47 | case PacketProperty.ConnectRequest: 48 | HeaderSizes[i] = NetConnectRequestPacket.HeaderSize; 49 | break; 50 | case PacketProperty.ConnectAccept: 51 | HeaderSizes[i] = NetConnectAcceptPacket.Size; 52 | break; 53 | case PacketProperty.Disconnect: 54 | HeaderSizes[i] = NetConstants.HeaderSize + 8; 55 | break; 56 | case PacketProperty.Pong: 57 | HeaderSizes[i] = NetConstants.HeaderSize + 10; 58 | break; 59 | default: 60 | HeaderSizes[i] = NetConstants.HeaderSize; 61 | break; 62 | } 63 | } 64 | } 65 | 66 | //Header 67 | public PacketProperty Property 68 | { 69 | get => (PacketProperty)(RawData[0] & 0x1F); 70 | set => RawData[0] = (byte)((RawData[0] & 0xE0) | (byte)value); 71 | } 72 | 73 | public byte ConnectionNumber 74 | { 75 | get => (byte)((RawData[0] & 0x60) >> 5); 76 | set => RawData[0] = (byte) ((RawData[0] & 0x9F) | (value << 5)); 77 | } 78 | 79 | public ushort Sequence 80 | { 81 | get => BitConverter.ToUInt16(RawData, 1); 82 | set => FastBitConverter.GetBytes(RawData, 1, value); 83 | } 84 | 85 | public bool IsFragmented => (RawData[0] & 0x80) != 0; 86 | 87 | public void MarkFragmented() 88 | { 89 | RawData[0] |= 0x80; //set first bit 90 | } 91 | 92 | public byte ChannelId 93 | { 94 | get => RawData[3]; 95 | set => RawData[3] = value; 96 | } 97 | 98 | public ushort FragmentId 99 | { 100 | get => BitConverter.ToUInt16(RawData, 4); 101 | set => FastBitConverter.GetBytes(RawData, 4, value); 102 | } 103 | 104 | public ushort FragmentPart 105 | { 106 | get => BitConverter.ToUInt16(RawData, 6); 107 | set => FastBitConverter.GetBytes(RawData, 6, value); 108 | } 109 | 110 | public ushort FragmentsTotal 111 | { 112 | get => BitConverter.ToUInt16(RawData, 8); 113 | set => FastBitConverter.GetBytes(RawData, 8, value); 114 | } 115 | 116 | //Data 117 | public byte[] RawData; 118 | public int Size; 119 | 120 | //Delivery 121 | public object UserData; 122 | 123 | //Pool node 124 | public NetPacket Next; 125 | 126 | public NetPacket(int size) 127 | { 128 | RawData = new byte[size]; 129 | Size = size; 130 | } 131 | 132 | public NetPacket(PacketProperty property, int size) 133 | { 134 | size += GetHeaderSize(property); 135 | RawData = new byte[size]; 136 | Property = property; 137 | Size = size; 138 | } 139 | 140 | public static int GetHeaderSize(PacketProperty property) 141 | { 142 | return HeaderSizes[(int)property]; 143 | } 144 | 145 | public int GetHeaderSize() 146 | { 147 | return HeaderSizes[RawData[0] & 0x1F]; 148 | } 149 | 150 | public bool Verify() 151 | { 152 | byte property = (byte)(RawData[0] & 0x1F); 153 | if (property >= PropertiesCount) 154 | return false; 155 | int headerSize = HeaderSizes[property]; 156 | bool fragmented = (RawData[0] & 0x80) != 0; 157 | return Size >= headerSize && (!fragmented || Size >= headerSize + NetConstants.FragmentHeaderSize); 158 | } 159 | 160 | #if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1 161 | public static implicit operator Span(NetPacket p) => new Span(p.RawData, 0, p.Size); 162 | #endif 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /LiteNetLib/NetStatistics.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace LiteNetLib 4 | { 5 | public sealed class NetStatistics 6 | { 7 | private long _packetsSent; 8 | private long _packetsReceived; 9 | private long _bytesSent; 10 | private long _bytesReceived; 11 | private long _packetLoss; 12 | 13 | public long PacketsSent => Interlocked.Read(ref _packetsSent); 14 | public long PacketsReceived => Interlocked.Read(ref _packetsReceived); 15 | public long BytesSent => Interlocked.Read(ref _bytesSent); 16 | public long BytesReceived => Interlocked.Read(ref _bytesReceived); 17 | public long PacketLoss => Interlocked.Read(ref _packetLoss); 18 | 19 | public long PacketLossPercent 20 | { 21 | get 22 | { 23 | long sent = PacketsSent, loss = PacketLoss; 24 | 25 | return sent == 0 ? 0 : loss * 100 / sent; 26 | } 27 | } 28 | 29 | public void Reset() 30 | { 31 | Interlocked.Exchange(ref _packetsSent, 0); 32 | Interlocked.Exchange(ref _packetsReceived, 0); 33 | Interlocked.Exchange(ref _bytesSent, 0); 34 | Interlocked.Exchange(ref _bytesReceived, 0); 35 | Interlocked.Exchange(ref _packetLoss, 0); 36 | } 37 | 38 | public void IncrementPacketsSent() 39 | { 40 | Interlocked.Increment(ref _packetsSent); 41 | } 42 | 43 | public void IncrementPacketsReceived() 44 | { 45 | Interlocked.Increment(ref _packetsReceived); 46 | } 47 | 48 | public void AddBytesSent(long bytesSent) 49 | { 50 | Interlocked.Add(ref _bytesSent, bytesSent); 51 | } 52 | 53 | public void AddBytesReceived(long bytesReceived) 54 | { 55 | Interlocked.Add(ref _bytesReceived, bytesReceived); 56 | } 57 | 58 | public void IncrementPacketLoss() 59 | { 60 | Interlocked.Increment(ref _packetLoss); 61 | } 62 | 63 | public void AddPacketLoss(long packetLoss) 64 | { 65 | Interlocked.Add(ref _packetLoss, packetLoss); 66 | } 67 | 68 | public override string ToString() 69 | { 70 | return 71 | string.Format( 72 | "BytesReceived: {0}\nPacketsReceived: {1}\nBytesSent: {2}\nPacketsSent: {3}\nPacketLoss: {4}\nPacketLossPercent: {5}\n", 73 | BytesReceived, 74 | PacketsReceived, 75 | BytesSent, 76 | PacketsSent, 77 | PacketLoss, 78 | PacketLossPercent); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /LiteNetLib/PausedSocketFix.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_2018_3_OR_NEWER 2 | using System.Net; 3 | using UnityEngine; 4 | 5 | namespace LiteNetLib 6 | { 7 | public class PausedSocketFix 8 | { 9 | private readonly NetManager _netManager; 10 | private readonly IPAddress _ipv4; 11 | private readonly IPAddress _ipv6; 12 | private readonly int _port; 13 | private readonly bool _manualMode; 14 | private bool _initialized; 15 | 16 | public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) 17 | { 18 | _netManager = netManager; 19 | _ipv4 = ipv4; 20 | _ipv6 = ipv6; 21 | _port = port; 22 | _manualMode = manualMode; 23 | Application.focusChanged += Application_focusChanged; 24 | Application.quitting += Deinitialize; 25 | _initialized = true; 26 | } 27 | 28 | public void Deinitialize() 29 | { 30 | if (_initialized) 31 | { 32 | Application.focusChanged -= Application_focusChanged; 33 | Application.quitting -= Deinitialize; 34 | } 35 | 36 | if (_netManager.IsRunning) 37 | { 38 | _netManager.Stop(); 39 | } 40 | _initialized = false; 41 | } 42 | 43 | private void Application_focusChanged(bool focused) 44 | { 45 | //If coming back into focus see if a reconnect is needed. 46 | if (focused) 47 | { 48 | //try reconnect 49 | if (!_initialized) 50 | return; 51 | //Was intentionally disconnected at some point. 52 | if (!_netManager.IsRunning) 53 | return; 54 | //Socket is in working state. 55 | if (_netManager.NotConnected == false) 56 | return; 57 | 58 | //Socket isn't running but should be. Try to start again. 59 | if (!_netManager.Start(_ipv4, _ipv6, _port, _manualMode)) 60 | { 61 | NetDebug.WriteError($"[S] Cannot restore connection. Ipv4 {_ipv4}, Ipv6 {_ipv6}, Port {_port}, ManualMode {_manualMode}"); 62 | } 63 | } 64 | } 65 | } 66 | } 67 | #endif 68 | -------------------------------------------------------------------------------- /LiteNetLib/PooledPacket.cs: -------------------------------------------------------------------------------- 1 | namespace LiteNetLib 2 | { 3 | public readonly ref struct PooledPacket 4 | { 5 | internal readonly NetPacket _packet; 6 | internal readonly byte _channelNumber; 7 | 8 | /// 9 | /// Maximum data size that you can put into such packet 10 | /// 11 | public readonly int MaxUserDataSize; 12 | 13 | /// 14 | /// Offset for user data when writing to Data array 15 | /// 16 | public readonly int UserDataOffset; 17 | 18 | /// 19 | /// Raw packet data. Do not modify header! Use UserDataOffset as start point for your data 20 | /// 21 | public byte[] Data => _packet.RawData; 22 | 23 | internal PooledPacket(NetPacket packet, int maxDataSize, byte channelNumber) 24 | { 25 | _packet = packet; 26 | UserDataOffset = _packet.GetHeaderSize(); 27 | _packet.Size = UserDataOffset; 28 | MaxUserDataSize = maxDataSize - UserDataOffset; 29 | _channelNumber = channelNumber; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LiteNetLib/SequencedChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LiteNetLib 4 | { 5 | internal sealed class SequencedChannel : BaseChannel 6 | { 7 | private int _localSequence; 8 | private ushort _remoteSequence; 9 | private readonly bool _reliable; 10 | private NetPacket _lastPacket; 11 | private readonly NetPacket _ackPacket; 12 | private bool _mustSendAck; 13 | private readonly byte _id; 14 | private long _lastPacketSendTime; 15 | 16 | public SequencedChannel(NetPeer peer, bool reliable, byte id) : base(peer) 17 | { 18 | _id = id; 19 | _reliable = reliable; 20 | if (_reliable) 21 | _ackPacket = new NetPacket(PacketProperty.Ack, 0) {ChannelId = id}; 22 | } 23 | 24 | protected override bool SendNextPackets() 25 | { 26 | if (_reliable && OutgoingQueue.Count == 0) 27 | { 28 | long currentTime = DateTime.UtcNow.Ticks; 29 | long packetHoldTime = currentTime - _lastPacketSendTime; 30 | if (packetHoldTime >= Peer.ResendDelay * TimeSpan.TicksPerMillisecond) 31 | { 32 | var packet = _lastPacket; 33 | if (packet != null) 34 | { 35 | _lastPacketSendTime = currentTime; 36 | Peer.SendUserData(packet); 37 | } 38 | } 39 | } 40 | else 41 | { 42 | lock (OutgoingQueue) 43 | { 44 | while (OutgoingQueue.Count > 0) 45 | { 46 | NetPacket packet = OutgoingQueue.Dequeue(); 47 | _localSequence = (_localSequence + 1) % NetConstants.MaxSequence; 48 | packet.Sequence = (ushort)_localSequence; 49 | packet.ChannelId = _id; 50 | Peer.SendUserData(packet); 51 | 52 | if (_reliable && OutgoingQueue.Count == 0) 53 | { 54 | _lastPacketSendTime = DateTime.UtcNow.Ticks; 55 | _lastPacket = packet; 56 | } 57 | else 58 | { 59 | Peer.NetManager.PoolRecycle(packet); 60 | } 61 | } 62 | } 63 | } 64 | 65 | if (_reliable && _mustSendAck) 66 | { 67 | _mustSendAck = false; 68 | _ackPacket.Sequence = _remoteSequence; 69 | Peer.SendUserData(_ackPacket); 70 | } 71 | 72 | return _lastPacket != null; 73 | } 74 | 75 | public override bool ProcessPacket(NetPacket packet) 76 | { 77 | if (packet.IsFragmented) 78 | return false; 79 | if (packet.Property == PacketProperty.Ack) 80 | { 81 | if (_reliable && _lastPacket != null && packet.Sequence == _lastPacket.Sequence) 82 | _lastPacket = null; 83 | return false; 84 | } 85 | int relative = NetUtils.RelativeSequenceNumber(packet.Sequence, _remoteSequence); 86 | bool packetProcessed = false; 87 | if (packet.Sequence < NetConstants.MaxSequence && relative > 0) 88 | { 89 | if (Peer.NetManager.EnableStatistics) 90 | { 91 | Peer.Statistics.AddPacketLoss(relative - 1); 92 | Peer.NetManager.Statistics.AddPacketLoss(relative - 1); 93 | } 94 | 95 | _remoteSequence = packet.Sequence; 96 | Peer.NetManager.CreateReceiveEvent( 97 | packet, 98 | _reliable ? DeliveryMethod.ReliableSequenced : DeliveryMethod.Sequenced, 99 | (byte)(packet.ChannelId / NetConstants.ChannelTypeCount), 100 | NetConstants.ChanneledHeaderSize, 101 | Peer); 102 | packetProcessed = true; 103 | } 104 | 105 | if (_reliable) 106 | { 107 | _mustSendAck = true; 108 | AddToPeerChannelSendQueue(); 109 | } 110 | 111 | return packetProcessed; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /LiteNetLib/Trimming.cs: -------------------------------------------------------------------------------- 1 | #if NET5_0_OR_GREATER 2 | using System.Diagnostics.CodeAnalysis; 3 | using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes; 4 | 5 | namespace LiteNetLib 6 | { 7 | internal static class Trimming 8 | { 9 | internal const DynamicallyAccessedMemberTypes SerializerMemberTypes = PublicProperties | NonPublicProperties; 10 | } 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /LiteNetLib/Utils/INetSerializable.cs: -------------------------------------------------------------------------------- 1 | namespace LiteNetLib.Utils 2 | { 3 | public interface INetSerializable 4 | { 5 | void Serialize(NetDataWriter writer); 6 | void Deserialize(NetDataReader reader); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /LiteNetLib/Utils/NtpRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | 4 | namespace LiteNetLib.Utils 5 | { 6 | internal sealed class NtpRequest 7 | { 8 | private const int ResendTimer = 1000; 9 | private const int KillTimer = 10000; 10 | public const int DefaultPort = 123; 11 | private readonly IPEndPoint _ntpEndPoint; 12 | private float _resendTime = ResendTimer; 13 | private float _killTime = 0; 14 | 15 | public NtpRequest(IPEndPoint endPoint) 16 | { 17 | _ntpEndPoint = endPoint; 18 | } 19 | 20 | public bool NeedToKill => _killTime >= KillTimer; 21 | 22 | public bool Send(Socket socket, float time) 23 | { 24 | _resendTime += time; 25 | _killTime += time; 26 | if (_resendTime < ResendTimer) 27 | { 28 | return false; 29 | } 30 | var packet = new NtpPacket(); 31 | try 32 | { 33 | int sendCount = socket.SendTo(packet.Bytes, 0, packet.Bytes.Length, SocketFlags.None, _ntpEndPoint); 34 | return sendCount == packet.Bytes.Length; 35 | } 36 | catch 37 | { 38 | return false; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LiteNetLib/Utils/Preserve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LiteNetLib.Utils 4 | { 5 | /// 6 | /// PreserveAttribute prevents byte code stripping from removing a class, method, field, or property. 7 | /// 8 | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] 9 | public class PreserveAttribute : Attribute 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /LiteNetLib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.revenantx.litenetlib", 3 | "version": "1.0.1-1", 4 | "displayName": "LiteNetLib", 5 | "description": "Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework)", 6 | "unity": "2018.3", 7 | "author": { 8 | "name": "RevenantX", 9 | "url": "https://github.com/RevenantX" 10 | } 11 | } -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/.gitignore: -------------------------------------------------------------------------------- 1 | # Autogenerated VS/MD solution and project files 2 | *.svd 3 | *.userprefs 4 | *.csproj 5 | *.pidb 6 | *.suo 7 | *.sln 8 | *.user 9 | *.unityproj 10 | *.booproj 11 | *.tmp 12 | *.pidb 13 | *.mdb 14 | !*.meta 15 | 16 | *.pdb 17 | *.pdb.meta 18 | *.mdb.meta 19 | 20 | #Folders 21 | /.vs/ 22 | /[Oo]bj/ 23 | /UnityGenerated/ 24 | /Content/ 25 | /ExportedObject/ 26 | /DllProject/ 27 | /[Ll]ibrary/ 28 | /obj/ 29 | /[Tt]emp/ 30 | /[Bb]uild/ 31 | /[Bb]uilds/ 32 | 33 | # Unity VSCode 34 | /.vscode/ 35 | 36 | /**/UnityVS 37 | /**/VSCode 38 | /**/UnityVS.meta 39 | /**/VSCode.meta 40 | 41 | # Unity3D generated meta files 42 | *.pidb.meta 43 | 44 | # Unity3D Generated File On Crash Reports 45 | sysinfo.txt 46 | 47 | #**/[Gg]enerated/**/*.meta 48 | #**/[Gg]enerated/*.meta 49 | #**/[Ss]hared/**/*.meta 50 | #**/[Ss]hared/*.meta -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/GameClient.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | using UnityEngine; 4 | using LiteNetLib; 5 | 6 | public class GameClient : MonoBehaviour, INetEventListener 7 | { 8 | private NetManager _netClient; 9 | 10 | [SerializeField] private GameObject _clientBall; 11 | [SerializeField] private GameObject _clientBallInterpolated; 12 | 13 | private float _newBallPosX; 14 | private float _oldBallPosX; 15 | private float _lerpTime; 16 | 17 | private void Start() 18 | { 19 | _netClient = new NetManager(this); 20 | _netClient.UnconnectedMessagesEnabled = true; 21 | _netClient.UpdateTime = 15; 22 | _netClient.Start(); 23 | } 24 | 25 | private void Update() 26 | { 27 | _netClient.PollEvents(); 28 | 29 | var peer = _netClient.FirstPeer; 30 | if (peer != null && peer.ConnectionState == ConnectionState.Connected) 31 | { 32 | //Fixed delta set to 0.05 33 | var pos = _clientBallInterpolated.transform.position; 34 | pos.x = Mathf.Lerp(_oldBallPosX, _newBallPosX, _lerpTime); 35 | _clientBallInterpolated.transform.position = pos; 36 | 37 | //Basic lerp 38 | _lerpTime += Time.deltaTime / Time.fixedDeltaTime; 39 | } 40 | else 41 | { 42 | _netClient.SendBroadcast(new byte[] {1}, 5000); 43 | } 44 | } 45 | 46 | private void OnDestroy() 47 | { 48 | if (_netClient != null) 49 | _netClient.Stop(); 50 | } 51 | 52 | void INetEventListener.OnPeerConnected(NetPeer peer) 53 | { 54 | Debug.Log("[CLIENT] We connected to " + peer); 55 | } 56 | 57 | void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) 58 | { 59 | Debug.Log("[CLIENT] We received error " + socketErrorCode); 60 | } 61 | 62 | void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) 63 | { 64 | _newBallPosX = reader.GetFloat(); 65 | 66 | var pos = _clientBall.transform.position; 67 | 68 | _oldBallPosX = pos.x; 69 | pos.x = _newBallPosX; 70 | 71 | _clientBall.transform.position = pos; 72 | 73 | _lerpTime = 0f; 74 | } 75 | 76 | void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) 77 | { 78 | if (messageType == UnconnectedMessageType.BasicMessage && _netClient.ConnectedPeersCount == 0 && reader.GetInt() == 1) 79 | { 80 | Debug.Log("[CLIENT] Received discovery response. Connecting to: " + remoteEndPoint); 81 | _netClient.Connect(remoteEndPoint, "sample_app"); 82 | } 83 | } 84 | 85 | void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) 86 | { 87 | 88 | } 89 | 90 | void INetEventListener.OnConnectionRequest(ConnectionRequest request) 91 | { 92 | 93 | } 94 | 95 | void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) 96 | { 97 | Debug.Log("[CLIENT] We disconnected because " + disconnectInfo.Reason); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/GameClient.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aea082f0aed8a9d479d0c771a3cf230e 3 | timeCreated: 1467152909 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/GameServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using UnityEngine; 5 | using LiteNetLib; 6 | using LiteNetLib.Utils; 7 | 8 | public class GameServer : MonoBehaviour, INetEventListener, INetLogger 9 | { 10 | private NetManager _netServer; 11 | private NetPeer _ourPeer; 12 | private NetDataWriter _dataWriter; 13 | 14 | [SerializeField] private GameObject _serverBall; 15 | 16 | private void Start() 17 | { 18 | NetDebug.Logger = this; 19 | _dataWriter = new NetDataWriter(); 20 | _netServer = new NetManager(this); 21 | _netServer.Start(5000); 22 | _netServer.BroadcastReceiveEnabled = true; 23 | _netServer.UpdateTime = 15; 24 | } 25 | 26 | private void Update() 27 | { 28 | _netServer.PollEvents(); 29 | } 30 | 31 | private void FixedUpdate() 32 | { 33 | if (_ourPeer != null) 34 | { 35 | _serverBall.transform.Translate(1f * Time.fixedDeltaTime, 0f, 0f); 36 | _dataWriter.Reset(); 37 | _dataWriter.Put(_serverBall.transform.position.x); 38 | _ourPeer.Send(_dataWriter, DeliveryMethod.Sequenced); 39 | } 40 | } 41 | 42 | private void OnDestroy() 43 | { 44 | NetDebug.Logger = null; 45 | if (_netServer != null) 46 | _netServer.Stop(); 47 | } 48 | 49 | void INetEventListener.OnPeerConnected(NetPeer peer) 50 | { 51 | Debug.Log("[SERVER] We have new peer " + peer); 52 | _ourPeer = peer; 53 | } 54 | 55 | void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) 56 | { 57 | Debug.Log("[SERVER] error " + socketErrorCode); 58 | } 59 | 60 | void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, 61 | UnconnectedMessageType messageType) 62 | { 63 | if (messageType == UnconnectedMessageType.Broadcast) 64 | { 65 | Debug.Log("[SERVER] Received discovery request. Send discovery response"); 66 | NetDataWriter resp = new NetDataWriter(); 67 | resp.Put(1); 68 | _netServer.SendUnconnectedMessage(resp, remoteEndPoint); 69 | } 70 | } 71 | 72 | void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) 73 | { 74 | } 75 | 76 | void INetEventListener.OnConnectionRequest(ConnectionRequest request) 77 | { 78 | request.AcceptIfKey("sample_app"); 79 | } 80 | 81 | void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) 82 | { 83 | Debug.Log("[SERVER] peer disconnected " + peer + ", info: " + disconnectInfo.Reason); 84 | if (peer == _ourPeer) 85 | _ourPeer = null; 86 | } 87 | 88 | void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) 89 | { 90 | } 91 | 92 | void INetLogger.WriteNet(NetLogLevel level, string str, params object[] args) 93 | { 94 | Debug.LogFormat(str, args); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/GameServer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e31e48c07e922af49af33ff69c665986 3 | timeCreated: 1470153825 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/MainScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d133d03d353e2da4ea63bfcfbaf385ac 3 | timeCreated: 1467153263 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0680635b8862cad41957568e3143c8c7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/Resources/BillingMode.json: -------------------------------------------------------------------------------- 1 | {"androidStore":"GooglePlay"} -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Assets/Resources/BillingMode.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 935f8151a9a85ee40bfcd6cbe0333137 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.revenantx.litenetlib": "1.3.0", 4 | "com.unity.2d.sprite": "1.0.0", 5 | "com.unity.collab-proxy": "2.5.2", 6 | "com.unity.ide.rider": "3.0.34", 7 | "com.unity.ide.visualstudio": "2.0.22", 8 | "com.unity.ide.vscode": "1.2.5", 9 | "com.unity.textmeshpro": "3.0.9", 10 | "com.unity.timeline": "1.7.6", 11 | "com.unity.ugui": "1.0.0", 12 | "com.unity.xr.legacyinputhelpers": "2.1.11", 13 | "com.unity.modules.ai": "1.0.0", 14 | "com.unity.modules.androidjni": "1.0.0", 15 | "com.unity.modules.animation": "1.0.0", 16 | "com.unity.modules.assetbundle": "1.0.0", 17 | "com.unity.modules.audio": "1.0.0", 18 | "com.unity.modules.cloth": "1.0.0", 19 | "com.unity.modules.director": "1.0.0", 20 | "com.unity.modules.imageconversion": "1.0.0", 21 | "com.unity.modules.imgui": "1.0.0", 22 | "com.unity.modules.jsonserialize": "1.0.0", 23 | "com.unity.modules.particlesystem": "1.0.0", 24 | "com.unity.modules.physics": "1.0.0", 25 | "com.unity.modules.physics2d": "1.0.0", 26 | "com.unity.modules.screencapture": "1.0.0", 27 | "com.unity.modules.terrain": "1.0.0", 28 | "com.unity.modules.terrainphysics": "1.0.0", 29 | "com.unity.modules.tilemap": "1.0.0", 30 | "com.unity.modules.ui": "1.0.0", 31 | "com.unity.modules.uielements": "1.0.0", 32 | "com.unity.modules.umbra": "1.0.0", 33 | "com.unity.modules.unityanalytics": "1.0.0", 34 | "com.unity.modules.unitywebrequest": "1.0.0", 35 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 36 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 37 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 38 | "com.unity.modules.unitywebrequestwww": "1.0.0", 39 | "com.unity.modules.vehicles": "1.0.0", 40 | "com.unity.modules.video": "1.0.0", 41 | "com.unity.modules.vr": "1.0.0", 42 | "com.unity.modules.wind": "1.0.0", 43 | "com.unity.modules.xr": "1.0.0" 44 | }, 45 | "scopedRegistries": [ 46 | { 47 | "name": "package.openupm.com", 48 | "url": "https://package.openupm.com", 49 | "scopes": [ 50 | "com.revenantx.litenetlib" 51 | ] 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_DisableAudio: 0 16 | m_VirtualizeEffects: 1 17 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 2 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_SolverIterationCount: 6 13 | m_SolverVelocityIterations: 1 14 | m_QueriesHitTriggers: 1 15 | m_EnableAdaptiveForce: 0 16 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 17 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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/MainScene.unity 10 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 3 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_WebSecurityEmulationEnabled: 0 10 | m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d 11 | m_DefaultBehaviorMode: 0 12 | m_SpritePackerMode: 2 13 | m_SpritePackerPaddingPower: 1 14 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 15 | m_ProjectGenerationRootNamespace: 16 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 7 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: 10770, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_ShaderSettings_Tier1: 42 | useCascadedShadowMaps: 1 43 | standardShaderQuality: 2 44 | useReflectionProbeBoxProjection: 1 45 | useReflectionProbeBlending: 1 46 | m_ShaderSettings_Tier2: 47 | useCascadedShadowMaps: 1 48 | standardShaderQuality: 2 49 | useReflectionProbeBoxProjection: 1 50 | useReflectionProbeBlending: 1 51 | m_ShaderSettings_Tier3: 52 | useCascadedShadowMaps: 1 53 | standardShaderQuality: 2 54 | useReflectionProbeBoxProjection: 1 55 | useReflectionProbeBlending: 1 56 | m_BuildTargetShaderSettings: [] 57 | m_LightmapStripping: 0 58 | m_FogStripping: 0 59 | m_LightmapKeepPlain: 1 60 | m_LightmapKeepDirCombined: 1 61 | m_LightmapKeepDirSeparate: 1 62 | m_LightmapKeepDynamicPlain: 1 63 | m_LightmapKeepDynamicDirCombined: 1 64 | m_LightmapKeepDynamicDirSeparate: 1 65 | m_FogKeepLinear: 1 66 | m_FogKeepExp: 1 67 | m_FogKeepExp2: 1 68 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/MemorySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!387306366 &1 4 | MemorySettings: 5 | m_ObjectHideFlags: 0 6 | m_EditorMemorySettings: 7 | m_MainAllocatorBlockSize: -1 8 | m_ThreadAllocatorBlockSize: -1 9 | m_MainGfxBlockSize: -1 10 | m_ThreadGfxBlockSize: -1 11 | m_CacheBlockSize: -1 12 | m_TypetreeBlockSize: -1 13 | m_ProfilerBlockSize: -1 14 | m_ProfilerEditorBlockSize: -1 15 | m_BucketAllocatorGranularity: -1 16 | m_BucketAllocatorBucketsCount: -1 17 | m_BucketAllocatorBlockSize: -1 18 | m_BucketAllocatorBlockCount: -1 19 | m_ProfilerBucketAllocatorGranularity: -1 20 | m_ProfilerBucketAllocatorBucketsCount: -1 21 | m_ProfilerBucketAllocatorBlockSize: -1 22 | m_ProfilerBucketAllocatorBlockCount: -1 23 | m_TempAllocatorSizeMain: -1 24 | m_JobTempAllocatorBlockSize: -1 25 | m_BackgroundJobTempAllocatorBlockSize: -1 26 | m_JobTempAllocatorReducedBlockSize: -1 27 | m_TempAllocatorSizeGIBakingWorker: -1 28 | m_TempAllocatorSizeNavMeshWorker: -1 29 | m_TempAllocatorSizeAudioWorker: -1 30 | m_TempAllocatorSizeCloudWorker: -1 31 | m_TempAllocatorSizeGfx: -1 32 | m_TempAllocatorSizeJobWorker: -1 33 | m_TempAllocatorSizeBackgroundWorker: -1 34 | m_TempAllocatorSizePreloadManager: -1 35 | m_PlatformMemorySettings: {} 36 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshAreas: 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 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 53 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_EnablePreReleasePackages: 0 16 | m_AdvancedSettingsExpanded: 1 17 | m_ScopedRegistriesSettingsExpanded: 1 18 | m_SeeAllPackageVersions: 0 19 | m_DismissPreviewPackagesInUse: 0 20 | oneTimeWarningShown: 0 21 | m_Registries: 22 | - m_Id: main 23 | m_Name: 24 | m_Url: https://packages.unity.com 25 | m_Scopes: [] 26 | m_IsDefault: 1 27 | m_Capabilities: 7 28 | m_ConfigSource: 0 29 | - m_Id: scoped:project:package.openupm.com 30 | m_Name: package.openupm.com 31 | m_Url: https://package.openupm.com 32 | m_Scopes: 33 | - com.revenantx.litenetlib 34 | m_IsDefault: 0 35 | m_Capabilities: 0 36 | m_ConfigSource: 4 37 | m_UserSelectedRegistryName: package.openupm.com 38 | m_UserAddingNewScopedRegistry: 0 39 | m_RegistryInfoDraft: 40 | m_Modified: 0 41 | m_ErrorMessage: 42 | m_UserModificationsInstanceId: -834 43 | m_OriginalInstanceId: -836 44 | m_LoadAssets: 0 45 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 2 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_MinPenetrationForPenalty: 0.01 17 | m_BaumgarteScale: 0.2 18 | m_BaumgarteTimeOfImpactScale: 0.75 19 | m_TimeToSleep: 0.5 20 | m_LinearSleepTolerance: 0.01 21 | m_AngularSleepTolerance: 2 22 | m_QueriesHitTriggers: 1 23 | m_QueriesStartInColliders: 1 24 | m_ChangeStopsCallbacks: 0 25 | m_AlwaysShowColliders: 0 26 | m_ShowColliderSleep: 1 27 | m_ShowColliderContacts: 0 28 | m_ContactArrowScale: 0.2 29 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 30 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 31 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 32 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 33 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2022.3.50f1 2 | m_EditorVersionWithRevision: 2022.3.50f1 (c3db7f8bf9b1) 3 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 2 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | blendWeights: 1 21 | textureQuality: 1 22 | anisotropicTextures: 0 23 | antiAliasing: 0 24 | softParticles: 0 25 | softVegetation: 0 26 | realtimeReflectionProbes: 0 27 | billboardsFaceCameraPosition: 0 28 | vSyncCount: 0 29 | lodBias: 0.3 30 | maximumLODLevel: 0 31 | particleRaycastBudget: 4 32 | asyncUploadTimeSlice: 2 33 | asyncUploadBufferSize: 4 34 | excludedTargetPlatforms: [] 35 | - serializedVersion: 2 36 | name: Fast 37 | pixelLightCount: 0 38 | shadows: 0 39 | shadowResolution: 0 40 | shadowProjection: 1 41 | shadowCascades: 1 42 | shadowDistance: 20 43 | shadowNearPlaneOffset: 2 44 | shadowCascade2Split: 0.33333334 45 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 46 | blendWeights: 2 47 | textureQuality: 0 48 | anisotropicTextures: 0 49 | antiAliasing: 0 50 | softParticles: 0 51 | softVegetation: 0 52 | realtimeReflectionProbes: 0 53 | billboardsFaceCameraPosition: 0 54 | vSyncCount: 0 55 | lodBias: 0.4 56 | maximumLODLevel: 0 57 | particleRaycastBudget: 16 58 | asyncUploadTimeSlice: 2 59 | asyncUploadBufferSize: 4 60 | excludedTargetPlatforms: [] 61 | - serializedVersion: 2 62 | name: Simple 63 | pixelLightCount: 1 64 | shadows: 1 65 | shadowResolution: 0 66 | shadowProjection: 1 67 | shadowCascades: 1 68 | shadowDistance: 20 69 | shadowNearPlaneOffset: 2 70 | shadowCascade2Split: 0.33333334 71 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 72 | blendWeights: 2 73 | textureQuality: 0 74 | anisotropicTextures: 1 75 | antiAliasing: 0 76 | softParticles: 0 77 | softVegetation: 0 78 | realtimeReflectionProbes: 0 79 | billboardsFaceCameraPosition: 0 80 | vSyncCount: 0 81 | lodBias: 0.7 82 | maximumLODLevel: 0 83 | particleRaycastBudget: 64 84 | asyncUploadTimeSlice: 2 85 | asyncUploadBufferSize: 4 86 | excludedTargetPlatforms: [] 87 | - serializedVersion: 2 88 | name: Good 89 | pixelLightCount: 2 90 | shadows: 2 91 | shadowResolution: 1 92 | shadowProjection: 1 93 | shadowCascades: 2 94 | shadowDistance: 40 95 | shadowNearPlaneOffset: 2 96 | shadowCascade2Split: 0.33333334 97 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 98 | blendWeights: 2 99 | textureQuality: 0 100 | anisotropicTextures: 1 101 | antiAliasing: 0 102 | softParticles: 0 103 | softVegetation: 1 104 | realtimeReflectionProbes: 1 105 | billboardsFaceCameraPosition: 1 106 | vSyncCount: 1 107 | lodBias: 1 108 | maximumLODLevel: 0 109 | particleRaycastBudget: 256 110 | asyncUploadTimeSlice: 2 111 | asyncUploadBufferSize: 4 112 | excludedTargetPlatforms: [] 113 | - serializedVersion: 2 114 | name: Beautiful 115 | pixelLightCount: 3 116 | shadows: 2 117 | shadowResolution: 2 118 | shadowProjection: 1 119 | shadowCascades: 2 120 | shadowDistance: 70 121 | shadowNearPlaneOffset: 2 122 | shadowCascade2Split: 0.33333334 123 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 124 | blendWeights: 4 125 | textureQuality: 0 126 | anisotropicTextures: 2 127 | antiAliasing: 2 128 | softParticles: 1 129 | softVegetation: 1 130 | realtimeReflectionProbes: 1 131 | billboardsFaceCameraPosition: 1 132 | vSyncCount: 1 133 | lodBias: 1.5 134 | maximumLODLevel: 0 135 | particleRaycastBudget: 1024 136 | asyncUploadTimeSlice: 2 137 | asyncUploadBufferSize: 4 138 | excludedTargetPlatforms: [] 139 | - serializedVersion: 2 140 | name: Fantastic 141 | pixelLightCount: 4 142 | shadows: 2 143 | shadowResolution: 2 144 | shadowProjection: 1 145 | shadowCascades: 4 146 | shadowDistance: 150 147 | shadowNearPlaneOffset: 2 148 | shadowCascade2Split: 0.33333334 149 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 150 | blendWeights: 4 151 | textureQuality: 0 152 | anisotropicTextures: 2 153 | antiAliasing: 2 154 | softParticles: 1 155 | softVegetation: 1 156 | realtimeReflectionProbes: 1 157 | billboardsFaceCameraPosition: 1 158 | vSyncCount: 1 159 | lodBias: 2 160 | maximumLODLevel: 0 161 | particleRaycastBudget: 4096 162 | asyncUploadTimeSlice: 2 163 | asyncUploadBufferSize: 4 164 | excludedTargetPlatforms: [] 165 | m_PerPlatformDefaultQuality: 166 | Android: 2 167 | BlackBerry: 2 168 | GLES Emulation: 5 169 | Nintendo 3DS: 5 170 | PS3: 5 171 | PS4: 5 172 | PSM: 5 173 | PSP2: 2 174 | Samsung TV: 2 175 | Standalone: 5 176 | Tizen: 2 177 | WP8: 5 178 | Web: 5 179 | WebGL: 3 180 | WiiU: 5 181 | Windows Store Apps: 5 182 | XBOX360: 5 183 | XboxOne: 5 184 | iPhone: 2 185 | tvOS: 5 186 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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 | - 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 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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.05 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/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: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | CrashReportingSettings: 11 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 12 | m_Enabled: 0 13 | m_CaptureEditorExceptions: 1 14 | UnityPurchasingSettings: 15 | m_Enabled: 0 16 | m_TestMode: 0 17 | UnityAnalyticsSettings: 18 | m_Enabled: 0 19 | m_InitializeOnStartup: 1 20 | m_TestMode: 0 21 | m_TestEventUrl: 22 | m_TestConfigUrl: 23 | UnityAdsSettings: 24 | m_Enabled: 0 25 | m_InitializeOnStartup: 1 26 | m_TestMode: 0 27 | m_EnabledPlatforms: 4294967295 28 | m_IosGameId: 29 | m_AndroidGameId: 30 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_EmptyShader: {fileID: 0} 11 | m_RenderPipeSettingsPath: 12 | m_FixedTimeStep: 0.016666668 13 | m_MaxDeltaTime: 0.05 14 | m_MaxScrubTime: 30 15 | m_CompiledVersion: 0 16 | m_RuntimeVersion: 0 17 | m_RuntimeResources: {fileID: 0} 18 | m_BatchEmptyLifetime: 300 19 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/ProjectSettings/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/UserSettings/EditorUserSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!162 &1 4 | EditorUserSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_ConfigSettings: 8 | RecentlyUsedSceneGuid-0: 9 | value: 0700075501055a5f5e5b5f2742275e4413164e792e2e25362f281b60bab5353b 10 | flags: 0 11 | vcSharedLogLevel: 12 | value: 0d5e400f0650 13 | flags: 0 14 | m_VCAutomaticAdd: 1 15 | m_VCDebugCom: 0 16 | m_VCDebugCmd: 0 17 | m_VCDebugOut: 0 18 | m_SemanticMergeMode: 2 19 | m_DesiredImportWorkerCount: 4 20 | m_StandbyImportWorkerCount: 2 21 | m_IdleImportWorkerShutdownDelay: 60000 22 | m_VCShowFailedCheckout: 1 23 | m_VCOverwriteFailedCheckoutAssets: 1 24 | m_VCProjectOverlayIcons: 1 25 | m_VCHierarchyOverlayIcons: 1 26 | m_VCOtherOverlayIcons: 1 27 | m_VCAllowAsyncUpdate: 1 28 | m_ArtifactGarbageCollection: 1 29 | -------------------------------------------------------------------------------- /LiteNetLibSampleUnity/UserSettings/Search.settings: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LiteNetLib 2 | 3 | Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework) 4 | 5 | [![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua) 6 | 7 | **HighLevel API Part**: [LiteEntitySystem](https://github.com/RevenantX/LiteEntitySystem) 8 | 9 | **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) 10 | 11 | [OLD BRANCH (and examples) for 0.9.x](https://github.com/RevenantX/LiteNetLib/tree/0.9) 12 | 13 | [Little Game Example on Unity](https://github.com/RevenantX/NetGameExample) 14 | 15 | [Documentation](https://revenantx.github.io/LiteNetLib/index.html) 16 | 17 | ## Build 18 | 19 | ### [NuGet](https://www.nuget.org/packages/LiteNetLib/) [![NuGet](https://img.shields.io/nuget/v/LiteNetLib?color=blue)](https://www.nuget.org/packages/LiteNetLib/) [![NuGet](https://img.shields.io/nuget/vpre/LiteNetLib)](https://www.nuget.org/packages/LiteNetLib/#versions-body-tab) [![NuGet](https://img.shields.io/nuget/dt/LiteNetLib)](https://www.nuget.org/packages/LiteNetLib/) 20 | 21 | ### [Release builds](https://github.com/RevenantX/LiteNetLib/releases) [![GitHub (pre-)release](https://img.shields.io/github/release/RevenantX/LiteNetLib/all.svg)](https://github.com/RevenantX/LiteNetLib/releases) 22 | 23 | ### [DLL build from master](https://ci.appveyor.com/project/RevenantX/litenetlib/branch/master/artifacts) [![](https://ci.appveyor.com/api/projects/status/354501wnvxs8kuh3/branch/master?svg=true)](https://ci.appveyor.com/project/RevenantX/litenetlib/branch/master) 24 | ( Warning! Master branch can be unstable! ) 25 | 26 | ## Features 27 | 28 | * Lightweight 29 | * Small CPU and RAM usage 30 | * Small packet size overhead ( 1 byte for unreliable, 4 bytes for reliable packets ) 31 | * Simple connection handling 32 | * Peer to peer connections 33 | * Helper classes for sending and reading messages 34 | * Multiple data channels 35 | * Different send mechanics 36 | * Reliable with order 37 | * Reliable without order 38 | * Reliable sequenced (reliable only last packet) 39 | * Ordered but unreliable with duplication prevention 40 | * Simple UDP packets without order and reliability 41 | * Fast packet serializer [(Usage manual)](https://revenantx.github.io/LiteNetLib/articles/netserializerusage.html) 42 | * Automatic small packets merging 43 | * Automatic fragmentation of reliable packets 44 | * Automatic MTU detection 45 | * Optional CRC32C checksums 46 | * UDP NAT hole punching 47 | * NTP time requests 48 | * Packet loss and latency simulation 49 | * IPv6 support (using separate socket for performance) 50 | * Connection statistics 51 | * Multicasting (for discovering hosts in local network) 52 | * Unity support 53 | * Support for .NET8 optimized socket calls (much less gc) 54 | * Supported platforms: 55 | * Windows/Mac/Linux (.NET Framework, Mono, .NET Core, .NET Standard) 56 | * Lumin OS (Magic Leap) 57 | * MonoGame 58 | * Godot 59 | * Unity 2018.3 (Desktop platforms, Android, iOS, Switch) 60 | 61 | ## Support developer 62 | * [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) 63 | 64 | * USDT TRC20: `TE5eBgq8SyEeZFKtCgZG9GwL34sANmbc67` 65 | 66 | * USDT BEP20/ERC20: `0x4c0D6DC76c6A6B354f5ec6c9e51893fFC6510d1E` 67 | 68 | * Bitcoin: `bc1q269ecs8r5vnrum5qr5j98sdglhnxlulv0f6egd` 69 | 70 | ## Unity notes!!! 71 | * Minimal supported Unity is 2018.3. For older Unity versions use [0.9.x library](https://github.com/RevenantX/LiteNetLib/tree/0.9) versions 72 | * Always use library sources or [OpenUPM package](https://openupm.com/packages/com.revenantx.litenetlib/) instead of precompiled DLL files ( because there are platform specific #ifdefs and workarounds for unity bugs ) 73 | 74 | ## Usage samples 75 | 76 | ### Client 77 | ```csharp 78 | EventBasedNetListener listener = new EventBasedNetListener(); 79 | NetManager client = new NetManager(listener); 80 | client.Start(); 81 | client.Connect("localhost" /* host IP or name */, 9050 /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); 82 | listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod, channel) => 83 | { 84 | Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); 85 | dataReader.Recycle(); 86 | }; 87 | 88 | while (!Console.KeyAvailable) 89 | { 90 | client.PollEvents(); 91 | Thread.Sleep(15); 92 | } 93 | 94 | client.Stop(); 95 | ``` 96 | ### Server 97 | ```csharp 98 | EventBasedNetListener listener = new EventBasedNetListener(); 99 | NetManager server = new NetManager(listener); 100 | server.Start(9050 /* port */); 101 | 102 | listener.ConnectionRequestEvent += request => 103 | { 104 | if(server.ConnectedPeersCount < 10 /* max connections */) 105 | request.AcceptIfKey("SomeConnectionKey"); 106 | else 107 | request.Reject(); 108 | }; 109 | 110 | listener.PeerConnectedEvent += peer => 111 | { 112 | Console.WriteLine("We got connection: {0}", peer); // Show peer IP 113 | NetDataWriter writer = new NetDataWriter(); // Create writer class 114 | writer.Put("Hello client!"); // Put some string 115 | peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability 116 | }; 117 | 118 | while (!Console.KeyAvailable) 119 | { 120 | server.PollEvents(); 121 | Thread.Sleep(15); 122 | } 123 | server.Stop(); 124 | ``` 125 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2022 2 | version: 1.0.{build} 3 | configuration: 4 | - Release 5 | before_build: 6 | - nuget restore 7 | - dotnet restore 8 | assembly_info: 9 | patch: false 10 | file: AssemblyInfo.cs 11 | assembly_version: '{version}' 12 | assembly_file_version: '{version}' 13 | build: 14 | project: LiteNetLib.sln 15 | test_script: 16 | - dotnet test -m:1 "LiteNetLib.Tests\LiteNetLib.Tests.csproj" --configuration Release --no-build 17 | artifacts: 18 | - path: LiteNetLib/bin/Release/net471 19 | name: LiteNetLib-$(appveyor_build_version) 20 | type: Zip 21 | - path: LiteNetLib/bin/Release/netstandard2.0 22 | name: LiteNetLibStandard-$(appveyor_build_version) 23 | type: Zip 24 | - path: LiteNetLib/bin/Release/netcoreapp3.1 25 | name: LiteNetLibNetCore-$(appveyor_build_version) 26 | type: Zip 27 | -------------------------------------------------------------------------------- /docfx_project/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | _site 10 | -------------------------------------------------------------------------------- /docfx_project/api/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # temp file # 3 | ############### 4 | *.yml 5 | .manifest 6 | -------------------------------------------------------------------------------- /docfx_project/api/index.md: -------------------------------------------------------------------------------- 1 | # LiteNetLib -------------------------------------------------------------------------------- /docfx_project/articles/toc.yml: -------------------------------------------------------------------------------- 1 | - name: NetSerializer usage 2 | href: netserializerusage.md 3 | -------------------------------------------------------------------------------- /docfx_project/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "files": [ "**/*.csproj" ], 7 | "src": "../LiteNetLib" 8 | } 9 | ], 10 | "dest": "api", 11 | "disableGitFeatures": true, 12 | "disableDefaultFilter": false, 13 | "filter": "filterConfig.yml", 14 | "properties": { 15 | "TargetFramework": "netstandard2.1" 16 | } 17 | } 18 | ], 19 | "build": { 20 | "content": [ 21 | { 22 | "files": [ 23 | "api/**.yml", 24 | "api/index.md" 25 | ] 26 | }, 27 | { 28 | "files": [ 29 | "articles/**.md", 30 | "articles/**/toc.yml", 31 | "toc.yml", 32 | "*.md" 33 | ] 34 | } 35 | ], 36 | "resource": [ 37 | { 38 | "files": [ 39 | "images/**" 40 | ] 41 | } 42 | ], 43 | "overwrite": [ 44 | { 45 | "files": [ 46 | "apidoc/**.md" 47 | ], 48 | "exclude": [ 49 | "obj/**", 50 | "_site/**" 51 | ] 52 | } 53 | ], 54 | "dest": "../docs", 55 | "globalMetadataFiles": [], 56 | "fileMetadataFiles": [], 57 | "template": [ 58 | "default" 59 | ], 60 | "postProcessors": [], 61 | "markdownEngineName": "dfm", 62 | "noLangKeyword": false, 63 | "keepFileLink": false, 64 | "cleanupCacheHistory": false, 65 | "disableGitFeatures": true 66 | } 67 | } -------------------------------------------------------------------------------- /docfx_project/filterConfig.yml: -------------------------------------------------------------------------------- 1 | apiRules: 2 | - exclude: 3 | uidRegex: ^System\.Object 4 | type: Type 5 | - exclude: 6 | uidRegex: ^System\.ValueType 7 | type: Type 8 | - exclude: 9 | uidRegex: ^LiteNetLib 10 | type: Delegate -------------------------------------------------------------------------------- /docfx_project/index.md: -------------------------------------------------------------------------------- 1 | # LiteNetLib 2 | 3 | Lite reliable UDP library for .NET Framework 3.5, Mono, .NET Core 2.0, .NET Standard 2.0. 4 | 5 | [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) 6 | 7 | [Little Game Example on Unity](https://github.com/RevenantX/NetGameExample) 8 | 9 | ## Features 10 | 11 | * Lightweight 12 | * Small CPU and RAM usage 13 | * Small packet size overhead ( 1 byte for unreliable, 3 bytes for reliable packets ) 14 | * Simple connection handling 15 | * Peer to peer connections 16 | * Helper classes for sending and reading messages 17 | * Multiple data channels 18 | * Different send mechanics 19 | * Reliable with order 20 | * Reliable without order 21 | * Reliable sequenced (realiable only last packet) 22 | * Ordered but unreliable with duplication prevention 23 | * Simple UDP packets without order and reliability 24 | * Fast packet serializer [(Usage manual)](https://github.com/RevenantX/LiteNetLib/wiki/NetSerializer-usage) 25 | * Automatic small packets merging 26 | * Automatic fragmentation of reliable packets 27 | * Automatic MTU detection 28 | * UDP NAT hole punching 29 | * NTP time requests 30 | * Packet loss and latency simulation 31 | * IPv6 support (dual mode) 32 | * Connection statisitcs (need DEBUG or STATS_ENABLED flag) 33 | * Multicasting (for discovering hosts in local network) 34 | * Unity support 35 | * Supported platforms: 36 | * Windows/Mac/Linux (.NET Framework, Mono, .NET Core) 37 | * Android (Unity) 38 | * iOS (Unity) 39 | * UWP Windows 10 including phones 40 | * Lumin OS (Magic Leap) 41 | 42 | ## Unity notes!!! 43 | * Always use library sources instead of precompiled DLL files ( because there are platform specific #ifdefs and workarounds for unity bugs ) 44 | 45 | ## Usage samples 46 | 47 | ### Client 48 | ```csharp 49 | EventBasedNetListener listener = new EventBasedNetListener(); 50 | NetManager client = new NetManager(listener); 51 | client.Start(); 52 | client.Connect("localhost" /* host ip or name */, 9050 /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); 53 | listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) => 54 | { 55 | Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); 56 | dataReader.Recycle(); 57 | }; 58 | 59 | while (!Console.KeyAvailable) 60 | { 61 | client.PollEvents(); 62 | Thread.Sleep(15); 63 | } 64 | 65 | client.Stop(); 66 | ``` 67 | ### Server 68 | ```csharp 69 | EventBasedNetListener listener = new EventBasedNetListener(); 70 | NetManager server = new NetManager(listener); 71 | server.Start(9050 /* port */); 72 | 73 | listener.ConnectionRequestEvent += request => 74 | { 75 | if(server.PeersCount < 10 /* max connections */) 76 | request.AcceptIfKey("SomeConnectionKey"); 77 | else 78 | request.Reject(); 79 | }; 80 | 81 | listener.PeerConnectedEvent += peer => 82 | { 83 | Console.WriteLine("We got connection: {0}", peer.EndPoint); // Show peer ip 84 | NetDataWriter writer = new NetDataWriter(); // Create writer class 85 | writer.Put("Hello client!"); // Put some string 86 | peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability 87 | }; 88 | 89 | while (!Console.KeyAvailable) 90 | { 91 | server.PollEvents(); 92 | Thread.Sleep(15); 93 | } 94 | server.Stop(); 95 | ``` 96 | 97 | ## NetManager settings description 98 | 99 | * **UnconnectedMessagesEnabled** 100 | * enable messages receiving without connection. (with SendUnconnectedMessage method) 101 | * default value: **false** 102 | * **NatPunchEnabled** 103 | * enable NAT punch messages 104 | * default value: **false** 105 | * **UpdateTime** 106 | * library logic update (and send) period in milliseconds 107 | * default value: **15 msec**. 108 | * **PingInterval** 109 | * Interval for latency detection and checking connection 110 | * default value: **1000 msec**. 111 | * **DisconnectTimeout** 112 | * if client or server doesn't receive any packet from remote peer during this time then connection will be closed 113 | * (including library internal keepalive packets) 114 | * default value: **5000 msec**. 115 | * **SimulatePacketLoss** 116 | * simulate packet loss by dropping random amout of packets. (Works only in DEBUG mode) 117 | * default value: **false** 118 | * **SimulateLatency** 119 | * simulate latency by holding packets for random time. (Works only in DEBUG mode) 120 | * default value: **false** 121 | * **SimulationPacketLossChance** 122 | * chance of packet loss when simulation enabled. value in percents. 123 | * default value: **10 (%)** 124 | * **SimulationMinLatency** 125 | * minimum simulated latency 126 | * default value: **30 msec** 127 | * **SimulationMaxLatency** 128 | * maximum simulated latency 129 | * default value: **100 msec** 130 | * **BroadcastEnabled** 131 | * Allows receive Broadcast packets 132 | * default value: **false** 133 | * **ReconnectDelay** 134 | * delay betwen connection attempts 135 | * default value: **500 msec** 136 | * **MaxConnectAttempts** 137 | * maximum connection attempts before client stops and call disconnect event. 138 | * default value: **10** 139 | * **UnsyncedEvents** 140 | * Experimental feature. Events automatically will be called without PollEvents method from another thread 141 | * default value: **false** 142 | -------------------------------------------------------------------------------- /docfx_project/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Articles 2 | href: articles/ 3 | - name: Api Documentation 4 | href: api/ 5 | homepage: api/index.md 6 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.ConnectionRequestType.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum ConnectionRequestType 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | 29 | 52 | 53 | 60 |
61 | 120 | 121 |
122 |
123 | 132 |
133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.ConnectionState.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum ConnectionState 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 140 | 141 |
142 |
143 | 152 |
153 |
154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.DeliveryMethod.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum DeliveryMethod 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 141 | 142 |
143 |
144 | 153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.INtpEventListener.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Interface INtpEventListener 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 132 | 133 |
134 |
135 | 144 |
145 |
146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.IPv6Mode.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum IPv6Mode 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 126 | 127 |
128 |
129 | 138 |
139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.Layers.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Namespace LiteNetLib.Layers 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 105 | 106 |
107 |
108 | 117 |
118 |
119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.LocalAddrType.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum LocalAddrType 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 128 | 129 |
130 |
131 | 140 |
141 |
142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.NatAddressType.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum NatAddressType 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 122 | 123 |
124 |
125 | 134 |
135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.NetDebug.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Class NetDebug 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 135 | 136 |
137 |
138 | 147 |
148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.NetLogLevel.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum NetLogLevel 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 130 | 131 |
132 |
133 | 142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.UnconnectedMessageType.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum UnconnectedMessageType 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 123 | 124 |
125 |
126 | 135 |
136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /docs/api/LiteNetLib.Utils.NtpMode.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Enum NtpMode 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 51 | 52 | 59 |
60 | 129 | 130 |
131 |
132 | 141 |
142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/api/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | LiteNetLib 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 | 26 | 49 | 50 | 57 |
58 | 89 | 90 |
91 |
92 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/articles/toc.html: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 19 |
20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /docs/articles/toc.json: -------------------------------------------------------------------------------- 1 | 2 | {"items":[{"name":"NetSerializer usage","href":"netserializerusage.html","topicHref":"netserializerusage.html"}]} 3 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/favicon.ico -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by Docfx 9 | 10 | 12 | 15 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/search-stopwords.json: -------------------------------------------------------------------------------- 1 | [ 2 | "a", 3 | "able", 4 | "about", 5 | "across", 6 | "after", 7 | "all", 8 | "almost", 9 | "also", 10 | "am", 11 | "among", 12 | "an", 13 | "and", 14 | "any", 15 | "are", 16 | "as", 17 | "at", 18 | "be", 19 | "because", 20 | "been", 21 | "but", 22 | "by", 23 | "can", 24 | "cannot", 25 | "could", 26 | "dear", 27 | "did", 28 | "do", 29 | "does", 30 | "either", 31 | "else", 32 | "ever", 33 | "every", 34 | "for", 35 | "from", 36 | "get", 37 | "got", 38 | "had", 39 | "has", 40 | "have", 41 | "he", 42 | "her", 43 | "hers", 44 | "him", 45 | "his", 46 | "how", 47 | "however", 48 | "i", 49 | "if", 50 | "in", 51 | "into", 52 | "is", 53 | "it", 54 | "its", 55 | "just", 56 | "least", 57 | "let", 58 | "like", 59 | "likely", 60 | "may", 61 | "me", 62 | "might", 63 | "most", 64 | "must", 65 | "my", 66 | "neither", 67 | "no", 68 | "nor", 69 | "not", 70 | "of", 71 | "off", 72 | "often", 73 | "on", 74 | "only", 75 | "or", 76 | "other", 77 | "our", 78 | "own", 79 | "rather", 80 | "said", 81 | "say", 82 | "says", 83 | "she", 84 | "should", 85 | "since", 86 | "so", 87 | "some", 88 | "than", 89 | "that", 90 | "the", 91 | "their", 92 | "them", 93 | "then", 94 | "there", 95 | "these", 96 | "they", 97 | "this", 98 | "tis", 99 | "to", 100 | "too", 101 | "twas", 102 | "us", 103 | "wants", 104 | "was", 105 | "we", 106 | "were", 107 | "what", 108 | "when", 109 | "where", 110 | "which", 111 | "while", 112 | "who", 113 | "whom", 114 | "why", 115 | "will", 116 | "with", 117 | "would", 118 | "yet", 119 | "you", 120 | "your" 121 | ] 122 | -------------------------------------------------------------------------------- /docs/styles/glyphicons-halflings-regular-ACNUA6UY.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/styles/glyphicons-halflings-regular-ACNUA6UY.ttf -------------------------------------------------------------------------------- /docs/styles/glyphicons-halflings-regular-JOUF32XT.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/styles/glyphicons-halflings-regular-JOUF32XT.woff -------------------------------------------------------------------------------- /docs/styles/glyphicons-halflings-regular-PIHUWCJO.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/styles/glyphicons-halflings-regular-PIHUWCJO.eot -------------------------------------------------------------------------------- /docs/styles/glyphicons-halflings-regular-W4DYDFZM.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/styles/glyphicons-halflings-regular-W4DYDFZM.woff2 -------------------------------------------------------------------------------- /docs/styles/main.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RevenantX/LiteNetLib/f11037374b05df1382cb7468223b2ce25a417aab/docs/styles/main.css -------------------------------------------------------------------------------- /docs/styles/main.js: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | -------------------------------------------------------------------------------- /docs/styles/search-worker.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | importScripts('lunr.min.js'); 3 | 4 | var lunrIndex; 5 | 6 | var stopWords = null; 7 | var searchData = {}; 8 | 9 | lunr.tokenizer.separator = /[\s\-\.\(\)]+/; 10 | 11 | var stopWordsRequest = new XMLHttpRequest(); 12 | stopWordsRequest.open('GET', '../search-stopwords.json'); 13 | stopWordsRequest.onload = function () { 14 | if (this.status != 200) { 15 | return; 16 | } 17 | stopWords = JSON.parse(this.responseText); 18 | buildIndex(); 19 | } 20 | stopWordsRequest.send(); 21 | 22 | var searchDataRequest = new XMLHttpRequest(); 23 | 24 | searchDataRequest.open('GET', '../index.json'); 25 | searchDataRequest.onload = function () { 26 | if (this.status != 200) { 27 | return; 28 | } 29 | searchData = JSON.parse(this.responseText); 30 | 31 | buildIndex(); 32 | 33 | postMessage({ e: 'index-ready' }); 34 | } 35 | searchDataRequest.send(); 36 | 37 | onmessage = function (oEvent) { 38 | var q = oEvent.data.q; 39 | var hits = lunrIndex.search(q); 40 | var results = []; 41 | hits.forEach(function (hit) { 42 | var item = searchData[hit.ref]; 43 | results.push({ 'href': item.href, 'title': item.title, 'keywords': item.keywords }); 44 | }); 45 | postMessage({ e: 'query-ready', q: q, d: results }); 46 | } 47 | 48 | function buildIndex() { 49 | if (stopWords !== null && !isEmpty(searchData)) { 50 | lunrIndex = lunr(function () { 51 | this.pipeline.remove(lunr.stopWordFilter); 52 | this.ref('href'); 53 | this.field('title', { boost: 50 }); 54 | this.field('keywords', { boost: 20 }); 55 | 56 | for (var prop in searchData) { 57 | if (searchData.hasOwnProperty(prop)) { 58 | this.add(searchData[prop]); 59 | } 60 | } 61 | 62 | var docfxStopWordFilter = lunr.generateStopWordFilter(stopWords); 63 | lunr.Pipeline.registerFunction(docfxStopWordFilter, 'docfxStopWordFilter'); 64 | this.pipeline.add(docfxStopWordFilter); 65 | this.searchPipeline.add(docfxStopWordFilter); 66 | }); 67 | } 68 | } 69 | 70 | function isEmpty(obj) { 71 | if(!obj) return true; 72 | 73 | for (var prop in obj) { 74 | if (obj.hasOwnProperty(prop)) 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | })(); 81 | -------------------------------------------------------------------------------- /docs/toc.html: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 22 |
23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /docs/toc.json: -------------------------------------------------------------------------------- 1 | 2 | {"items":[{"name":"Articles","href":"articles/netserializerusage.html","tocHref":"articles/toc.html","topicHref":"articles/netserializerusage.html"},{"name":"Api Documentation","href":"api/index.html","tocHref":"api/toc.html","topicHref":"api/index.html","homepage":"api/index.html"}]} 3 | -------------------------------------------------------------------------------- /update_docs.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | docfx docfx_project/docfx.json --------------------------------------------------------------------------------