├── .gitignore ├── Example ├── Example Client │ ├── .gitignore │ ├── Assets │ │ ├── Plugins.meta │ │ ├── Plugins │ │ │ ├── Lidgren.Network.dll │ │ │ ├── Lidgren.Network.dll.meta │ │ │ ├── Lidgren.Network.xml │ │ │ ├── Lidgren.Network.xml.meta │ │ │ ├── PNet.dll │ │ │ ├── PNet.dll.meta │ │ │ ├── PNet.xml │ │ │ ├── PNet.xml.meta │ │ │ ├── PNetC.dll │ │ │ ├── PNetC.dll.meta │ │ │ ├── PNetC.xml │ │ │ ├── PNetC.xml.meta │ │ │ ├── PNetU.dll │ │ │ ├── PNetU.dll.meta │ │ │ ├── PNetU.xml │ │ │ └── PNetU.xml.meta │ │ ├── Resources.meta │ │ ├── Resources │ │ │ ├── Player.prefab │ │ │ └── Player.prefab.meta │ │ ├── Scenes.meta │ │ ├── Scenes │ │ │ ├── Main.unity │ │ │ └── Main.unity.meta │ │ ├── Scripts.meta │ │ ├── Scripts │ │ │ ├── ExamplePNet.cs │ │ │ ├── ExamplePNet.cs.meta │ │ │ ├── NetPlayer.cs │ │ │ └── NetPlayer.cs.meta │ │ ├── Standard Assets.meta │ │ └── Standard Assets │ │ │ ├── Character Controllers.meta │ │ │ └── Character Controllers │ │ │ ├── Sources.meta │ │ │ └── Sources │ │ │ ├── Scripts.meta │ │ │ └── Scripts │ │ │ ├── CharacterMotor.js │ │ │ ├── CharacterMotor.js.meta │ │ │ ├── FPSInputController.js │ │ │ ├── FPSInputController.js.meta │ │ │ ├── MouseLook.cs │ │ │ ├── MouseLook.cs.meta │ │ │ ├── PlatformInputController.js │ │ │ ├── PlatformInputController.js.meta │ │ │ ├── ThirdPersonCamera.js │ │ │ ├── ThirdPersonCamera.js.meta │ │ │ ├── ThirdPersonController.js │ │ │ └── ThirdPersonController.js.meta │ └── ProjectSettings │ │ ├── AudioManager.asset │ │ ├── DynamicsManager.asset │ │ ├── EditorBuildSettings.asset │ │ ├── EditorSettings.asset │ │ ├── GraphicsSettings.asset │ │ ├── InputManager.asset │ │ ├── NavMeshLayers.asset │ │ ├── NetworkManager.asset │ │ ├── Physics2DSettings.asset │ │ ├── ProjectSettings.asset │ │ ├── QualitySettings.asset │ │ ├── TagManager.asset │ │ └── TimeManager.asset └── ExampleServer │ ├── BasicRoom.cs │ ├── ExampleServer.csproj │ ├── ExampleServer.sln │ ├── PlayerComponent.cs │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings │ └── app.config ├── PNet.sln ├── PNet.vsmdi ├── PNet ├── Channels.cs ├── DictionarySerializer.cs ├── INetSerializable.cs ├── IntDictionary.cs ├── JetBrains.Annotations.cs ├── LidgrenExtensions.cs ├── ObjectArraySerializer.cs ├── PNet.csproj ├── Properties │ └── AssemblyInfo.cs └── RPCUtils.cs ├── PNetC ├── ClientConfiguration.cs ├── IEngineHook.cs ├── Log │ ├── ILogger.cs │ ├── Log.cs │ ├── NetworkLogLevel.cs │ └── NullLogger.cs ├── NetworkStateSynchronization.cs ├── NetworkView.cs ├── NetworkViewId.cs ├── NetworkViewManager.cs ├── NetworkedSceneObject.cs ├── PNet.cs ├── PNetC.csproj ├── Properties │ └── AssemblyInfo.cs ├── RPCMode.cs ├── SerializedStructs.cs └── SynchronizedField.cs ├── PNetS ├── GameMachine │ ├── GameObject │ │ ├── Component.cs │ │ ├── GameObject.Components.cs │ │ ├── GameObject.RunMethods.cs │ │ ├── GameObject.cs │ │ └── Prefab.cs │ ├── State │ │ ├── Coroutine.cs │ │ ├── GameState.Coroutine.cs │ │ ├── GameState.cs │ │ └── Time.cs │ └── Yield │ │ ├── Coroutine.cs │ │ ├── WaitForFrames.cs │ │ ├── WaitForSeconds.cs │ │ └── YieldInstruction.cs ├── Log │ ├── DefaultConsoleLogger.cs │ ├── ILogger.cs │ ├── Log.cs │ ├── NetworkLogLevel.cs │ └── NullLogger.cs ├── NetPeer.cs ├── NetworkView │ ├── NetMessageInfo.cs │ ├── NetworkView.RPC.cs │ ├── NetworkView.Static.cs │ ├── NetworkView.cs │ ├── NetworkViewId.cs │ ├── NetworkedSceneObject.cs │ └── NetworkedSceneView.cs ├── PNetS.csproj ├── Player.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources.cs ├── Serializers │ └── SlimMathSerializer.cs ├── Server │ ├── PNetServer.Update.cs │ ├── PNetServer.cs │ ├── Room.Coroutine.cs │ ├── Room.State.cs │ ├── Room.cs │ ├── RoomBehaviour.cs │ └── TcpServer.cs ├── ServerConfiguration.cs └── Utils │ ├── IPoolItem.cs │ ├── NetworkStateSynchronization.cs │ ├── ObjectCreateMethod.cs │ ├── Pool.cs │ ├── RPCMode.cs │ └── RPCProcessor.cs ├── PNetU ├── NetBehaviour.cs ├── NetworkView.Static.cs ├── NetworkView.cs ├── NetworkedSceneObject.cs ├── PNet.cs ├── PNetU.csproj ├── Properties │ └── AssemblyInfo.cs ├── UnityDebugLogger.cs ├── UnityEngineHook.cs ├── UnityExtensions.cs ├── UnityNetworkViewManager.cs └── UnitySerializers.cs ├── README.md ├── Tests ├── ClientServerIntegrationTests │ ├── BasicTests.cs │ ├── ClientServerIntegrationTests.csproj │ ├── ClientTestComponent.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RPCTests.cs │ ├── RoomTests.cs │ └── TestComponent.cs ├── PNet.Testing.Common │ ├── ASerializableTest.cs │ ├── IntDictionaryTest.cs │ ├── PNet.Testing.Common.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ReflectionHelpers.cs │ ├── SerializableTest.cs │ ├── ServerUtils.cs │ ├── TestClientLogger.cs │ ├── TestEngineHook.cs │ ├── TestServerLogger.cs │ └── TestablePNet.cs ├── PNetSUnitTests │ ├── GameStateTest.cs │ ├── PNetSUnitTests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── TcpServerTests.cs │ └── TcpStateTest.cs └── UnitTestsPNetC │ ├── NetTest.cs │ ├── NetworkManagerCreateAndRecycle.orderedtest │ ├── NetworkViewManagerTest.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Test References │ └── PNetC.accessor │ └── UnitTestsPNetC.csproj ├── TraceAndTestImpact.testsettings ├── directions for lidgren and slimmath projects.txt ├── lib ├── UnityEngine.dll ├── YamlSerializer.XML └── YamlSerializer.dll ├── lidgren_patch.patch └── slimmath_patch.patch /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | 110 | /Lidgren.Network 111 | /SlimMath 112 | /Example/Example Client/Library 113 | /Example/Example Client/Assembly-CSharp.csproj 114 | /Example/Example Client/Assembly-CSharp-firstpass.csproj 115 | /Example/Example Client/Assembly-CSharp-firstpass-vs.csproj 116 | /Example/Example Client/Assembly-CSharp-vs.csproj 117 | /Example/Example Client/Assembly-UnityScript-firstpass.unityproj 118 | /Example/Example Client/Assembly-UnityScript-firstpass-vs.unityproj 119 | /Example/Example Client/Example Client.sln 120 | /Example/Example Client/Example Client-csharp.sln 121 | *.DotSettings 122 | Local.testsettings 123 | Example/Example Client/Temp/ 124 | Example/Example Client/Build/ 125 | -------------------------------------------------------------------------------- /Example/Example Client/.gitignore: -------------------------------------------------------------------------------- 1 | !*.meta -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39b0f40fba1eb334abc0274062809db2 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/Lidgren.Network.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/Example/Example Client/Assets/Plugins/Lidgren.Network.dll -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/Lidgren.Network.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1525541826f69d4ba664107cf04ed5f 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/Lidgren.Network.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80a56eaeeae8e164690bd4d7b274264c 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/Example/Example Client/Assets/Plugins/PNet.dll -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNet.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d63ca83a729e8cf40930004d8f5fc442 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNet.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1abeead6daa60a74eaef3b8c9637f068 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetC.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/Example/Example Client/Assets/Plugins/PNetC.dll -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetC.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab204cad109625641938fc7d4a9c54ca 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetC.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33860c282606350458e15178acd59900 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetU.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/Example/Example Client/Assets/Plugins/PNetU.dll -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetU.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 343af965dfdea4c46945f54610f57ac1 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Plugins/PNetU.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e5160a5f611b6048a19ad1f9a35d805 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bff5a160cd6613e408202b8f3179d7bb 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Resources/Player.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d4133d5d30b644bd87802a347eaccbe 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c896229ac45fa3459c3feda1d288668 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scenes/Main.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd0acbc2f3a88814ebfe3fc569cc338b 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 262ef8b219ba1674fb94956947ccfa94 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scripts/ExamplePNet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lidgren.Network; 3 | using PNet; 4 | using Debug = UnityEngine.Debug; 5 | using UnityEngine; 6 | using Net = PNetU.Net; 7 | 8 | public class ExamplePNet : MonoBehaviour 9 | { 10 | 11 | public string ip = "127.0.0.1"; 12 | public int port = 14000; 13 | 14 | private static ExamplePNet _singleton; 15 | 16 | void Awake() 17 | { 18 | //singleton behaviour, to prevent multiple event subscriptions/connectings 19 | if (_singleton) 20 | { 21 | Destroy(this); 22 | return; 23 | } 24 | 25 | _singleton = this; 26 | DontDestroyOnLoad(this); 27 | 28 | Net.OnRoomChange += OnRoomChange; 29 | Net.OnFailedToConnect += NetOnOnFailedToConnect; 30 | Net.OnDisconnectedFromServer += OnDisconnectedFromServer; 31 | Net.WriteHailMessage = WriteHailMessage; 32 | Net.ProcessRPC += ProcessRpc; 33 | } 34 | 35 | private void NetOnOnFailedToConnect(string s) 36 | { 37 | Debug.LogError("Failed to connect. " + s); 38 | } 39 | 40 | private void WriteHailMessage(NetOutgoingMessage netOutgoingMessage) 41 | { 42 | //TODO: serialize authentication information to the netoutgoingMessage 43 | //The data written here is what is in the ApproveConnection delegate on the server 44 | } 45 | 46 | //This is run whenever a room or server RPC is received 47 | private void ProcessRpc(byte b, NetIncomingMessage msg) 48 | { 49 | Debug.Log("Room rpc " + b + " received"); 50 | 51 | //TODO: deserialize data from the msg object 52 | //this can be done via if/else, switches, or Dictionary>. 53 | //The dictionary is recommended for its cleanness 54 | //the if/else is fastest if you only have a few Room/Server RPCs 55 | } 56 | 57 | private void OnDisconnectedFromServer() 58 | { 59 | Debug.Log("Disconnected from server"); 60 | } 61 | 62 | private void OnRoomChange(string s) 63 | { 64 | Debug.Log("server switched us to room " + s); 65 | 66 | //TODO: this should probably be called after we actually switch scenes, but because we're not changing scenes, we'll call it right now 67 | Net.FinishedRoomChange(); 68 | 69 | Net.RPC(3, StringSerializer.Instance.Update("This is a static rpc call. It goes to a room behaviour that is subscribed to it.")); 70 | } 71 | 72 | private void OnDestroy() 73 | { 74 | //This is required for cleanup, as unity can't clean up delegates very well 75 | Net.OnRoomChange -= OnRoomChange; 76 | Net.OnDisconnectedFromServer -= OnDisconnectedFromServer; 77 | Net.WriteHailMessage = null; 78 | Net.ProcessRPC -= ProcessRpc; 79 | } 80 | 81 | // Use this for initialization 82 | void Start () 83 | { 84 | var config = new PNetC.ClientConfiguration(ip, port); 85 | Debug.Log("connecting to " + ip + ":" + port); 86 | Net.Connect(config); 87 | } 88 | } -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scripts/ExamplePNet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a6459bb883628a4182e845b335bcbf8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scripts/NetPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lidgren.Network; 3 | using PNet; 4 | using PNetU; 5 | using UnityEngine; 6 | 7 | public class NetPlayer : NetBehaviour 8 | { 9 | [SerializeField] 10 | private MonoBehaviour[] _behavioursToDisableIfNotMine = null; 11 | [SerializeField] 12 | private GameObject[] _objectsToDisableIfNotMine = null; 13 | 14 | void Awake() 15 | { 16 | netView.OnFinishedCreation += OnFinishedCreation; 17 | } 18 | 19 | private void OnFinishedCreation() 20 | { 21 | //TODO: enable/disable things because this is mine/not mine. 22 | 23 | if (netView.IsMine) 24 | { 25 | Debug.Log("network view " + netView.viewID + " is mine", netView); 26 | 27 | //The object is mine, so let's stream things to the server 28 | netView.SetSerializationMethod(SerializeStream); 29 | //turn serialization on 30 | netView.StateSynchronization = NetworkStateSynchronization.Unreliable; 31 | //but do not subscribe to deserialization, as we want to ignore stuff for ourselves 32 | } 33 | else 34 | { 35 | //subscribe to the stream from the server for objects owned by others. 36 | netView.OnDeserializeStream += OnDeserializeStream; 37 | 38 | //Anything in this array shouldn't be enabled, so disable them 39 | foreach (var comp in _behavioursToDisableIfNotMine) 40 | { 41 | comp.enabled = false; 42 | } 43 | foreach (var gobj in _objectsToDisableIfNotMine) 44 | { 45 | gobj.SetActive(false); 46 | } 47 | } 48 | } 49 | 50 | private readonly Vector3Serializer _serializer = new Vector3Serializer(); 51 | 52 | private void OnDeserializeStream(NetIncomingMessage netIncomingMessage) 53 | { 54 | //deserialize position from the stream 55 | //TODO: implement smoothing/lag compensation 56 | _serializer.OnDeserialize(netIncomingMessage); 57 | transform.position = _serializer.vector3; 58 | } 59 | 60 | private void SerializeStream(NetOutgoingMessage netOutgoingMessage) 61 | { 62 | //send our position to the server 63 | //this should only be happening on an object that is ours 64 | _serializer.vector3 = transform.position; 65 | _serializer.OnSerialize(netOutgoingMessage); 66 | } 67 | 68 | //TODO: use a shared library with client and server with const byte fields 69 | //then use those in the Rpc attributes, so you have names instead of numbers 70 | [Rpc(1)] 71 | void SimpleMessage(NetIncomingMessage msg) 72 | { 73 | Debug.Log("Message from the server on the player: " + msg.ReadString(), this); 74 | 75 | netView.RPC(7, RPCMode.Server, StringSerializer.Instance.Update("This rpc goes only to the corresponding gameobject/component on the server")); 76 | } 77 | } -------------------------------------------------------------------------------- /Example/Example Client/Assets/Scripts/NetPlayer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efc78aed602f8b744bc14ff31ba89965 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00d4e2e510bd13546893daa7b68182fa 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54216e9ed42974e30967824b7f0b2806 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e0b0a994d8934541a387e092630b5db 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f781c091d1c8647c380d5230adfaee54 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/CharacterMotor.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ab79d7f243824f5d9826bd83522c8df 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/FPSInputController.js: -------------------------------------------------------------------------------- 1 | private var motor : CharacterMotor; 2 | 3 | // Use this for initialization 4 | function Awake () { 5 | motor = GetComponent(CharacterMotor); 6 | } 7 | 8 | // Update is called once per frame 9 | function Update () { 10 | // Get the input vector from kayboard or analog stick 11 | var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); 12 | 13 | if (directionVector != Vector3.zero) { 14 | // Get the length of the directon vector and then normalize it 15 | // Dividing by the length is cheaper than normalizing when we already have the length anyway 16 | var directionLength = directionVector.magnitude; 17 | directionVector = directionVector / directionLength; 18 | 19 | // Make sure the length is no bigger than 1 20 | directionLength = Mathf.Min(1, directionLength); 21 | 22 | // Make the input vector more sensitive towards the extremes and less sensitive in the middle 23 | // This makes it easier to control slow speeds when using analog sticks 24 | directionLength = directionLength * directionLength; 25 | 26 | // Multiply the normalized direction vector by the modified length 27 | directionVector = directionVector * directionLength; 28 | } 29 | 30 | // Apply the direction to the CharacterMotor 31 | motor.inputMoveDirection = transform.rotation * directionVector; 32 | motor.inputJump = Input.GetButton("Jump"); 33 | } 34 | 35 | // Require a character controller to be attached to the same game object 36 | @script RequireComponent (CharacterMotor) 37 | @script AddComponentMenu ("Character/FPS Input Controller") 38 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/FPSInputController.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60bca8f58a0b8478e946e6e86658cb29 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/MouseLook.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | /// MouseLook rotates the transform based on the mouse delta. 5 | /// Minimum and Maximum values can be used to constrain the possible rotation 6 | 7 | /// To make an FPS style character: 8 | /// - Create a capsule. 9 | /// - Add the MouseLook script to the capsule. 10 | /// -> Set the mouse look to use LookX. (You want to only turn character but not tilt it) 11 | /// - Add FPSInputController script to the capsule 12 | /// -> A CharacterMotor and a CharacterController component will be automatically added. 13 | 14 | /// - Create a camera. Make the camera a child of the capsule. Reset it's transform. 15 | /// - Add a MouseLook script to the camera. 16 | /// -> Set the mouse look to use LookY. (You want the camera to tilt up and down like a head. The character already turns.) 17 | [AddComponentMenu("Camera-Control/Mouse Look")] 18 | public class MouseLook : MonoBehaviour { 19 | 20 | public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 } 21 | public RotationAxes axes = RotationAxes.MouseXAndY; 22 | public float sensitivityX = 15F; 23 | public float sensitivityY = 15F; 24 | 25 | public float minimumX = -360F; 26 | public float maximumX = 360F; 27 | 28 | public float minimumY = -60F; 29 | public float maximumY = 60F; 30 | 31 | float rotationY = 0F; 32 | 33 | void Update () 34 | { 35 | if (axes == RotationAxes.MouseXAndY) 36 | { 37 | float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX; 38 | 39 | rotationY += Input.GetAxis("Mouse Y") * sensitivityY; 40 | rotationY = Mathf.Clamp (rotationY, minimumY, maximumY); 41 | 42 | transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); 43 | } 44 | else if (axes == RotationAxes.MouseX) 45 | { 46 | transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0); 47 | } 48 | else 49 | { 50 | rotationY += Input.GetAxis("Mouse Y") * sensitivityY; 51 | rotationY = Mathf.Clamp (rotationY, minimumY, maximumY); 52 | 53 | transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0); 54 | } 55 | } 56 | 57 | void Start () 58 | { 59 | // Make the rigid body not change rotation 60 | if (rigidbody) 61 | rigidbody.freezeRotation = true; 62 | } 63 | } -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/MouseLook.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68ec2fe99d1108b9d0006a298d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/PlatformInputController.js: -------------------------------------------------------------------------------- 1 | // This makes the character turn to face the current movement speed per default. 2 | var autoRotate : boolean = true; 3 | var maxRotationSpeed : float = 360; 4 | 5 | private var motor : CharacterMotor; 6 | 7 | // Use this for initialization 8 | function Awake () { 9 | motor = GetComponent(CharacterMotor); 10 | } 11 | 12 | // Update is called once per frame 13 | function Update () { 14 | // Get the input vector from kayboard or analog stick 15 | var directionVector = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0); 16 | 17 | if (directionVector != Vector3.zero) { 18 | // Get the length of the directon vector and then normalize it 19 | // Dividing by the length is cheaper than normalizing when we already have the length anyway 20 | var directionLength = directionVector.magnitude; 21 | directionVector = directionVector / directionLength; 22 | 23 | // Make sure the length is no bigger than 1 24 | directionLength = Mathf.Min(1, directionLength); 25 | 26 | // Make the input vector more sensitive towards the extremes and less sensitive in the middle 27 | // This makes it easier to control slow speeds when using analog sticks 28 | directionLength = directionLength * directionLength; 29 | 30 | // Multiply the normalized direction vector by the modified length 31 | directionVector = directionVector * directionLength; 32 | } 33 | 34 | // Rotate the input vector into camera space so up is camera's up and right is camera's right 35 | directionVector = Camera.main.transform.rotation * directionVector; 36 | 37 | // Rotate input vector to be perpendicular to character's up vector 38 | var camToCharacterSpace = Quaternion.FromToRotation(-Camera.main.transform.forward, transform.up); 39 | directionVector = (camToCharacterSpace * directionVector); 40 | 41 | // Apply the direction to the CharacterMotor 42 | motor.inputMoveDirection = directionVector; 43 | motor.inputJump = Input.GetButton("Jump"); 44 | 45 | // Set rotation to the move direction 46 | if (autoRotate && directionVector.sqrMagnitude > 0.01) { 47 | var newForward : Vector3 = ConstantSlerp( 48 | transform.forward, 49 | directionVector, 50 | maxRotationSpeed * Time.deltaTime 51 | ); 52 | newForward = ProjectOntoPlane(newForward, transform.up); 53 | transform.rotation = Quaternion.LookRotation(newForward, transform.up); 54 | } 55 | } 56 | 57 | function ProjectOntoPlane (v : Vector3, normal : Vector3) { 58 | return v - Vector3.Project(v, normal); 59 | } 60 | 61 | function ConstantSlerp (from : Vector3, to : Vector3, angle : float) { 62 | var value : float = Mathf.Min(1, angle / Vector3.Angle(from, to)); 63 | return Vector3.Slerp(from, to, value); 64 | } 65 | 66 | // Require a character controller to be attached to the same game object 67 | @script RequireComponent (CharacterMotor) 68 | @script AddComponentMenu ("Character/Platform Input Controller") 69 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/PlatformInputController.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da93ddd6928094e24bb1f3f665f143d3 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonCamera.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b167d00b3108411a8a963cba5ddde1b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonController.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d5ac211a643e447ca78c2d794a16381 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Example/Example Client/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 | m_SpeedOfSound: 347 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_DSPBufferSize: 0 12 | m_DisableAudio: 0 13 | -------------------------------------------------------------------------------- /Example/Example Client/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 | m_Gravity: {x: 0, y: -9.81000042, z: 0} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_BounceThreshold: 2 9 | m_SleepVelocity: .150000006 10 | m_SleepAngularVelocity: .140000001 11 | m_MaxAngularVelocity: 7 12 | m_MinPenetrationForPenalty: .00999999978 13 | m_SolverIterationCount: 6 14 | m_RaycastsHitTriggers: 1 15 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 16 | -------------------------------------------------------------------------------- /Example/Example Client/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/Main.unity 10 | -------------------------------------------------------------------------------- /Example/Example Client/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: 0 13 | -------------------------------------------------------------------------------- /Example/Example Client/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 | m_AlwaysIncludedShaders: 7 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 8 | -------------------------------------------------------------------------------- /Example/Example Client/ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshLayers: 5 | m_ObjectHideFlags: 0 6 | Built-in Layer 0: 7 | name: Default 8 | cost: 1 9 | editType: 2 10 | Built-in Layer 1: 11 | name: Not Walkable 12 | cost: 1 13 | editType: 0 14 | Built-in Layer 2: 15 | name: Jump 16 | cost: 2 17 | editType: 2 18 | User Layer 0: 19 | name: 20 | cost: 1 21 | editType: 3 22 | User Layer 1: 23 | name: 24 | cost: 1 25 | editType: 3 26 | User Layer 2: 27 | name: 28 | cost: 1 29 | editType: 3 30 | User Layer 3: 31 | name: 32 | cost: 1 33 | editType: 3 34 | User Layer 4: 35 | name: 36 | cost: 1 37 | editType: 3 38 | User Layer 5: 39 | name: 40 | cost: 1 41 | editType: 3 42 | User Layer 6: 43 | name: 44 | cost: 1 45 | editType: 3 46 | User Layer 7: 47 | name: 48 | cost: 1 49 | editType: 3 50 | User Layer 8: 51 | name: 52 | cost: 1 53 | editType: 3 54 | User Layer 9: 55 | name: 56 | cost: 1 57 | editType: 3 58 | User Layer 10: 59 | name: 60 | cost: 1 61 | editType: 3 62 | User Layer 11: 63 | name: 64 | cost: 1 65 | editType: 3 66 | User Layer 12: 67 | name: 68 | cost: 1 69 | editType: 3 70 | User Layer 13: 71 | name: 72 | cost: 1 73 | editType: 3 74 | User Layer 14: 75 | name: 76 | cost: 1 77 | editType: 3 78 | User Layer 15: 79 | name: 80 | cost: 1 81 | editType: 3 82 | User Layer 16: 83 | name: 84 | cost: 1 85 | editType: 3 86 | User Layer 17: 87 | name: 88 | cost: 1 89 | editType: 3 90 | User Layer 18: 91 | name: 92 | cost: 1 93 | editType: 3 94 | User Layer 19: 95 | name: 96 | cost: 1 97 | editType: 3 98 | User Layer 20: 99 | name: 100 | cost: 1 101 | editType: 3 102 | User Layer 21: 103 | name: 104 | cost: 1 105 | editType: 3 106 | User Layer 22: 107 | name: 108 | cost: 1 109 | editType: 3 110 | User Layer 23: 111 | name: 112 | cost: 1 113 | editType: 3 114 | User Layer 24: 115 | name: 116 | cost: 1 117 | editType: 3 118 | User Layer 25: 119 | name: 120 | cost: 1 121 | editType: 3 122 | User Layer 26: 123 | name: 124 | cost: 1 125 | editType: 3 126 | User Layer 27: 127 | name: 128 | cost: 1 129 | editType: 3 130 | User Layer 28: 131 | name: 132 | cost: 1 133 | editType: 3 134 | -------------------------------------------------------------------------------- /Example/Example Client/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 | -------------------------------------------------------------------------------- /Example/Example Client/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 | m_Gravity: {x: 0, y: -9.81000042} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_VelocityIterations: 8 9 | m_PositionIterations: 3 10 | m_RaycastsHitTriggers: 1 11 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 12 | -------------------------------------------------------------------------------- /Example/Example Client/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: 3 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 | blendWeights: 1 18 | textureQuality: 1 19 | anisotropicTextures: 0 20 | antiAliasing: 0 21 | softParticles: 0 22 | softVegetation: 0 23 | vSyncCount: 0 24 | lodBias: .300000012 25 | maximumLODLevel: 0 26 | particleRaycastBudget: 4 27 | excludedTargetPlatforms: [] 28 | - serializedVersion: 2 29 | name: Fast 30 | pixelLightCount: 0 31 | shadows: 0 32 | shadowResolution: 0 33 | shadowProjection: 1 34 | shadowCascades: 1 35 | shadowDistance: 20 36 | blendWeights: 2 37 | textureQuality: 0 38 | anisotropicTextures: 0 39 | antiAliasing: 0 40 | softParticles: 0 41 | softVegetation: 0 42 | vSyncCount: 0 43 | lodBias: .400000006 44 | maximumLODLevel: 0 45 | particleRaycastBudget: 16 46 | excludedTargetPlatforms: [] 47 | - serializedVersion: 2 48 | name: Simple 49 | pixelLightCount: 1 50 | shadows: 1 51 | shadowResolution: 0 52 | shadowProjection: 1 53 | shadowCascades: 1 54 | shadowDistance: 20 55 | blendWeights: 2 56 | textureQuality: 0 57 | anisotropicTextures: 1 58 | antiAliasing: 0 59 | softParticles: 0 60 | softVegetation: 0 61 | vSyncCount: 0 62 | lodBias: .699999988 63 | maximumLODLevel: 0 64 | particleRaycastBudget: 64 65 | excludedTargetPlatforms: [] 66 | - serializedVersion: 2 67 | name: Good 68 | pixelLightCount: 2 69 | shadows: 2 70 | shadowResolution: 1 71 | shadowProjection: 1 72 | shadowCascades: 2 73 | shadowDistance: 40 74 | blendWeights: 2 75 | textureQuality: 0 76 | anisotropicTextures: 1 77 | antiAliasing: 0 78 | softParticles: 0 79 | softVegetation: 1 80 | vSyncCount: 1 81 | lodBias: 1 82 | maximumLODLevel: 0 83 | particleRaycastBudget: 256 84 | excludedTargetPlatforms: [] 85 | - serializedVersion: 2 86 | name: Beautiful 87 | pixelLightCount: 3 88 | shadows: 2 89 | shadowResolution: 2 90 | shadowProjection: 1 91 | shadowCascades: 2 92 | shadowDistance: 70 93 | blendWeights: 4 94 | textureQuality: 0 95 | anisotropicTextures: 2 96 | antiAliasing: 2 97 | softParticles: 1 98 | softVegetation: 1 99 | vSyncCount: 1 100 | lodBias: 1.5 101 | maximumLODLevel: 0 102 | particleRaycastBudget: 1024 103 | excludedTargetPlatforms: [] 104 | - serializedVersion: 2 105 | name: Fantastic 106 | pixelLightCount: 4 107 | shadows: 2 108 | shadowResolution: 2 109 | shadowProjection: 1 110 | shadowCascades: 4 111 | shadowDistance: 150 112 | blendWeights: 4 113 | textureQuality: 0 114 | anisotropicTextures: 2 115 | antiAliasing: 2 116 | softParticles: 1 117 | softVegetation: 1 118 | vSyncCount: 1 119 | lodBias: 2 120 | maximumLODLevel: 0 121 | particleRaycastBudget: 4096 122 | excludedTargetPlatforms: [] 123 | m_PerPlatformDefaultQuality: {} 124 | -------------------------------------------------------------------------------- /Example/Example Client/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | tags: 6 | - 7 | Builtin Layer 0: Default 8 | Builtin Layer 1: TransparentFX 9 | Builtin Layer 2: Ignore Raycast 10 | Builtin Layer 3: 11 | Builtin Layer 4: Water 12 | Builtin Layer 5: 13 | Builtin Layer 6: 14 | Builtin Layer 7: 15 | User Layer 8: 16 | User Layer 9: 17 | User Layer 10: 18 | User Layer 11: 19 | User Layer 12: 20 | User Layer 13: 21 | User Layer 14: 22 | User Layer 15: 23 | User Layer 16: 24 | User Layer 17: 25 | User Layer 18: 26 | User Layer 19: 27 | User Layer 20: 28 | User Layer 21: 29 | User Layer 22: 30 | User Layer 23: 31 | User Layer 24: 32 | User Layer 25: 33 | User Layer 26: 34 | User Layer 27: 35 | User Layer 28: 36 | User Layer 29: 37 | User Layer 30: 38 | User Layer 31: 39 | m_SortingLayers: 40 | - name: Default 41 | userID: 0 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /Example/Example Client/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: .0199999996 7 | Maximum Allowed Timestep: .333333343 8 | m_TimeScale: 1 9 | -------------------------------------------------------------------------------- /Example/ExampleServer/BasicRoom.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Lidgren.Network; 3 | using PNet; 4 | using PNetS; 5 | using SlimMath; 6 | 7 | namespace ExampleServer 8 | { 9 | class BasicRoom : RoomBehaviour 10 | { 11 | public override void OnPlayerEnter(Player player) 12 | { 13 | //make a new object for the player who just entered the room 14 | var playerObject = Room.NetworkInstantiate("player", Vector3.Zero, Quaternion.Identity, player); 15 | playerObject.AddComponent(); 16 | 17 | //so we can reference the player's object easier in things like rpcs 18 | player.UserData = playerObject; 19 | } 20 | public override void OnPlayerExit(Player player) 21 | { 22 | //cleanup 23 | foreach (var actor in Room.actors.Where(a => a.owner == player)) 24 | { 25 | Room.NetworkDestroy(actor); 26 | } 27 | player.UserData = null; 28 | } 29 | 30 | [Rpc(3, false)] 31 | void PlayerStaticMessage3(NetIncomingMessage msg, NetMessageInfo info) 32 | { 33 | Debug.Log("Got a room-wide/static message {0} from player {1}", msg.ReadString(), info.player); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Example/ExampleServer/ExampleServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9} 9 | Exe 10 | Properties 11 | ExampleServer 12 | ExampleServer 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\..\bin\Release\Lidgren.Network.dll 39 | 40 | 41 | ..\..\bin\Release\PNet.dll 42 | 43 | 44 | ..\..\bin\Release\PNetS.dll 45 | 46 | 47 | ..\..\bin\Release\SlimMath.dll 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | True 64 | True 65 | Settings.settings 66 | 67 | 68 | 69 | 70 | 71 | SettingsSingleFileGenerator 72 | Settings.Designer.cs 73 | 74 | 75 | 76 | 83 | -------------------------------------------------------------------------------- /Example/ExampleServer/ExampleServer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleServer", "ExampleServer.csproj", "{85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9}.Debug|x86.ActiveCfg = Debug|x86 13 | {85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9}.Debug|x86.Build.0 = Debug|x86 14 | {85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9}.Release|x86.ActiveCfg = Release|x86 15 | {85A1A4A2-D3C7-4B0A-BD24-760E4667BCD9}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Example/ExampleServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ExampleServer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("ExampleServer")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("eaeb0ce5-a24b-464e-895f-cc37df4ed713")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Example/ExampleServer/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.296 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ExampleServer.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("14000")] 29 | public ushort ListenPort { 30 | get { 31 | return ((ushort)(this["ListenPort"])); 32 | } 33 | } 34 | 35 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 36 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 37 | [global::System.Configuration.DefaultSettingValueAttribute("0.02")] 38 | public double FrameTime { 39 | get { 40 | return ((double)(this["FrameTime"])); 41 | } 42 | } 43 | 44 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 45 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 46 | [global::System.Configuration.DefaultSettingValueAttribute("64")] 47 | public ushort MaximumPlayers { 48 | get { 49 | return ((ushort)(this["MaximumPlayers"])); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/ExampleServer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 14000 7 | 8 | 9 | 0.02 10 | 11 | 12 | 64 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/ExampleServer/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 14000 12 | 13 | 14 | 0.02 15 | 16 | 17 | 64 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /PNet.vsmdi: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PNet/Channels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNet 7 | { 8 | /// 9 | /// Channels for various rpcs 10 | /// 11 | public class Channels 12 | { 13 | /// 14 | /// unreliable streaming 15 | /// 16 | public const int UNRELIABLE_STREAM = 0; 17 | /// 18 | /// Reliable, unordered, for static rpcs 19 | /// 20 | public const int STATIC_RPC_UNORDERED = 0; 21 | /// 22 | /// reliable streaming 23 | /// 24 | public const int RELIABLE_STREAM = 1; 25 | /// 26 | /// static rpcs (rooms) 27 | /// 28 | public const int STATIC_RPC = 3; 29 | /// 30 | /// utility rpcs 31 | /// 32 | public const int STATIC_UTILS = 5; 33 | /// 34 | /// beginning RPCMode channels 35 | /// 36 | public const int BEGIN_RPCMODES = 10; 37 | /// 38 | /// channel for owner rcpmode 39 | /// 40 | public const int OWNER_RPC = 17; 41 | /// 42 | /// channel for NetworkedSceneObject rpcs 43 | /// 44 | public const int OBJECT_RPC = 19; 45 | /// 46 | /// channel for synchronized fields 47 | /// 48 | public const int SYNCHED_FIELD = 21; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /PNet/DictionarySerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Lidgren.Network; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace PNet 8 | { 9 | /// 10 | /// THIS ONLY WORKS WITH BUILT IN TYPES AND STRING. USER DEFINED STRUCTS WILL BREAK 11 | /// 12 | /// 13 | /// 14 | public class DictionarySerializer : INetSerializable 15 | where T : struct 16 | where U : struct 17 | { 18 | /// 19 | /// serialized value 20 | /// 21 | public Dictionary dictionary; 22 | /// 23 | /// create a new serializer from the dictionary 24 | /// 25 | /// 26 | public DictionarySerializer(Dictionary dictionary) 27 | { 28 | this.dictionary = dictionary; 29 | } 30 | /// 31 | /// create a new serializer with no values 32 | /// 33 | public DictionarySerializer() 34 | { 35 | dictionary = new Dictionary(0); 36 | } 37 | /// 38 | /// size in bytes 39 | /// 40 | public int AllocSize 41 | { 42 | get { return dictionary.Count * (Marshal.SizeOf(new T()) + Marshal.SizeOf(new U())); } 43 | } 44 | /// 45 | /// deserialize from the message 46 | /// 47 | /// 48 | public void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 49 | { 50 | var size = message.ReadInt32(); 51 | dictionary = new Dictionary(size); 52 | 53 | for (int i = 0; i < size; ++i) 54 | { 55 | var key = message.Read(); 56 | var value = message.Read(); 57 | 58 | dictionary[key] = value; 59 | } 60 | } 61 | /// 62 | /// serialize to the message 63 | /// 64 | /// 65 | public void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 66 | { 67 | message.Write(dictionary.Count); 68 | 69 | foreach (var kvp in dictionary) 70 | { 71 | message.Write(kvp.Key); 72 | message.Write(kvp.Value); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /PNet/LidgrenExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Lidgren.Network; 6 | 7 | namespace PNet 8 | { 9 | /// 10 | /// class for extensions to lidgren 11 | /// 12 | public static class LidgrenExtensions 13 | { 14 | static Dictionary> messageReadMethods = new Dictionary>() 15 | { 16 | { typeof(byte), (msg) => {return msg.ReadByte();}} 17 | , { typeof(sbyte), (msg) => {return msg.ReadSByte();}} 18 | , { typeof(short), (msg) => {return msg.ReadInt16();}} 19 | , { typeof(ushort), (msg) => {return msg.ReadUInt16();}} 20 | , { typeof(int), (msg) => {return msg.ReadInt32();}} 21 | , { typeof(uint), (msg) => {return msg.ReadUInt32();}} 22 | , { typeof(long), (msg) => {return msg.ReadInt64();}} 23 | , { typeof(ulong), (msg) => {return msg.ReadUInt64();}} 24 | , { typeof(float), (msg) => {return msg.ReadFloat();}} 25 | , { typeof(double), (msg) => {return msg.ReadDouble();}} 26 | , { typeof(string), (msg) => {return msg.ReadString();}} 27 | }; 28 | static Dictionary> messageWriteMethods = new Dictionary>() 29 | { 30 | { typeof(byte), (msg, obj) => { msg.Write((byte)obj);}} 31 | , { typeof(sbyte), (msg, obj) => { msg.Write((sbyte)obj);}} 32 | , { typeof(short), (msg, obj) => { msg.Write((short)obj);}} 33 | , { typeof(ushort), (msg, obj) => { msg.Write((ushort)obj);}} 34 | , { typeof(int), (msg, obj) => { msg.Write((int)obj);}} 35 | , { typeof(uint), (msg, obj) => { msg.Write((uint)obj);}} 36 | , { typeof(long), (msg, obj) => { msg.Write((long)obj);}} 37 | , { typeof(ulong), (msg, obj) => { msg.Write((ulong)obj);}} 38 | , { typeof(float), (msg, obj) => { msg.Write((float)obj);}} 39 | , { typeof(double), (msg, obj) => { msg.Write((double)obj);}} 40 | , { typeof(string), (msg, obj) => {msg.Write((string)obj);}} 41 | }; 42 | 43 | public static void AddWriteMethod(Action writeMethod) where T : struct 44 | { 45 | messageWriteMethods.Add(typeof (T), writeMethod); 46 | } 47 | 48 | public static void AddReadMethod(Func readMethod) where T : struct 49 | { 50 | messageReadMethods.Add(typeof(T), readMethod); 51 | } 52 | /// 53 | /// ONLY WORKS FOR VALUE TYPES AND STRING. NO ENUMS. 54 | /// 55 | /// 56 | /// 57 | /// 58 | public static T Read(this NetIncomingMessage msg) 59 | where T : struct 60 | { 61 | var type = typeof(T); 62 | 63 | return (T)messageReadMethods[type](msg); 64 | } 65 | 66 | /// 67 | /// Read an INetSerializable out of the NetIncomingMessage 68 | /// 69 | /// 70 | /// 71 | /// 72 | public static T ReadINet(this NetIncomingMessage msg) 73 | where T : INetSerializable, new() 74 | { 75 | var ret = new T(); 76 | ret.OnDeserialize(msg); 77 | return ret; 78 | } 79 | /// 80 | /// ONLY WORKS FOR VALUE TYPES AND STRING. NO ENUMS. 81 | /// 82 | /// 83 | /// 84 | /// 85 | public static void Write(this NetOutgoingMessage msg, T val) 86 | where T : struct 87 | { 88 | var type = typeof(T); 89 | 90 | messageWriteMethods[type](msg, val); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /PNet/ObjectArraySerializer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace PNet 4 | { 5 | /// 6 | /// A serializer for an array of INetSerializable 7 | /// 8 | /// 9 | public class ObjectArraySerializer : INetSerializable 10 | where T : INetSerializable, new() 11 | { 12 | /// 13 | /// items 14 | /// 15 | public T[] items; 16 | 17 | /// 18 | /// Whether or not the index is preserved with an array with nulls 19 | /// Takes an additional bit per index 20 | /// only makes sense for nullable types 21 | /// 22 | public bool PreserveIndex = false; 23 | 24 | // ReSharper disable StaticFieldInGenericType 25 | private static readonly bool IsValueType = typeof (T).IsValueType; 26 | // ReSharper restore StaticFieldInGenericType 27 | 28 | /// 29 | /// Create a new serializer 30 | /// 31 | public ObjectArraySerializer() 32 | { 33 | } 34 | 35 | /// 36 | /// Create a new serializer from the specified array 37 | /// 38 | /// 39 | public ObjectArraySerializer(T[] newItems) 40 | { 41 | items = newItems; 42 | } 43 | 44 | /// 45 | /// Create a new serializer from the specified list 46 | /// 47 | /// 48 | public ObjectArraySerializer(List newItems) 49 | { 50 | items = newItems.ToArray(); 51 | } 52 | 53 | /// 54 | /// Size when writing to the stream 55 | /// 56 | public int AllocSize 57 | { 58 | get 59 | { 60 | if (items != null && items.Length >= 1) 61 | return (4 + items[0].AllocSize + (PreserveIndex ? 1 : 0)) * items.Length; 62 | return 0; 63 | } 64 | } 65 | 66 | /// 67 | /// Deserialize the array from the message 68 | /// 69 | /// 70 | public void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 71 | { 72 | var length = message.ReadInt32(); 73 | items = new T[length]; 74 | 75 | for (int i = 0; i < length; i++) 76 | { 77 | var hasValue = true; 78 | if (PreserveIndex && !IsValueType) 79 | { 80 | hasValue = message.ReadBoolean(); 81 | } 82 | if (!hasValue) continue; 83 | 84 | var t = new T(); 85 | t.OnDeserialize(message); 86 | items[i] = t; 87 | } 88 | } 89 | 90 | /// 91 | /// Serialize the array to the message 92 | /// 93 | /// 94 | public void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 95 | { 96 | if (items == null || items.Length == 0) 97 | { 98 | message.Write(0); 99 | return; 100 | } 101 | 102 | message.Write(items.Length); 103 | foreach (var item in items) 104 | { 105 | if (!IsValueType) 106 | { 107 | if (PreserveIndex) 108 | { 109 | message.Write(item != null); 110 | } 111 | if (item != null) 112 | item.OnSerialize(message); 113 | } 114 | else 115 | { 116 | item.OnSerialize(message); 117 | } 118 | } 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /PNet/PNet.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 9 | Library 10 | Properties 11 | PNet 12 | PNet 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | ..\bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | ..\bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | ..\bin\Release\PNet.xml 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 52 | Lidgren.Network 53 | 54 | 55 | 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /PNet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNet")] 9 | [assembly: AssemblyDescription("PNetwork Shared")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PNet")] 13 | [assembly: AssemblyCopyright("Copyright © Justin Bruening")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9edbd50f-9b71-409a-a658-f67465c70493")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /PNet/RPCUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lidgren.Network; 3 | 4 | namespace PNet 5 | { 6 | /// 7 | /// Helpers for RPCs 8 | /// 9 | public static class RPCUtils 10 | { 11 | /// 12 | /// get the allocation size from the specified serializing objects 13 | /// 14 | /// 15 | /// 16 | public static void AllocSize(ref int prealloc, INetSerializable[] towrite) 17 | { 18 | foreach (var arg in towrite) 19 | { 20 | prealloc += arg.AllocSize; 21 | } 22 | } 23 | 24 | /// 25 | /// write all the serializing objects to the stream 26 | /// 27 | /// 28 | /// 29 | public static void WriteParams(ref NetOutgoingMessage msg, INetSerializable[] towrite) 30 | { 31 | foreach (var arg in towrite) 32 | { 33 | arg.OnSerialize(msg); 34 | } 35 | } 36 | 37 | /// 38 | /// Serialize to an IntSerializer. This will have issues if the enum isn't an int type. 39 | /// 40 | /// 41 | /// 42 | public static IntSerializer Serialize(this Enum enumeration) 43 | { 44 | return new IntSerializer(Convert.ToInt32(enumeration)); 45 | } 46 | 47 | 48 | /// 49 | /// string resourcepath 50 | /// ushort viewid 51 | /// ushort ownerid 52 | /// 53 | public const byte Instantiate = 1; 54 | /// 55 | /// Network destroy 56 | /// 57 | public const byte Remove = 2; 58 | /// 59 | /// new time 60 | /// 61 | public const byte TimeUpdate = 3; 62 | /// 63 | /// set the id of this client 64 | /// 65 | public const byte SetPlayerId = 4; 66 | /// 67 | /// change to the specified room 68 | /// 69 | public const byte ChangeRoom = 5; 70 | /// 71 | /// sent to the server when the client has finished changing rooms 72 | /// 73 | public const byte FinishedRoomChange = 6; 74 | /// 75 | /// sent to the server when a networkview has been created 76 | /// 77 | public const byte FinishedInstantiate = 8; 78 | /// 79 | /// sent to the clients when a view is added to an already existing gameobject with a network view 80 | /// 81 | public const byte AddView = 10; 82 | } 83 | 84 | /// 85 | /// Attribute for marking rpc methods 86 | /// 87 | /// 88 | /// Only one rpc attribute is valid per rpc id per receiving object (room, networkview, etc). If there are multiple, they are overwritten 89 | /// 90 | [JetBrains.Annotations.MeansImplicitUse] 91 | [AttributeUsage(AttributeTargets.Method, AllowMultiple=true, Inherited=true)] 92 | public class RpcAttribute : Attribute 93 | { 94 | /// 95 | /// id of the rpc 96 | /// 97 | public byte rpcId = 0; 98 | 99 | /// 100 | /// Server only. what the default value for continue forwarding is set to 101 | /// 102 | public bool defaultContinueForwarding = true; 103 | 104 | /// 105 | /// mark the specified method with this rpc id 106 | /// 107 | /// 108 | public RpcAttribute(byte rpcId) 109 | { 110 | this.rpcId = rpcId; 111 | } 112 | 113 | /// 114 | /// Server only 115 | /// 116 | /// 117 | /// what the default value for continue forwarding is set to 118 | public RpcAttribute(byte rpcId, bool defaultContinueForwarding) 119 | { 120 | this.rpcId = rpcId; 121 | this.defaultContinueForwarding = defaultContinueForwarding; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /PNetC/ClientConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetC 7 | { 8 | /// 9 | /// Configuration for the client 10 | /// 11 | public class ClientConfiguration 12 | { 13 | /// 14 | /// the ip or domain name of the server 15 | /// 16 | public readonly string Ip; 17 | 18 | /// 19 | /// the port to connect to on the server 20 | /// 21 | public readonly int Port; 22 | 23 | /// 24 | /// this should be unique per game, and should be the same on the client and server 25 | /// 26 | public readonly string AppIdentifier; 27 | 28 | /// 29 | /// the port to bind the game to. 0 will cause it to bind to the first available port 30 | /// 31 | public readonly int BindPort; 32 | 33 | /// 34 | /// if true, delete network instantiates on changing rooms (after OnRoomChange is run) 35 | /// 36 | public bool DeleteNetworkInstantiatesOnRoomChange = true; 37 | /// 38 | /// if true, delete network instantiates on disconnecting from a server 39 | /// 40 | public bool DeleteNetworkInstantiatesOnDisconnect = true; 41 | 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | public ClientConfiguration(string ip, int port, int bindPort = 0, string appIdentifier = "PNet") 50 | { 51 | BindPort = bindPort; 52 | AppIdentifier = appIdentifier; 53 | Ip = ip; 54 | Port = port; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PNetC/IEngineHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace PNetC 3 | { 4 | /// 5 | /// network hooking into the Update method of unity. Don't put in the scene. 6 | /// 7 | public interface IEngineHook 8 | { 9 | /// 10 | /// This should be run every frame by whatever engine you're using PNetC in. 11 | /// 12 | event Action EngineUpdate; 13 | /// 14 | /// Create an object, and return it. Said object should be a container to hold the NetworkView 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | void Instantiate(string path, NetworkView newView, Vector3 location, Quaternion rotation); 21 | 22 | /// 23 | /// Add a NetworkView to the same container as an already existing NetworkView 24 | /// 25 | /// 26 | /// 27 | /// 28 | void AddNetworkView(NetworkView view, NetworkView newView, string customFunction); 29 | } 30 | } -------------------------------------------------------------------------------- /PNetC/Log/ILogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | // ReSharper disable CheckNamespace 7 | namespace PNetC 8 | // ReSharper restore CheckNamespace 9 | { 10 | /// 11 | /// Interface for logging information 12 | /// 13 | public interface ILogger 14 | { 15 | /// 16 | /// message only done during full debugging 17 | /// 18 | /// 19 | /// 20 | /// 21 | void Full(Net sender, string info, params object[] args); 22 | 23 | /// 24 | /// informational message 25 | /// 26 | /// 27 | /// 28 | /// 29 | void Info(Net sender, string info, params object[] args); 30 | 31 | /// 32 | /// warning message 33 | /// 34 | /// 35 | /// 36 | /// 37 | void Warning(Net sender, string info, params object[] args); 38 | 39 | /// 40 | /// error message 41 | /// 42 | /// 43 | /// 44 | /// 45 | void Error(Net sender, string info, params object[] args); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /PNetC/Log/Log.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetC 7 | { 8 | /// 9 | /// Debug 10 | /// 11 | public static class Debug 12 | { 13 | /// 14 | /// Reference to the actual log receiver 15 | /// 16 | public static ILogger Logger = new NullLogger(); 17 | 18 | /// 19 | /// Only done when you want full logging 20 | /// 21 | /// 22 | /// 23 | /// 24 | [JetBrains.Annotations.StringFormatMethod("value")] 25 | public static void Log(Net sender, string value, params object[] args) 26 | { 27 | Logger.Full(sender, value, args); 28 | } 29 | 30 | /// 31 | /// Info message. Semi important. 32 | /// 33 | /// 34 | /// 35 | /// 36 | [JetBrains.Annotations.StringFormatMethod("value")] 37 | public static void LogInfo(Net sender, string value, params object[] args) 38 | { 39 | Logger.Info(sender, value, args); 40 | } 41 | 42 | /// 43 | /// Error message 44 | /// 45 | /// 46 | /// 47 | /// 48 | [JetBrains.Annotations.StringFormatMethod("value")] 49 | public static void LogError(Net sender, string value, params object[] args) 50 | { 51 | Logger.Error(sender, value, args); 52 | } 53 | 54 | /// 55 | /// Warning message 56 | /// 57 | /// 58 | /// 59 | /// 60 | [JetBrains.Annotations.StringFormatMethod("value")] 61 | public static void LogWarning(Net sender, string value, params object[] args) 62 | { 63 | Logger.Warning(sender, value, args); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PNetC/Log/NetworkLogLevel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetC 7 | { 8 | /// 9 | /// Not used yet 10 | /// 11 | public enum NetworkLogLevel 12 | { 13 | /// 14 | /// no logging except errors 15 | /// 16 | Off = 0, 17 | /// 18 | /// only logging of important information 19 | /// 20 | Informational = 1, 21 | /// 22 | /// all messages 23 | /// 24 | Full = 3, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PNetC/Log/NullLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetC 7 | { 8 | /// 9 | /// Logger, but logs to nowhere 10 | /// 11 | public sealed class NullLogger : ILogger 12 | { 13 | /// 14 | /// message only done during full debugging 15 | /// 16 | /// 17 | /// 18 | /// 19 | public void Full(Net sender, string info, params object[] args) 20 | { 21 | 22 | } 23 | 24 | /// 25 | /// informational message 26 | /// 27 | /// 28 | /// 29 | /// 30 | public void Info(Net sender, string info, params object[] args) 31 | { 32 | 33 | } 34 | 35 | /// 36 | /// warning message 37 | /// 38 | /// 39 | /// 40 | /// 41 | public void Warning(Net sender, string info, params object[] args) 42 | { 43 | 44 | } 45 | 46 | /// 47 | /// error message 48 | /// 49 | /// 50 | /// 51 | /// 52 | public void Error(Net sender, string info, params object[] args) 53 | { 54 | 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PNetC/NetworkStateSynchronization.cs: -------------------------------------------------------------------------------- 1 | namespace PNetC 2 | { 3 | /// 4 | /// way to serialize the changes to the network view 5 | /// 6 | public enum NetworkStateSynchronization 7 | { 8 | /// 9 | /// do not run serialization 10 | /// 11 | Off = 0, 12 | /// 13 | /// only if there are changes in the stream, reliably 14 | /// 15 | ReliableDeltaCompressed = 1, 16 | /// 17 | /// always, but unreliably 18 | /// 19 | Unreliable = 2, 20 | } 21 | } -------------------------------------------------------------------------------- /PNetC/NetworkViewId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lidgren.Network; 3 | using PNet; 4 | 5 | namespace PNetC 6 | { 7 | /// 8 | /// Identifier for a NetworkView 9 | /// 10 | public struct NetworkViewId : INetSerializable 11 | { 12 | /// 13 | /// Whether or not I own the object 14 | /// 15 | public bool IsMine { get; internal set; } 16 | 17 | /// 18 | /// network id 19 | /// 20 | public ushort guid { get; internal set; } 21 | 22 | /// 23 | /// Network ID of nothing 24 | /// 25 | public static NetworkViewId Zero 26 | { 27 | get 28 | { 29 | return new NetworkViewId() { guid = 0, IsMine = false }; 30 | } 31 | } 32 | 33 | /// 34 | /// write to the message 35 | /// 36 | /// message to write to 37 | public void OnSerialize(NetOutgoingMessage message) 38 | { 39 | message.Write(guid); 40 | } 41 | 42 | /// 43 | /// Be careful! It is not recommended to be directly serializing networkviewids. 44 | /// 45 | /// message to read from 46 | public void OnDeserialize(NetIncomingMessage message) 47 | { 48 | guid = message.ReadUInt16(); 49 | } 50 | 51 | /// 52 | /// Deserialize a networkviewid from the networkmessage 53 | /// 54 | /// 55 | /// 56 | internal static NetworkViewId Deserialize(NetIncomingMessage message) 57 | { 58 | var id = new NetworkViewId(); 59 | id.OnDeserialize(message); 60 | return id; 61 | } 62 | 63 | /// 64 | /// size when serializing to stream 65 | /// 66 | public int AllocSize { get { return 2; } } 67 | 68 | /// 69 | /// Returns the hash code for this instance. 70 | /// 71 | /// 72 | /// A 32-bit signed integer that is the hash code for this instance. 73 | /// 74 | /// 2 75 | public override int GetHashCode() 76 | { 77 | return guid; 78 | } 79 | 80 | /// 81 | /// Whether or not the this viewid refers to the same id 82 | /// 83 | /// 84 | /// 85 | public bool Equals(NetworkViewId other) 86 | { 87 | return other.guid == guid; 88 | } 89 | 90 | /// 91 | /// Indicates whether this instance and a specified object are equal. 92 | /// 93 | /// 94 | /// true if and this instance are the same type and represent the same value; otherwise, false. 95 | /// 96 | /// Another object to compare to. 2 97 | public override bool Equals(object obj) 98 | { 99 | if (!(obj is NetworkViewId)) 100 | return false; 101 | return Equals((NetworkViewId) obj); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /PNetC/NetworkViewManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Lidgren.Network; 3 | using PNet; 4 | 5 | namespace PNetC 6 | { 7 | /// 8 | /// A container, object pool, and general manager for the network views associated with all Networked objects 9 | /// 10 | public sealed class NetworkViewManager 11 | { 12 | private const int ViewPoolSize = 150; 13 | readonly IntDictionary _allViews = new IntDictionary(); 14 | private readonly Stack _netViewPool = new Stack(150); 15 | internal readonly Net Net; 16 | 17 | /// 18 | /// Container for all the NetworkViews associated with the PNetC.Net object 19 | /// 20 | internal NetworkViewManager(Net net) 21 | { 22 | Net = net; 23 | } 24 | 25 | /// 26 | /// find a network view based on the given NetworkViewId 27 | /// 28 | /// 29 | /// 30 | public NetworkView Find(NetworkViewId viewId) 31 | { 32 | return _allViews[viewId.guid]; 33 | } 34 | 35 | /// 36 | /// find a networkview based on a networkviewid that was serialized into an rpc 37 | /// 38 | /// uses deserialize, so the read location does advance 39 | /// 40 | /// 41 | public bool Find(ref NetIncomingMessage message, out NetworkView view) 42 | { 43 | var id = new NetworkViewId(); 44 | id.OnDeserialize(message); 45 | 46 | return Find(id, out view); 47 | } 48 | 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | /// 55 | public bool Find(NetworkViewId id, out NetworkView view) 56 | { 57 | return _allViews.TryGetValue(id.guid, out view); 58 | } 59 | 60 | internal void RemoveView(NetworkView view) 61 | { 62 | if (view.Manager == this) 63 | { 64 | _allViews.Remove(view.ViewID.guid); 65 | RecycleNetworkView(view); 66 | } 67 | } 68 | 69 | internal void DestroyAllViews() 70 | { 71 | var cap = _allViews.Capacity; 72 | for (int i = 0; i < cap; i++) 73 | { 74 | NetworkView view; 75 | if (_allViews.TryGetValue(i, out view)) 76 | { 77 | if (view != null) 78 | view.DoOnRemove(0); 79 | } 80 | } 81 | } 82 | 83 | private void RegisterView(NetworkView view, NetworkViewId viewId) 84 | { 85 | _allViews.Add(viewId.guid, view); 86 | } 87 | 88 | internal NetworkView Create(NetworkViewId viewId, ushort ownerId) 89 | { 90 | viewId.IsMine = Net.PlayerId == ownerId; 91 | 92 | var newView = GetNetworkView(); 93 | newView.ViewID = viewId; 94 | newView.OwnerId = ownerId; 95 | RegisterView(newView, viewId); 96 | return newView; 97 | } 98 | 99 | //pool get for networkviews 100 | NetworkView GetNetworkView() 101 | { 102 | if (_netViewPool.Count == 0) 103 | return new NetworkView(this); 104 | return _netViewPool.Pop(); 105 | } 106 | //pool recycle for networkviews 107 | void RecycleNetworkView(NetworkView view) 108 | { 109 | if (!view.EventsAreCleared()) 110 | Debug.LogError(Net, "Networkview {0} didn't appear to cleanup properly", view.ViewID.guid); 111 | 112 | if (_netViewPool.Count < ViewPoolSize) 113 | _netViewPool.Push(view); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /PNetC/PNetC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {314D16A0-FF83-4D3D-919E-8255D8BC9728} 9 | Library 10 | Properties 11 | PNetC 12 | PNetC 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\PNetC.XML 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\PNetC.XML 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 60 | Lidgren.Network 61 | 62 | 63 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 64 | PNet 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /PNetC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNetC")] 9 | [assembly: AssemblyDescription("PNetwork Client")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PNetC")] 13 | [assembly: AssemblyCopyright("Copyright © Justin Bruening")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e7278cb1-b2b2-40e9-84dd-a4098374315a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTestsPNetC")] -------------------------------------------------------------------------------- /PNetC/RPCMode.cs: -------------------------------------------------------------------------------- 1 | namespace PNetC 2 | { 3 | /// 4 | /// how to send the rpc 5 | /// 6 | public enum RPCMode 7 | { 8 | /// 9 | /// to the server 10 | /// 11 | Server = 0, 12 | /// 13 | /// to everyone but me 14 | /// 15 | Others = 1, 16 | /// 17 | /// to everyone 18 | /// 19 | All = 2, 20 | /// 21 | /// to everyone but me, buffered to new players after the initial call 22 | /// 23 | OthersBuffered = 5, 24 | /// 25 | /// to everyone, buffered to new players after the initial call 26 | /// 27 | AllBuffered = 6, 28 | } 29 | } -------------------------------------------------------------------------------- /PNetC/SerializedStructs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Lidgren.Network; 6 | using PNet; 7 | using System.Globalization; 8 | 9 | namespace PNetC 10 | { 11 | /// 12 | /// rotation struct 13 | /// 14 | public struct Quaternion : INetSerializable 15 | { 16 | /// 17 | /// delta of the 4d rotation 18 | /// 19 | public float X, Y, Z, W; 20 | 21 | /// 22 | /// write to the message 23 | /// 24 | /// message to write to 25 | public void OnSerialize(NetOutgoingMessage message) 26 | { 27 | message.Write(X); 28 | message.Write(Y); 29 | message.Write(Z); 30 | message.Write(W); 31 | } 32 | 33 | /// 34 | /// read the message 35 | /// 36 | /// message to read from 37 | public void OnDeserialize(NetIncomingMessage message) 38 | { 39 | X = message.ReadFloat(); 40 | Y = message.ReadFloat(); 41 | Z = message.ReadFloat(); 42 | W = message.ReadFloat(); 43 | } 44 | 45 | /// 46 | /// size in bytes 47 | /// 48 | public int AllocSize 49 | { 50 | get { return 16; } 51 | } 52 | 53 | /// 54 | /// invariant culture 55 | /// 56 | /// 57 | public override string ToString() 58 | { 59 | return string.Format("{0}, {1}, {2}, {3}", 60 | X.ToString(CultureInfo.InvariantCulture), 61 | Y.ToString(CultureInfo.InvariantCulture), 62 | Z.ToString(CultureInfo.InvariantCulture), 63 | W.ToString(CultureInfo.InvariantCulture)); 64 | } 65 | } 66 | 67 | /// 68 | /// position/direction struct 69 | /// 70 | public struct Vector3 : INetSerializable 71 | { 72 | /// 73 | /// delta of the three axis 74 | /// 75 | public float X, Y, Z; 76 | 77 | /// 78 | /// write to the message 79 | /// 80 | /// message to write to 81 | public void OnSerialize(NetOutgoingMessage message) 82 | { 83 | message.Write(X); 84 | message.Write(Y); 85 | message.Write(Z); 86 | } 87 | 88 | /// 89 | /// read the message 90 | /// 91 | /// message to read from 92 | public void OnDeserialize(NetIncomingMessage message) 93 | { 94 | X = message.ReadFloat(); 95 | Y = message.ReadFloat(); 96 | Z = message.ReadFloat(); 97 | } 98 | 99 | /// 100 | /// size in bytes 101 | /// 102 | public int AllocSize 103 | { 104 | get { return 12; } 105 | } 106 | 107 | /// 108 | /// invariant culture 109 | /// 110 | /// 111 | public override string ToString() 112 | { 113 | return string.Format("{0}, {1}, {2}", 114 | X.ToString(CultureInfo.InvariantCulture), 115 | Y.ToString(CultureInfo.InvariantCulture), 116 | Z.ToString(CultureInfo.InvariantCulture)); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /PNetS/GameMachine/GameObject/Component.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | using System.Threading; 7 | using System.Yaml.Serialization; 8 | 9 | namespace PNetS 10 | { 11 | /// 12 | /// Base class for components that can attach to GameObjects 13 | /// 14 | public abstract class Component 15 | { 16 | /// 17 | /// The gameobject this is attached to. cached result. 18 | /// 19 | [YamlSerialize(YamlSerializeMethod.Never)] 20 | public GameObject gameObject { get; internal set; } 21 | 22 | /// 23 | /// Get the first component on the gameObject of type T 24 | /// 25 | /// 26 | /// 27 | public T GetComponent() 28 | where T : Component 29 | { 30 | return gameObject.GetComponent(); 31 | } 32 | 33 | /// 34 | /// Get all components of the type T 35 | /// 36 | /// 37 | /// 38 | public List GetComponents() 39 | where T : Component 40 | { 41 | return gameObject.GetComponents(); 42 | } 43 | 44 | #region coroutine 45 | 46 | /// 47 | /// Start a coroutine 48 | /// Not thread safe. 49 | /// 50 | /// 51 | /// 52 | public Coroutine StartCoroutine(IEnumerator routine) 53 | { 54 | routine.MoveNext(); 55 | _shouldRunNextFrame.Add(routine); 56 | return new Coroutine(routine); 57 | } 58 | 59 | List _unblockedCoroutines = new List(); 60 | List _shouldRunNextFrame = new List(); 61 | 62 | internal void RunCoroutines() 63 | { 64 | GameMachine.State.Coroutine.Run(ref _unblockedCoroutines, ref _shouldRunNextFrame); 65 | } 66 | 67 | #endregion 68 | 69 | internal void Dispose() 70 | { 71 | try 72 | {Disposing();} 73 | catch(Exception e) 74 | { 75 | Debug.LogError("[Disposing {0}] {1}", gameObject.Name, e); 76 | } 77 | //help prevent bad use of the library from keeping the other components around. 78 | gameObject = null; 79 | } 80 | /// 81 | /// The object is being deleted 82 | /// 83 | protected virtual void Disposing() { } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /PNetS/GameMachine/GameObject/Prefab.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// An object containing information about spawning a GameObject 10 | /// 11 | public class Prefab 12 | { 13 | /// 14 | /// Path to the resource description 15 | /// 16 | public string ResourcePath { get; private set; } 17 | 18 | internal List Components = new List(); 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /PNetS/GameMachine/State/Coroutine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace PNetS.GameMachine.State 6 | { 7 | static class Coroutine 8 | { 9 | /// 10 | /// standardized behaviour to run through coroutines 11 | /// 12 | /// 13 | /// 14 | public static void Run(ref List unblockedCoroutines, ref List shouldRunNextFrame) 15 | { 16 | for (int i = 0; i < unblockedCoroutines.Count; i++ ) 17 | { 18 | var coroutine = unblockedCoroutines[i]; 19 | 20 | var yRoute = coroutine.Current as YieldInstruction; 21 | if (yRoute != null) 22 | { 23 | //yielding on a yieldinstruction 24 | //running IsDone is equivilent to MoveNext for yieldinstructions 25 | if (!yRoute.IsDone()) 26 | { 27 | shouldRunNextFrame.Add(coroutine); 28 | continue; 29 | } 30 | } 31 | 32 | //everything else... 33 | if (!coroutine.MoveNext()) 34 | // This coroutine has finished 35 | continue; 36 | 37 | yRoute = coroutine.Current as YieldInstruction; 38 | if (yRoute is PNetS.Coroutine) 39 | { 40 | //remove the routine we just made from the top of the stack... 41 | var croute = yRoute as PNetS.Coroutine; 42 | lock (shouldRunNextFrame) 43 | { 44 | var last = shouldRunNextFrame[shouldRunNextFrame.Count - 1]; 45 | if (!ReferenceEquals(croute.Routine, last)) 46 | { 47 | Debug.LogError( 48 | "Something went wrong when yielding on a coroutine. Are you using coroutines in other threads?"); 49 | continue; 50 | } 51 | shouldRunNextFrame.RemoveAt(shouldRunNextFrame.Count - 1); 52 | 53 | //add the outer so that it can call the inner. 54 | shouldRunNextFrame.Add(coroutine); 55 | } 56 | continue; 57 | } 58 | 59 | if (yRoute == null) 60 | { 61 | // This coroutine yielded null, or some other value we don't understand; run it next frame. 62 | shouldRunNextFrame.Add(coroutine); 63 | continue; 64 | } 65 | 66 | if (!yRoute.IsDone()) 67 | { 68 | shouldRunNextFrame.Add(coroutine); 69 | } 70 | } 71 | 72 | unblockedCoroutines.Clear(); 73 | unblockedCoroutines.AddRange(shouldRunNextFrame); 74 | shouldRunNextFrame.Clear(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /PNetS/GameMachine/State/GameState.Coroutine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace PNetS 5 | { 6 | static partial class GameState 7 | { 8 | /// 9 | /// Start a coroutine 10 | /// Not thread safe. 11 | /// 12 | /// 13 | /// 14 | public static Coroutine StartCoroutine(IEnumerator routine) 15 | { 16 | routine.MoveNext(); 17 | _shouldRunNextFrame.Add(routine); 18 | return new Coroutine(routine); 19 | } 20 | 21 | static List _unblockedCoroutines = new List(); 22 | static List _shouldRunNextFrame = new List(); 23 | 24 | static void RunCoroutines() 25 | { 26 | GameMachine.State.Coroutine.Run(ref _unblockedCoroutines, ref _shouldRunNextFrame); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /PNetS/GameMachine/State/Time.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Game time. Duplication class of unity's Time class 10 | /// 11 | public static class Time 12 | { 13 | /// 14 | /// Time since the game started, affected by the timescale 15 | /// 16 | public static double time 17 | { 18 | get 19 | { 20 | return GameState.TimeSinceStartup - GameState.TimeSinceStartupScaleOffset; 21 | } 22 | } 23 | /// 24 | /// time since the game started, unaffected by timescale 25 | /// 26 | public static double realtimeSinceStartup { get { return GameState.TimeSinceStartup; } } 27 | static double _scale = 1d; 28 | /// 29 | /// Time scaling. Setting to anything other than 1 will affect time and deltaTime. 30 | /// 31 | public static double Scale 32 | { 33 | get { return _scale; } 34 | set 35 | { 36 | _scale = Math.Min(Math.Max(0, value), double.MaxValue); 37 | } 38 | } 39 | /// 40 | /// Time since last 'frame', scaled via the Scale 41 | /// 42 | public static float deltaTime { get { return (float)((GameState.TimeSinceStartup - GameState.PreviousFrameTime) * _scale); } } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /PNetS/GameMachine/Yield/Coroutine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace PNetS 8 | { 9 | /// 10 | /// Used for yielding yields via StartCoroutine. should support infinite depth. 11 | /// 12 | public sealed class Coroutine : YieldInstruction 13 | { 14 | internal IEnumerator Routine; 15 | private bool innerFinished = false; 16 | 17 | internal Coroutine(IEnumerator routine) 18 | { 19 | Routine = routine; 20 | } 21 | 22 | /// 23 | /// method that says if the YieldInstruction is done 24 | /// 25 | public override bool IsDone() 26 | { 27 | if (innerFinished) return true; 28 | 29 | if (Routine.Current != null) 30 | { 31 | if (Routine.Current is YieldInstruction) 32 | { 33 | if ((Routine.Current as YieldInstruction).IsDone()) 34 | { 35 | innerFinished = true; 36 | return false; 37 | } 38 | } 39 | } 40 | 41 | //if the routine finishes, then we need to say we're finished 42 | innerFinished = !Routine.MoveNext(); 43 | return false; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /PNetS/GameMachine/Yield/WaitForFrames.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace PNetS 8 | { 9 | /// 10 | /// Yield for the specified time 11 | /// 12 | public class WaitForFrames : YieldInstruction 13 | { 14 | private int _waitFrames; 15 | private int _frameCounter; 16 | 17 | /// 18 | /// wait for the specified number of seconds 19 | /// 20 | public WaitForFrames(int waitFrames) 21 | { 22 | _waitFrames = waitFrames; 23 | } 24 | 25 | /// 26 | /// when the yieldinstruction finishes 27 | /// 28 | public override bool IsDone() 29 | { 30 | _frameCounter++; 31 | if (_frameCounter < _waitFrames) 32 | { 33 | return false; 34 | } 35 | return true; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PNetS/GameMachine/Yield/WaitForSeconds.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace PNetS 8 | { 9 | /// 10 | /// Yield for the specified time 11 | /// 12 | public class WaitForSeconds : YieldInstruction 13 | { 14 | float waitTime; 15 | double startTime; 16 | 17 | /// 18 | /// wait for the specified number of seconds 19 | /// 20 | /// 21 | public WaitForSeconds(float seconds) 22 | { 23 | this.waitTime = seconds; 24 | this.startTime = Time.time; 25 | } 26 | 27 | /// 28 | /// when the yieldinstruction finishes 29 | /// 30 | public override bool IsDone() 31 | { 32 | if (Time.time - startTime > waitTime) 33 | return true; 34 | return false; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /PNetS/GameMachine/Yield/YieldInstruction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Waiting threads, basically. 10 | /// 11 | public abstract class YieldInstruction 12 | { 13 | /// 14 | /// If the coroutine has finished 15 | /// 16 | public abstract bool IsDone(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PNetS/Log/DefaultConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PNet; 3 | 4 | namespace PNetS 5 | { 6 | /// 7 | /// Console recipient for the log 8 | /// 9 | public sealed class DefaultConsoleLogger : ILogger 10 | { 11 | /// 12 | /// Info 13 | /// 14 | /// 15 | /// 16 | public void Info(string info, params object[] args) 17 | { 18 | Console.WriteLine(info, args); 19 | } 20 | 21 | /// 22 | /// Warning 23 | /// 24 | /// 25 | /// 26 | public void Warning(string info, params object[] args) 27 | { 28 | Console.WriteLine(info, args); 29 | } 30 | 31 | /// 32 | /// error 33 | /// 34 | /// 35 | /// 36 | public void Error(string info, params object[] args) 37 | { 38 | Console.WriteLine(info, args); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /PNetS/Log/ILogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Interface for logging information 10 | /// 11 | public interface ILogger 12 | { 13 | /// 14 | /// informational message 15 | /// 16 | /// 17 | /// 18 | void Info(string info, params object[] args); 19 | /// 20 | /// warning message 21 | /// 22 | /// 23 | /// 24 | void Warning(string info, params object[] args); 25 | /// 26 | /// error message 27 | /// 28 | /// 29 | /// 30 | void Error(string info, params object[] args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /PNetS/Log/Log.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using JetBrains.Annotations; 6 | 7 | namespace PNetS 8 | { 9 | /// 10 | /// Debug 11 | /// 12 | public static class Debug 13 | { 14 | /// 15 | /// Reference to the actual log receiver 16 | /// 17 | public static ILogger logger = new NullLogger(); 18 | 19 | /// 20 | /// Info message 21 | /// 22 | /// 23 | /// 24 | [StringFormatMethod("value")] 25 | public static void Log(string value, params object[] args) 26 | { 27 | logger.Info(value, args); 28 | } 29 | /// 30 | /// Error message 31 | /// 32 | /// 33 | /// 34 | [StringFormatMethod("value")] 35 | public static void LogError(string value, params object[] args) 36 | { 37 | logger.Error(value, args); 38 | } 39 | /// 40 | /// Warning message 41 | /// 42 | /// 43 | /// 44 | [StringFormatMethod("value")] 45 | public static void LogWarning(string value, params object[] args) 46 | { 47 | logger.Warning(value, args); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /PNetS/Log/NetworkLogLevel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Not used yet 10 | /// 11 | public enum NetworkLogLevel 12 | { 13 | /// 14 | /// no logging except errors 15 | /// 16 | Off = 0, 17 | /// 18 | /// only logging of important information 19 | /// 20 | Informational = 1, 21 | /// 22 | /// all messages 23 | /// 24 | Full = 3, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PNetS/Log/NullLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Logger, but logs to nowhere 10 | /// 11 | public sealed class NullLogger : ILogger 12 | { 13 | /// 14 | /// informational message 15 | /// 16 | /// 17 | /// 18 | public void Info(string info, params object[] args) 19 | { 20 | 21 | } 22 | 23 | /// 24 | /// warning message 25 | /// 26 | /// 27 | /// 28 | public void Warning(string info, params object[] args) 29 | { 30 | 31 | } 32 | 33 | /// 34 | /// error message 35 | /// 36 | /// 37 | /// 38 | public void Error(string info, params object[] args) 39 | { 40 | 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /PNetS/NetworkView/NetMessageInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// contains information about the message 10 | /// 11 | public class NetMessageInfo 12 | { 13 | /// 14 | /// Mode the rpc was sent from by the client 15 | /// 16 | public readonly RPCMode mode; 17 | /// 18 | /// change this to false if the message should not continue forwarding to the rest of the players (you can tell who it'll forward to by the rpcmode) 19 | /// 20 | public bool continueForwarding = true; 21 | /// 22 | /// Player who sent the message 23 | /// 24 | public readonly Player player; 25 | 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | internal NetMessageInfo(RPCMode mode, Player player) 32 | { 33 | this.mode = mode; 34 | this.player = player; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /PNetS/NetworkView/NetworkView.Static.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Lidgren.Network; 6 | using PNet; 7 | using System.Collections; 8 | using PNetS; 9 | using System.Threading; 10 | 11 | namespace PNetS 12 | { 13 | /// 14 | /// Class used for networking 15 | /// 16 | public partial class NetworkView 17 | { 18 | 19 | static readonly IntDictionary Views = new IntDictionary(); 20 | 21 | /// 22 | /// Find the networkview based on a viewID 23 | /// 24 | /// 25 | /// 26 | public static NetworkView Find(NetworkViewId viewID) 27 | { 28 | NetworkView view; 29 | Find(viewID.guid, out view); 30 | return view; 31 | } 32 | /// 33 | /// Find a network view from an ID 34 | /// 35 | /// 36 | /// 37 | /// 38 | public static bool Find(ushort id, out NetworkView view) 39 | { 40 | lock (ViewsLock) {view = Views[id];} 41 | return view != null; 42 | } 43 | 44 | /// 45 | /// find a networkview via a networkviewid serialize to the message 46 | /// 47 | /// read location is advanced 48 | /// 49 | /// 50 | public static bool Find(ref NetIncomingMessage message, out NetworkView view) 51 | { 52 | var id = NetworkViewId.Deserialize(message); 53 | 54 | return Find(id, out view); 55 | } 56 | 57 | private readonly static object ViewsLock = new object(); 58 | internal static void RemoveView(NetworkView view) 59 | { 60 | lock (ViewsLock) 61 | { 62 | var findView = Views[view.viewID.guid]; 63 | if (findView != null) 64 | { 65 | if (findView == view) 66 | { 67 | Views.Remove(view.viewID.guid); 68 | } 69 | } 70 | } 71 | } 72 | 73 | internal static void RegisterView(NetworkView view, ushort viewId) 74 | { 75 | lock(ViewsLock) {Views.Add(viewId, view);} 76 | } 77 | 78 | /// 79 | /// register a network view you've just added as a component. Assignes the network id. 80 | /// 81 | /// 82 | public static void RegisterNewView(ref NetworkView view) 83 | { 84 | int addedId; 85 | lock (ViewsLock) 86 | { 87 | addedId = Views.Add(view); 88 | } 89 | view.viewID.guid = (ushort) addedId; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /PNetS/NetworkView/NetworkViewId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Lidgren.Network; 6 | using PNet; 7 | 8 | namespace PNetS 9 | { 10 | /// 11 | /// The identifier for a network view 12 | /// 13 | public class NetworkViewId : INetSerializable 14 | { 15 | /// 16 | /// whether or not the server is the owner of the view 17 | /// 18 | public bool IsMine { get; internal set; } 19 | /// 20 | /// network identifier 21 | /// 22 | public ushort guid { get; internal set; } 23 | 24 | /// 25 | /// id of 0, ie, no id 26 | /// 27 | public static NetworkViewId Zero 28 | { 29 | get 30 | { 31 | return new NetworkViewId() { guid = 0, IsMine = false }; 32 | } 33 | } 34 | 35 | /// 36 | /// write to the message 37 | /// 38 | /// message to write to 39 | public void OnSerialize(NetOutgoingMessage message) 40 | { 41 | message.Write(guid); 42 | } 43 | 44 | /// 45 | /// doesn't do anything for integrity 46 | /// 47 | /// 48 | [Obsolete("Use NetworkView.Find(NetIncomingMessage, out NetworkView)")] 49 | public void OnDeserialize(NetIncomingMessage message){} 50 | 51 | internal static ushort Deserialize(NetIncomingMessage message) 52 | { 53 | return message.ReadUInt16(); 54 | } 55 | 56 | /// 57 | /// size to allocate for bytes in the message 58 | /// 59 | public int AllocSize { get { return 2; } } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /PNetS/NetworkView/NetworkedSceneObject.cs: -------------------------------------------------------------------------------- 1 | using SlimMath; 2 | using System.Text.RegularExpressions; 3 | using PNetS; 4 | 5 | /// 6 | /// Objects that exist in a scene with pre-synchronized network id's 7 | /// 8 | public class NetworkedSceneObject : Component 9 | { 10 | /// 11 | /// The scene/room Network ID of this item. Should only be one per room 12 | /// 13 | public ushort NetworkID = 0; 14 | /// 15 | /// data for the object 16 | /// 17 | public string ObjectData; 18 | /// 19 | /// type of the object 20 | /// 21 | public string ObjectType; 22 | 23 | /// 24 | /// position of the object 25 | /// 26 | public Vector3 position; 27 | /// 28 | /// rotation of the object 29 | /// 30 | public Quaternion rotation; 31 | 32 | static System.Globalization.CultureInfo noCulture; 33 | 34 | /// 35 | /// Deserialize a networked scene object from a string 36 | /// 37 | /// 38 | /// 39 | public static NetworkedSceneObject Deserialize(string data) 40 | { 41 | NetworkedSceneObject newObject = new NetworkedSceneObject(); 42 | noCulture = System.Globalization.CultureInfo.InvariantCulture; 43 | 44 | 45 | 46 | 47 | var line = Regex.Match(data, "id: ?([0-9]+?) ?;"); 48 | if (line.Success) 49 | { 50 | ushort.TryParse(line.Groups[1].Value, out newObject.NetworkID); 51 | } 52 | 53 | line = Regex.Match(data, "type:([\\s\\S]+?);"); 54 | if (line.Success) 55 | { 56 | newObject.ObjectType = line.Groups[1].Value; 57 | } 58 | 59 | line = Regex.Match(data, "data:([\\s\\S]+?);"); 60 | if (line.Success) 61 | { 62 | newObject.ObjectData = line.Groups[1].Value; 63 | } 64 | 65 | line = Regex.Match(data, @"pos: ?\(?(-?\d+(?:\.\d*)?), ?(-?\d+(?:\.\d*)?), ?(-?\d+(?:\.\d*)?)\)? ?;"); 66 | if (line.Success) 67 | { 68 | newObject.position = new Vector3(float.Parse(line.Groups[1].Value, noCulture), float.Parse(line.Groups[2].Value, noCulture), float.Parse(line.Groups[3].Value, noCulture)); 69 | } 70 | 71 | line = Regex.Match(data, @"rot: ?\(?(-?\d+(?:\.\d*)?), ?(-?\d+(?:\.\d*)?), ?(-?\d+(?:\.\d*)?), ?(-?\d+(?:\.\d*)?)\)? ?;"); 72 | if (line != null) 73 | { 74 | newObject.rotation = new Quaternion( 75 | float.Parse(line.Groups[1].Value, noCulture), 76 | float.Parse(line.Groups[2].Value, noCulture), 77 | float.Parse(line.Groups[3].Value, noCulture), 78 | float.Parse(line.Groups[4].Value, noCulture) 79 | ); 80 | } 81 | 82 | return newObject; 83 | } 84 | } -------------------------------------------------------------------------------- /PNetS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNetS")] 9 | [assembly: AssemblyDescription("PNetwork Server")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PNetS")] 13 | [assembly: AssemblyCopyright("Copyright © Justin Bruening")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("42302cdf-8c3c-4175-b4f8-96a73cbd3a09")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: InternalsVisibleTo("PNetSUnitTests")] 38 | [assembly: InternalsVisibleTo("ClientServerIntegrationTests")] 39 | -------------------------------------------------------------------------------- /PNetS/Serializers/SlimMathSerializer.cs: -------------------------------------------------------------------------------- 1 | using SlimMath; 2 | using PNet; 3 | 4 | namespace PNetS 5 | { 6 | /// 7 | /// Serializer for vectors 8 | /// 9 | public class Vector3Serializer : ASerializable 10 | { 11 | /// 12 | /// create a new serializer from the specified vector3 13 | /// 14 | /// 15 | public Vector3Serializer(Vector3 vector3) 16 | { 17 | Value = vector3; 18 | } 19 | 20 | /// 21 | /// New serializer, value is Zero 22 | /// 23 | public Vector3Serializer() 24 | { 25 | Value = Vector3.Zero; 26 | } 27 | /// 28 | /// serialize to the stream 29 | /// 30 | /// 31 | public override void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 32 | { 33 | message.Write(Value.X); 34 | message.Write(Value.Y); 35 | message.Write(Value.Z); 36 | } 37 | 38 | /// 39 | /// deserialize from the stream 40 | /// 41 | /// 42 | public override void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 43 | { 44 | Value.X = message.ReadFloat(); 45 | Value.Y = message.ReadFloat(); 46 | Value.Z = message.ReadFloat(); 47 | } 48 | 49 | /// 50 | /// size of vector3 in bytes 51 | /// 52 | public override int AllocSize 53 | { 54 | get { return 12; } 55 | } 56 | } 57 | 58 | /// 59 | /// Serializer for quaternions 60 | /// 61 | public class QuaternionSerializer : ASerializable 62 | { 63 | /// 64 | /// create a new serializer from the specified quaternion 65 | /// 66 | /// 67 | public QuaternionSerializer(Quaternion quaternion) 68 | { 69 | Value = quaternion; 70 | } 71 | 72 | /// 73 | /// new serializer, quaternion is identity 74 | /// 75 | public QuaternionSerializer() 76 | { 77 | Value = Quaternion.Identity; 78 | } 79 | 80 | /// 81 | /// serialize to the stream 82 | /// 83 | /// 84 | public override void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 85 | { 86 | message.Write(Value.X); 87 | message.Write(Value.Y); 88 | message.Write(Value.Z); 89 | message.Write(Value.W); 90 | } 91 | 92 | /// 93 | /// deserialize from the stream 94 | /// 95 | /// 96 | public override void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 97 | { 98 | Value.X = message.ReadFloat(); 99 | Value.Y = message.ReadFloat(); 100 | Value.Z = message.ReadFloat(); 101 | Value.W = message.ReadFloat(); 102 | } 103 | 104 | /// 105 | /// size of quaternion in bytes 106 | /// 107 | public override int AllocSize 108 | { 109 | get { return 16; } 110 | } 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /PNetS/Server/Room.Coroutine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace PNetS 6 | { 7 | partial class Room 8 | { 9 | /// 10 | /// Start a coroutine 11 | /// Not thread safe. 12 | /// 13 | /// 14 | /// 15 | public Coroutine StartCoroutine(IEnumerator routine) 16 | { 17 | _shouldRunNextFrame.Add(routine); 18 | return new Coroutine(routine); 19 | } 20 | 21 | List _unblockedCoroutines = new List(); 22 | List _shouldRunNextFrame = new List(); 23 | 24 | internal void RunCoroutines() 25 | { 26 | GameMachine.State.Coroutine.Run(ref _unblockedCoroutines, ref _shouldRunNextFrame); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /PNetS/Server/Room.State.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using PNet; 6 | 7 | namespace PNetS 8 | { 9 | partial class Room 10 | { 11 | private readonly List _roomBehaviours = new List(); 12 | 13 | private readonly IntDictionary _gameObjects = new IntDictionary(256); 14 | 15 | internal void Update() 16 | { 17 | try 18 | { 19 | for (int i = 0; i < _roomBehaviours.Count; ++i) 20 | { 21 | _roomBehaviours[i].Update(); 22 | } 23 | for (int i = 0; i < _gameObjects.Capacity; ++i) 24 | { 25 | GameObject gobj; 26 | if (_gameObjects.TryGetValue(i, out gobj)) 27 | gobj.Update(); 28 | } 29 | } 30 | catch (Exception e) 31 | { 32 | Debug.LogError("[Room Update] {0}: {1}", Name, e); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /PNetS/Server/RoomBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// behaviour for rooms 10 | /// 11 | public abstract class RoomBehaviour 12 | { 13 | /// 14 | /// The room this is attached to 15 | /// 16 | public Room Room { get; internal set; } 17 | 18 | /// 19 | /// run when a player enters the room 20 | /// 21 | public virtual void OnPlayerEnter(Player player){} 22 | 23 | /// 24 | /// run when a player exits the room 25 | /// 26 | public virtual void OnPlayerExit(Player player){} 27 | 28 | /// 29 | /// run when a room behaviour is added to the room we're attached to 30 | /// 31 | /// 32 | public virtual void OnBehaviourAdded(RoomBehaviour behaviour){} 33 | 34 | /// 35 | /// Loop after the behaviour is instantiated 36 | /// 37 | public virtual void Start(){} 38 | 39 | /// 40 | /// run once every update loop, after gameobjects update 41 | /// 42 | public virtual void Update(){} 43 | 44 | /// 45 | /// run when the room is shutting down 46 | /// 47 | public virtual void Closing(){} 48 | 49 | /// 50 | /// run when the behaviour is being removed from the room 51 | /// 52 | public void Disposing(){} 53 | 54 | /// 55 | /// run when a gameobject is added to the room 56 | /// 57 | /// 58 | public virtual void OnGameObjectAdded(GameObject gameObject){} 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /PNetS/ServerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | 7 | [assembly:InternalsVisibleTo("PNetSUnitTests")] 8 | namespace PNetS 9 | { 10 | /// 11 | /// configuration for the server 12 | /// 13 | public class ServerConfiguration 14 | { 15 | /// 16 | /// 17 | /// 18 | public readonly int MaximumConnections; 19 | /// 20 | /// 21 | /// 22 | public readonly int ListenPort; 23 | /// 24 | /// 25 | /// 26 | public int TcpListenPort { get { return ListenPort + 1; } } 27 | /// 28 | /// 29 | /// 30 | public readonly int TickRate; 31 | /// 32 | /// this should be unique per game, and should be the same on the client and server 33 | /// 34 | public readonly string AppIdentifier; 35 | /// 36 | /// size of outgoing buffer. 131071 bytes 37 | /// 38 | public readonly int SendBuffer; 39 | /// 40 | /// size of incoming buffer. 131071 bytes 41 | /// 42 | public readonly int ReceiveBuffer; 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | public ServerConfiguration( 54 | int maximumConnections = 32, 55 | int listenPort = 14000, 56 | int tickRate = 66, 57 | string appIdentifier = "PNet", 58 | int sendBuffer = 131071, 59 | int receiveBuffer = 131071) 60 | { 61 | MaximumConnections = maximumConnections; 62 | ListenPort = listenPort; 63 | TickRate = tickRate; 64 | AppIdentifier = appIdentifier; 65 | SendBuffer = sendBuffer; 66 | ReceiveBuffer = receiveBuffer; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /PNetS/Utils/IPoolItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS.Utils 7 | { 8 | interface IPoolItem 9 | { 10 | void Reset(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /PNetS/Utils/NetworkStateSynchronization.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS 7 | { 8 | /// 9 | /// Type of synchronization used for stream 10 | /// 11 | public enum NetworkStateSynchronization 12 | { 13 | /// 14 | /// no streaming 15 | /// 16 | Off = 0, 17 | /// 18 | /// reliably, ordered, but only when there's a chnage 19 | /// 20 | ReliableDeltaCompressed = 1, 21 | /// 22 | /// unreliable, unordered, and all the time 23 | /// 24 | Unreliable = 2, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PNetS/Utils/ObjectCreateMethod.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | 8 | namespace PNet 9 | { 10 | /// 11 | /// Class which creates a dynamic constructor method for the given type 12 | /// T is root type, if you want to restrict it to a parent + child types. Otherwise just use object. 13 | /// 14 | internal class ObjectCreateMethod where T : class, new() 15 | { 16 | delegate T MethodInvoker(); 17 | MethodInvoker methodHandler = null; 18 | 19 | public ObjectCreateMethod(Type type) 20 | { 21 | CreateMethod(type.GetConstructor(Type.EmptyTypes)); 22 | } 23 | 24 | public ObjectCreateMethod(ConstructorInfo target) 25 | { 26 | if (typeof(T) != typeof(object) && target.DeclaringType.BaseType != typeof(T)) 27 | throw new ArgumentException("The specified type must a child class of the generic type"); 28 | CreateMethod(target); 29 | } 30 | 31 | void CreateMethod(ConstructorInfo target) 32 | { 33 | DynamicMethod dynamic = new DynamicMethod(string.Empty, 34 | typeof(T), 35 | new Type[0], 36 | target.DeclaringType); 37 | 38 | ILGenerator il = dynamic.GetILGenerator(); 39 | il.DeclareLocal(target.DeclaringType); 40 | il.Emit(OpCodes.Newobj, target); 41 | il.Emit(OpCodes.Stloc_0); 42 | il.Emit(OpCodes.Ldloc_0); 43 | il.Emit(OpCodes.Ret); 44 | 45 | methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker)); 46 | } 47 | 48 | public T CreateInstance() 49 | { 50 | return methodHandler(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PNetS/Utils/Pool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PNetS.Utils 7 | { 8 | class Pool where T:IPoolItem 9 | { 10 | private readonly Stack _pool; 11 | private readonly Func _ctor; 12 | 13 | public Pool(Func ctorFunc) 14 | { 15 | _ctor = ctorFunc; 16 | _pool = new Stack(); 17 | } 18 | 19 | public int MaxPoolSize; 20 | 21 | public T GetItem() 22 | { 23 | lock (_pool) 24 | { 25 | if (_pool.Count > 0) 26 | return _pool.Pop(); 27 | } 28 | return _ctor(); 29 | } 30 | 31 | public void Recycle(T item) 32 | { 33 | item.Reset(); 34 | lock (_pool) 35 | { 36 | if (_pool.Count < MaxPoolSize) 37 | { 38 | _pool.Push(item); 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /PNetS/Utils/RPCMode.cs: -------------------------------------------------------------------------------- 1 | using Lidgren.Network; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PNetS 8 | { 9 | /// 10 | /// Ways of sending messages 11 | /// 12 | public enum RPCMode : byte 13 | { 14 | /// 15 | /// send to the server (not used) 16 | /// 17 | Server = 0, 18 | /// 19 | /// Send to everyone but the caller(from a client)/owner(from server) 20 | /// 21 | Others = 1, 22 | /// 23 | /// Send to everyone 24 | /// 25 | All = 2, 26 | /// 27 | /// Send to everyone but the caller(from a client)/owner(from server), buffered 28 | /// 29 | OthersBuffered = 5, 30 | /// 31 | /// Send to everyone buffered 32 | /// 33 | AllBuffered = 6, 34 | /// 35 | /// send to the owner of the networkview 36 | /// 37 | Owner = 7, 38 | 39 | /// 40 | /// send to no one? 41 | /// 42 | None = 10, 43 | 44 | /// 45 | /// send to everyone but the owner, in an unordered fashion. CURRENTLY IS ORDERED FOR NETWORKVIEWS, DUE TO LIDGREN ISSUES 46 | /// 47 | OthersUnordered = 11, 48 | /// 49 | /// send to everyone, in an unordered fashion. CURRENTLY IS ORDERED FOR NETWORKVIEWS, DUE TO LIDGREN ISSUES 50 | /// 51 | AllUnordered = 12, 52 | } 53 | 54 | internal static class RPCModeExtensions 55 | { 56 | public static NetDeliveryMethod GetDeliveryMethod(this RPCMode mode) 57 | { 58 | return NetDeliveryMethod.ReliableOrdered; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /PNetS/Utils/RPCProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lidgren.Network; 3 | 4 | namespace PNetS.Utils 5 | { 6 | internal sealed class RPCProcessor 7 | { 8 | internal readonly Action Method; 9 | internal readonly bool DefaultContinueForwarding; 10 | 11 | public RPCProcessor(Action method, bool defaultContinueForwarding) 12 | { 13 | Method = method; 14 | DefaultContinueForwarding = defaultContinueForwarding; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PNetU/NetBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | /// 5 | /// Simple class to override instead of monobehaviour, has some extra network functions 6 | /// 7 | public class NetBehaviour : MonoBehaviour 8 | { 9 | PNetU.NetworkView _netView; 10 | 11 | /// 12 | /// Get the PNetU.NetworkView attached to the gameObject 13 | /// 14 | public PNetU.NetworkView netView 15 | { 16 | get { return _netView ?? (_netView = GetComponent()); } 17 | internal set 18 | { 19 | _netView = value; 20 | } 21 | } 22 | internal void CallFinished() { OnFinishedCreating(); } 23 | /// 24 | /// Called once the network view has finished attaching and instantiating 25 | /// 26 | protected virtual void OnFinishedCreating() { } 27 | } -------------------------------------------------------------------------------- /PNetU/NetworkView.Static.cs: -------------------------------------------------------------------------------- 1 | using Lidgren.Network; 2 | using PNetC; 3 | 4 | namespace PNetU 5 | { 6 | public partial class NetworkView 7 | { 8 | /// 9 | /// find a network view based on the given NetworkViewId 10 | /// 11 | /// 12 | /// 13 | public static NetworkView Find(NetworkViewId viewId) 14 | { 15 | if (!UnityEngineHook.ValidInstance) 16 | return null; 17 | 18 | NetworkView view; 19 | UnityEngineHook.Instance.Manager.TryGetView(viewId, out view); 20 | return view; 21 | } 22 | 23 | /// 24 | /// find a networkview based on a networkviewid that was serialized into an rpc 25 | /// 26 | /// uses deserialize, so the read location does advance 27 | /// 28 | /// 29 | public static bool Find(ref NetIncomingMessage message, out NetworkView view) 30 | { 31 | var viewId = new NetworkViewId(); 32 | viewId.OnDeserialize(message); 33 | if (UnityEngineHook.ValidInstance) 34 | return UnityEngineHook.Instance.Manager.TryGetView(viewId, out view); 35 | 36 | view = null; 37 | return false; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /PNetU/NetworkedSceneObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using UnityEngine; 5 | using PNet; 6 | using PNetU; 7 | using Lidgren.Network; 8 | 9 | /// 10 | /// Objects that exist in a scene with pre-synchronized network id's 11 | /// 12 | [AddComponentMenu("PNet/Networked Scene Object")] 13 | public abstract class NetworkedSceneObject : MonoBehaviour 14 | { 15 | /// 16 | /// The scene/room Network ID of this item. Should unique per room 17 | /// 18 | public int NetworkID = 0; 19 | 20 | PNetC.NetworkedSceneObject _sceneObject; 21 | 22 | /// 23 | /// If you override, you need to run SetupPNetC, probably first. 24 | /// 25 | protected void Awake() 26 | { 27 | SetupPNetC(); 28 | } 29 | 30 | /// 31 | /// Only do this if you override awake 32 | /// 33 | protected void SetupPNetC() 34 | { 35 | _sceneObject = new PNetC.NetworkedSceneObject(NetworkID, Net.Peer); 36 | } 37 | 38 | 39 | #region RPC Processing 40 | /// 41 | /// Subscribe to an rpc 42 | /// 43 | /// id of the rpc 44 | /// action to process the rpc with 45 | /// overwrite the existing processor if one exists. 46 | /// Whether or not the rpc was subscribed to. Will return false if an existing rpc was attempted to be subscribed to, and overwriteexisting was set to false 47 | public bool SubscribeToRPC(byte rpcID, Action rpcProcessor, bool overwriteExisting = true) 48 | { 49 | return _sceneObject.SubscribeToRPC(rpcID, rpcProcessor, overwriteExisting); 50 | } 51 | 52 | /// 53 | /// Unsubscribe from an rpc 54 | /// 55 | /// 56 | public void UnsubscribeFromRPC(byte rpcID) 57 | { 58 | _sceneObject.UnsubscribeFromRPC(rpcID); 59 | } 60 | #endregion 61 | 62 | /// 63 | /// Send an rpc to the server 64 | /// 65 | /// 66 | /// 67 | public void RPC(byte rpcID, params INetSerializable[] args) 68 | { 69 | _sceneObject.RPC(rpcID, args); 70 | } 71 | 72 | /// 73 | /// serialize this into a string 74 | /// 75 | /// 76 | public string Serialize() 77 | { 78 | var serObj = new PNetC.NetworkedSceneObject(NetworkID); 79 | var sb = new StringBuilder(); 80 | sb.Append(serObj.Serialize()); 81 | sb.Append("type:").Append(this.GetType().Name).AppendLine(";"); 82 | sb.Append("data:").Append(SerializeObjectData()).AppendLine(";"); 83 | sb.Append("pos:").Append(transform.position.ToString()).AppendLine(";"); 84 | sb.Append("rot:").Append(transform.rotation.ToString()).AppendLine(";"); 85 | 86 | return sb.ToString(); 87 | } 88 | 89 | /// 90 | /// Get the data to serialize for this scene object 91 | /// 92 | /// 93 | protected abstract string SerializeObjectData(); 94 | } -------------------------------------------------------------------------------- /PNetU/PNetU.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {C4B8A2DF-4ED8-459B-91C8-6B5CE524CF58} 9 | Library 10 | Properties 11 | PNetU 12 | PNetU 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | ..\bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | 28 | 29 | pdbonly 30 | true 31 | ..\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | ..\bin\Release\PNetU.xml 36 | AnyCPU 37 | 38 | 39 | 40 | 41 | 42 | ..\lib\UnityEngine.dll 43 | False 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 62 | Lidgren.Network 63 | 64 | 65 | {314D16A0-FF83-4D3D-919E-8255D8BC9728} 66 | PNetC 67 | 68 | 69 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 70 | PNet 71 | 72 | 73 | 74 | 75 | "C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.0\pdb2mdb.exe" "$(TargetDir)PNetU.dll" 76 | "C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.0\pdb2mdb.exe" "$(TargetDir)PNet.dll" 77 | "C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.0\pdb2mdb.exe" "$(TargetDir)PNetC.dll" 78 | 79 | 86 | -------------------------------------------------------------------------------- /PNetU/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNetU")] 9 | [assembly: AssemblyDescription("PNetwork client binding for Unity")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PNetU")] 13 | [assembly: AssemblyCopyright("Copyright © Justin Bruening")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("eca75811-9948-4f4e-806f-81956afa22e4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /PNetU/UnityDebugLogger.cs: -------------------------------------------------------------------------------- 1 | using PNetC; 2 | using UnityEngine; 3 | using NetworkLogLevel = UnityEngine.NetworkLogLevel; 4 | 5 | namespace PNetU 6 | { 7 | /// 8 | /// Logs to standard UnityEngine.Debug class 9 | /// 10 | internal sealed class UnityDebugLogger : ILogger 11 | { 12 | /// 13 | /// Same as PNetC.Debug.Log. 14 | /// Only shows up if you have Network.logLevel set to full 15 | /// 16 | /// 17 | /// 18 | /// 19 | public static void Full(string info, UnityEngine.Object context, params object[] args) 20 | { 21 | if (Network.logLevel == NetworkLogLevel.Full) 22 | UnityEngine.Debug.Log(string.Format(info, args), context); 23 | } 24 | /// 25 | /// Same as PNetC.Debug.Info 26 | /// Shows up if Network.logLevel is set to Info, or running in a debug build 27 | /// 28 | /// 29 | /// 30 | /// 31 | public static void Info(string info, UnityEngine.Object context, params object[] args) 32 | { 33 | if (Network.logLevel > NetworkLogLevel.Off || UnityEngine.Debug.isDebugBuild) 34 | UnityEngine.Debug.Log(string.Format(info, args), context); 35 | } 36 | 37 | void ILogger.Full(PNetC.Net sender, string info, params object[] args) 38 | { 39 | if (Network.logLevel == NetworkLogLevel.Full) 40 | UnityEngine.Debug.Log(string.Format(info, args)); 41 | } 42 | 43 | void ILogger.Info(PNetC.Net sender, string info, params object[] args) 44 | { 45 | if (Network.logLevel > NetworkLogLevel.Off || UnityEngine.Debug.isDebugBuild) 46 | UnityEngine.Debug.Log(string.Format(info, args)); 47 | } 48 | 49 | void ILogger.Warning(PNetC.Net sender, string info, params object[] args) 50 | { 51 | UnityEngine.Debug.LogWarning(string.Format(info, args)); 52 | } 53 | 54 | void ILogger.Error(PNetC.Net sender, string info, params object[] args) 55 | { 56 | UnityEngine.Debug.LogError(string.Format(info, args)); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /PNetU/UnityExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace PNetU 8 | { 9 | /// 10 | /// Extensions for unity stuff 11 | /// 12 | public static class UnityExtensions 13 | { 14 | /// 15 | /// Serialize the quaternion to the message 16 | /// 17 | /// 18 | /// 19 | public static void Serialize(this Quaternion quaternion, Lidgren.Network.NetOutgoingMessage message) 20 | { 21 | message.Write(quaternion.x); 22 | message.Write(quaternion.y); 23 | message.Write(quaternion.z); 24 | message.Write(quaternion.w); 25 | } 26 | 27 | /// 28 | /// serialize the vector3 to the message 29 | /// 30 | /// 31 | /// 32 | public static void Serialize(this Vector3 vector3, Lidgren.Network.NetOutgoingMessage message) 33 | { 34 | message.Write(vector3.x); 35 | message.Write(vector3.y); 36 | message.Write(vector3.z); 37 | } 38 | 39 | /// 40 | /// Get the 3 bytes 41 | /// 42 | /// 43 | /// 44 | public static byte[] RGBBytes(this Color color) 45 | { 46 | Color32 col32 = color; 47 | 48 | byte[] bytes = new byte[3]; 49 | bytes[0] = col32.r; 50 | bytes[1] = col32.g; 51 | bytes[2] = col32.b; 52 | 53 | return bytes; 54 | } 55 | 56 | /// 57 | /// Get the 4 bytes 58 | /// 59 | /// 60 | /// 61 | public static byte[] ARGBBytes(this Color color) 62 | { 63 | Color32 col32 = color; 64 | 65 | byte[] bytes = new byte[4]; 66 | bytes[0] = col32.a; 67 | bytes[1] = col32.r; 68 | bytes[2] = col32.g; 69 | bytes[3] = col32.b; 70 | 71 | return bytes; 72 | } 73 | 74 | /// 75 | /// Get the 3 bytes 76 | /// 77 | /// 78 | /// 79 | public static byte[] RGBBytes(this Color32 color) 80 | { 81 | byte[] bytes = new byte[3]; 82 | bytes[0] = color.r; 83 | bytes[1] = color.g; 84 | bytes[2] = color.b; 85 | 86 | return bytes; 87 | } 88 | 89 | /// 90 | /// Get the 4 bytes 91 | /// 92 | /// 93 | /// 94 | public static byte[] ARGBBytes(this Color32 color) 95 | { 96 | byte[] bytes = new byte[4]; 97 | bytes[0] = color.a; 98 | bytes[1] = color.r; 99 | bytes[2] = color.g; 100 | bytes[3] = color.b; 101 | 102 | return bytes; 103 | } 104 | 105 | internal static PNetC.RPCMode ToPNetCMode(this UnityEngine.RPCMode mode) 106 | { 107 | switch (mode) 108 | { 109 | case RPCMode.Others: return PNetC.RPCMode.Others; 110 | case RPCMode.Server: return PNetC.RPCMode.Server; 111 | case RPCMode.All: return PNetC.RPCMode.All; 112 | case RPCMode.OthersBuffered: return PNetC.RPCMode.OthersBuffered; 113 | case RPCMode.AllBuffered: return PNetC.RPCMode.AllBuffered; 114 | default: return PNetC.RPCMode.Server; 115 | } 116 | } 117 | 118 | internal static PNetC.NetworkStateSynchronization ToPNetC(this UnityEngine.NetworkStateSynchronization state) 119 | { 120 | switch (state) 121 | { 122 | case NetworkStateSynchronization.Off: return PNetC.NetworkStateSynchronization.Off; 123 | case NetworkStateSynchronization.ReliableDeltaCompressed: return PNetC.NetworkStateSynchronization.ReliableDeltaCompressed; 124 | case NetworkStateSynchronization.Unreliable: return PNetC.NetworkStateSynchronization.Unreliable; 125 | default: return PNetC.NetworkStateSynchronization.Off; 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /PNetU/UnityNetworkViewManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PNetC; 3 | 4 | namespace PNetU 5 | { 6 | internal class UnityNetworkViewManager 7 | { 8 | readonly Dictionary _networkViews = new Dictionary(); 9 | 10 | internal void AddView(PNetC.NetworkView newView, NetworkView view) 11 | { 12 | _networkViews.Add(newView.ViewID, view); 13 | view.SetNetworkView(newView); 14 | } 15 | 16 | internal bool TryGetView(NetworkViewId viewId, out NetworkView view) 17 | { 18 | return _networkViews.TryGetValue(viewId, out view); 19 | } 20 | 21 | internal bool Remove(NetworkViewId viewId) 22 | { 23 | return _networkViews.Remove(viewId); 24 | } 25 | 26 | internal void Clear() 27 | { 28 | _networkViews.Clear(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /PNetU/UnitySerializers.cs: -------------------------------------------------------------------------------- 1 | using PNet; 2 | using UnityEngine; 3 | 4 | namespace PNetU 5 | { 6 | /// 7 | /// Serializer for vectors 8 | /// 9 | public class Vector3Serializer : ASerializable 10 | { 11 | /// 12 | /// create a new serializer from the Vector3 13 | /// 14 | /// 15 | public Vector3Serializer(Vector3 vector3) 16 | { 17 | this.Value = vector3; 18 | } 19 | 20 | /// 21 | /// New serializer, value at zero 22 | /// 23 | public Vector3Serializer() 24 | { 25 | this.Value = Vector3.zero; 26 | } 27 | 28 | /// 29 | /// serialize vector3 into message 30 | /// 31 | /// 32 | public override void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 33 | { 34 | message.Write(Value.x); 35 | message.Write(Value.y); 36 | message.Write(Value.z); 37 | } 38 | 39 | /// 40 | /// deserialize into vector3 41 | /// 42 | /// 43 | public override void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 44 | { 45 | Value.x = message.ReadFloat(); 46 | Value.y = message.ReadFloat(); 47 | Value.z = message.ReadFloat(); 48 | } 49 | 50 | /// 51 | /// 12 bytes 52 | /// 53 | public override int AllocSize 54 | { 55 | get { return 12; } 56 | } 57 | } 58 | 59 | /// 60 | /// Serializer for quaternions 61 | /// 62 | public class QuaternionSerializer : ASerializable 63 | { 64 | /// 65 | /// create a new serializer from the quaternion 66 | /// 67 | /// 68 | public QuaternionSerializer(Quaternion quaternion) 69 | { 70 | this.Value = quaternion; 71 | } 72 | 73 | /// 74 | /// new serializer, value is identity 75 | /// 76 | public QuaternionSerializer() 77 | { 78 | this.Value = Quaternion.identity; 79 | } 80 | /// 81 | /// serialize quaternion into the stream 82 | /// 83 | /// 84 | public override void OnSerialize(Lidgren.Network.NetOutgoingMessage message) 85 | { 86 | message.Write(Value.x); 87 | message.Write(Value.y); 88 | message.Write(Value.z); 89 | message.Write(Value.w); 90 | } 91 | 92 | /// 93 | /// deserialize into quaternion 94 | /// 95 | /// 96 | public override void OnDeserialize(Lidgren.Network.NetIncomingMessage message) 97 | { 98 | Value.x = message.ReadFloat(); 99 | Value.y = message.ReadFloat(); 100 | Value.z = message.ReadFloat(); 101 | Value.w = message.ReadFloat(); 102 | } 103 | 104 | /// 105 | /// 16 bytes 106 | /// 107 | public override int AllocSize 108 | { 109 | get { return 16; } 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /Tests/ClientServerIntegrationTests/ClientServerIntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {89FEA82B-53FA-450B-A3D7-7E8102483FC2} 10 | Library 11 | Properties 12 | ClientServerIntegrationTests 13 | ClientServerIntegrationTests 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 3.5 40 | 41 | 42 | 43 | 44 | False 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 58 | Lidgren.Network 59 | 60 | 61 | {314D16A0-FF83-4D3D-919E-8255D8BC9728} 62 | PNetC 63 | 64 | 65 | {9167E35B-50F3-4980-B1AC-FA42828F6804} 66 | PNetS 67 | 68 | 69 | {C4B8A2DF-4ED8-459B-91C8-6B5CE524CF58} 70 | PNetU 71 | 72 | 73 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 74 | PNet 75 | 76 | 77 | {820FE441-822F-4519-994B-04F1DE27FF15} 78 | SlimMathVS2010 79 | 80 | 81 | {D2D2F82B-3456-4E91-AD1B-8A52D71F233D} 82 | PNet.Testing.Common 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /Tests/ClientServerIntegrationTests/ClientTestComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using PNetS; 6 | 7 | namespace ClientServerIntegrationTests 8 | { 9 | class ClientTestComponent : Component 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/ClientServerIntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClientServerIntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("ClientServerIntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e7ac5ba8-85a5-4400-9634-2c4b109f6423")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Tests/ClientServerIntegrationTests/RoomTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using Lidgren.Network; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | using PNet.Testing.Common; 9 | using PNetS; 10 | 11 | namespace ClientServerIntegrationTests 12 | { 13 | /// 14 | /// Summary description for RoomTests 15 | /// 16 | [TestClass] 17 | public class RoomTests 18 | { 19 | private Room _testRoom; 20 | private Room _testRoom2; 21 | private TestablePNet _client; 22 | 23 | public RoomTests() 24 | { 25 | // 26 | // TODO: Add constructor logic here 27 | // 28 | } 29 | 30 | /// 31 | ///Gets or sets the test context which provides 32 | ///information about and functionality for the current test run. 33 | /// 34 | public TestContext TestContext { get; set; } 35 | 36 | #region Additional test attributes 37 | // 38 | // Use ClassInitialize to run code before running the first test in the class 39 | [ClassInitialize()] 40 | public static void MyClassInitialize(TestContext testContext) 41 | { 42 | ServerUtils.SetupDefaultServer(); 43 | ServerUtils.StartServerOnNewThread(); 44 | } 45 | // 46 | // Use ClassCleanup to run code after all tests in a class have run 47 | [ClassCleanup()] 48 | public static void MyClassCleanup() 49 | { 50 | ServerUtils.TeardownServer(); 51 | } 52 | // 53 | // Use TestInitialize to run code before running each test 54 | [TestInitialize()] 55 | public void MyTestInitialize() 56 | { 57 | _client = new TestablePNet(); 58 | _client.TestableHook.StartUpdateThread(); 59 | 60 | _testRoom = Room.CreateRoom("test room"); 61 | _testRoom2 = Room.CreateRoom("test room 2"); 62 | } 63 | // 64 | // Use TestCleanup to run code after each test has run 65 | [TestCleanup()] 66 | public void MyTestCleanup() 67 | { 68 | _client.Disconnect(); 69 | while(_client.Status != NetConnectionStatus.Disconnected) 70 | {Thread.Sleep(10);} 71 | _client.TestableHook.StopUpdateThread(); 72 | } 73 | // 74 | #endregion 75 | 76 | [TestMethod] 77 | public void TestRoomJoining() 78 | { 79 | _client.OnRoomChange += s => _client.FinishedRoomChange(); 80 | PNetServer.OnPlayerConnected += OnPlayerConnected; 81 | 82 | 83 | 84 | _client.Connect(TestablePNet.GetTestConnectionConfig()); 85 | 86 | Thread.Sleep(250); 87 | 88 | Assert.AreEqual(NetConnectionStatus.Connected, _client.Status, "Client did not connect in 250 ms"); 89 | 90 | Thread.Sleep(100); 91 | 92 | var tPlayer = PNetServer.AllPlayers()[1]; 93 | 94 | Assert.AreSame(_testRoom, tPlayer.CurrentRoom, "Client did not change to the room within 100 ms"); 95 | 96 | GameState.InvokeIfRequired(() => 97 | { 98 | tPlayer.ChangeRoom(_testRoom2); 99 | }); 100 | 101 | Thread.Sleep(100); 102 | 103 | Assert.AreSame(_testRoom2, tPlayer.CurrentRoom, "Client did not switch to room 2 within 100 ms"); 104 | 105 | GameState.InvokeIfRequired(() => 106 | { 107 | tPlayer.ChangeRoom(_testRoom); 108 | }); 109 | 110 | Thread.Sleep(100); 111 | 112 | Assert.AreSame(_testRoom, tPlayer.CurrentRoom, "Client did not change back to room within 100 ms"); 113 | } 114 | 115 | private void OnPlayerConnected(Player player) 116 | { 117 | player.ChangeRoom(_testRoom); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Tests/ClientServerIntegrationTests/TestComponent.cs: -------------------------------------------------------------------------------- 1 | using PNetS; 2 | 3 | namespace ClientServerIntegrationTests 4 | { 5 | class TestComponent : Component 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/PNet.Testing.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {D2D2F82B-3456-4E91-AD1B-8A52D71F233D} 10 | Library 11 | Properties 12 | PNet.Testing.Common 13 | PNet.Testing.Common 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 3.5 40 | 41 | 42 | 43 | 44 | False 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 62 | Lidgren.Network 63 | 64 | 65 | {314D16A0-FF83-4D3D-919E-8255D8BC9728} 66 | PNetC 67 | 68 | 69 | {9167E35B-50F3-4980-B1AC-FA42828F6804} 70 | PNetS 71 | 72 | 73 | {C4B8A2DF-4ED8-459B-91C8-6B5CE524CF58} 74 | PNetU 75 | 76 | 77 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 78 | PNet 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNet.Testing.Common")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("PNet.Testing.Common")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("423600bb-3a0f-4527-aba6-5110da9451d7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/SerializableTest.cs: -------------------------------------------------------------------------------- 1 | using PNet; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System; 4 | using Lidgren.Network; 5 | 6 | namespace PNet.Testing.Common 7 | { 8 | 9 | 10 | /// 11 | ///This is a test class for SerializableTest and is intended 12 | ///to contain all SerializableTest Unit Tests 13 | /// 14 | [TestClass()] 15 | public class SerializableTest 16 | { 17 | 18 | 19 | private TestContext testContextInstance; 20 | 21 | /// 22 | ///Gets or sets the test context which provides 23 | ///information about and functionality for the current test run. 24 | /// 25 | public TestContext TestContext 26 | { 27 | get 28 | { 29 | return testContextInstance; 30 | } 31 | set 32 | { 33 | testContextInstance = value; 34 | } 35 | } 36 | 37 | #region Additional test attributes 38 | // 39 | //You can use the following additional attributes as you write your tests: 40 | // 41 | //Use ClassInitialize to run code before running the first test in the class 42 | //[ClassInitialize()] 43 | //public static void MyClassInitialize(TestContext testContext) 44 | //{ 45 | //} 46 | // 47 | //Use ClassCleanup to run code after all tests in a class have run 48 | //[ClassCleanup()] 49 | //public static void MyClassCleanup() 50 | //{ 51 | //} 52 | // 53 | //Use TestInitialize to run code before running each test 54 | //[TestInitialize()] 55 | //public void MyTestInitialize() 56 | //{ 57 | //} 58 | // 59 | //Use TestCleanup to run code after each test has run 60 | //[TestCleanup()] 61 | //public void MyTestCleanup() 62 | //{ 63 | //} 64 | // 65 | #endregion 66 | 67 | [TestMethod] 68 | public void DifferentSerializerInstanceValuesTest() 69 | { 70 | var v1 = StringSerializer.Instance; 71 | var v2 = IntSerializer.Instance; 72 | 73 | Assert.AreNotSame(v1, v2); 74 | } 75 | 76 | [TestMethod] 77 | public void InstanceDifferentFromConstructedTest() 78 | { 79 | Assert.AreNotSame(StringSerializer.Instance, new StringSerializer()); 80 | } 81 | 82 | /// 83 | /// Expects not to throw an error 84 | /// 85 | [TestMethod] 86 | public void NonDefinedConstructorInheritableTest() 87 | { 88 | var test = new ByteArraySerializer(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/ServerUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using Lidgren.Network; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | using PNetS; 9 | 10 | namespace PNet.Testing.Common 11 | { 12 | public static class ServerUtils 13 | { 14 | private static Thread _serverThread; 15 | 16 | public static void StartServerOnNewThread() 17 | { 18 | _serverThread = new Thread(() => PNetServer.Start()); 19 | _serverThread.Start(); 20 | } 21 | 22 | public static void SetupDefaultServer() 23 | { 24 | PNetS.PNetServer.InitializeServer(GetDefaultServerConfig()); 25 | 26 | Debug.logger = new DefaultConsoleLogger(); 27 | } 28 | 29 | public static ServerConfiguration GetDefaultServerConfig() 30 | { 31 | return new ServerConfiguration(appIdentifier: "PNetTest"); 32 | } 33 | 34 | public static void TeardownServer() 35 | { 36 | PNetServer.Disconnect(); 37 | while(PNetServer.PeerStatus != NetPeerStatus.NotRunning) 38 | {Thread.Sleep(10);} 39 | PNetServer.Shutdown(); 40 | Thread.Sleep(100); 41 | } 42 | } 43 | 44 | /// 45 | /// Outputs info and warning to console, but fails on Error 46 | /// 47 | public class TestLogger : ILogger 48 | { 49 | public void Info(string info, params object[] args) 50 | { 51 | Console.WriteLine(info, args); 52 | } 53 | 54 | public void Warning(string info, params object[] args) 55 | { 56 | Console.WriteLine(info, args); 57 | } 58 | 59 | public void Error(string info, params object[] args) 60 | { 61 | Assert.Fail(info, args); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/TestClientLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace PNet.Testing.Common 9 | { 10 | class TestClientLogger : PNetC.ILogger 11 | { 12 | public void Full(PNetC.Net sender, string info, params object[] args) 13 | { 14 | Debug.WriteLine(string.Format(info, args)); 15 | } 16 | 17 | public void Info(PNetC.Net sender, string info, params object[] args) 18 | { 19 | Debug.WriteLine(string.Format(info, args)); 20 | } 21 | 22 | public void Warning(PNetC.Net sender, string info, params object[] args) 23 | { 24 | Debug.WriteLine(string.Format(info, args)); 25 | } 26 | 27 | public void Error(PNetC.Net sender, string info, params object[] args) 28 | { 29 | Assert.Fail(info, args); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/TestEngineHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using PNetC; 6 | 7 | namespace PNet.Testing.Common 8 | { 9 | public class TestEngineHook : IEngineHook 10 | { 11 | private Thread _clientThread; 12 | 13 | public int UpdateSleepTime = 30; 14 | public event Action EngineUpdate; 15 | 16 | public Dictionary Instantiates = new Dictionary(); 17 | public void Instantiate(string path, NetworkView newView, Vector3 location, Quaternion rotation) 18 | { 19 | Console.WriteLine("{0} instantiated", path); 20 | Instantiates.Add(path, newView); 21 | } 22 | 23 | public void AddNetworkView(NetworkView view, NetworkView newView, string customFunction) 24 | { 25 | 26 | } 27 | 28 | public void RunOneUpdate() 29 | { 30 | Assert.IsNotNull(EngineUpdate); 31 | EngineUpdate(); 32 | } 33 | 34 | public void StartUpdateThread() 35 | { 36 | _clientThread = new Thread(DoUpdateThread); 37 | _clientThread.Start(); 38 | } 39 | public void StopUpdateThread() 40 | { 41 | _quit = true; 42 | } 43 | 44 | private bool _quit = false; 45 | 46 | public bool UpdatePause = false; 47 | 48 | private void DoUpdateThread() 49 | { 50 | while (!_quit) 51 | { 52 | if (EngineUpdate != null && !UpdatePause) 53 | EngineUpdate(); 54 | Thread.Sleep(UpdateSleepTime); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/TestServerLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace PNet.Testing.Common 9 | { 10 | class TestServerLogger : PNetS.ILogger 11 | { 12 | public void Full(string info, params object[] args) 13 | { 14 | Debug.WriteLine(string.Format(info, args)); 15 | } 16 | 17 | public void Info(string info, params object[] args) 18 | { 19 | Debug.WriteLine(string.Format(info, args)); 20 | } 21 | 22 | public void Warning(string info, params object[] args) 23 | { 24 | Debug.WriteLine(string.Format(info, args)); 25 | } 26 | 27 | public void Error(string info, params object[] args) 28 | { 29 | Assert.Fail(info, args); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/PNet.Testing.Common/TestablePNet.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using PNetC; 3 | 4 | namespace PNet.Testing.Common 5 | { 6 | public class TestablePNet : PNetC.Net 7 | { 8 | private static readonly PropertyInfo PlayerIDProp = typeof (PNetC.Net).GetProperty("PlayerId"); 9 | 10 | public TestablePNet(IEngineHook engineHook) : base(engineHook) 11 | { 12 | Debug.Logger = new TestClientLogger(); 13 | } 14 | 15 | public TestablePNet() : this(new TestEngineHook()){} 16 | 17 | public TestEngineHook TestableHook 18 | { 19 | get { return EngineHook as TestEngineHook; } 20 | } 21 | 22 | public ushort TestablePlayerID 23 | { 24 | get { return PlayerId; } 25 | set { PlayerIDProp.SetValue(this, value, null); } 26 | } 27 | 28 | public static ClientConfiguration GetTestConnectionConfig() 29 | { 30 | return new ClientConfiguration("127.0.0.1", 14000, appIdentifier: "PNetTest"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/PNetSUnitTests/PNetSUnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {8186E93F-1456-4893-B3BF-953DDEA5C93E} 10 | Library 11 | Properties 12 | PNetSUnitTests 13 | PNetSUnitTests 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 3.5 40 | 41 | 42 | ..\..\lib\YamlSerializer.dll 43 | True 44 | 45 | 46 | 47 | 48 | False 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 60 | Lidgren.Network 61 | 62 | 63 | {9167E35B-50F3-4980-B1AC-FA42828F6804} 64 | PNetS 65 | 66 | 67 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 68 | PNet 69 | 70 | 71 | {820FE441-822F-4519-994B-04F1DE27FF15} 72 | SlimMathVS2010 73 | 74 | 75 | {D2D2F82B-3456-4E91-AD1B-8A52D71F233D} 76 | PNet.Testing.Common 77 | 78 | 79 | 80 | 87 | -------------------------------------------------------------------------------- /Tests/PNetSUnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PNetSUnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("PNetSUnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cde2451b-403c-4495-bc07-a43bc7f5ad02")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Tests/PNetSUnitTests/TcpStateTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using PNetS.Server; 5 | 6 | namespace PNetSUnitTests 7 | { 8 | [TestClass] 9 | public class TcpStateTest 10 | { 11 | /// 12 | /// test to ensure that the message can be received even if broken into parts 13 | /// 14 | [TestMethod] 15 | public void DividedTest() 16 | { 17 | var state = new TcpServer.NetworkMessage(); 18 | 19 | var strmsg = "Hello world"; 20 | var message = Encoding.UTF8.GetBytes(strmsg); 21 | var msgSize = message.Length; 22 | 23 | var sizeBytes = BitConverter.GetBytes(msgSize); 24 | 25 | var firstPart = new byte[2]; 26 | Buffer.BlockCopy(sizeBytes, 0, firstPart, 0, 2); 27 | var secondSize = message.Length/2; 28 | var secondPart = new byte[secondSize + 2]; 29 | Buffer.BlockCopy(sizeBytes, 2, secondPart, 0, 2); 30 | Buffer.BlockCopy(message, 0, secondPart, 2, secondSize); 31 | var lastSize = message.Length - secondSize; 32 | var lastPart = new byte[lastSize]; 33 | Buffer.BlockCopy(message, secondSize, lastPart, 0, lastSize); 34 | 35 | state.Reset(); 36 | 37 | Buffer.BlockCopy(firstPart, 0, state.Buffer, 0, firstPart.Length); 38 | state.ConsumeBuffer(firstPart.Length); 39 | Buffer.BlockCopy(secondPart, 0, state.Buffer, 0, secondPart.Length); 40 | state.ConsumeBuffer(secondPart.Length); 41 | Buffer.BlockCopy(lastPart, 0, state.Buffer, 0, lastPart.Length); 42 | state.ConsumeBuffer(lastPart.Length); 43 | 44 | 45 | Assert.IsTrue(state.IsValidMessage); 46 | Assert.AreEqual(state.MessageSize, msgSize); 47 | var result = Encoding.UTF8.GetString(state.Message, 0, state.MessageSize); 48 | Assert.AreEqual(strmsg, result); 49 | } 50 | 51 | /// 52 | /// Test to ensure that states are capable of resizing their message array to fit messages larger than their inital size 53 | /// 54 | [TestMethod] 55 | public void LargeMessageTest() 56 | { 57 | var state = new TcpServer.NetworkMessage(); 58 | 59 | Random rand = new Random(); 60 | var message = new byte[2000]; 61 | rand.NextBytes(message); 62 | var msgSize = message.Length; 63 | 64 | var sizeBytes = BitConverter.GetBytes(msgSize); 65 | 66 | var firstPart = new byte[1000]; 67 | firstPart[0] = sizeBytes[0]; 68 | firstPart[1] = sizeBytes[1]; 69 | firstPart[2] = sizeBytes[2]; 70 | firstPart[3] = sizeBytes[3]; 71 | 72 | Buffer.BlockCopy(message, 0, firstPart, 4, firstPart.Length - 4); 73 | 74 | var secondPart = new byte[message.Length - firstPart.Length + 4]; 75 | Buffer.BlockCopy(message, firstPart.Length - 4, secondPart, 0, secondPart.Length); 76 | 77 | state.Reset(); 78 | Buffer.BlockCopy(firstPart, 0, state.Buffer, 0, firstPart.Length); 79 | state.ConsumeBuffer(firstPart.Length); 80 | Buffer.BlockCopy(secondPart, 0, state.Buffer, 0, secondPart.Length); 81 | state.ConsumeBuffer(secondPart.Length); 82 | 83 | Assert.IsTrue(state.IsValidMessage); 84 | Assert.AreEqual(msgSize, state.MessageSize); 85 | var stateMessage = new byte[state.MessageSize]; 86 | Buffer.BlockCopy(state.Message, 0, stateMessage, 0, state.MessageSize); 87 | CollectionAssert.AreEqual(message, stateMessage); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/NetTest.cs: -------------------------------------------------------------------------------- 1 | using PNetC; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System; 4 | 5 | namespace UnitTestsPNetC 6 | { 7 | 8 | 9 | /// 10 | ///This is a test class for NetTest and is intended 11 | ///to contain all NetTest Unit Tests 12 | /// 13 | [TestClass()] 14 | public class NetTest 15 | { 16 | 17 | 18 | private TestContext testContextInstance; 19 | 20 | /// 21 | ///Gets or sets the test context which provides 22 | ///information about and functionality for the current test run. 23 | /// 24 | public TestContext TestContext 25 | { 26 | get 27 | { 28 | return testContextInstance; 29 | } 30 | set 31 | { 32 | testContextInstance = value; 33 | } 34 | } 35 | 36 | #region Additional test attributes 37 | // 38 | //You can use the following additional attributes as you write your tests: 39 | // 40 | //Use ClassInitialize to run code before running the first test in the class 41 | //[ClassInitialize()] 42 | //public static void MyClassInitialize(TestContext testContext) 43 | //{ 44 | //} 45 | // 46 | //Use ClassCleanup to run code after all tests in a class have run 47 | //[ClassCleanup()] 48 | //public static void MyClassCleanup() 49 | //{ 50 | //} 51 | // 52 | //Use TestInitialize to run code before running each test 53 | //[TestInitialize()] 54 | //public void MyTestInitialize() 55 | //{ 56 | //} 57 | // 58 | //Use TestCleanup to run code after each test has run 59 | //[TestCleanup()] 60 | //public void MyTestCleanup() 61 | //{ 62 | //} 63 | // 64 | #endregion 65 | 66 | 67 | /// 68 | /// Test that a single run of Update doesn't throw an error without being set up. 69 | /// 70 | [TestMethod()] 71 | [DeploymentItem("PNetC.dll")] 72 | public void UpdateDoesNotErrorTest() 73 | { 74 | var pnet = new PNetC.Net(new PNet.Testing.Common.TestEngineHook()); 75 | var param0 = new PrivateObject(pnet); 76 | var target = new Net_Accessor(param0); 77 | target.Update(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/NetworkManagerCreateAndRecycle.orderedtest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/NetworkViewManagerTest.cs: -------------------------------------------------------------------------------- 1 | using PNet.Testing.Common; 2 | using PNetC; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using System; 5 | using Debug = System.Diagnostics.Debug; 6 | 7 | namespace UnitTestsPNetC 8 | { 9 | 10 | 11 | /// 12 | ///This is a test class for NetworkViewManagerTest and is intended 13 | ///to contain all NetworkViewManagerTest Unit Tests 14 | /// 15 | [TestClass()] 16 | public class NetworkViewManagerTest 17 | { 18 | private TestablePNet _net; 19 | 20 | private TestContext testContextInstance; 21 | private NetworkViewManager _target; 22 | 23 | /// 24 | ///Gets or sets the test context which provides 25 | ///information about and functionality for the current test run. 26 | /// 27 | public TestContext TestContext 28 | { 29 | get 30 | { 31 | return testContextInstance; 32 | } 33 | set 34 | { 35 | testContextInstance = value; 36 | } 37 | } 38 | 39 | #region Additional test attributes 40 | // 41 | //You can use the following additional attributes as you write your tests: 42 | // 43 | //Use ClassInitialize to run code before running the first test in the class 44 | [ClassInitialize()] 45 | public static void MyClassInitialize(TestContext testContext) 46 | { 47 | 48 | } 49 | // 50 | //Use ClassCleanup to run code after all tests in a class have run 51 | //[ClassCleanup()] 52 | //public static void MyClassCleanup() 53 | //{ 54 | //} 55 | // 56 | //Use TestInitialize to run code before running each test 57 | [TestInitialize()] 58 | public void MyTestInitialize() 59 | { 60 | _net = new TestablePNet(); 61 | _target = new NetworkViewManager(_net); 62 | } 63 | // 64 | //Use TestCleanup to run code after each test has run 65 | //[TestCleanup()] 66 | //public void MyTestCleanup() 67 | //{ 68 | //} 69 | // 70 | #endregion 71 | 72 | 73 | /// 74 | ///A test for Create 75 | /// 76 | [TestMethod()] 77 | public void CreateTest() 78 | { 79 | var viewId = new NetworkViewId{guid =15}; 80 | ushort ownerId = 14; 81 | 82 | _net.TestablePlayerID = 12; 83 | NetworkView actual = _target.Create(viewId, ownerId); 84 | 85 | 86 | //test regular creation with an empty pool 87 | Assert.AreEqual(viewId, actual.ViewID); 88 | Assert.AreEqual(ownerId, actual.OwnerId); 89 | Assert.IsFalse(actual.IsMine); 90 | } 91 | 92 | [TestMethod()] 93 | public void IsMineTest() 94 | { 95 | ushort playerID = 15; 96 | _net.TestablePlayerID = playerID; 97 | 98 | var actual = _target.Create(new NetworkViewId{guid =16}, playerID); 99 | 100 | Assert.IsTrue(actual.IsMine, "The networkview should be mine"); 101 | 102 | actual = _target.Create(new NetworkViewId{guid = 16}, 17); 103 | 104 | Assert.IsFalse(actual.IsMine, "The networkview should not be mine"); 105 | } 106 | 107 | [TestMethod()] 108 | public void RecycleTest() 109 | { 110 | var vid1 = new NetworkViewId{guid =15}; 111 | var vid2 = new NetworkViewId{guid =16}; 112 | var vid3 = new NetworkViewId{guid =17}; 113 | 114 | ushort owner1 = 1; 115 | ushort owner2 = 2; 116 | ushort owner3 = 3; 117 | 118 | var first = _target.Create(vid1, owner1); 119 | var second = _target.Create(vid2, owner2); 120 | 121 | _target.RemoveView(first); 122 | first = null; 123 | 124 | var third = _target.Create(vid3, owner3); 125 | 126 | Assert.AreNotEqual(vid1, third.ViewID.guid); 127 | Assert.AreNotEqual(owner1, third.OwnerId); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnitTestsPNetC")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("UnitTestsPNetC")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("95cd5132-21dc-4d03-9c57-e9778caff799")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/Test References/PNetC.accessor: -------------------------------------------------------------------------------- 1 | PNetC.dll 2 | Desktop 3 | -------------------------------------------------------------------------------- /Tests/UnitTestsPNetC/UnitTestsPNetC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {C4A89324-0C65-4B8F-8F71-519DD5FBA9BF} 10 | Library 11 | Properties 12 | UnitTestsPNetC 13 | UnitTestsPNetC 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 3.5 40 | 41 | 42 | 43 | 44 | False 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {49BA1C69-6104-41AC-A5D8-B54FA9F696E8} 55 | Lidgren.Network 56 | 57 | 58 | {314D16A0-FF83-4D3D-919E-8255D8BC9728} 59 | PNetC 60 | 61 | 62 | {2DA9878B-D8F8-4F19-B3FC-DF5B83DBF8F4} 63 | PNet 64 | 65 | 66 | {D2D2F82B-3456-4E91-AD1B-8A52D71F233D} 67 | PNet.Testing.Common 68 | 69 | 70 | 71 | 72 | Always 73 | 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /TraceAndTestImpact.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are test settings for Trace and Test Impact. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /directions for lidgren and slimmath projects.txt: -------------------------------------------------------------------------------- 1 | lidgren: 2 | 3 | svn checkout http://lidgren-network-gen3.googlecode.com/svn/trunk/Lidgren.Network 4 | 5 | into a new folder named 6 | 7 | Lidgren.Network 8 | 9 | in this folder, then apply the lidgren_patch.patch to that folder. 10 | 11 | 12 | SlimMath: 13 | 14 | svn checkout http://slimmath.googlecode.com/svn/trunk/SlimMath 15 | 16 | into a new folder named 17 | 18 | SlimMath 19 | 20 | in this folder, then apply the slimmath_patch.patch to that folder 21 | 22 | 23 | 24 | 25 | After you are done, you should have at least the following folders: 26 | 27 | Example 28 | lib 29 | Lidgren.Network 30 | PNet 31 | PNetC 32 | PNetS 33 | PNetU 34 | SlimMath 35 | Tests 36 | -------------------------------------------------------------------------------- /lib/UnityEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/lib/UnityEngine.dll -------------------------------------------------------------------------------- /lib/YamlSerializer.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbruening/PNet/95fa1ad83c4ffef0f60df0a32ccf6e3a15d6f2f2/lib/YamlSerializer.dll --------------------------------------------------------------------------------