diff --git a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Config.cs b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Config.cs index a961dca..683e3f9 100644 --- a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Config.cs +++ b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Config.cs @@ -12,5 +12,6 @@ namespace LightReflectiveMirror.LoadBalancing public string AuthKey = "AuthKey"; public ushort EndpointPort = 7070; public bool ShowDebugLogs = false; + public int RandomlyGeneratedIDLength = 5; } } diff --git a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/Program.cs b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/Program.cs index f07b874..910f428 100644 --- a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/Program.cs +++ b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/Program.cs @@ -23,6 +23,8 @@ namespace LightReflectiveMirror.LoadBalancing const string API_PATH = "/api/stats"; readonly string CONFIG_PATH = System.Environment.GetEnvironmentVariable("LRM_LB_CONFIG_PATH") ?? "config.json"; + private Random _cachedRandom = new(); + public static Config conf; public static Program instance; diff --git a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/ProgramExtra.cs b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/ProgramExtra.cs index 84c17f7..02adf21 100644 --- a/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/ProgramExtra.cs +++ b/LoadBalancerProject-DONT-IMPORT-INTO-UNITY/LRM_LoadBalancer/Program/ProgramExtra.cs @@ -28,14 +28,13 @@ namespace LightReflectiveMirror.LoadBalancing public string GenerateServerID() { - const int LENGTH = 5; const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var randomID = ""; + var random = _cachedRandom; do { - var random = new System.Random(); - randomID = new string(Enumerable.Repeat(chars, LENGTH) + randomID = new string(Enumerable.Repeat(chars, conf.RandomlyGeneratedIDLength) .Select(s => s[random.Next(s.Length)]).ToArray()); } while (cachedRooms.ContainsKey(randomID)); diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Config.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Config.cs index 38227e1..7578ffd 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Config.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Config.cs @@ -1,5 +1,7 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Text; namespace LightReflectiveMirror @@ -9,12 +11,15 @@ namespace LightReflectiveMirror //======================== // Required Settings //======================== - public string TransportDLL = "MultiCompiled.dll"; public string TransportClass = "kcp2k.KcpTransport"; public string AuthenticationKey = "Secret Auth Key"; public ushort TransportPort = 7777; public int UpdateLoopTime = 10; public int UpdateHeartbeatInterval = 100; + + // this wont be used if you are using load balancer + // load balancer will generate instead. + public int RandomlyGeneratedIDLength = 5; //======================== // Endpoint REST API Settings @@ -37,5 +42,10 @@ namespace LightReflectiveMirror public string LoadBalancerAddress = "127.0.0.1"; public ushort LoadBalancerPort = 7070; public LRMRegions LoadBalancerRegion = LRMRegions.NorthAmerica; + + public static string GetTransportDLL() + { + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "MultiCompiled_WIN.dll" : "MultiCompiled_LINUX.dll"; + } } } diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs index dc203ab..3a5b6a3 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs @@ -41,7 +41,7 @@ namespace LightReflectiveMirror WriteLogMessage("Loading Assembly... ", ConsoleColor.White, true); try { - var asm = Assembly.LoadFile(Path.GetFullPath(conf.TransportDLL)); + var asm = Assembly.LoadFile(Path.GetFullPath(Config.GetTransportDLL())); WriteLogMessage($"OK", ConsoleColor.Green); WriteLogMessage("\nLoading Transport Class... ", ConsoleColor.White, true); diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs index 5e800f2..2839a1b 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs @@ -9,7 +9,7 @@ namespace LightReflectiveMirror // constructor for new relay handler public RelayHandler(int maxPacketSize) { - this._maxPacketSize = maxPacketSize; + _maxPacketSize = maxPacketSize; _sendBuffers = ArrayPool.Create(maxPacketSize, 50); } @@ -22,14 +22,13 @@ namespace LightReflectiveMirror private string GenerateRoomID() { - const int LENGTH = 5; const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var randomID = ""; var random = _cachedRandom; do { - randomID = new string(Enumerable.Repeat(chars, LENGTH) + randomID = new string(Enumerable.Repeat(chars, Program.conf.RandomlyGeneratedIDLength) .Select(s => s[random.Next(s.Length)]).ToArray()); } while (DoesServerIdExist(randomID)); @@ -74,7 +73,7 @@ namespace LightReflectiveMirror { if (room.clients.Contains(sendTo)) { - SendData(clientData, channel, sendTo); + SendData(clientData, channel, sendTo, clientId); } } else @@ -84,11 +83,22 @@ namespace LightReflectiveMirror } } - private void SendData(byte[] clientData, int channel, int sendTo) + private void SendData(byte[] clientData, int channel, int sendTo, int senderId) { - int pos = 0; - byte[] sendBuffer = _sendBuffers.Rent(_maxPacketSize); + // 1 byte for opcode + var headerLength = 1; + var payloadLength = headerLength + clientData.Length; + if (payloadLength > _maxPacketSize) + { + Program.transport.ServerDisconnect(senderId); + Program.WriteLogMessage($"Client {senderId} tried to send more than max packet size! Disconnecting..."); + return; + } + + int pos = 0; + byte[] sendBuffer = _sendBuffers.Rent(payloadLength); + sendBuffer.WriteByte(ref pos, (byte)OpCodes.GetData); sendBuffer.WriteBytes(ref pos, clientData); @@ -96,15 +106,26 @@ namespace LightReflectiveMirror _sendBuffers.Return(sendBuffer); } - private void SendDataToRoomHost(int clientId, byte[] clientData, int channel, Room room) + private void SendDataToRoomHost(int senderId, byte[] clientData, int channel, Room room) { + // 1 byte - opcode, 4 bytes for sizeof(int) client id + var headerLength = 5; + var payloadLength = headerLength + clientData.Length; + + if(payloadLength > _maxPacketSize) + { + Program.transport.ServerDisconnect(senderId); + Program.WriteLogMessage($"Client {senderId} tried to send more than max packet size! Disconnecting..."); + return; + } + // We are not the host, so send the data to the host. - int pos = 0; - byte[] sendBuffer = _sendBuffers.Rent(_maxPacketSize); + int pos = 0; + byte[] sendBuffer = _sendBuffers.Rent(payloadLength); sendBuffer.WriteByte(ref pos, (byte)OpCodes.GetData); sendBuffer.WriteBytes(ref pos, clientData); - sendBuffer.WriteInt(ref pos, clientId); + sendBuffer.WriteInt(ref pos, senderId); Program.transport.ServerSend(room.hostId, channel, new ArraySegment(sendBuffer, 0, pos)); _sendBuffers.Return(sendBuffer); diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerCallbacks.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerCallbacks.cs index 2bfe4a2..c7f2da9 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerCallbacks.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerCallbacks.cs @@ -58,8 +58,15 @@ namespace LightReflectiveMirror switch (opcode) { - case OpCodes.CreateRoom: - CreateRoom(clientId, data.ReadInt(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadInt(ref pos)); + case OpCodes.CreateRoom: // bruh + CreateRoom(clientId, data.ReadInt (ref pos), + data.ReadString(ref pos), + data.ReadBool (ref pos), + data.ReadString(ref pos), + data.ReadBool (ref pos), + data.ReadString(ref pos), + data.ReadBool (ref pos), + data.ReadInt (ref pos)); break; case OpCodes.RequestID: SendClientID(clientId); @@ -100,7 +107,9 @@ namespace LightReflectiveMirror } catch { - // Do Nothing. Client probably sent some invalid data. + // sent invalid data, boot them hehe + Program.WriteLogMessage($"Client {clientId} sent bad data! Removing from LRM node."); + Program.transport.ServerDisconnect(clientId); } } diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerRoomMethods.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerRoomMethods.cs index 622d69a..c0668a3 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerRoomMethods.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerRoomMethods.cs @@ -98,7 +98,7 @@ namespace LightReflectiveMirror { sendJoinPos = 0; sendJoinBuffer.WriteByte(ref sendJoinPos, (byte)OpCodes.DirectConnectIP); - Console.WriteLine(Program.instance.NATConnections[clientId].Address.ToString()); + sendJoinBuffer.WriteString(ref sendJoinPos, Program.instance.NATConnections[clientId].Address.ToString()); sendJoinBuffer.WriteInt(ref sendJoinPos, Program.instance.NATConnections[clientId].Port); sendJoinBuffer.WriteBool(ref sendJoinPos, true); diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceClient.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceClient.cs new file mode 100644 index 0000000..f5b902b --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceClient.cs @@ -0,0 +1,288 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. + +using ENet; +// using NetStack.Buffers; +using System; +using System.Collections.Concurrent; +using System.Threading; +using Event = ENet.Event; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using EventType = ENet.EventType; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using Object = System.Object; // fixes CS0104 ambigous reference between the same thing in UnityEngine + +namespace IgnoranceTransport +{ + public class IgnoranceClient + { + // Client connection address and port + public string ConnectAddress = "127.0.0.1"; + public int ConnectPort = 7777; + // How many channels are expected + public int ExpectedChannels = 2; + // Native poll waiting time + public int PollTime = 1; + // Maximum Packet Size + public int MaximumPacketSize = 33554432; + // General Verbosity by default. + public int Verbosity = 1; + + // Queues + public ConcurrentQueue Incoming = new ConcurrentQueue(); + public ConcurrentQueue Outgoing = new ConcurrentQueue(); + public ConcurrentQueue Commands = new ConcurrentQueue(); + public ConcurrentQueue ConnectionEvents = new ConcurrentQueue(); + public ConcurrentQueue StatusUpdates = new ConcurrentQueue(); + + public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive; + + private volatile bool CeaseOperation = false; + private Thread WorkerThread; + + public void Start() + { + // Debug.Log("IgnoranceClient.Start()"); + + if (WorkerThread != null && WorkerThread.IsAlive) + { + // Cannot do that. + // Debug.LogError("A worker thread is already running. Cannot start another."); + return; + } + + CeaseOperation = false; + ThreadParamInfo threadParams = new ThreadParamInfo() + { + Address = ConnectAddress, + Port = ConnectPort, + Channels = ExpectedChannels, + PollTime = PollTime, + PacketSizeLimit = MaximumPacketSize, + Verbosity = Verbosity + }; + + // Drain queues. + if (Incoming != null) while (Incoming.TryDequeue(out _)) ; + if (Outgoing != null) while (Outgoing.TryDequeue(out _)) ; + if (Commands != null) while (Commands.TryDequeue(out _)) ; + if (ConnectionEvents != null) while (ConnectionEvents.TryDequeue(out _)) ; + if (StatusUpdates != null) while (StatusUpdates.TryDequeue(out _)) ; + + WorkerThread = new Thread(ThreadWorker); + WorkerThread.Start(threadParams); + + // Debug.Log("Client has dispatched worker thread."); + } + + public void Stop() + { + // Debug.Log("Telling client thread to stop, this may take a while depending on network load"); + CeaseOperation = true; + } + + // This runs in a seperate thread, be careful accessing anything outside of it's thread + // or you may get an AccessViolation/crash. + private void ThreadWorker(Object parameters) + { + // if (Verbosity > 0) + // Debug.Log("Ignorance Client: Initializing. Please stand by..."); + + ThreadParamInfo setupInfo; + Address clientAddress = new Address(); + Peer clientPeer; + Host clientENetHost; + Event clientENetEvent; + IgnoranceClientStats icsu = default; + + // Grab the setup information. + if (parameters.GetType() == typeof(ThreadParamInfo)) + { + setupInfo = (ThreadParamInfo)parameters; + } + else + { + // Debug.LogError("Ignorance Client: Startup failure: Invalid thread parameters. Aborting."); + return; + } + + // Attempt to initialize ENet inside the thread. + if (Library.Initialize()) + { + Console.WriteLine("Ignorance Client: ENet initialized."); + } + else + { + // Debug.LogError("Ignorance Client: Failed to initialize ENet. This threads' fucked."); + return; + } + + // Attempt to connect to our target. + clientAddress.SetHost(setupInfo.Address); + clientAddress.Port = (ushort)setupInfo.Port; + + using (clientENetHost = new Host()) + { + // TODO: Maybe try catch this + clientENetHost.Create(); + clientPeer = clientENetHost.Connect(clientAddress, setupInfo.Channels); + + while (!CeaseOperation) + { + bool pollComplete = false; + + // Step 0: Handle commands. + while (Commands.TryDequeue(out IgnoranceCommandPacket commandPacket)) + { + switch (commandPacket.Type) + { + default: + break; + + case IgnoranceCommandType.ClientWantsToStop: + CeaseOperation = true; + break; + + case IgnoranceCommandType.ClientRequestsStatusUpdate: + // Respond with statistics so far. + if (!clientPeer.IsSet) + break; + + icsu.RTT = clientPeer.RoundTripTime; + + icsu.BytesReceived = clientPeer.BytesReceived; + icsu.BytesSent = clientPeer.BytesSent; + + icsu.PacketsReceived = clientENetHost.PacketsReceived; + icsu.PacketsSent = clientPeer.PacketsSent; + icsu.PacketsLost = clientPeer.PacketsLost; + + StatusUpdates.Enqueue(icsu); + break; + } + } + // Step 1: Send out data. + // ---> Sending to Server + while (Outgoing.TryDequeue(out IgnoranceOutgoingPacket outgoingPacket)) + { + // TODO: Revise this, could we tell the Peer to disconnect right here? + // Stop early if we get a client stop packet. + // if (outgoingPacket.Type == IgnorancePacketType.ClientWantsToStop) break; + + int ret = clientPeer.Send(outgoingPacket.Channel, ref outgoingPacket.Payload); + + } + + // Step 2: + // <----- Receive Data packets + // This loops until polling is completed. It may take a while, if it's + // a slow networking day. + while (!pollComplete) + { + Packet incomingPacket; + Peer incomingPeer; + int incomingPacketLength; + + // Any events worth checking out? + if (clientENetHost.CheckEvents(out clientENetEvent) <= 0) + { + // If service time is met, break out of it. + if (clientENetHost.Service(setupInfo.PollTime, out clientENetEvent) <= 0) break; + + // Poll is done. + pollComplete = true; + } + + // Setup the packet references. + incomingPeer = clientENetEvent.Peer; + + // Now, let's handle those events. + switch (clientENetEvent.Type) + { + case EventType.None: + default: + break; + + case EventType.Connect: + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + NativePeerId = incomingPeer.ID, + IP = incomingPeer.IP, + Port = incomingPeer.Port + }); + break; + + case EventType.Disconnect: + case EventType.Timeout: + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + WasDisconnect = true + }); + break; + + + case EventType.Receive: + // Receive event type usually includes a packet; so cache its reference. + incomingPacket = clientENetEvent.Packet; + + if (!incomingPacket.IsSet) + { + + break; + } + + incomingPacketLength = incomingPacket.Length; + + // Never consume more than we can have capacity for. + if (incomingPacketLength > setupInfo.PacketSizeLimit) + { + + incomingPacket.Dispose(); + break; + } + + IgnoranceIncomingPacket incomingQueuePacket = new IgnoranceIncomingPacket + { + Channel = clientENetEvent.ChannelID, + NativePeerId = incomingPeer.ID, + Payload = incomingPacket + }; + + Incoming.Enqueue(incomingQueuePacket); + break; + } + } + } + + Console.WriteLine("Ignorance Server: Shutdown commencing, disconnecting and flushing connection."); + + // Flush the client and disconnect. + clientPeer.Disconnect(0); + clientENetHost.Flush(); + + // Fix for client stuck in limbo, since the disconnection event may not be fired until next loop. + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + WasDisconnect = true + }); + } + + // Deinitialize + Library.Deinitialize(); + } + + + private struct ThreadParamInfo + { + public int Channels; + public int PollTime; + public int Port; + public int PacketSizeLimit; + public int Verbosity; + public string Address; + } + } +} diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceServer.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceServer.cs new file mode 100644 index 0000000..0e7bae9 --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Core/IgnoranceServer.cs @@ -0,0 +1,303 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. + +using ENet; +// using NetStack.Buffers; +using System.Collections.Concurrent; +using System.Threading; +using Event = ENet.Event; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using EventType = ENet.EventType; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using Object = System.Object; // fixes CS0104 ambigous reference between the same thing in UnityEngine + +namespace IgnoranceTransport +{ + public class IgnoranceServer + { + // Server Properties + // - Bind Settings + public string BindAddress = "127.0.0.1"; + public int BindPort = 7777; + // - Maximum allowed channels, peers, etc. + public int MaximumChannels = 2; + public int MaximumPeers = 100; + public int MaximumPacketSize = 33554432; // ENet.cs: uint maxPacketSize = 32 * 1024 * 1024 = 33554432 + // - Native poll waiting time + public int PollTime = 1; + public int Verbosity = 1; + + public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive; + + private volatile bool CeaseOperation = false; + + // Queues + public ConcurrentQueue Incoming = new ConcurrentQueue(); + public ConcurrentQueue Outgoing = new ConcurrentQueue(); + public ConcurrentQueue Commands = new ConcurrentQueue(); + public ConcurrentQueue ConnectionEvents = new ConcurrentQueue(); + public ConcurrentQueue DisconnectionEvents = new ConcurrentQueue(); + + // Thread + private Thread WorkerThread; + + public void Start() + { + if (WorkerThread != null && WorkerThread.IsAlive) + { + // Cannot do that. + + return; + } + + CeaseOperation = false; + ThreadParamInfo threadParams = new ThreadParamInfo() + { + Address = BindAddress, + Port = BindPort, + Peers = MaximumPeers, + Channels = MaximumChannels, + PollTime = PollTime, + PacketSizeLimit = MaximumPacketSize, + Verbosity = Verbosity + }; + + // Drain queues. + if (Incoming != null) while (Incoming.TryDequeue(out _)) ; + if (Outgoing != null) while (Outgoing.TryDequeue(out _)) ; + if (Commands != null) while (Commands.TryDequeue(out _)) ; + if (ConnectionEvents != null) while (ConnectionEvents.TryDequeue(out _)) ; + if (DisconnectionEvents != null) while (DisconnectionEvents.TryDequeue(out _)) ; + + WorkerThread = new Thread(ThreadWorker); + WorkerThread.Start(threadParams); + + + } + + public void Stop() + { + + CeaseOperation = true; + } + + private void ThreadWorker(Object parameters) + { + + // Thread cache items + ThreadParamInfo setupInfo; + Address serverAddress = new Address(); + Host serverENetHost; + Event serverENetEvent; + + Peer[] serverPeerArray; + + // Grab the setup information. + if (parameters.GetType() == typeof(ThreadParamInfo)) + { + setupInfo = (ThreadParamInfo)parameters; + } + else + { + return; + } + + // Attempt to initialize ENet inside the thread. + if (Library.Initialize()) + { + + } + else + { + + return; + } + + // Configure the server address. + serverAddress.SetHost(setupInfo.Address); + serverAddress.Port = (ushort)setupInfo.Port; + serverPeerArray = new Peer[setupInfo.Peers]; + + using (serverENetHost = new Host()) + { + // Create the server object. + serverENetHost.Create(serverAddress, setupInfo.Peers, setupInfo.Channels); + + // Loop until we're told to cease operations. + while (!CeaseOperation) + { + // Intermission: Command Handling + while (Commands.TryDequeue(out IgnoranceCommandPacket commandPacket)) + { + switch (commandPacket.Type) + { + default: + break; + + // Boot a Peer off the Server. + case IgnoranceCommandType.ServerKickPeer: + uint targetPeer = commandPacket.PeerId; + + if (!serverPeerArray[targetPeer].IsSet) continue; + + IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent() + { + WasDisconnect = true, + NativePeerId = targetPeer + }; + + DisconnectionEvents.Enqueue(iced); + + // Disconnect and reset the peer array's entry for that peer. + serverPeerArray[targetPeer].DisconnectNow(0); + serverPeerArray[targetPeer] = default; + break; + } + } + + // Step One: + // ---> Sending to peers + while (Outgoing.TryDequeue(out IgnoranceOutgoingPacket outgoingPacket)) + { + // Only create a packet if the server knows the peer. + if (serverPeerArray[outgoingPacket.NativePeerId].IsSet) + { + int ret = serverPeerArray[outgoingPacket.NativePeerId].Send(outgoingPacket.Channel, ref outgoingPacket.Payload); + + } + else + { + // A peer might have disconnected, this is OK - just log the packet if set to paranoid. + + } + + } + + // Step 2 + // <--- Receiving from peers + bool pollComplete = false; + + while (!pollComplete) + { + Packet incomingPacket; + Peer incomingPeer; + int incomingPacketLength; + + // Any events happening? + if (serverENetHost.CheckEvents(out serverENetEvent) <= 0) + { + // If service time is met, break out of it. + if (serverENetHost.Service(setupInfo.PollTime, out serverENetEvent) <= 0) break; + + pollComplete = true; + } + + // Setup the packet references. + incomingPeer = serverENetEvent.Peer; + + switch (serverENetEvent.Type) + { + // Idle. + case EventType.None: + default: + break; + + // Connection Event. + case EventType.Connect: + IgnoranceConnectionEvent ice = new IgnoranceConnectionEvent() + { + NativePeerId = incomingPeer.ID, + IP = incomingPeer.IP, + Port = incomingPeer.Port + }; + + ConnectionEvents.Enqueue(ice); + + // Assign a reference to the Peer. + serverPeerArray[incomingPeer.ID] = incomingPeer; + break; + + // Disconnect/Timeout. Mirror doesn't care if it's either, so we lump them together. + case EventType.Disconnect: + case EventType.Timeout: + if (!serverPeerArray[incomingPeer.ID].IsSet) break; + + IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent() + { + WasDisconnect = true, + NativePeerId = incomingPeer.ID + }; + + DisconnectionEvents.Enqueue(iced); + + // Reset the peer array's entry for that peer. + serverPeerArray[incomingPeer.ID] = default; + break; + + case EventType.Receive: + // Receive event type usually includes a packet; so cache its reference. + incomingPacket = serverENetEvent.Packet; + if (!incomingPacket.IsSet) + { + + break; + } + + incomingPacketLength = incomingPacket.Length; + + // Firstly check if the packet is too big. If it is, do not process it - drop it. + if (incomingPacketLength > setupInfo.PacketSizeLimit) + { + + incomingPacket.Dispose(); + break; + } + + IgnoranceIncomingPacket incomingQueuePacket = new IgnoranceIncomingPacket + { + Channel = serverENetEvent.ChannelID, + NativePeerId = incomingPeer.ID, + Payload = incomingPacket, + }; + + // Enqueue. + Incoming.Enqueue(incomingQueuePacket); + break; + } + } + } + + + // Cleanup and flush everything. + serverENetHost.Flush(); + + // Kick everyone. + for (int i = 0; i < serverPeerArray.Length; i++) + { + if (!serverPeerArray[i].IsSet) continue; + serverPeerArray[i].DisconnectNow(0); + } + } + + // Flush again to ensure ENet gets those Disconnection stuff out. + // May not be needed; better to err on side of caution + + + Library.Deinitialize(); + } + + private struct ThreadParamInfo + { + public int Channels; + public int Peers; + public int PollTime; + public int Port; + public int PacketSizeLimit; + public int Verbosity; + public string Address; + } + } +} diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Dependencies/ENet.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Dependencies/ENet.cs new file mode 100644 index 0000000..564c4b5 --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Dependencies/ENet.cs @@ -0,0 +1,1385 @@ +/* + * Managed C# wrapper for an extended version of ENet + * This is a fork from upstream and is available at http://github.com/SoftwareGuy/ENet-CSharp + * + * Copyright (c) 2019 Matt Coburn (SoftwareGuy/Coburn64), Chris Burns (c6burns) + * Copyright (c) 2013 James Bellinger, 2016 Nate Shoffner, 2018 Stanislav Denisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace ENet +{ + [Flags] + public enum PacketFlags + { + None = 0, + Reliable = 1 << 0, + Unsequenced = 1 << 1, + NoAllocate = 1 << 2, + UnreliableFragmented = 1 << 3, + Instant = 1 << 4, + Unthrottled = 1 << 5, + Sent = 1 << 8 + } + + public enum EventType + { + None = 0, + Connect = 1, + Disconnect = 2, + Receive = 3, + Timeout = 4 + } + + public enum PeerState + { + Uninitialized = -1, + Disconnected = 0, + Connecting = 1, + AcknowledgingConnect = 2, + ConnectionPending = 3, + ConnectionSucceeded = 4, + Connected = 5, + DisconnectLater = 6, + Disconnecting = 7, + AcknowledgingDisconnect = 8, + Zombie = 9 + } + + [StructLayout(LayoutKind.Explicit, Size = 18)] + internal struct ENetAddress + { + [FieldOffset(16)] + public ushort port; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ENetEvent + { + public EventType type; + public IntPtr peer; + public byte channelID; + public uint data; + public IntPtr packet; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ENetCallbacks + { + public AllocCallback malloc; + public FreeCallback free; + public NoMemoryCallback noMemory; + } + + public delegate IntPtr AllocCallback(IntPtr size); + public delegate void FreeCallback(IntPtr memory); + public delegate void NoMemoryCallback(); + public delegate void PacketFreeCallback(Packet packet); + public delegate int InterceptCallback(ref Event @event, ref Address address, IntPtr receivedData, int receivedDataLength); + public delegate ulong ChecksumCallback(IntPtr buffers, int bufferCount); + + internal static class ArrayPool + { + [ThreadStatic] + private static byte[] byteBuffer; + [ThreadStatic] + private static IntPtr[] pointerBuffer; + + public static byte[] GetByteBuffer() + { + if (byteBuffer == null) + byteBuffer = new byte[64]; + + return byteBuffer; + } + + public static IntPtr[] GetPointerBuffer() + { + if (pointerBuffer == null) + pointerBuffer = new IntPtr[Library.maxPeers]; + + return pointerBuffer; + } + } + + public struct Address + { + private ENetAddress nativeAddress; + + internal ENetAddress NativeData + { + get + { + return nativeAddress; + } + + set + { + nativeAddress = value; + } + } + + internal Address(ENetAddress address) + { + nativeAddress = address; + } + + public ushort Port + { + get + { + return nativeAddress.port; + } + + set + { + nativeAddress.port = value; + } + } + + public string GetIP() + { + StringBuilder ip = new StringBuilder(1025); + + if (Native.enet_address_get_ip(ref nativeAddress, ip, (IntPtr)ip.Capacity) != 0) + return String.Empty; + + return ip.ToString(); + } + + public bool SetIP(string ip) + { + if (ip == null) + throw new ArgumentNullException("ip"); + + return Native.enet_address_set_ip(ref nativeAddress, ip) == 0; + } + + public string GetHost() + { + StringBuilder hostName = new StringBuilder(1025); + + if (Native.enet_address_get_hostname(ref nativeAddress, hostName, (IntPtr)hostName.Capacity) != 0) + return String.Empty; + + return hostName.ToString(); + } + + public bool SetHost(string hostName) + { + if (hostName == null) + throw new ArgumentNullException("hostName"); + + return Native.enet_address_set_hostname(ref nativeAddress, hostName) == 0; + } + } + + public struct Event + { + private ENetEvent nativeEvent; + + internal ENetEvent NativeData + { + get + { + return nativeEvent; + } + + set + { + nativeEvent = value; + } + } + + internal Event(ENetEvent @event) + { + nativeEvent = @event; + } + + public EventType Type + { + get + { + return nativeEvent.type; + } + } + + public Peer Peer + { + get + { + return new Peer(nativeEvent.peer); + } + } + + public byte ChannelID + { + get + { + return nativeEvent.channelID; + } + } + + public uint Data + { + get + { + return nativeEvent.data; + } + } + + public Packet Packet + { + get + { + return new Packet(nativeEvent.packet); + } + } + } + + public class Callbacks + { + private ENetCallbacks nativeCallbacks; + + internal ENetCallbacks NativeData + { + get + { + return nativeCallbacks; + } + + set + { + nativeCallbacks = value; + } + } + + public Callbacks(AllocCallback allocCallback, FreeCallback freeCallback, NoMemoryCallback noMemoryCallback) + { + nativeCallbacks.malloc = allocCallback; + nativeCallbacks.free = freeCallback; + nativeCallbacks.noMemory = noMemoryCallback; + } + } + + public struct Packet : IDisposable + { + private IntPtr nativePacket; + + internal IntPtr NativeData + { + get + { + return nativePacket; + } + + set + { + nativePacket = value; + } + } + + internal Packet(IntPtr packet) + { + nativePacket = packet; + } + + public void Dispose() + { + if (nativePacket != IntPtr.Zero) + { + Native.enet_packet_dispose(nativePacket); + nativePacket = IntPtr.Zero; + } + } + + public bool IsSet + { + get + { + return nativePacket != IntPtr.Zero; + } + } + + public IntPtr Data + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_data(nativePacket); + } + } + + public IntPtr UserData + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_user_data(nativePacket); + } + + set + { + ThrowIfNotCreated(); + + Native.enet_packet_set_user_data(nativePacket, value); + } + } + + public int Length + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_length(nativePacket); + } + } + + public bool HasReferences + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_check_references(nativePacket) != 0; + } + } + + internal void ThrowIfNotCreated() + { + if (nativePacket == IntPtr.Zero) + throw new InvalidOperationException("Packet not created"); + } + + public void SetFreeCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_packet_set_free_callback(nativePacket, callback); + } + + public void SetFreeCallback(PacketFreeCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_packet_set_free_callback(nativePacket, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void Create(byte[] data) + { + if (data == null) + throw new ArgumentNullException("data"); + + Create(data, data.Length); + } + + public void Create(byte[] data, int length) + { + Create(data, length, PacketFlags.None); + } + + public void Create(byte[] data, PacketFlags flags) + { + Create(data, data.Length, flags); + } + + public void Create(byte[] data, int length, PacketFlags flags) + { + if (data == null) + throw new ArgumentNullException("data"); + + if (length < 0 || length > data.Length) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create(data, (IntPtr)length, flags); + } + + public void Create(IntPtr data, int length, PacketFlags flags) + { + if (data == IntPtr.Zero) + throw new ArgumentNullException("data"); + + if (length < 0) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create(data, (IntPtr)length, flags); + } + + public void Create(byte[] data, int offset, int length, PacketFlags flags) + { + if (data == null) + throw new ArgumentNullException("data"); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + + if (length < 0 || length > data.Length) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create_offset(data, (IntPtr)length, (IntPtr)offset, flags); + } + + public void Create(IntPtr data, int offset, int length, PacketFlags flags) + { + if (data == IntPtr.Zero) + throw new ArgumentNullException("data"); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + + if (length < 0) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create_offset(data, (IntPtr)length, (IntPtr)offset, flags); + } + + public void CopyTo(byte[] destination, int startPos = 0) + { + if (destination == null) + throw new ArgumentNullException("destination"); + + // Fix by katori, prevents trying to copy a NULL + // from native world (ie. disconnect a client) + if (Data == null) + { + return; + } + + Marshal.Copy(Data, destination, startPos, Length); + } + } + + public class Host : IDisposable + { + private IntPtr nativeHost; + + internal IntPtr NativeData + { + get + { + return nativeHost; + } + + set + { + nativeHost = value; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (nativeHost != IntPtr.Zero) + { + Native.enet_host_destroy(nativeHost); + nativeHost = IntPtr.Zero; + } + } + + ~Host() + { + Dispose(false); + } + + public bool IsSet + { + get + { + return nativeHost != IntPtr.Zero; + } + } + + public uint PeersCount + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_peers_count(nativeHost); + } + } + + public uint PacketsSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_packets_sent(nativeHost); + } + } + + public uint PacketsReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_packets_received(nativeHost); + } + } + + public uint BytesSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_bytes_sent(nativeHost); + } + } + + public uint BytesReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_bytes_received(nativeHost); + } + } + + internal void ThrowIfNotCreated() + { + if (nativeHost == IntPtr.Zero) + throw new InvalidOperationException("Host not created"); + } + + private static void ThrowIfChannelsExceeded(int channelLimit) + { + if (channelLimit < 0 || channelLimit > Library.maxChannelCount) + throw new ArgumentOutOfRangeException("channelLimit"); + } + + public void Create() + { + Create(null, 1, 0); + } + + public void Create(int bufferSize) + { + Create(null, 1, 0, 0, 0, bufferSize); + } + + public void Create(Address? address, int peerLimit) + { + Create(address, peerLimit, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit) + { + Create(address, peerLimit, channelLimit, 0, 0, 0); + } + + public void Create(int peerLimit, int channelLimit) + { + Create(null, peerLimit, channelLimit, 0, 0, 0); + } + + public void Create(int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth) + { + Create(null, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth) + { + Create(address, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize) + { + if (nativeHost != IntPtr.Zero) + throw new InvalidOperationException("Host already created"); + + if (peerLimit < 0 || peerLimit > Library.maxPeers) + throw new ArgumentOutOfRangeException("peerLimit"); + + ThrowIfChannelsExceeded(channelLimit); + + if (address != null) + { + var nativeAddress = address.Value.NativeData; + + nativeHost = Native.enet_host_create(ref nativeAddress, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth, outgoingBandwidth, bufferSize); + } + else + { + nativeHost = Native.enet_host_create(IntPtr.Zero, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth, outgoingBandwidth, bufferSize); + } + + if (nativeHost == IntPtr.Zero) + throw new InvalidOperationException("Host creation call failed"); + } + + public void PreventConnections(bool state) + { + ThrowIfNotCreated(); + + Native.enet_host_prevent_connections(nativeHost, (byte)(state ? 1 : 0)); + } + + public void Broadcast(byte channelID, ref Packet packet) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + Native.enet_host_broadcast(nativeHost, channelID, packet.NativeData); + packet.NativeData = IntPtr.Zero; + } + + public void Broadcast(byte channelID, ref Packet packet, Peer excludedPeer) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + Native.enet_host_broadcast_exclude(nativeHost, channelID, packet.NativeData, excludedPeer.NativeData); + packet.NativeData = IntPtr.Zero; + } + + public void Broadcast(byte channelID, ref Packet packet, Peer[] peers) + { + if (peers == null) + throw new ArgumentNullException("peers"); + + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + + if (peers.Length > 0) + { + IntPtr[] nativePeers = ArrayPool.GetPointerBuffer(); + int nativeCount = 0; + + for (int i = 0; i < peers.Length; i++) + { + if (peers[i].NativeData != IntPtr.Zero) + { + nativePeers[nativeCount] = peers[i].NativeData; + nativeCount++; + } + } + + Native.enet_host_broadcast_selective(nativeHost, channelID, packet.NativeData, nativePeers, (IntPtr)nativeCount); + } + + packet.NativeData = IntPtr.Zero; + } + + public int CheckEvents(out Event @event) + { + ThrowIfNotCreated(); + + ENetEvent nativeEvent; + + var result = Native.enet_host_check_events(nativeHost, out nativeEvent); + + if (result <= 0) + { + @event = default(Event); + + return result; + } + + @event = new Event(nativeEvent); + + return result; + } + + public Peer Connect(Address address) + { + return Connect(address, 0, 0); + } + + public Peer Connect(Address address, int channelLimit) + { + return Connect(address, channelLimit, 0); + } + + public Peer Connect(Address address, int channelLimit, uint data) + { + ThrowIfNotCreated(); + ThrowIfChannelsExceeded(channelLimit); + + var nativeAddress = address.NativeData; + var peer = new Peer(Native.enet_host_connect(nativeHost, ref nativeAddress, (IntPtr)channelLimit, data)); + + if (peer.NativeData == IntPtr.Zero) + throw new InvalidOperationException("Host connect call failed"); + + return peer; + } + + public int Service(int timeout, out Event @event) + { + if (timeout < 0) + throw new ArgumentOutOfRangeException("timeout"); + + ThrowIfNotCreated(); + + ENetEvent nativeEvent; + + var result = Native.enet_host_service(nativeHost, out nativeEvent, (uint)timeout); + + if (result <= 0) + { + @event = default(Event); + + return result; + } + + @event = new Event(nativeEvent); + + return result; + } + + public void SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth) + { + ThrowIfNotCreated(); + + Native.enet_host_bandwidth_limit(nativeHost, incomingBandwidth, outgoingBandwidth); + } + + public void SetChannelLimit(int channelLimit) + { + ThrowIfNotCreated(); + ThrowIfChannelsExceeded(channelLimit); + + Native.enet_host_channel_limit(nativeHost, (IntPtr)channelLimit); + } + + public void SetMaxDuplicatePeers(ushort number) + { + ThrowIfNotCreated(); + + Native.enet_host_set_max_duplicate_peers(nativeHost, number); + } + + public void SetInterceptCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, callback); + } + + public void SetInterceptCallback(InterceptCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void SetChecksumCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_checksum_callback(nativeHost, callback); + } + + public void SetChecksumCallback(ChecksumCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_checksum_callback(nativeHost, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void Flush() + { + ThrowIfNotCreated(); + + Native.enet_host_flush(nativeHost); + } + } + + public struct Peer + { + private IntPtr nativePeer; + private uint nativeID; + + internal IntPtr NativeData + { + get + { + return nativePeer; + } + + set + { + nativePeer = value; + } + } + + internal Peer(IntPtr peer) + { + nativePeer = peer; + nativeID = nativePeer != IntPtr.Zero ? Native.enet_peer_get_id(nativePeer) : 0; + } + + public bool IsSet + { + get + { + return nativePeer != IntPtr.Zero; + } + } + + public uint ID + { + get + { + return nativeID; + } + } + + public string IP + { + get + { + ThrowIfNotCreated(); + + byte[] ip = ArrayPool.GetByteBuffer(); + + if (Native.enet_peer_get_ip(nativePeer, ip, (IntPtr)ip.Length) == 0) + return Encoding.ASCII.GetString(ip, 0, ip.StringLength()); + else + return String.Empty; + } + } + + public ushort Port + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_port(nativePeer); + } + } + + public uint MTU + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_mtu(nativePeer); + } + } + + public PeerState State + { + get + { + return nativePeer == IntPtr.Zero ? PeerState.Uninitialized : Native.enet_peer_get_state(nativePeer); + } + } + + public uint RoundTripTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_rtt(nativePeer); + } + } + + public uint LastRoundTripTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_last_rtt(nativePeer); + } + } + + public uint LastSendTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_lastsendtime(nativePeer); + } + } + + public uint LastReceiveTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_lastreceivetime(nativePeer); + } + } + + public ulong PacketsSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_sent(nativePeer); + } + } + + public ulong PacketsLost + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_lost(nativePeer); + } + } + + public float PacketsThrottle + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_throttle(nativePeer); + } + } + + public ulong BytesSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_bytes_sent(nativePeer); + } + } + + public ulong BytesReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_bytes_received(nativePeer); + } + } + + public IntPtr Data + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_data(nativePeer); + } + + set + { + ThrowIfNotCreated(); + + Native.enet_peer_set_data(nativePeer, value); + } + } + + internal void ThrowIfNotCreated() + { + if (nativePeer == IntPtr.Zero) + throw new InvalidOperationException("Peer not created"); + } + + public void ConfigureThrottle(uint interval, uint acceleration, uint deceleration, uint threshold) + { + ThrowIfNotCreated(); + + Native.enet_peer_throttle_configure(nativePeer, interval, acceleration, deceleration, threshold); + } + + public int Send(byte channelID, ref Packet packet) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + + return Native.enet_peer_send(nativePeer, channelID, packet.NativeData); + } + + public bool Receive(out byte channelID, out Packet packet) + { + ThrowIfNotCreated(); + + IntPtr nativePacket = Native.enet_peer_receive(nativePeer, out channelID); + + if (nativePacket != IntPtr.Zero) + { + packet = new Packet(nativePacket); + + return true; + } + + packet = default(Packet); + + return false; + } + + public void Ping() + { + ThrowIfNotCreated(); + + Native.enet_peer_ping(nativePeer); + } + + public void PingInterval(uint interval) + { + ThrowIfNotCreated(); + + Native.enet_peer_ping_interval(nativePeer, interval); + } + + public void Timeout(uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum) + { + ThrowIfNotCreated(); + + Native.enet_peer_timeout(nativePeer, timeoutLimit, timeoutMinimum, timeoutMaximum); + } + + public void Disconnect(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect(nativePeer, data); + } + + public void DisconnectNow(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect_now(nativePeer, data); + } + + public void DisconnectLater(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect_later(nativePeer, data); + } + + public void Reset() + { + ThrowIfNotCreated(); + + Native.enet_peer_reset(nativePeer); + } + } + + public static class Extensions + { + public static int StringLength(this byte[] data) + { + if (data == null) + throw new ArgumentNullException("data"); + + int i; + + for (i = 0; i < data.Length && data[i] != 0; i++) ; + + return i; + } + } + + public static class Library + { + public const uint maxChannelCount = 0xFF; + public const uint maxPeers = 0xFFF; + public const uint maxPacketSize = 32 * 1024 * 1024; + public const uint throttleThreshold = 40; + public const uint throttleScale = 32; + public const uint throttleAcceleration = 2; + public const uint throttleDeceleration = 2; + public const uint throttleInterval = 5000; + public const uint timeoutLimit = 32; + public const uint timeoutMinimum = 5000; + public const uint timeoutMaximum = 30000; + public const uint version = (2 << 16) | (4 << 8) | (7); + + public static uint Time + { + get + { + return Native.enet_time_get(); + } + } + + public static bool Initialize() + { + if (Native.enet_linked_version() != version) + throw new InvalidOperationException("ENet native is out of date. Download the latest release from https://github.com/SoftwareGuy/ENet-CSharp/releases"); + + return Native.enet_initialize() == 0; + } + + public static bool Initialize(Callbacks callbacks) + { + if (callbacks == null) + throw new ArgumentNullException("callbacks"); + + if (Native.enet_linked_version() != version) + throw new InvalidOperationException("ENet native is out of date. Download the latest release from https://github.com/SoftwareGuy/ENet-CSharp/releases"); + + ENetCallbacks nativeCallbacks = callbacks.NativeData; + + return Native.enet_initialize_with_callbacks(version, ref nativeCallbacks) == 0; + } + + public static void Deinitialize() + { + Native.enet_deinitialize(); + } + + public static ulong CRC64(IntPtr buffers, int bufferCount) + { + return Native.enet_crc64(buffers, bufferCount); + } + } + + [SuppressUnmanagedCodeSecurity] + internal static class Native + { + private const string nativeLibrary = enetWindows; + + private const string enetLinux = "lib/linux/libenet"; + private const string enetWindows = "lib/win/enet"; + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_initialize(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_initialize_with_callbacks(uint version, ref ENetCallbacks inits); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_deinitialize(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_linked_version(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_time_get(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_crc64(IntPtr buffers, int bufferCount); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_set_ip(ref ENetAddress address, string ip); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_set_hostname(ref ENetAddress address, string hostName); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_get_ip(ref ENetAddress address, StringBuilder ip, IntPtr ipLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_get_hostname(ref ENetAddress address, StringBuilder hostName, IntPtr nameLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create(byte[] data, IntPtr dataLength, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create(IntPtr data, IntPtr dataLength, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create_offset(byte[] data, IntPtr dataLength, IntPtr dataOffset, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create_offset(IntPtr data, IntPtr dataLength, IntPtr dataOffset, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_packet_check_references(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_get_data(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_get_user_data(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_set_user_data(IntPtr packet, IntPtr userData); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_packet_get_length(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_packet_set_free_callback(IntPtr packet, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_packet_dispose(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_create(ref ENetAddress address, IntPtr peerLimit, IntPtr channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_create(IntPtr address, IntPtr peerLimit, IntPtr channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_connect(IntPtr host, ref ENetAddress address, IntPtr channelCount, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast(IntPtr host, byte channelID, IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast_exclude(IntPtr host, byte channelID, IntPtr packet, IntPtr excludedPeer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast_selective(IntPtr host, byte channelID, IntPtr packet, IntPtr[] peers, IntPtr peersLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_host_service(IntPtr host, out ENetEvent @event, uint timeout); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_host_check_events(IntPtr host, out ENetEvent @event); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_channel_limit(IntPtr host, IntPtr channelLimit); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_bandwidth_limit(IntPtr host, uint incomingBandwidth, uint outgoingBandwidth); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_peers_count(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_packets_sent(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_packets_received(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_bytes_sent(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_bytes_received(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_max_duplicate_peers(IntPtr host, ushort number); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_intercept_callback(IntPtr host, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_checksum_callback(IntPtr host, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_flush(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_destroy(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_prevent_connections(IntPtr host, byte state); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_throttle_configure(IntPtr peer, uint interval, uint acceleration, uint deceleration, uint threshold); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_id(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_peer_get_ip(IntPtr peer, byte[] ip, IntPtr ipLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ushort enet_peer_get_port(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_mtu(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern PeerState enet_peer_get_state(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_rtt(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_last_rtt(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_lastsendtime(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_lastreceivetime(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_packets_sent(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_packets_lost(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern float enet_peer_get_packets_throttle(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_bytes_sent(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_bytes_received(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_peer_get_data(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_set_data(IntPtr peer, IntPtr data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_peer_send(IntPtr peer, byte channelID, IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_peer_receive(IntPtr peer, out byte channelID); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_ping(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_ping_interval(IntPtr peer, uint pingInterval); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_timeout(IntPtr peer, uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect_now(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect_later(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_reset(IntPtr peer); + } +} diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Ignorance.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Ignorance.cs new file mode 100644 index 0000000..9abff62 --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Ignorance.cs @@ -0,0 +1,510 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. +// ----------------- +// Ignorance Experimental (New) Version +// ----------------- +using ENet; +using Mirror; +using System; +using System.Collections.Generic; + +namespace IgnoranceTransport +{ + public class Ignorance : Transport + { + public int port = 7777; + + public IgnoranceLogType LogType = IgnoranceLogType.Standard; + public bool DebugDisplay = false; + + public bool serverBindsAll = true; + public string serverBindAddress = string.Empty; + public int serverMaxPeerCapacity = 50; + public int serverMaxNativeWaitTime = 1; + + public int clientMaxNativeWaitTime = 3; + + public IgnoranceChannelTypes[] Channels = new[] { IgnoranceChannelTypes.Reliable, IgnoranceChannelTypes.Unreliable }; + + public int PacketBufferCapacity = 4096; + + public int MaxAllowedPacketSize = 33554432; + + public IgnoranceClientStats ClientStatistics; + + public override bool Available() + { + return true; + } + + public override void Awake() + { + if (LogType != IgnoranceLogType.Nothing) + Console.WriteLine($"Thanks for using Ignorance {IgnoranceInternals.Version}. Keep up to date, report bugs and support the developer at https://github.com/SoftwareGuy/Ignorance!"); + } + + public override string ToString() + { + return $"Ignorance v{IgnoranceInternals.Version}"; + } + + public override void ClientConnect(string address) + { + ClientState = ConnectionState.Connecting; + cachedConnectionAddress = address; + + // Initialize. + InitializeClientBackend(); + + // Get going. + ignoreDataPackets = false; + + // Start! + Client.Start(); + } + + public override void ClientConnect(Uri uri) + { + if (uri.Scheme != IgnoranceInternals.Scheme) + throw new ArgumentException($"You used an invalid URI: {uri}. Please use {IgnoranceInternals.Scheme}://host:port instead", nameof(uri)); + + if (!uri.IsDefaultPort) + // Set the communication port to the one specified. + port = uri.Port; + + // Pass onwards to the proper handler. + ClientConnect(uri.Host); + } + + public override bool ClientConnected() => ClientState == ConnectionState.Connected; + + public override void ClientDisconnect() + { + if (Client != null) + Client.Stop(); + + // TODO: Figure this one out to see if it's related to a race condition. + // Maybe experiment with a while loop to pause main thread when disconnecting, + // since client might not stop on a dime. + // while(Client.IsAlive) ; + // v1.4.0b1: Probably fixed in IgnoranceClient.cs; need further testing. + + // ignoreDataPackets = true; + ClientState = ConnectionState.Disconnected; + } + + + // v1.4.0b6: Mirror rearranged the ClientSend params, so we need to apply a fix for that or + // we end up using the obsoleted version. The obsolete version isn't a fatal error, but + // it's best to stick with the new structures. + public override void ClientSend(int channelId, ArraySegment segment) + { + if (Client == null) + { + + return; + } + + if (channelId < 0 || channelId > Channels.Length) + { + + return; + } + + // Create our struct... + Packet clientOutgoingPacket = default; + int byteCount = segment.Count; + int byteOffset = segment.Offset; + // Set our desired flags... + PacketFlags desiredFlags = (PacketFlags)Channels[channelId]; + + // Create the packet. + clientOutgoingPacket.Create(segment.Array, byteOffset, byteCount + byteOffset, desiredFlags); + // byteCount + + // Enqueue the packet. + IgnoranceOutgoingPacket dispatchPacket = new IgnoranceOutgoingPacket + { + Channel = (byte)channelId, + Payload = clientOutgoingPacket + }; + + // Pass the packet onto the thread for dispatch. + Client.Outgoing.Enqueue(dispatchPacket); + } + + public override bool ServerActive() + { + // Very simple check. + return Server != null && Server.IsAlive; + } + + public override bool ServerDisconnect(int connectionId) => ServerDisconnectLegacy(connectionId); + + public override string ServerGetClientAddress(int connectionId) + { + if (ConnectionLookupDict.TryGetValue(connectionId, out PeerConnectionData details)) + return $"{details.IP}:{details.Port}"; + + return "(unavailable)"; + } + + public override void ServerSend(int connectionId, int channelId, ArraySegment segment) + { + // Debug.Log($"ServerSend({connectionId}, {channelId}, <{segment.Count} byte segment>)"); + + if (Server == null) + { + // Debug.LogError("Cannot enqueue data packet; our Server object is null. Something has gone wrong."); + return; + } + + if (channelId < 0 || channelId > Channels.Length) + { + // Debug.LogError("Channel ID is out of bounds."); + return; + } + + // Packet Struct + Packet serverOutgoingPacket = default; + int byteCount = segment.Count; + int byteOffset = segment.Offset; + PacketFlags desiredFlags = (PacketFlags)Channels[channelId]; + + // Create the packet. + serverOutgoingPacket.Create(segment.Array, byteOffset, byteCount + byteOffset, desiredFlags); + + // Enqueue the packet. + IgnoranceOutgoingPacket dispatchPacket = new IgnoranceOutgoingPacket + { + Channel = (byte)channelId, + NativePeerId = (uint)connectionId - 1, // ENet's native peer ID will be ConnID - 1 + Payload = serverOutgoingPacket + }; + + Server.Outgoing.Enqueue(dispatchPacket); + + } + + public override void ServerStart(ushort _port) + { + if (LogType != IgnoranceLogType.Nothing) + Console.WriteLine("Ignorance Server Instance starting up..."); + port = _port; + + InitializeServerBackend(); + + Server.Start(); + } + + public override void ServerStop() + { + if (Server != null) + { + if (LogType != IgnoranceLogType.Nothing) + Console.WriteLine("Ignorance Server Instance shutting down..."); + + Server.Stop(); + } + + ConnectionLookupDict.Clear(); + } + + public override Uri ServerUri() + { + UriBuilder builder = new UriBuilder + { + Scheme = IgnoranceInternals.Scheme, + Host = serverBindAddress, + Port = port + }; + + return builder.Uri; + } + + public override void Shutdown() + { + // TODO: Nothing needed here? + } + + private void InitializeServerBackend() + { + if (Server == null) + { + // Debug.LogWarning("IgnoranceServer reference for Server mode was null. This shouldn't happen, but to be safe we'll reinitialize it."); + Server = new IgnoranceServer(); + } + + // Set up the new IgnoranceServer reference. + if (serverBindsAll) + // MacOS is special. It's also a massive thorn in my backside. + Server.BindAddress = IgnoranceInternals.BindAllMacs; + else + // Use the supplied bind address. + Server.BindAddress = serverBindAddress; + + // Sets port, maximum peers, max channels, the server poll time, maximum packet size and verbosity. + Server.BindPort = port; + Server.MaximumPeers = serverMaxPeerCapacity; + Server.MaximumChannels = Channels.Length; + Server.PollTime = serverMaxNativeWaitTime; + Server.MaximumPacketSize = MaxAllowedPacketSize; + Server.Verbosity = (int)LogType; + + // Initializes the packet buffer. + // Allocates once, that's it. + if (InternalPacketBuffer == null) + InternalPacketBuffer = new byte[PacketBufferCapacity]; + } + + private void InitializeClientBackend() + { + if (Client == null) + { + // Debug.LogWarning("Ignorance: IgnoranceClient reference for Client mode was null. This shouldn't happen, but to be safe we'll reinitialize it."); + Client = new IgnoranceClient(); + } + + // Sets address, port, channels to expect, verbosity, the server poll time and maximum packet size. + Client.ConnectAddress = cachedConnectionAddress; + Client.ConnectPort = port; + Client.ExpectedChannels = Channels.Length; + Client.PollTime = clientMaxNativeWaitTime; + Client.MaximumPacketSize = MaxAllowedPacketSize; + Client.Verbosity = (int)LogType; + + // Initializes the packet buffer. + // Allocates once, that's it. + if (InternalPacketBuffer == null) + InternalPacketBuffer = new byte[PacketBufferCapacity]; + } + + private void ProcessServerPackets() + { + IgnoranceIncomingPacket incomingPacket; + IgnoranceConnectionEvent connectionEvent; + int adjustedConnectionId; + Packet payload; + + // Incoming connection events. + while (Server.ConnectionEvents.TryDequeue(out connectionEvent)) + { + adjustedConnectionId = (int)connectionEvent.NativePeerId + 1; + + // TODO: Investigate ArgumentException: An item with the same key has already been added. Key: + ConnectionLookupDict.Add(adjustedConnectionId, new PeerConnectionData + { + NativePeerId = connectionEvent.NativePeerId, + IP = connectionEvent.IP, + Port = connectionEvent.Port + }); + + OnServerConnected?.Invoke(adjustedConnectionId); + } + + // Handle incoming data packets. + // Console.WriteLine($"Server Incoming Queue is {Server.Incoming.Count}"); + while (Server.Incoming.TryDequeue(out incomingPacket)) + { + adjustedConnectionId = (int)incomingPacket.NativePeerId + 1; + payload = incomingPacket.Payload; + + int length = payload.Length; + ArraySegment dataSegment; + + // Copy to working buffer and dispose of it. + if (length > InternalPacketBuffer.Length) + { + byte[] oneFreshNTastyGcAlloc = new byte[length]; + + payload.CopyTo(oneFreshNTastyGcAlloc); + dataSegment = new ArraySegment(oneFreshNTastyGcAlloc, 0, length); + } + else + { + payload.CopyTo(InternalPacketBuffer); + dataSegment = new ArraySegment(InternalPacketBuffer, 0, length); + } + + payload.Dispose(); + + OnServerDataReceived?.Invoke(adjustedConnectionId, dataSegment, incomingPacket.Channel); + } + + // Disconnection events. + while (Server.DisconnectionEvents.TryDequeue(out IgnoranceConnectionEvent disconnectionEvent)) + { + adjustedConnectionId = (int)disconnectionEvent.NativePeerId + 1; + + ConnectionLookupDict.Remove(adjustedConnectionId); + + // Invoke Mirror handler. + OnServerDisconnected?.Invoke(adjustedConnectionId); + } + } + + private void ProcessClientPackets() + { + Packet payload; + + // Handle connection events. + while (Client.ConnectionEvents.TryDequeue(out IgnoranceConnectionEvent connectionEvent)) + { + + if (connectionEvent.WasDisconnect) + { + // Disconnected from server. + ClientState = ConnectionState.Disconnected; + + ignoreDataPackets = true; + OnClientDisconnected?.Invoke(); + } + else + { + // Connected to server. + ClientState = ConnectionState.Connected; + + ignoreDataPackets = false; + OnClientConnected?.Invoke(); + } + } + + // Now handle the incoming messages. + while (Client.Incoming.TryDequeue(out IgnoranceIncomingPacket incomingPacket)) + { + // Temporary fix: if ENet thread is too fast for Mirror, then ignore the packet. + // This is seen sometimes if you stop the client and there's still stuff in the queue. + if (ignoreDataPackets) + { + break; + } + + // Otherwise client recieved data, advise Mirror. + // print($"Byte array: {incomingPacket.RentedByteArray.Length}. Packet Length: {incomingPacket.Length}"); + payload = incomingPacket.Payload; + int length = payload.Length; + ArraySegment dataSegment; + + // Copy to working buffer and dispose of it. + if (length > InternalPacketBuffer.Length) + { + // Unity's favourite: A fresh 'n' tasty GC Allocation! + byte[] oneFreshNTastyGcAlloc = new byte[length]; + + payload.CopyTo(oneFreshNTastyGcAlloc); + dataSegment = new ArraySegment(oneFreshNTastyGcAlloc, 0, length); + } + else + { + payload.CopyTo(InternalPacketBuffer); + dataSegment = new ArraySegment(InternalPacketBuffer, 0, length); + } + + payload.Dispose(); + + OnClientDataReceived?.Invoke(dataSegment, incomingPacket.Channel); + } + + // Step 3: Handle other commands. + while (Client.Commands.TryDequeue(out IgnoranceCommandPacket commandPacket)) + { + switch (commandPacket.Type) + { + // ... + default: + break; + } + } + + // Step 4: Handle status updates. + if (Client.StatusUpdates.TryDequeue(out IgnoranceClientStats clientStats)) + { + ClientStatistics = clientStats; + } + } + + // Ignorance 1.4.0b5: To use Mirror's polling or not use Mirror's polling, that is up to the developer to decide + + // IMPORTANT: Set Ignorance' execution order before everything else. Yes, that's -32000 !! + // This ensures it has priority over other things. + + // FixedUpdate can be called many times per frame. + // Once we've handled stuff, we set a flag so that we don't poll again for this frame. + + private bool fixedUpdateCompletedWork; + public void FixedUpdate() + { + if (fixedUpdateCompletedWork) return; + + ProcessAndExecuteAllPackets(); + + // Flip the bool to signal we've done our work. + fixedUpdateCompletedWork = true; + } + + // Normally, Mirror blocks Update() due to poor design decisions... + // But thanks to Vincenzo, we've found a way to bypass that block. + // Update is called once per frame. We don't have to worry about this shit now. + public override void Update() + { + // Process what FixedUpdate missed, only if the boolean is not set. + if (!fixedUpdateCompletedWork) + ProcessAndExecuteAllPackets(); + + // Flip back the bool, so it can be reset. + fixedUpdateCompletedWork = false; + } + + // Processes and Executes All Packets. + private void ProcessAndExecuteAllPackets() + { + // Process Server Events... + if (Server.IsAlive) + ProcessServerPackets(); + + // Process Client Events... + if (Client.IsAlive) + { + ProcessClientPackets(); + } + } + + public override int GetMaxPacketSize(int channelId = 0) => MaxAllowedPacketSize; + + private bool ignoreDataPackets; + private string cachedConnectionAddress = string.Empty; + private IgnoranceServer Server = new IgnoranceServer(); + private IgnoranceClient Client = new IgnoranceClient(); + private Dictionary ConnectionLookupDict = new Dictionary(); + + private enum ConnectionState { Connecting, Connected, Disconnecting, Disconnected } + private ConnectionState ClientState = ConnectionState.Disconnected; + private byte[] InternalPacketBuffer; + + public bool ServerDisconnectLegacy(int connectionId) + { + if (Server == null) + { + // Debug.LogError("Cannot enqueue kick packet; our Server object is null. Something has gone wrong."); + // Return here because otherwise we will get a NRE when trying to enqueue the kick packet. + return false; + } + + IgnoranceCommandPacket kickPacket = new IgnoranceCommandPacket + { + Type = IgnoranceCommandType.ServerKickPeer, + PeerId = (uint)connectionId - 1 // ENet's native peer ID will be ConnID - 1 + }; + + // Pass the packet onto the thread for dispatch. + Server.Commands.Enqueue(kickPacket); + return true; + } + + } +} diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/IgnoranceDefinitions.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/IgnoranceDefinitions.cs new file mode 100644 index 0000000..ca677ac --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/IgnoranceDefinitions.cs @@ -0,0 +1,94 @@ +using System; +using ENet; + +namespace IgnoranceTransport +{ + // Snipped from the transport files, as this will help + // me keep things up to date. + [Serializable] + public enum IgnoranceChannelTypes + { + Reliable = PacketFlags.Reliable, // TCP Emulation. + ReliableUnsequenced = PacketFlags.Reliable | PacketFlags.Unsequenced, // TCP Emulation, but no sequencing. + Unreliable = PacketFlags.Unsequenced, // Pure UDP. + UnreliableFragmented = PacketFlags.UnreliableFragmented, // Pure UDP, but fragmented. + UnreliableSequenced = PacketFlags.None, // Pure UDP, but sequenced. + Unthrottled = PacketFlags.Unthrottled, // Apparently ENet's version of Taco Bell. + } + + public class IgnoranceInternals + { + public const string Version = "1.4.0b6"; + public const string Scheme = "enet"; + public const string BindAllIPv4 = "0.0.0.0"; + public const string BindAllMacs = "::0"; + } + + public enum IgnoranceLogType + { + Nothing, + Standard, + Verbose + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceIncomingPacket + { + public byte Channel; + public uint NativePeerId; + public Packet Payload; + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceOutgoingPacket + { + public byte Channel; + public uint NativePeerId; + public Packet Payload; + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceConnectionEvent + { + public bool WasDisconnect; + public ushort Port; + public uint NativePeerId; + public string IP; + } + + public struct IgnoranceCommandPacket + { + public IgnoranceCommandType Type; + public uint PeerId; + } + + public struct IgnoranceClientStats + { + // Stats only - may not always be used! + public uint RTT; + public ulong BytesReceived; + public ulong BytesSent; + public ulong PacketsReceived; + public ulong PacketsSent; + public ulong PacketsLost; + } + + public enum IgnoranceCommandType + { + // Client + ClientWantsToStop, + ClientRequestsStatusUpdate, + // ENet internal + ResponseToClientStatusRequest, + // Server + ServerKickPeer + } + + // TODO: Optimize struct for Cache performance. + public struct PeerConnectionData + { + public ushort Port; + public uint NativePeerId; + public string IP; + } +} diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Linux/libenet.so b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Linux/libenet.so new file mode 100644 index 0000000..c64bfb7 Binary files /dev/null and b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Linux/libenet.so differ diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/README.txt b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/README.txt new file mode 100644 index 0000000..1bb2563 --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/README.txt @@ -0,0 +1,3 @@ +This is a Windows x64 build of ENet-CSharp. + +If you require a version of ENet for 32 Bit computer systems (ie. Windows 7/8/10 32Bit) then please get in touch, or you can install the requirements yourself and compile it using ENet-CSharp's MSBuild-based build system. Get in touch if you want me to compile them for you, but keep in mind that I do not support them when reporting bugs. \ No newline at end of file diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/enet.dll b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/enet.dll new file mode 100644 index 0000000..f75351b Binary files /dev/null and b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/Windows/enet.dll differ diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/readme.txt b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/readme.txt new file mode 100644 index 0000000..66f084a --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Ignorance/Plugins/readme.txt @@ -0,0 +1,35 @@ +ENET Pre-compiled Binary Library Blobs +========================== +This folder contains pre-compiled binaries for a variety of different platforms. + +A brief summary of these folders are as follows: + +- Windows, Mac, Linux +-- 64bit (x64) + +- Android (Kitkat 4.4 minimum target OS) +-- ARMv7 (armeabi-v7a), ARMv8/AArch64 (arm64-v8a) + +- iOS +-- FAT Library (armv7 + arm64). Targeted for iOS 8 minimum. Unsigned library. + +DEBUG VERSIONS +=============== +Debug versions of the libraries can be obtained at https://github.com/SoftwareGuy/ENet-CSharp/releases. +Otherwise you can also compile the library yourself with Debug enabled. + +DOT POINTS +=========== +1. 32bit Support for Ignorance has been removed. Originally, I did not want to support 32bit operating systems, +however due to some countries in the world still stuck in the 32bit era (Brasil, some Russian areas, etc) I added them as a +goodwill gesture. However, since those who needed the libraries have now vanished, I have stopped building 32bit versions of ENet. + +COMPILE THE CODE YOURSELF +========================= +If you don't trust the above binaries then git clone the ENET-CSharp repository (http://github.com/SoftwareGuy/ENet-CSharp) and read the readme. + +EXCLUSION INSTRUCTIONS +====================== +No need, the meta data will cover that for you. + +Still don't know what to do with these? Drop by the Mirror discord and post in the Ignorance channel. \ No newline at end of file diff --git a/UnityProject/Assets/Ignorance.meta b/UnityProject/Assets/Ignorance.meta new file mode 100644 index 0000000..a52c77f --- /dev/null +++ b/UnityProject/Assets/Ignorance.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e62b1f8d9ebd624a9fc425eda441bcd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo.meta b/UnityProject/Assets/Ignorance/Demo.meta new file mode 100644 index 0000000..74b45a7 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f3dc386b0074be4caf7b858e3189529 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp.meta new file mode 100644 index 0000000..fbf9985 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 634f781b33ac69147bff9edd5829cfd6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab new file mode 100644 index 0000000..84b8f93 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab @@ -0,0 +1,188 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1080679924113744 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4700925592147096} + - component: {fileID: 212107498293566416} + - component: {fileID: 61279514624852186} + - component: {fileID: 50354248948880112} + - component: {fileID: 114290021321007948} + - component: {fileID: 2590138469697868697} + - component: {fileID: 114121325390084138} + m_Layer: 0 + m_Name: AtariBall + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4700925592147096 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -3, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &212107498293566416 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 4b66f21097323d44ab40669b2fb9c53d, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!61 &61279514624852186 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 6200000, guid: 97a3e4cddb8635c4eba1265f44d106bf, type: 2} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!50 &50354248948880112 +Rigidbody2D: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_BodyType: 0 + m_Simulated: 0 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 0.0001 + m_LinearDrag: 0 + m_AngularDrag: 0.05 + m_GravityScale: 0 + m_Material: {fileID: 0} + m_Interpolate: 0 + m_SleepingMode: 1 + m_CollisionDetection: 0 + m_Constraints: 4 +--- !u!114 &114290021321007948 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3} + m_Name: + m_EditorClassIdentifier: + sceneId: 0 + serverOnly: 0 + visible: 0 + m_AssetId: + hasSpawned: 0 +--- !u!114 &2590138469697868697 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a08d5ab1f59230458264367f00c54d8, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0.1 + speed: 100 +--- !u!114 &114121325390084138 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1080679924113744} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0 + clientAuthority: 0 + localPositionSensitivity: 0.01 + localRotationSensitivity: 0.01 + localScaleSensitivity: 0.01 + compressRotation: 1 + interpolateScale: 0 + syncScale: 0 diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab.meta new file mode 100644 index 0000000..84850be --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariBall.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da367a4c269be6d4a855ee1a9a68256b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab new file mode 100644 index 0000000..44aaae1 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab @@ -0,0 +1,188 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1240244544407914 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4118252415362944} + - component: {fileID: 212641192162007874} + - component: {fileID: 61279767645666242} + - component: {fileID: 50389918509199184} + - component: {fileID: 114104497298166850} + - component: {fileID: -4874889082967523790} + - component: {fileID: 114398896143473162} + m_Layer: 0 + m_Name: AtariRacket + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4118252415362944 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &212641192162007874 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 619ccff3ba2f2a04f9ddd19c264a1ecd, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!61 &61279767645666242 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 2, y: 4} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 2, y: 4} + m_EdgeRadius: 0 +--- !u!50 &50389918509199184 +Rigidbody2D: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_BodyType: 0 + m_Simulated: 1 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 1 + m_LinearDrag: 0 + m_AngularDrag: 0.05 + m_GravityScale: 0 + m_Material: {fileID: 0} + m_Interpolate: 1 + m_SleepingMode: 1 + m_CollisionDetection: 1 + m_Constraints: 4 +--- !u!114 &114104497298166850 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3} + m_Name: + m_EditorClassIdentifier: + sceneId: 0 + serverOnly: 0 + visible: 0 + m_AssetId: + hasSpawned: 0 +--- !u!114 &-4874889082967523790 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b68eb08343b29a54dbd5ed7830fb9211, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0.1 + speed: 1500 +--- !u!114 &114398896143473162 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1240244544407914} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0 + clientAuthority: 1 + localPositionSensitivity: 0.01 + localRotationSensitivity: 0.01 + localScaleSensitivity: 0.01 + compressRotation: 1 + interpolateScale: 0 + syncScale: 0 diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab.meta new file mode 100644 index 0000000..f6d6f53 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a85b24263182aae4bbc1829bb2b73d7a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity b/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity new file mode 100644 index 0000000..bbaa0a4 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity @@ -0,0 +1,1166 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &4 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 0 +--- !u!196 &5 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &289876230 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 289876232} + - component: {fileID: 289876231} + m_Layer: 0 + m_Name: DottedLine + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &289876231 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289876230} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 4294967295 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 75254f20e37ff3640beccde38f796fed, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &289876232 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 289876230} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1607538195} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &473997959 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 473997961} + - component: {fileID: 473997960} + m_Layer: 0 + m_Name: RacketSpawnLeft + m_TagString: Untagged + m_Icon: {fileID: -964228994112308473, guid: 0000000000000000d000000000000000, type: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &473997960 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 473997959} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &473997961 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 473997959} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -20, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &753891880 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 753891882} + - component: {fileID: 753891881} + - component: {fileID: 753891883} + m_Layer: 0 + m_Name: WallBottom + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &753891881 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753891880} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 4294967295 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 51f6a08479c829a49b6a15df6849e727, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &753891882 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753891880} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: -16, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1607538195} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!61 &753891883 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753891880} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 50, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 50, y: 1} + m_EdgeRadius: 0 +--- !u!1 &1212086918 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1212086921} + - component: {fileID: 1212086920} + - component: {fileID: 1212086919} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1212086919 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1212086918} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1212086920 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1212086918} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1212086921 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1212086918} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1278075347 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1278075350} + - component: {fileID: 1278075348} + - component: {fileID: 1278075349} + m_Layer: 0 + m_Name: Timer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1278075348 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278075347} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0996ec573094c24890a4d4233ee871e, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0.1 +--- !u!114 &1278075349 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278075347} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3} + m_Name: + m_EditorClassIdentifier: + sceneId: 3073769009 + serverOnly: 0 + visible: 0 + m_AssetId: + hasSpawned: 0 +--- !u!4 &1278075350 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278075347} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1346799726 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1346799731} + - component: {fileID: 1346799730} + - component: {fileID: 1346799728} + - component: {fileID: 1346799727} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1346799727 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346799726} + m_Enabled: 1 +--- !u!124 &1346799728 +Behaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346799726} + m_Enabled: 1 +--- !u!20 &1346799730 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346799726} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0.019607844} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 40 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1346799731 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346799726} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1352350029 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1352350031} + - component: {fileID: 1352350030} + - component: {fileID: 1352350032} + m_Layer: 0 + m_Name: WallLeft + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &1352350030 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1352350029} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 4294967295 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: b41679787bea72d419d10a6df7dc137f, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1352350031 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1352350029} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -24.5, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1607538195} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!61 &1352350032 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1352350029} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 32} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 32} + m_EdgeRadius: 0 +--- !u!1 &1368547944 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1368547946} + - component: {fileID: 1368547945} + - component: {fileID: 1368547947} + m_Layer: 0 + m_Name: WallTop + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &1368547945 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1368547944} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 4294967295 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 51f6a08479c829a49b6a15df6849e727, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1368547946 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1368547944} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 16, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1607538195} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!61 &1368547947 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1368547944} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 50, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 50, y: 1} + m_EdgeRadius: 0 +--- !u!1 &1397990094 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1397990096} + - component: {fileID: 1397990095} + m_Layer: 0 + m_Name: RacketSpawnRight + m_TagString: Untagged + m_Icon: {fileID: -964228994112308473, guid: 0000000000000000d000000000000000, type: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1397990095 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1397990094} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1397990096 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1397990094} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 20, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1575697329 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1575697331} + - component: {fileID: 1575697330} + - component: {fileID: 1575697332} + m_Layer: 0 + m_Name: WallRight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &1575697330 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1575697329} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 4294967295 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: b41679787bea72d419d10a6df7dc137f, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &1575697331 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1575697329} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 24.5, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1607538195} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!61 &1575697332 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1575697329} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 32} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1, y: 32} + m_EdgeRadius: 0 +--- !u!1 &1607538194 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1607538195} + m_Layer: 0 + m_Name: Table + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1607538195 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1607538194} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1368547946} + - {fileID: 753891882} + - {fileID: 1575697331} + - {fileID: 1352350031} + - {fileID: 289876232} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1886246549 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1886246550} + - component: {fileID: 1886246552} + - component: {fileID: 1886246551} + - component: {fileID: 1886246553} + m_Layer: 0 + m_Name: NetworkManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1886246550 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1886246549} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1886246551 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1886246549} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6442dc8070ceb41f094e44de0bf87274, type: 3} + m_Name: + m_EditorClassIdentifier: + showGUI: 1 + offsetX: 0 + offsetY: 0 +--- !u!114 &1886246552 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1886246549} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8aab4c8111b7c411b9b92cf3dbc5bd4e, type: 3} + m_Name: + m_EditorClassIdentifier: + dontDestroyOnLoad: 1 + PersistNetworkManagerToOfflineScene: 0 + runInBackground: 1 + autoStartServerBuild: 1 + serverTickRate: 60 + serverBatching: 0 + serverBatchInterval: 0 + offlineScene: + onlineScene: + transport: {fileID: 1886246553} + networkAddress: localhost + maxConnections: 4 + disconnectInactiveConnections: 0 + disconnectInactiveTimeout: 60 + authenticator: {fileID: 0} + playerPrefab: {fileID: 1240244544407914, guid: a85b24263182aae4bbc1829bb2b73d7a, + type: 3} + autoCreatePlayer: 1 + playerSpawnMethod: 1 + spawnPrefabs: [] +--- !u!114 &1886246553 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1886246549} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 872fa23ef6e77334ca452ce16f6cd091, type: 3} + m_Name: + m_EditorClassIdentifier: + port: 7777 + LogType: 1 + DebugDisplay: 0 + serverBindsAll: 1 + serverBindAddress: + serverMaxPeerCapacity: 50 + serverMaxNativeWaitTime: 1 + clientMaxNativeWaitTime: 3 + clientStatusUpdateInterval: 3 + Channels: 0100000002000000 + PacketBufferCapacity: 4096 + MaxAllowedPacketSize: 33554432 +--- !u!1001 &543632697568170294 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 440601958556739609, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: sceneId + value: 1882393603 + objectReference: {fileID: 0} + - target: {fileID: 440601958556739609, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_AssetId + value: 5339554c46006dd4e91cae9ff34c095d + objectReference: {fileID: 0} + - target: {fileID: 542835289192032773, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_Name + value: Ball + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_RootOrder + value: 4 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 548291784780898253, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5995301680282788937, guid: 5339554c46006dd4e91cae9ff34c095d, + type: 3} + propertyPath: speed + value: 60 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 5339554c46006dd4e91cae9ff34c095d, type: 3} diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity.meta new file mode 100644 index 0000000..32f0c43 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Demo.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c63e1eea85874ae43a7fdd723a38741e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts.meta new file mode 100644 index 0000000..7ecdffd --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e2898db03f0b9654498df19a98dc9503 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs new file mode 100644 index 0000000..a0e43c2 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs @@ -0,0 +1,67 @@ +using UnityEngine; +using Mirror; + +namespace Ignorance.Examples.PongChamp +{ + public class AtariPongBall : NetworkBehaviour + { + public float speed = 100; + private Rigidbody2D rigidbody2d; + + private void Awake() + { + rigidbody2d = GetComponent(); + } + + public override void OnStartServer() + { + base.OnStartServer(); + + // only simulate ball physics on server + rigidbody2d.simulated = true; + + // Serve the ball from left player + rigidbody2d.velocity = Vector2.right * speed; + } + + float HitFactor(Vector2 ballPos, Vector2 racketPos, float racketHeight) + { + // ascii art: + // || 1 <- at the top of the racket + // || + // || 0 <- at the middle of the racket + // || + // || -1 <- at the bottom of the racket + return (ballPos.y - racketPos.y) / racketHeight; + } + + // only call this on server + [ServerCallback] + void OnCollisionEnter2D(Collision2D col) + { + // Note: 'col' holds the collision information. If the + // Ball collided with a racket, then: + // col.gameObject is the racket + // col.transform.position is the racket's position + // col.collider is the racket's collider + + // did we hit a racket? then we need to calculate the hit factor + if (col.transform.GetComponent()) + { + // Calculate y direction via hit Factor + float y = HitFactor(transform.position, + col.transform.position, + col.collider.bounds.size.y); + + // Calculate x direction via opposite collision + float x = col.relativeVelocity.x > 0 ? 1 : -1; + + // Calculate direction, make length=1 via .normalized + Vector2 dir = new Vector2(x, y).normalized; + + // Set Velocity with dir * speed + rigidbody2d.velocity = dir * speed; + } + } + } +} diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs.meta new file mode 100644 index 0000000..951bb58 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2a08d5ab1f59230458264367f00c54d8 +timeCreated: 1426602353 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs new file mode 100644 index 0000000..75f9d93 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using Mirror; + +namespace Ignorance.Examples.PongChamp +{ + public class AtariPongRacket : NetworkBehaviour + { + public float speed = 1500; + private Rigidbody2D rigidbody2d; + + private void Awake() + { + rigidbody2d = GetComponent(); + } + + // need to use FixedUpdate for rigidbody + void FixedUpdate() + { + // only let the local player control the racket. + // don't control other player's rackets + if (isLocalPlayer) + rigidbody2d.velocity = new Vector2(0, Input.GetAxisRaw("Vertical")) * speed * Time.fixedDeltaTime; + } + } +} diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs.meta new file mode 100644 index 0000000..f0168bc --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b68eb08343b29a54dbd5ed7830fb9211 +timeCreated: 1426597826 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs new file mode 100644 index 0000000..6f76470 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs @@ -0,0 +1,49 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Mirror; +using System.Diagnostics; +using Debug = UnityEngine.Debug; + +public class OnlineTimer : NetworkBehaviour +{ + private Stopwatch stopwatch; + + // Start is called before the first frame update + private void Awake() + { + stopwatch = new Stopwatch(); + } + + public override void OnStartClient() + { + stopwatch.Reset(); + stopwatch.Start(); + + Debug.Log("Stopwatch started!"); + + base.OnStartClient(); + } + + public void OnDisable() + { + if(stopwatch.IsRunning) + { + System.TimeSpan ts = stopwatch.Elapsed; + stopwatch.Stop(); + + Debug.Log("Stopwatch stopped: duration " + string.Format("{0:00}:{1:00}:{2:00}.{3:00}", + ts.Hours, ts.Minutes, ts.Seconds, + ts.Milliseconds / 10)); + } + } + + private void OnGUI() + { + if (!stopwatch.IsRunning) return; + + GUI.Box(new Rect(new Vector2(2, Screen.height - 36), new Vector2(320, 32)), "ONLINE TIME: " + string.Format("{0:00}:{1:00}:{2:00}.{3:00}", + stopwatch.Elapsed.Hours, stopwatch.Elapsed.Minutes, stopwatch.Elapsed.Seconds, + stopwatch.Elapsed.Milliseconds / 10)); + } +} diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs.meta new file mode 100644 index 0000000..2f627ba --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0996ec573094c24890a4d4233ee871e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab b/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab new file mode 100644 index 0000000..cec29bc --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab @@ -0,0 +1,178 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &542835289192032773 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 548291784780898253} + - component: {fileID: 394858453892616325} + - component: {fileID: 520653813702449573} + - component: {fileID: 440601958556739609} + - component: {fileID: 440842259441939327} + - component: {fileID: 8881572407762724401} + - component: {fileID: 5995301680282788937} + m_Layer: 0 + m_Name: TenryuuBall + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &548291784780898253 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -3, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &394858453892616325 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 824ee62c0fc357b4081855e43253a948, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!50 &520653813702449573 +Rigidbody2D: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_BodyType: 0 + m_Simulated: 1 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 0.0001 + m_LinearDrag: 0 + m_AngularDrag: 0 + m_GravityScale: 0 + m_Material: {fileID: 6200000, guid: 97a3e4cddb8635c4eba1265f44d106bf, type: 2} + m_Interpolate: 2 + m_SleepingMode: 1 + m_CollisionDetection: 1 + m_Constraints: 4 +--- !u!114 &440601958556739609 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3} + m_Name: + m_EditorClassIdentifier: + sceneId: 0 + serverOnly: 0 + visible: 0 + m_AssetId: + hasSpawned: 0 +--- !u!114 &440842259441939327 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0.1 + clientAuthority: 0 + localPositionSensitivity: 0.01 + localRotationSensitivity: 0.01 + localScaleSensitivity: 0.01 + compressRotation: 0 + interpolateScale: 1 + syncScale: 1 +--- !u!58 &8881572407762724401 +CircleCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + serializedVersion: 2 + m_Radius: 1.28 +--- !u!114 &5995301680282788937 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 542835289192032773} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a08d5ab1f59230458264367f00c54d8, type: 3} + m_Name: + m_EditorClassIdentifier: + syncMode: 0 + syncInterval: 0.1 + speed: 70 diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab.meta new file mode 100644 index 0000000..1a63d00 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5339554c46006dd4e91cae9ff34c095d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures.meta new file mode 100644 index 0000000..793f2f2 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 23b5913b9b8b2e1419a41acde1b49883 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png new file mode 100644 index 0000000..9db08b5 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png.meta new file mode 100644 index 0000000..6253866 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png.meta @@ -0,0 +1,128 @@ +fileFormatVersion: 2 +guid: 824ee62c0fc357b4081855e43253a948 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites.meta new file mode 100644 index 0000000..a6798fb --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0dbfc247338e79a4dbe7474f69b46503 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png new file mode 100644 index 0000000..20c4387 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png.meta new file mode 100644 index 0000000..72a3307 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: 03167da12fa50334e8c8641a23df41b0 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: c5a291323e0d5f34883a55625f66ca70 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png new file mode 100644 index 0000000..0bcab09 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png.meta new file mode 100644 index 0000000..02fbe24 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: 75254f20e37ff3640beccde38f796fed +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 98b4e2aa86aa3d843821adfe71dbbac0 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png new file mode 100644 index 0000000..c73938d Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png.meta new file mode 100644 index 0000000..d3760fb --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: e11aad367beb44f4b8a3def9b8fc57ec +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 09819c66a21defd49b2cfc87fea685d2 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png new file mode 100644 index 0000000..6bb5dc3 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png.meta new file mode 100644 index 0000000..67ceb63 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallHorizontal.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: 51f6a08479c829a49b6a15df6849e727 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 74c5541eed52f67428025c83260d8bec + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png new file mode 100644 index 0000000..32406c1 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png.meta new file mode 100644 index 0000000..dd00149 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/Sprites/WallVertical.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: b41679787bea72d419d10a6df7dc137f +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 0 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 3a92f998f14389948aa928ac64e8e426 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png new file mode 100644 index 0000000..35f6989 Binary files /dev/null and b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png differ diff --git a/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png.meta b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png.meta new file mode 100644 index 0000000..41f17f3 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png.meta @@ -0,0 +1,121 @@ +fileFormatVersion: 2 +guid: 160d53f9f2b149c418d6d07e95438e53 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 1a75587224e4a5f468c03dbd1af78d0b + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/Super Basic.meta b/UnityProject/Assets/Ignorance/Demo/Super Basic.meta new file mode 100644 index 0000000..fee012b --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/Super Basic.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c94e6c7a1a2b13d41b83aebf5c6ac6b6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity b/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity new file mode 100644 index 0000000..b470ed4 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity @@ -0,0 +1,641 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &249891953 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 249891957} + - component: {fileID: 249891954} + - component: {fileID: 249891956} + - component: {fileID: 249891958} + m_Layer: 0 + m_Name: NetworkManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &249891954 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249891953} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6442dc8070ceb41f094e44de0bf87274, type: 3} + m_Name: + m_EditorClassIdentifier: + showGUI: 1 + offsetX: 0 + offsetY: 0 +--- !u!114 &249891956 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249891953} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8aab4c8111b7c411b9b92cf3dbc5bd4e, type: 3} + m_Name: + m_EditorClassIdentifier: + dontDestroyOnLoad: 0 + runInBackground: 1 + autoStartServerBuild: 1 + showDebugMessages: 0 + serverTickRate: 60 + serverBatching: 0 + serverBatchInterval: 0 + offlineScene: + onlineScene: + transport: {fileID: 249891958} + networkAddress: localhost + maxConnections: 16 + disconnectInactiveConnections: 1 + disconnectInactiveTimeout: 60 + authenticator: {fileID: 0} + playerPrefab: {fileID: 897184729387425976, guid: dc2c4328591bef748abb8df795c17202, + type: 3} + autoCreatePlayer: 1 + playerSpawnMethod: 1 + spawnPrefabs: [] +--- !u!4 &249891957 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249891953} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -10, y: 4, z: 5} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &249891958 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249891953} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 872fa23ef6e77334ca452ce16f6cd091, type: 3} + m_Name: + m_EditorClassIdentifier: + port: 7777 + LogType: 1 + DebugDisplay: 0 + serverBindsAll: 1 + serverBindAddress: + serverMaxPeerCapacity: 50 + serverMaxNativeWaitTime: 1 + clientMaxNativeWaitTime: 3 + clientStatusUpdateInterval: -1 + Channels: 0100000002000000 + PacketBufferCapacity: 4096 + MaxAllowedPacketSize: 33554432 +--- !u!1 &288173824 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 288173827} + - component: {fileID: 288173826} + - component: {fileID: 288173825} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &288173825 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 288173824} + m_Enabled: 1 +--- !u!20 &288173826 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 288173824} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &288173827 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 288173824} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -1} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &379082678 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 379082679} + - component: {fileID: 379082681} + - component: {fileID: 379082680} + m_Layer: 5 + m_Name: PlayersPanel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &379082679 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 379082678} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 533055204} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &379082680 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 379082678} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0} + m_RaycastTarget: 0 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &379082681 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 379082678} + m_CullTransparentMesh: 0 +--- !u!1 &522137823 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 522137826} + - component: {fileID: 522137825} + - component: {fileID: 522137824} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &522137824 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 522137823} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &522137825 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 522137823} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &522137826 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 522137823} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &533055200 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 533055204} + - component: {fileID: 533055203} + - component: {fileID: 533055202} + - component: {fileID: 533055201} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &533055201 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 533055200} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &533055202 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 533055200} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &533055203 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 533055200} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &533055204 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 533055200} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 379082679} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &707756284 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 707756286} + - component: {fileID: 707756285} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &707756285 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707756284} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &707756286 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 707756284} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} diff --git a/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity.meta b/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity.meta new file mode 100644 index 0000000..b9c9a89 --- /dev/null +++ b/UnityProject/Assets/Ignorance/Demo/Super Basic/SuperBasic.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 41ad25598d342f240bd8830833bfb1c5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/LRMTestScene.unity b/UnityProject/Assets/LRMTestScene.unity index 04167cc..5379b75 100644 --- a/UnityProject/Assets/LRMTestScene.unity +++ b/UnityProject/Assets/LRMTestScene.unity @@ -411,6 +411,61 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!1 &627350787 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 627350789} + - component: {fileID: 627350788} + m_Layer: 0 + m_Name: LRM - Connector + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &627350788 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 627350787} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 872fa23ef6e77334ca452ce16f6cd091, type: 3} + m_Name: + m_EditorClassIdentifier: + port: 7778 + LogType: 1 + DebugDisplay: 0 + serverBindsAll: 1 + serverBindAddress: + serverMaxPeerCapacity: 50 + serverMaxNativeWaitTime: 1 + clientMaxNativeWaitTime: 3 + clientStatusUpdateInterval: -1 + Channels: 0100000002000000 + PacketBufferCapacity: 4096 + MaxAllowedPacketSize: 33554432 +--- !u!4 &627350789 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 627350787} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1282001518} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &664671251 GameObject: m_ObjectHideFlags: 0 @@ -1160,7 +1215,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 1226094909} - - {fileID: 1521806212} + - {fileID: 627350789} m_Father: {fileID: 0} m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -1237,17 +1292,20 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 7064b1b1d0671194baf55fa8d5f564d6, type: 3} m_Name: m_EditorClassIdentifier: - clientToServerTransport: {fileID: 1521806211} - serverIP: 68.174.160.78 + clientToServerTransport: {fileID: 627350788} + serverIP: 127.0.0.1 serverPort: 7777 endpointServerPort: 8080 heartBeatInterval: 3 connectOnAwake: 1 authenticationKey: Secret Auth Key - diconnectedFromRelay: + disconnectedFromRelay: m_PersistentCalls: m_Calls: [] - useNATPunch: 1 + connectedToRelay: + m_PersistentCalls: + m_Calls: [] + useNATPunch: 0 NATPunchtroughPort: 1 useLoadBalancer: 0 loadBalancerPort: 7070 @@ -1348,60 +1406,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1 &1521806210 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1521806212} - - component: {fileID: 1521806211} - m_Layer: 0 - m_Name: LRM - Connector - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1521806211 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1521806210} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 6b0fecffa3f624585964b0d0eb21b18e, type: 3} - m_Name: - m_EditorClassIdentifier: - Port: 7777 - NoDelay: 1 - Interval: 10 - Timeout: 10000 - FastResend: 2 - CongestionWindow: 0 - SendWindowSize: 4096 - ReceiveWindowSize: 4096 - debugLog: 0 - statisticsGUI: 0 - statisticsLog: 0 ---- !u!4 &1521806212 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1521806210} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1282001518} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1600541100 GameObject: m_ObjectHideFlags: 0 diff --git a/UnityProject/Assets/Mirror/Examples/Pong/PhysicsMaterials/BallMaterial.physicsMaterial2D.meta b/UnityProject/Assets/Mirror/Examples/Pong/PhysicsMaterials/BallMaterial.physicsMaterial2D.meta index ce1eb3f..bf2d3b6 100644 --- a/UnityProject/Assets/Mirror/Examples/Pong/PhysicsMaterials/BallMaterial.physicsMaterial2D.meta +++ b/UnityProject/Assets/Mirror/Examples/Pong/PhysicsMaterials/BallMaterial.physicsMaterial2D.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 97a3e4cddb8635c4eba1265f44d106bf timeCreated: 1426602119 -licenseType: Free +licenseType: Store NativeFormatImporter: - userData: '' - assetBundleName: '' - assetBundleVariant: '' + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Examples/Pong/Sprites/Racket.png.meta b/UnityProject/Assets/Mirror/Examples/Pong/Sprites/Racket.png.meta index cc68660..47b9fc8 100644 --- a/UnityProject/Assets/Mirror/Examples/Pong/Sprites/Racket.png.meta +++ b/UnityProject/Assets/Mirror/Examples/Pong/Sprites/Racket.png.meta @@ -77,12 +77,12 @@ TextureImporter: bones: [] spriteID: 09819c66a21defd49b2cfc87fea685d2 vertices: [] - indices: '' + indices: edges: [] weights: [] - spritePackingTag: '' + spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 - userData: '' - assetBundleName: '' - assetBundleVariant: '' + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance.meta new file mode 100644 index 0000000..b56e66c --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cc98cd95e3fb22b4eb88082706967357 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core.meta new file mode 100644 index 0000000..2b3246b --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e03829cb9e647274db0f6a7b8b1b757b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs new file mode 100644 index 0000000..2542fd4 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs @@ -0,0 +1,296 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. + +using ENet; +// using NetStack.Buffers; +using System; +using System.Collections.Concurrent; +using System.Threading; +using UnityEngine; +using Event = ENet.Event; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using EventType = ENet.EventType; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using Object = System.Object; // fixes CS0104 ambigous reference between the same thing in UnityEngine + +namespace IgnoranceTransport +{ + public class IgnoranceClient + { + // Client connection address and port + public string ConnectAddress = "127.0.0.1"; + public int ConnectPort = 7777; + // How many channels are expected + public int ExpectedChannels = 2; + // Native poll waiting time + public int PollTime = 1; + // Maximum Packet Size + public int MaximumPacketSize = 33554432; + // General Verbosity by default. + public int Verbosity = 1; + + // Queues + public ConcurrentQueue Incoming = new ConcurrentQueue(); + public ConcurrentQueue Outgoing = new ConcurrentQueue(); + public ConcurrentQueue Commands = new ConcurrentQueue(); + public ConcurrentQueue ConnectionEvents = new ConcurrentQueue(); + public ConcurrentQueue StatusUpdates = new ConcurrentQueue(); + + public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive; + + private volatile bool CeaseOperation = false; + private Thread WorkerThread; + + public void Start() + { + Debug.Log("IgnoranceClient.Start()"); + + if (WorkerThread != null && WorkerThread.IsAlive) + { + // Cannot do that. + Debug.LogError("A worker thread is already running. Cannot start another."); + return; + } + + CeaseOperation = false; + ThreadParamInfo threadParams = new ThreadParamInfo() + { + Address = ConnectAddress, + Port = ConnectPort, + Channels = ExpectedChannels, + PollTime = PollTime, + PacketSizeLimit = MaximumPacketSize, + Verbosity = Verbosity + }; + + // Drain queues. + if (Incoming != null) while (Incoming.TryDequeue(out _)) ; + if (Outgoing != null) while (Outgoing.TryDequeue(out _)) ; + if (Commands != null) while (Commands.TryDequeue(out _)) ; + if (ConnectionEvents != null) while (ConnectionEvents.TryDequeue(out _)) ; + if (StatusUpdates != null) while (StatusUpdates.TryDequeue(out _)) ; + + WorkerThread = new Thread(ThreadWorker); + WorkerThread.Start(threadParams); + + Debug.Log("Client has dispatched worker thread."); + } + + public void Stop() + { + Debug.Log("Telling client thread to stop, this may take a while depending on network load"); + CeaseOperation = true; + } + + // This runs in a seperate thread, be careful accessing anything outside of it's thread + // or you may get an AccessViolation/crash. + private void ThreadWorker(Object parameters) + { + if (Verbosity > 0) + Debug.Log("Ignorance Client: Initializing. Please stand by..."); + + ThreadParamInfo setupInfo; + Address clientAddress = new Address(); + Peer clientPeer; + Host clientENetHost; + Event clientENetEvent; + IgnoranceClientStats icsu = default; + + // Grab the setup information. + if (parameters.GetType() == typeof(ThreadParamInfo)) + { + setupInfo = (ThreadParamInfo)parameters; + } + else + { + Debug.LogError("Ignorance Client: Startup failure: Invalid thread parameters. Aborting."); + return; + } + + // Attempt to initialize ENet inside the thread. + if (Library.Initialize()) + { + Debug.Log("Ignorance Client: ENet initialized."); + } + else + { + Debug.LogError("Ignorance Client: Failed to initialize ENet. This threads' fucked."); + return; + } + + // Attempt to connect to our target. + clientAddress.SetHost(setupInfo.Address); + clientAddress.Port = (ushort)setupInfo.Port; + + using (clientENetHost = new Host()) + { + // TODO: Maybe try catch this + clientENetHost.Create(); + clientPeer = clientENetHost.Connect(clientAddress, setupInfo.Channels); + + while (!CeaseOperation) + { + bool pollComplete = false; + + // Step 0: Handle commands. + while (Commands.TryDequeue(out IgnoranceCommandPacket commandPacket)) + { + switch (commandPacket.Type) + { + default: + break; + + case IgnoranceCommandType.ClientWantsToStop: + CeaseOperation = true; + break; + + case IgnoranceCommandType.ClientRequestsStatusUpdate: + // Respond with statistics so far. + if (!clientPeer.IsSet) + break; + + icsu.RTT = clientPeer.RoundTripTime; + + icsu.BytesReceived = clientPeer.BytesReceived; + icsu.BytesSent = clientPeer.BytesSent; + + icsu.PacketsReceived = clientENetHost.PacketsReceived; + icsu.PacketsSent = clientPeer.PacketsSent; + icsu.PacketsLost = clientPeer.PacketsLost; + + StatusUpdates.Enqueue(icsu); + break; + } + } + // Step 1: Send out data. + // ---> Sending to Server + while (Outgoing.TryDequeue(out IgnoranceOutgoingPacket outgoingPacket)) + { + // TODO: Revise this, could we tell the Peer to disconnect right here? + // Stop early if we get a client stop packet. + // if (outgoingPacket.Type == IgnorancePacketType.ClientWantsToStop) break; + + int ret = clientPeer.Send(outgoingPacket.Channel, ref outgoingPacket.Payload); + + if (ret < 0 && setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Client: ENet error code {ret} while sending packet to Peer {outgoingPacket.NativePeerId}."); + } + + // Step 2: + // <----- Receive Data packets + // This loops until polling is completed. It may take a while, if it's + // a slow networking day. + while (!pollComplete) + { + Packet incomingPacket; + Peer incomingPeer; + int incomingPacketLength; + + // Any events worth checking out? + if (clientENetHost.CheckEvents(out clientENetEvent) <= 0) + { + // If service time is met, break out of it. + if (clientENetHost.Service(setupInfo.PollTime, out clientENetEvent) <= 0) break; + + // Poll is done. + pollComplete = true; + } + + // Setup the packet references. + incomingPeer = clientENetEvent.Peer; + + // Now, let's handle those events. + switch (clientENetEvent.Type) + { + case EventType.None: + default: + break; + + case EventType.Connect: + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + NativePeerId = incomingPeer.ID, + IP = incomingPeer.IP, + Port = incomingPeer.Port + }); + break; + + case EventType.Disconnect: + case EventType.Timeout: + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + WasDisconnect = true + }); + break; + + + case EventType.Receive: + // Receive event type usually includes a packet; so cache its reference. + incomingPacket = clientENetEvent.Packet; + + if (!incomingPacket.IsSet) + { + if (setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Client: A receive event did not supply us with a packet to work with. This should never happen."); + break; + } + + incomingPacketLength = incomingPacket.Length; + + // Never consume more than we can have capacity for. + if (incomingPacketLength > setupInfo.PacketSizeLimit) + { + if (setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Client: Incoming packet is too big. My limit is {setupInfo.PacketSizeLimit} byte(s) whilest this packet is {incomingPacketLength} bytes."); + + incomingPacket.Dispose(); + break; + } + + IgnoranceIncomingPacket incomingQueuePacket = new IgnoranceIncomingPacket + { + Channel = clientENetEvent.ChannelID, + NativePeerId = incomingPeer.ID, + Payload = incomingPacket + }; + + Incoming.Enqueue(incomingQueuePacket); + break; + } + } + } + + Debug.Log("Ignorance Server: Shutdown commencing, disconnecting and flushing connection."); + + // Flush the client and disconnect. + clientPeer.Disconnect(0); + clientENetHost.Flush(); + + // Fix for client stuck in limbo, since the disconnection event may not be fired until next loop. + ConnectionEvents.Enqueue(new IgnoranceConnectionEvent() + { + WasDisconnect = true + }); + } + + // Deinitialize + Library.Deinitialize(); + if (setupInfo.Verbosity > 0) + Debug.Log("Ignorance Client: Shutdown complete."); + } + + + private struct ThreadParamInfo + { + public int Channels; + public int PollTime; + public int Port; + public int PacketSizeLimit; + public int Verbosity; + public string Address; + } + } +} diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs.meta new file mode 100644 index 0000000..fe965ca --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7b9e2c091c3d42439840a02fe700252 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs new file mode 100644 index 0000000..4f71947 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs @@ -0,0 +1,328 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. + +using ENet; +// using NetStack.Buffers; +using System.Collections.Concurrent; +using System.Threading; +using UnityEngine; +using Event = ENet.Event; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using EventType = ENet.EventType; // fixes CS0104 ambigous reference between the same thing in UnityEngine +using Object = System.Object; // fixes CS0104 ambigous reference between the same thing in UnityEngine + +namespace IgnoranceTransport +{ + public class IgnoranceServer + { + // Server Properties + // - Bind Settings + public string BindAddress = "127.0.0.1"; + public int BindPort = 7777; + // - Maximum allowed channels, peers, etc. + public int MaximumChannels = 2; + public int MaximumPeers = 100; + public int MaximumPacketSize = 33554432; // ENet.cs: uint maxPacketSize = 32 * 1024 * 1024 = 33554432 + // - Native poll waiting time + public int PollTime = 1; + public int Verbosity = 1; + + public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive; + + private volatile bool CeaseOperation = false; + + // Queues + public ConcurrentQueue Incoming = new ConcurrentQueue(); + public ConcurrentQueue Outgoing = new ConcurrentQueue(); + public ConcurrentQueue Commands = new ConcurrentQueue(); + public ConcurrentQueue ConnectionEvents = new ConcurrentQueue(); + public ConcurrentQueue DisconnectionEvents = new ConcurrentQueue(); + + // Thread + private Thread WorkerThread; + + public void Start() + { + if (WorkerThread != null && WorkerThread.IsAlive) + { + // Cannot do that. + Debug.LogError("A worker thread is already running. Cannot start another."); + return; + } + + CeaseOperation = false; + ThreadParamInfo threadParams = new ThreadParamInfo() + { + Address = BindAddress, + Port = BindPort, + Peers = MaximumPeers, + Channels = MaximumChannels, + PollTime = PollTime, + PacketSizeLimit = MaximumPacketSize, + Verbosity = Verbosity + }; + + // Drain queues. + if (Incoming != null) while (Incoming.TryDequeue(out _)) ; + if (Outgoing != null) while (Outgoing.TryDequeue(out _)) ; + if (Commands != null) while (Commands.TryDequeue(out _)) ; + if (ConnectionEvents != null) while (ConnectionEvents.TryDequeue(out _)) ; + if (DisconnectionEvents != null) while (DisconnectionEvents.TryDequeue(out _)) ; + + WorkerThread = new Thread(ThreadWorker); + WorkerThread.Start(threadParams); + + // Announce + if (Verbosity > 0) + Debug.Log("Server has dispatched worker thread."); + } + + public void Stop() + { + if (Verbosity > 0) + Debug.Log("Telling server thread to stop, this may take a while depending on network load"); + CeaseOperation = true; + } + + private void ThreadWorker(Object parameters) + { + if (Verbosity > 0) + Debug.Log("Ignorance Server: Initializing. Please stand by..."); + + // Thread cache items + ThreadParamInfo setupInfo; + Address serverAddress = new Address(); + Host serverENetHost; + Event serverENetEvent; + + Peer[] serverPeerArray; + + // Grab the setup information. + if (parameters.GetType() == typeof(ThreadParamInfo)) + { + setupInfo = (ThreadParamInfo)parameters; + } + else + { + Debug.LogError("Ignorance Server: Startup failure: Invalid thread parameters. Aborting."); + return; + } + + // Attempt to initialize ENet inside the thread. + if (Library.Initialize()) + { + Debug.Log("Ignorance Server: ENet initialized."); + } + else + { + Debug.LogError("Ignorance Server: Failed to initialize ENet. This threads' fucked."); + return; + } + + // Configure the server address. + serverAddress.SetHost(setupInfo.Address); + serverAddress.Port = (ushort)setupInfo.Port; + serverPeerArray = new Peer[setupInfo.Peers]; + + using (serverENetHost = new Host()) + { + // Create the server object. + serverENetHost.Create(serverAddress, setupInfo.Peers, setupInfo.Channels); + + // Loop until we're told to cease operations. + while (!CeaseOperation) + { + // Intermission: Command Handling + while (Commands.TryDequeue(out IgnoranceCommandPacket commandPacket)) + { + switch (commandPacket.Type) + { + default: + break; + + // Boot a Peer off the Server. + case IgnoranceCommandType.ServerKickPeer: + uint targetPeer = commandPacket.PeerId; + + if (!serverPeerArray[targetPeer].IsSet) continue; + if (setupInfo.Verbosity > 0) + Debug.Log($"Ignorance Server: Booting Peer {targetPeer} off this server instance."); + + IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent() + { + WasDisconnect = true, + NativePeerId = targetPeer + }; + + DisconnectionEvents.Enqueue(iced); + + // Disconnect and reset the peer array's entry for that peer. + serverPeerArray[targetPeer].DisconnectNow(0); + serverPeerArray[targetPeer] = default; + break; + } + } + + // Step One: + // ---> Sending to peers + while (Outgoing.TryDequeue(out IgnoranceOutgoingPacket outgoingPacket)) + { + // Only create a packet if the server knows the peer. + if (serverPeerArray[outgoingPacket.NativePeerId].IsSet) + { + int ret = serverPeerArray[outgoingPacket.NativePeerId].Send(outgoingPacket.Channel, ref outgoingPacket.Payload); + + if (ret < 0 && setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Server: ENet error code {ret} while sending packet to Peer {outgoingPacket.NativePeerId}."); + } + else + { + // A peer might have disconnected, this is OK - just log the packet if set to paranoid. + if (setupInfo.Verbosity > 1) + Debug.LogWarning("Ignorance Server: Can't send packet, a native peer object is not set. This may be normal if the Peer has disconnected before this send cycle."); + } + + } + + // Step 2 + // <--- Receiving from peers + bool pollComplete = false; + + while (!pollComplete) + { + Packet incomingPacket; + Peer incomingPeer; + int incomingPacketLength; + + // Any events happening? + if (serverENetHost.CheckEvents(out serverENetEvent) <= 0) + { + // If service time is met, break out of it. + if (serverENetHost.Service(setupInfo.PollTime, out serverENetEvent) <= 0) break; + + pollComplete = true; + } + + // Setup the packet references. + incomingPeer = serverENetEvent.Peer; + + switch (serverENetEvent.Type) + { + // Idle. + case EventType.None: + default: + break; + + // Connection Event. + case EventType.Connect: + if (setupInfo.Verbosity > 1) + Debug.Log("Ignorance Server: Here comes a new Peer connection."); + + IgnoranceConnectionEvent ice = new IgnoranceConnectionEvent() + { + NativePeerId = incomingPeer.ID, + IP = incomingPeer.IP, + Port = incomingPeer.Port + }; + + ConnectionEvents.Enqueue(ice); + + // Assign a reference to the Peer. + serverPeerArray[incomingPeer.ID] = incomingPeer; + break; + + // Disconnect/Timeout. Mirror doesn't care if it's either, so we lump them together. + case EventType.Disconnect: + case EventType.Timeout: + if (!serverPeerArray[incomingPeer.ID].IsSet) break; + + if (setupInfo.Verbosity > 1) + Debug.Log("Ignorance Server: Peer disconnection."); + + IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent() + { + WasDisconnect = true, + NativePeerId = incomingPeer.ID + }; + + DisconnectionEvents.Enqueue(iced); + + // Reset the peer array's entry for that peer. + serverPeerArray[incomingPeer.ID] = default; + break; + + case EventType.Receive: + // Receive event type usually includes a packet; so cache its reference. + incomingPacket = serverENetEvent.Packet; + if (!incomingPacket.IsSet) + { + if (setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Server: A receive event did not supply us with a packet to work with. This should never happen."); + break; + } + + incomingPacketLength = incomingPacket.Length; + + // Firstly check if the packet is too big. If it is, do not process it - drop it. + if (incomingPacketLength > setupInfo.PacketSizeLimit) + { + if (setupInfo.Verbosity > 0) + Debug.LogWarning($"Ignorance Server: Incoming packet is too big. My limit is {setupInfo.PacketSizeLimit} byte(s) whilest this packet is {incomingPacketLength} bytes."); + + incomingPacket.Dispose(); + break; + } + + IgnoranceIncomingPacket incomingQueuePacket = new IgnoranceIncomingPacket + { + Channel = serverENetEvent.ChannelID, + NativePeerId = incomingPeer.ID, + Payload = incomingPacket, + }; + + // Enqueue. + Incoming.Enqueue(incomingQueuePacket); + break; + } + } + } + + if (Verbosity > 0) + Debug.Log("Ignorance Server: Shutdown commencing, flushing connections."); + + // Cleanup and flush everything. + serverENetHost.Flush(); + + // Kick everyone. + for (int i = 0; i < serverPeerArray.Length; i++) + { + if (!serverPeerArray[i].IsSet) continue; + serverPeerArray[i].DisconnectNow(0); + } + } + + // Flush again to ensure ENet gets those Disconnection stuff out. + // May not be needed; better to err on side of caution + + if (setupInfo.Verbosity > 0) + Debug.Log("Ignorance Server: Shutdown complete."); + + Library.Deinitialize(); + } + + private struct ThreadParamInfo + { + public int Channels; + public int Peers; + public int PollTime; + public int Port; + public int PacketSizeLimit; + public int Verbosity; + public string Address; + } + } +} diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs.meta new file mode 100644 index 0000000..8b3212b --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Core/IgnoranceServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1069f42b88a4adb4ab1990cec4949343 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies.meta new file mode 100644 index 0000000..565dc3b --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12f903db684732e45b130ad56f7c86c1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs new file mode 100644 index 0000000..cf4336c --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs @@ -0,0 +1,1411 @@ +/* + * Managed C# wrapper for an extended version of ENet + * This is a fork from upstream and is available at http://github.com/SoftwareGuy/ENet-CSharp + * + * Copyright (c) 2019 Matt Coburn (SoftwareGuy/Coburn64), Chris Burns (c6burns) + * Copyright (c) 2013 James Bellinger, 2016 Nate Shoffner, 2018 Stanislav Denisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace ENet +{ + [Flags] + public enum PacketFlags + { + None = 0, + Reliable = 1 << 0, + Unsequenced = 1 << 1, + NoAllocate = 1 << 2, + UnreliableFragmented = 1 << 3, + Instant = 1 << 4, + Unthrottled = 1 << 5, + Sent = 1 << 8 + } + + public enum EventType + { + None = 0, + Connect = 1, + Disconnect = 2, + Receive = 3, + Timeout = 4 + } + + public enum PeerState + { + Uninitialized = -1, + Disconnected = 0, + Connecting = 1, + AcknowledgingConnect = 2, + ConnectionPending = 3, + ConnectionSucceeded = 4, + Connected = 5, + DisconnectLater = 6, + Disconnecting = 7, + AcknowledgingDisconnect = 8, + Zombie = 9 + } + + [StructLayout(LayoutKind.Explicit, Size = 18)] + internal struct ENetAddress + { + [FieldOffset(16)] + public ushort port; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ENetEvent + { + public EventType type; + public IntPtr peer; + public byte channelID; + public uint data; + public IntPtr packet; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ENetCallbacks + { + public AllocCallback malloc; + public FreeCallback free; + public NoMemoryCallback noMemory; + } + + public delegate IntPtr AllocCallback(IntPtr size); + public delegate void FreeCallback(IntPtr memory); + public delegate void NoMemoryCallback(); + public delegate void PacketFreeCallback(Packet packet); + public delegate int InterceptCallback(ref Event @event, ref Address address, IntPtr receivedData, int receivedDataLength); + public delegate ulong ChecksumCallback(IntPtr buffers, int bufferCount); + + internal static class ArrayPool + { + [ThreadStatic] + private static byte[] byteBuffer; + [ThreadStatic] + private static IntPtr[] pointerBuffer; + + public static byte[] GetByteBuffer() + { + if (byteBuffer == null) + byteBuffer = new byte[64]; + + return byteBuffer; + } + + public static IntPtr[] GetPointerBuffer() + { + if (pointerBuffer == null) + pointerBuffer = new IntPtr[Library.maxPeers]; + + return pointerBuffer; + } + } + + public struct Address + { + private ENetAddress nativeAddress; + + internal ENetAddress NativeData + { + get + { + return nativeAddress; + } + + set + { + nativeAddress = value; + } + } + + internal Address(ENetAddress address) + { + nativeAddress = address; + } + + public ushort Port + { + get + { + return nativeAddress.port; + } + + set + { + nativeAddress.port = value; + } + } + + public string GetIP() + { + StringBuilder ip = new StringBuilder(1025); + + if (Native.enet_address_get_ip(ref nativeAddress, ip, (IntPtr)ip.Capacity) != 0) + return String.Empty; + + return ip.ToString(); + } + + public bool SetIP(string ip) + { + if (ip == null) + throw new ArgumentNullException("ip"); + + return Native.enet_address_set_ip(ref nativeAddress, ip) == 0; + } + + public string GetHost() + { + StringBuilder hostName = new StringBuilder(1025); + + if (Native.enet_address_get_hostname(ref nativeAddress, hostName, (IntPtr)hostName.Capacity) != 0) + return String.Empty; + + return hostName.ToString(); + } + + public bool SetHost(string hostName) + { + if (hostName == null) + throw new ArgumentNullException("hostName"); + + return Native.enet_address_set_hostname(ref nativeAddress, hostName) == 0; + } + } + + public struct Event + { + private ENetEvent nativeEvent; + + internal ENetEvent NativeData + { + get + { + return nativeEvent; + } + + set + { + nativeEvent = value; + } + } + + internal Event(ENetEvent @event) + { + nativeEvent = @event; + } + + public EventType Type + { + get + { + return nativeEvent.type; + } + } + + public Peer Peer + { + get + { + return new Peer(nativeEvent.peer); + } + } + + public byte ChannelID + { + get + { + return nativeEvent.channelID; + } + } + + public uint Data + { + get + { + return nativeEvent.data; + } + } + + public Packet Packet + { + get + { + return new Packet(nativeEvent.packet); + } + } + } + + public class Callbacks + { + private ENetCallbacks nativeCallbacks; + + internal ENetCallbacks NativeData + { + get + { + return nativeCallbacks; + } + + set + { + nativeCallbacks = value; + } + } + + public Callbacks(AllocCallback allocCallback, FreeCallback freeCallback, NoMemoryCallback noMemoryCallback) + { + nativeCallbacks.malloc = allocCallback; + nativeCallbacks.free = freeCallback; + nativeCallbacks.noMemory = noMemoryCallback; + } + } + + public struct Packet : IDisposable + { + private IntPtr nativePacket; + + internal IntPtr NativeData + { + get + { + return nativePacket; + } + + set + { + nativePacket = value; + } + } + + internal Packet(IntPtr packet) + { + nativePacket = packet; + } + + public void Dispose() + { + if (nativePacket != IntPtr.Zero) + { + Native.enet_packet_dispose(nativePacket); + nativePacket = IntPtr.Zero; + } + } + + public bool IsSet + { + get + { + return nativePacket != IntPtr.Zero; + } + } + + public IntPtr Data + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_data(nativePacket); + } + } + + public IntPtr UserData + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_user_data(nativePacket); + } + + set + { + ThrowIfNotCreated(); + + Native.enet_packet_set_user_data(nativePacket, value); + } + } + + public int Length + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_get_length(nativePacket); + } + } + + public bool HasReferences + { + get + { + ThrowIfNotCreated(); + + return Native.enet_packet_check_references(nativePacket) != 0; + } + } + + internal void ThrowIfNotCreated() + { + if (nativePacket == IntPtr.Zero) + throw new InvalidOperationException("Packet not created"); + } + + public void SetFreeCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_packet_set_free_callback(nativePacket, callback); + } + + public void SetFreeCallback(PacketFreeCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_packet_set_free_callback(nativePacket, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void Create(byte[] data) + { + if (data == null) + throw new ArgumentNullException("data"); + + Create(data, data.Length); + } + + public void Create(byte[] data, int length) + { + Create(data, length, PacketFlags.None); + } + + public void Create(byte[] data, PacketFlags flags) + { + Create(data, data.Length, flags); + } + + public void Create(byte[] data, int length, PacketFlags flags) + { + if (data == null) + throw new ArgumentNullException("data"); + + if (length < 0 || length > data.Length) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create(data, (IntPtr)length, flags); + } + + public void Create(IntPtr data, int length, PacketFlags flags) + { + if (data == IntPtr.Zero) + throw new ArgumentNullException("data"); + + if (length < 0) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create(data, (IntPtr)length, flags); + } + + public void Create(byte[] data, int offset, int length, PacketFlags flags) + { + if (data == null) + throw new ArgumentNullException("data"); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + + if (length < 0 || length > data.Length) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create_offset(data, (IntPtr)length, (IntPtr)offset, flags); + } + + public void Create(IntPtr data, int offset, int length, PacketFlags flags) + { + if (data == IntPtr.Zero) + throw new ArgumentNullException("data"); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + + if (length < 0) + throw new ArgumentOutOfRangeException("length"); + + nativePacket = Native.enet_packet_create_offset(data, (IntPtr)length, (IntPtr)offset, flags); + } + + public void CopyTo(byte[] destination, int startPos = 0) + { + if (destination == null) + throw new ArgumentNullException("destination"); + + // Fix by katori, prevents trying to copy a NULL + // from native world (ie. disconnect a client) + if (Data == null) + { + return; + } + + Marshal.Copy(Data, destination, startPos, Length); + } + } + + public class Host : IDisposable + { + private IntPtr nativeHost; + + internal IntPtr NativeData + { + get + { + return nativeHost; + } + + set + { + nativeHost = value; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (nativeHost != IntPtr.Zero) + { + Native.enet_host_destroy(nativeHost); + nativeHost = IntPtr.Zero; + } + } + + ~Host() + { + Dispose(false); + } + + public bool IsSet + { + get + { + return nativeHost != IntPtr.Zero; + } + } + + public uint PeersCount + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_peers_count(nativeHost); + } + } + + public uint PacketsSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_packets_sent(nativeHost); + } + } + + public uint PacketsReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_packets_received(nativeHost); + } + } + + public uint BytesSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_bytes_sent(nativeHost); + } + } + + public uint BytesReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_host_get_bytes_received(nativeHost); + } + } + + internal void ThrowIfNotCreated() + { + if (nativeHost == IntPtr.Zero) + throw new InvalidOperationException("Host not created"); + } + + private static void ThrowIfChannelsExceeded(int channelLimit) + { + if (channelLimit < 0 || channelLimit > Library.maxChannelCount) + throw new ArgumentOutOfRangeException("channelLimit"); + } + + public void Create() + { + Create(null, 1, 0); + } + + public void Create(int bufferSize) + { + Create(null, 1, 0, 0, 0, bufferSize); + } + + public void Create(Address? address, int peerLimit) + { + Create(address, peerLimit, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit) + { + Create(address, peerLimit, channelLimit, 0, 0, 0); + } + + public void Create(int peerLimit, int channelLimit) + { + Create(null, peerLimit, channelLimit, 0, 0, 0); + } + + public void Create(int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth) + { + Create(null, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth) + { + Create(address, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth, 0); + } + + public void Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize) + { + if (nativeHost != IntPtr.Zero) + throw new InvalidOperationException("Host already created"); + + if (peerLimit < 0 || peerLimit > Library.maxPeers) + throw new ArgumentOutOfRangeException("peerLimit"); + + ThrowIfChannelsExceeded(channelLimit); + + if (address != null) + { + var nativeAddress = address.Value.NativeData; + + nativeHost = Native.enet_host_create(ref nativeAddress, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth, outgoingBandwidth, bufferSize); + } + else + { + nativeHost = Native.enet_host_create(IntPtr.Zero, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth, outgoingBandwidth, bufferSize); + } + + if (nativeHost == IntPtr.Zero) + throw new InvalidOperationException("Host creation call failed"); + } + + public void PreventConnections(bool state) + { + ThrowIfNotCreated(); + + Native.enet_host_prevent_connections(nativeHost, (byte)(state ? 1 : 0)); + } + + public void Broadcast(byte channelID, ref Packet packet) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + Native.enet_host_broadcast(nativeHost, channelID, packet.NativeData); + packet.NativeData = IntPtr.Zero; + } + + public void Broadcast(byte channelID, ref Packet packet, Peer excludedPeer) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + Native.enet_host_broadcast_exclude(nativeHost, channelID, packet.NativeData, excludedPeer.NativeData); + packet.NativeData = IntPtr.Zero; + } + + public void Broadcast(byte channelID, ref Packet packet, Peer[] peers) + { + if (peers == null) + throw new ArgumentNullException("peers"); + + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + + if (peers.Length > 0) + { + IntPtr[] nativePeers = ArrayPool.GetPointerBuffer(); + int nativeCount = 0; + + for (int i = 0; i < peers.Length; i++) + { + if (peers[i].NativeData != IntPtr.Zero) + { + nativePeers[nativeCount] = peers[i].NativeData; + nativeCount++; + } + } + + Native.enet_host_broadcast_selective(nativeHost, channelID, packet.NativeData, nativePeers, (IntPtr)nativeCount); + } + + packet.NativeData = IntPtr.Zero; + } + + public int CheckEvents(out Event @event) + { + ThrowIfNotCreated(); + + ENetEvent nativeEvent; + + var result = Native.enet_host_check_events(nativeHost, out nativeEvent); + + if (result <= 0) + { + @event = default(Event); + + return result; + } + + @event = new Event(nativeEvent); + + return result; + } + + public Peer Connect(Address address) + { + return Connect(address, 0, 0); + } + + public Peer Connect(Address address, int channelLimit) + { + return Connect(address, channelLimit, 0); + } + + public Peer Connect(Address address, int channelLimit, uint data) + { + ThrowIfNotCreated(); + ThrowIfChannelsExceeded(channelLimit); + + var nativeAddress = address.NativeData; + var peer = new Peer(Native.enet_host_connect(nativeHost, ref nativeAddress, (IntPtr)channelLimit, data)); + + if (peer.NativeData == IntPtr.Zero) + throw new InvalidOperationException("Host connect call failed"); + + return peer; + } + + public int Service(int timeout, out Event @event) + { + if (timeout < 0) + throw new ArgumentOutOfRangeException("timeout"); + + ThrowIfNotCreated(); + + ENetEvent nativeEvent; + + var result = Native.enet_host_service(nativeHost, out nativeEvent, (uint)timeout); + + if (result <= 0) + { + @event = default(Event); + + return result; + } + + @event = new Event(nativeEvent); + + return result; + } + + public void SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth) + { + ThrowIfNotCreated(); + + Native.enet_host_bandwidth_limit(nativeHost, incomingBandwidth, outgoingBandwidth); + } + + public void SetChannelLimit(int channelLimit) + { + ThrowIfNotCreated(); + ThrowIfChannelsExceeded(channelLimit); + + Native.enet_host_channel_limit(nativeHost, (IntPtr)channelLimit); + } + + public void SetMaxDuplicatePeers(ushort number) + { + ThrowIfNotCreated(); + + Native.enet_host_set_max_duplicate_peers(nativeHost, number); + } + + public void SetInterceptCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, callback); + } + + public void SetInterceptCallback(InterceptCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void SetChecksumCallback(IntPtr callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_checksum_callback(nativeHost, callback); + } + + public void SetChecksumCallback(ChecksumCallback callback) + { + ThrowIfNotCreated(); + + Native.enet_host_set_checksum_callback(nativeHost, Marshal.GetFunctionPointerForDelegate(callback)); + } + + public void Flush() + { + ThrowIfNotCreated(); + + Native.enet_host_flush(nativeHost); + } + } + + public struct Peer + { + private IntPtr nativePeer; + private uint nativeID; + + internal IntPtr NativeData + { + get + { + return nativePeer; + } + + set + { + nativePeer = value; + } + } + + internal Peer(IntPtr peer) + { + nativePeer = peer; + nativeID = nativePeer != IntPtr.Zero ? Native.enet_peer_get_id(nativePeer) : 0; + } + + public bool IsSet + { + get + { + return nativePeer != IntPtr.Zero; + } + } + + public uint ID + { + get + { + return nativeID; + } + } + + public string IP + { + get + { + ThrowIfNotCreated(); + + byte[] ip = ArrayPool.GetByteBuffer(); + + if (Native.enet_peer_get_ip(nativePeer, ip, (IntPtr)ip.Length) == 0) + return Encoding.ASCII.GetString(ip, 0, ip.StringLength()); + else + return String.Empty; + } + } + + public ushort Port + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_port(nativePeer); + } + } + + public uint MTU + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_mtu(nativePeer); + } + } + + public PeerState State + { + get + { + return nativePeer == IntPtr.Zero ? PeerState.Uninitialized : Native.enet_peer_get_state(nativePeer); + } + } + + public uint RoundTripTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_rtt(nativePeer); + } + } + + public uint LastRoundTripTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_last_rtt(nativePeer); + } + } + + public uint LastSendTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_lastsendtime(nativePeer); + } + } + + public uint LastReceiveTime + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_lastreceivetime(nativePeer); + } + } + + public ulong PacketsSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_sent(nativePeer); + } + } + + public ulong PacketsLost + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_lost(nativePeer); + } + } + + public float PacketsThrottle + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_packets_throttle(nativePeer); + } + } + + public ulong BytesSent + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_bytes_sent(nativePeer); + } + } + + public ulong BytesReceived + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_bytes_received(nativePeer); + } + } + + public IntPtr Data + { + get + { + ThrowIfNotCreated(); + + return Native.enet_peer_get_data(nativePeer); + } + + set + { + ThrowIfNotCreated(); + + Native.enet_peer_set_data(nativePeer, value); + } + } + + internal void ThrowIfNotCreated() + { + if (nativePeer == IntPtr.Zero) + throw new InvalidOperationException("Peer not created"); + } + + public void ConfigureThrottle(uint interval, uint acceleration, uint deceleration, uint threshold) + { + ThrowIfNotCreated(); + + Native.enet_peer_throttle_configure(nativePeer, interval, acceleration, deceleration, threshold); + } + + public int Send(byte channelID, ref Packet packet) + { + ThrowIfNotCreated(); + + packet.ThrowIfNotCreated(); + + return Native.enet_peer_send(nativePeer, channelID, packet.NativeData); + } + + public bool Receive(out byte channelID, out Packet packet) + { + ThrowIfNotCreated(); + + IntPtr nativePacket = Native.enet_peer_receive(nativePeer, out channelID); + + if (nativePacket != IntPtr.Zero) + { + packet = new Packet(nativePacket); + + return true; + } + + packet = default(Packet); + + return false; + } + + public void Ping() + { + ThrowIfNotCreated(); + + Native.enet_peer_ping(nativePeer); + } + + public void PingInterval(uint interval) + { + ThrowIfNotCreated(); + + Native.enet_peer_ping_interval(nativePeer, interval); + } + + public void Timeout(uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum) + { + ThrowIfNotCreated(); + + Native.enet_peer_timeout(nativePeer, timeoutLimit, timeoutMinimum, timeoutMaximum); + } + + public void Disconnect(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect(nativePeer, data); + } + + public void DisconnectNow(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect_now(nativePeer, data); + } + + public void DisconnectLater(uint data) + { + ThrowIfNotCreated(); + + Native.enet_peer_disconnect_later(nativePeer, data); + } + + public void Reset() + { + ThrowIfNotCreated(); + + Native.enet_peer_reset(nativePeer); + } + } + + public static class Extensions + { + public static int StringLength(this byte[] data) + { + if (data == null) + throw new ArgumentNullException("data"); + + int i; + + for (i = 0; i < data.Length && data[i] != 0; i++) ; + + return i; + } + } + + public static class Library + { + public const uint maxChannelCount = 0xFF; + public const uint maxPeers = 0xFFF; + public const uint maxPacketSize = 32 * 1024 * 1024; + public const uint throttleThreshold = 40; + public const uint throttleScale = 32; + public const uint throttleAcceleration = 2; + public const uint throttleDeceleration = 2; + public const uint throttleInterval = 5000; + public const uint timeoutLimit = 32; + public const uint timeoutMinimum = 5000; + public const uint timeoutMaximum = 30000; + public const uint version = (2 << 16) | (4 << 8) | (7); + + public static uint Time + { + get + { + return Native.enet_time_get(); + } + } + + public static bool Initialize() + { + if (Native.enet_linked_version() != version) + throw new InvalidOperationException("ENet native is out of date. Download the latest release from https://github.com/SoftwareGuy/ENet-CSharp/releases"); + + return Native.enet_initialize() == 0; + } + + public static bool Initialize(Callbacks callbacks) + { + if (callbacks == null) + throw new ArgumentNullException("callbacks"); + + if (Native.enet_linked_version() != version) + throw new InvalidOperationException("ENet native is out of date. Download the latest release from https://github.com/SoftwareGuy/ENet-CSharp/releases"); + + ENetCallbacks nativeCallbacks = callbacks.NativeData; + + return Native.enet_initialize_with_callbacks(version, ref nativeCallbacks) == 0; + } + + public static void Deinitialize() + { + Native.enet_deinitialize(); + } + + public static ulong CRC64(IntPtr buffers, int bufferCount) + { + return Native.enet_crc64(buffers, bufferCount); + } + } + + [SuppressUnmanagedCodeSecurity] + internal static class Native + { + // This should address Unity usage and bug #66: Platform specific Enet / libenet + // https://github.com/SoftwareGuy/Ignorance/issues/66 +#if UNITY_EDITOR + // We are inside the Unity Editor. +#if UNITY_EDITOR_OSX + // Unity Editor on macOS needs to use libenet. + private const string nativeLibrary = "libenet"; +#else + private const string nativeLibrary = "enet"; +#endif +#endif + +#if !UNITY_EDITOR + // We're not inside the Unity Editor. +#if __APPLE__ && !(__IOS__ || UNITY_IOS) + // Use libenet on macOS. + private const string nativeLibrary = "libenet"; +#elif __IOS__ || UNITY_IOS + // We're building for a certain mobile fruity OS. + private const string nativeLibrary = "__Internal"; +#else + // Assume everything else, Windows et al. + private const string nativeLibrary = "enet"; +#endif +#endif + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_initialize(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_initialize_with_callbacks(uint version, ref ENetCallbacks inits); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_deinitialize(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_linked_version(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_time_get(); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_crc64(IntPtr buffers, int bufferCount); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_set_ip(ref ENetAddress address, string ip); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_set_hostname(ref ENetAddress address, string hostName); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_get_ip(ref ENetAddress address, StringBuilder ip, IntPtr ipLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_address_get_hostname(ref ENetAddress address, StringBuilder hostName, IntPtr nameLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create(byte[] data, IntPtr dataLength, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create(IntPtr data, IntPtr dataLength, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create_offset(byte[] data, IntPtr dataLength, IntPtr dataOffset, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_create_offset(IntPtr data, IntPtr dataLength, IntPtr dataOffset, PacketFlags flags); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_packet_check_references(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_get_data(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_get_user_data(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_packet_set_user_data(IntPtr packet, IntPtr userData); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_packet_get_length(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_packet_set_free_callback(IntPtr packet, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_packet_dispose(IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_create(ref ENetAddress address, IntPtr peerLimit, IntPtr channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_create(IntPtr address, IntPtr peerLimit, IntPtr channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_host_connect(IntPtr host, ref ENetAddress address, IntPtr channelCount, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast(IntPtr host, byte channelID, IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast_exclude(IntPtr host, byte channelID, IntPtr packet, IntPtr excludedPeer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_broadcast_selective(IntPtr host, byte channelID, IntPtr packet, IntPtr[] peers, IntPtr peersLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_host_service(IntPtr host, out ENetEvent @event, uint timeout); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_host_check_events(IntPtr host, out ENetEvent @event); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_channel_limit(IntPtr host, IntPtr channelLimit); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_bandwidth_limit(IntPtr host, uint incomingBandwidth, uint outgoingBandwidth); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_peers_count(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_packets_sent(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_packets_received(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_bytes_sent(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_host_get_bytes_received(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_max_duplicate_peers(IntPtr host, ushort number); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_intercept_callback(IntPtr host, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_checksum_callback(IntPtr host, IntPtr callback); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_flush(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_destroy(IntPtr host); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_prevent_connections(IntPtr host, byte state); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_throttle_configure(IntPtr peer, uint interval, uint acceleration, uint deceleration, uint threshold); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_id(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_peer_get_ip(IntPtr peer, byte[] ip, IntPtr ipLength); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ushort enet_peer_get_port(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_mtu(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern PeerState enet_peer_get_state(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_rtt(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_last_rtt(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_lastsendtime(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint enet_peer_get_lastreceivetime(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_packets_sent(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_packets_lost(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern float enet_peer_get_packets_throttle(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_bytes_sent(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong enet_peer_get_bytes_received(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_peer_get_data(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_set_data(IntPtr peer, IntPtr data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern int enet_peer_send(IntPtr peer, byte channelID, IntPtr packet); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr enet_peer_receive(IntPtr peer, out byte channelID); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_ping(IntPtr peer); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_ping_interval(IntPtr peer, uint pingInterval); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_timeout(IntPtr peer, uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect_now(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_disconnect_later(IntPtr peer, uint data); + + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_peer_reset(IntPtr peer); + +#if UNITY_EDITOR + public static string nativeLibraryName { get { return nativeLibrary; } } +#endif + + } +} diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs.meta new file mode 100644 index 0000000..d58413a --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Dependencies/ENet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12a7875e95f5ebb4a9b58390441dd933 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor.meta new file mode 100644 index 0000000..40c6fd2 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0995e08af14888348b42ecaa6eb21544 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs new file mode 100644 index 0000000..0ff3186 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs @@ -0,0 +1,83 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using System.Linq; +using UnityEditor; + +namespace IgnoranceTransport +{ + /// + /// Adds the given define symbols to PlayerSettings define symbols. + /// Just add your own define symbols to the Symbols property at the below. + /// + [InitializeOnLoad] + public class AddIgnoranceDefine : Editor + { + private static string existingDefines = string.Empty; + + /// + /// Symbols that will be added to the editor + /// + public static readonly string[] Symbols = new string[] { + "IGNORANCE", // Ignorance exists + "IGNORANCE_1", // Major version + "IGNORANCE_1_4" // Major and minor version + }; + + /// + /// Do not remove these symbols + /// + public static readonly string[] DoNotRemoveTheseSymbols = new string[] + { + "IGNORANCE_NO_UPNP", + "IGNORANCE_MIRROR_POLLING" + }; + + /// + /// Add define symbols as soon as Unity gets done compiling. + /// + static AddIgnoranceDefine() + { + // Get the current scripting defines + string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); + if (existingDefines == definesString) + { + // 1.2.6: There is no need to apply the changes, return. + return; + } + + // Convert the string to a list + List allDefines = definesString.Split(';').ToList(); + // Remove any old version defines from previous installs + allDefines.RemoveAll(IsSafeToRemove); + // x => x.StartsWith("IGNORANCE") && !DoesSymbolExistInBlacklist(x)); + // Add any symbols that weren't already in the list + allDefines.AddRange(Symbols.Except(allDefines)); + + string newDefines = string.Join(";", allDefines.ToArray()); + PlayerSettings.SetScriptingDefineSymbolsForGroup( + EditorUserBuildSettings.selectedBuildTargetGroup, + newDefines + ); + + existingDefines = newDefines; + } + + // 1.2.4: Workaround to stop things from eating custom IGNORANCE_ symbols + static bool DoesSymbolExistInBlacklist(string symbol) + { + foreach(string s in DoNotRemoveTheseSymbols) + { + if (s == symbol.Trim()) return true; + } + + return false; + } + + static bool IsSafeToRemove (string input) + { + if (input.StartsWith("IGNORANCE") && !DoesSymbolExistInBlacklist(input)) return true; + return false; + } + } +} +#endif diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs.meta new file mode 100644 index 0000000..dbff870 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/AddScriptingDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed8acbde141f2d8469baf2142712de9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs new file mode 100644 index 0000000..dee6b62 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs @@ -0,0 +1,44 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using UnityEditor; + +namespace IgnoranceTransport +{ + public class IgnoranceToolbox + { +#pragma warning disable IDE0051 + [MenuItem("Ignorance/Mirror/Switch Update Method")] + public static void SwitchIgnoranceUpdateMethod () + { + + } + + [MenuItem("Ignorance/Debug/Reveal ENet Native Library Name")] + public static void RevealEnetLibraryName() + { + EditorUtility.DisplayDialog("Enet Library Name", $"Use this for debugging.\nYour platform expects the native Enet library to be called: {ENet.Native.nativeLibraryName}", "Got it"); + } + + [MenuItem("Ignorance/RTFM/Github Repository")] + private static void LaunchGithubRepo() + { + UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/Ignorance"); + } + + [MenuItem("Ignorance/RTFM/Github Issue Tracker")] + private static void LaunchGithubIssueTracker() + { + UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/Ignorance/issues"); + } + + [MenuItem("Ignorance/RTFM/ENet-CSharp Fork")] + private static void LaunchENetCSharpForkRepo() + { + UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/ENet-CSharp"); + } + + +#pragma warning restore + } +} +#endif diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs.meta new file mode 100644 index 0000000..cf61ba3 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Editor/IgnoranceToolbox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fdecc996313d614ca16214d4e2b9162 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs new file mode 100644 index 0000000..28dbf7a --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs @@ -0,0 +1,746 @@ +// Ignorance 1.4.x +// Ignorance. It really kicks the Unity LLAPIs ass. +// https://github.com/SoftwareGuy/Ignorance +// ----------------- +// Copyright (c) 2019 - 2020 Matt Coburn (SoftwareGuy/Coburn64) +// Ignorance Transport is licensed under the MIT license. Refer +// to the LICENSE file for more information. +// ----------------- +// Ignorance Experimental (New) Version +// ----------------- +using ENet; +using Mirror; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace IgnoranceTransport +{ + [DisallowMultipleComponent] + public class Ignorance : Transport + { + #region Inspector options + public int port = 7777; + + [Header("Debug & Logging Configuration")] + [Tooltip("How verbose do you want Ignorance to be?")] + public IgnoranceLogType LogType = IgnoranceLogType.Standard; + [Tooltip("Uses OnGUI to present you with statistics for Server and Client backend instances.")] + public bool DebugDisplay = false; + + [Header("Server Configuration")] + [Tooltip("Should the server bind to all interfaces?")] + public bool serverBindsAll = true; + [Tooltip("This is only used if Server Binds All is unticked.")] + public string serverBindAddress = string.Empty; + [Tooltip("This tells ENet how many Peer slots to create. Helps performance, avoids looping over huge native arrays. Recommended: Max Mirror players, rounded to nearest 10. (Example: 16 -> 20).")] + public int serverMaxPeerCapacity = 50; + [Tooltip("How long ENet waits in native world. The higher this value, the more CPU usage. Lower values may/may not impact performance at high packet load.")] + public int serverMaxNativeWaitTime = 1; + + [Header("Client Configuration")] + [Tooltip("How long ENet waits in native world. The higher this value, the more CPU usage used. This is for the client, unlike the one above. Higher value probably trades CPU for more responsive networking.")] + public int clientMaxNativeWaitTime = 3; + [Tooltip("Interval between asking ENet for client status updates. Set to -1 to disable.")] + public int clientStatusUpdateInterval = -1; + + [Header("Channel Configuration")] + [Tooltip("You must define your channels in the array shown here, otherwise ENet will not know what channel delivery type to use.")] + public IgnoranceChannelTypes[] Channels; + + [Header("Low-level Tweaking")] + [Tooltip("Used internally to keep allocations to a minimum. This is how much memory will be consumed by the packet buffer on startup, and then reused.")] + public int PacketBufferCapacity = 4096; + + [Tooltip("For UDP based protocols, it's best to keep your data under the safe MTU of 1200 bytes. You can increase this, however beware this may open you up to allocation attacks.")] + public int MaxAllowedPacketSize = 33554432; + #endregion + + #region Public Statistics + public IgnoranceClientStats ClientStatistics; + #endregion + +#if MIRROR_26_0_OR_NEWER + public override bool Available() + { + // Ignorance is not available for Unity WebGL, the PS4 (no dev kit to confirm) or Switch (port exists but I have no access to said code). + // Ignorance is available for most other operating systems. +#if (UNITY_WEBGL || UNITY_PS4 || UNITY_SWITCH) + return false; +#else + return true; +#endif + } + + public void Awake() + { + if (LogType != IgnoranceLogType.Nothing) + Debug.Log($"Thanks for using Ignorance {IgnoranceInternals.Version}. Keep up to date, report bugs and support the developer at https://github.com/SoftwareGuy/Ignorance!"); + } + + public override string ToString() + { + return $"Ignorance v{IgnoranceInternals.Version}"; + } + + public override void ClientConnect(string address) + { + ClientState = ConnectionState.Connecting; + cachedConnectionAddress = address; + + // Initialize. + InitializeClientBackend(); + + // Get going. + ignoreDataPackets = false; + + // Start! + Client.Start(); + } + + public override void ClientConnect(Uri uri) + { + if (uri.Scheme != IgnoranceInternals.Scheme) + throw new ArgumentException($"You used an invalid URI: {uri}. Please use {IgnoranceInternals.Scheme}://host:port instead", nameof(uri)); + + if (!uri.IsDefaultPort) + // Set the communication port to the one specified. + port = uri.Port; + + // Pass onwards to the proper handler. + ClientConnect(uri.Host); + } + + public override bool ClientConnected() => ClientState == ConnectionState.Connected; + + public override void ClientDisconnect() + { + if (Client != null) + Client.Stop(); + + // TODO: Figure this one out to see if it's related to a race condition. + // Maybe experiment with a while loop to pause main thread when disconnecting, + // since client might not stop on a dime. + // while(Client.IsAlive) ; + // v1.4.0b1: Probably fixed in IgnoranceClient.cs; need further testing. + + // ignoreDataPackets = true; + ClientState = ConnectionState.Disconnected; + } + +#if !MIRROR_37_0_OR_NEWER + public override void ClientSend(int channelId, ArraySegment segment) +#else + // v1.4.0b6: Mirror rearranged the ClientSend params, so we need to apply a fix for that or + // we end up using the obsoleted version. The obsolete version isn't a fatal error, but + // it's best to stick with the new structures. + public override void ClientSend(ArraySegment segment, int channelId) +#endif + { + if (Client == null) + { + Debug.LogError("Client object is null, this shouldn't really happen but it did..."); + return; + } + + if (channelId < 0 || channelId > Channels.Length) + { + Debug.LogError("Channel ID is out of bounds."); + return; + } + + // Create our struct... + Packet clientOutgoingPacket = default; + int byteCount = segment.Count; + int byteOffset = segment.Offset; + // Set our desired flags... + PacketFlags desiredFlags = (PacketFlags)Channels[channelId]; + + // Warn if over recommended MTU... + bool flagsSet = (desiredFlags & ReliableOrUnreliableFragmented) > 0; + + if (LogType != IgnoranceLogType.Nothing && byteCount > 1200 && !flagsSet) + Debug.LogWarning($"Warning: Client trying to send a Unreliable packet bigger than the recommended ENet 1200 byte MTU ({byteCount} > 1200). ENet will force Reliable Fragmented delivery."); + + // Create the packet. + clientOutgoingPacket.Create(segment.Array, byteOffset, byteCount + byteOffset, desiredFlags); + // byteCount + + // Enqueue the packet. + IgnoranceOutgoingPacket dispatchPacket = new IgnoranceOutgoingPacket + { + Channel = (byte)channelId, + Payload = clientOutgoingPacket + }; + + // Pass the packet onto the thread for dispatch. + Client.Outgoing.Enqueue(dispatchPacket); + } + + public override bool ServerActive() + { + // Very simple check. + return Server != null && Server.IsAlive; + } + +#if !MIRROR_37_0_OR_NEWER + // Workaround for legacy Mirror versions. + public override bool ServerDisconnect(int connectionId) => ServerDisconnectLegacy(connectionId); +#else + public override void ServerDisconnect(int connectionId) + { + if (Server == null) + { + Debug.LogError("Cannot enqueue kick packet; our Server object is null. Something has gone wrong."); + // Return here because otherwise we will get a NRE when trying to enqueue the kick packet. + return; + } + + IgnoranceCommandPacket kickPacket = new IgnoranceCommandPacket + { + Type = IgnoranceCommandType.ServerKickPeer, + PeerId = (uint)connectionId - 1 // ENet's native peer ID will be ConnID - 1 + }; + + // Pass the packet onto the thread for dispatch. + Server.Commands.Enqueue(kickPacket); + } +#endif + + public override string ServerGetClientAddress(int connectionId) + { + if (ConnectionLookupDict.TryGetValue(connectionId, out PeerConnectionData details)) + return $"{details.IP}:{details.Port}"; + + return "(unavailable)"; + } + +#if !MIRROR_37_0_OR_NEWER + public override void ServerSend(int connectionId, int channelId, ArraySegment segment) +#else + // v1.4.0b6: Mirror rearranged the ServerSend params, so we need to apply a fix for that or + // we end up using the obsoleted version. The obsolete version isn't a fatal error, but + // it's best to stick with the new structures. + public override void ServerSend(int connectionId, ArraySegment segment, int channelId) +#endif + { + // Debug.Log($"ServerSend({connectionId}, {channelId}, <{segment.Count} byte segment>)"); + + if (Server == null) + { + Debug.LogError("Cannot enqueue data packet; our Server object is null. Something has gone wrong."); + return; + } + + if (channelId < 0 || channelId > Channels.Length) + { + Debug.LogError("Channel ID is out of bounds."); + return; + } + + // Packet Struct + Packet serverOutgoingPacket = default; + int byteCount = segment.Count; + int byteOffset = segment.Offset; + PacketFlags desiredFlags = (PacketFlags)Channels[channelId]; + + // Warn if over recommended MTU + bool flagsSet = (desiredFlags & ReliableOrUnreliableFragmented) > 0; + + if (LogType != IgnoranceLogType.Nothing && byteCount > 1200 && !flagsSet) + Debug.LogWarning($"Warning: Server trying to send a Unreliable packet bigger than the recommended ENet 1200 byte MTU ({byteCount} > 1200). ENet will force Reliable Fragmented delivery."); + + // Create the packet. + serverOutgoingPacket.Create(segment.Array, byteOffset, byteCount + byteOffset, (PacketFlags)Channels[channelId]); + + // Enqueue the packet. + IgnoranceOutgoingPacket dispatchPacket = new IgnoranceOutgoingPacket + { + Channel = (byte)channelId, + NativePeerId = (uint)connectionId - 1, // ENet's native peer ID will be ConnID - 1 + Payload = serverOutgoingPacket + }; + + Server.Outgoing.Enqueue(dispatchPacket); + + } + + public override void ServerStart() + { + if (LogType != IgnoranceLogType.Nothing) + Debug.Log("Ignorance Server Instance starting up..."); + + InitializeServerBackend(); + + Server.Start(); + } + + public override void ServerStop() + { + if (Server != null) + { + if (LogType != IgnoranceLogType.Nothing) + Debug.Log("Ignorance Server Instance shutting down..."); + + Server.Stop(); + } + + ConnectionLookupDict.Clear(); + } + + public override Uri ServerUri() + { + UriBuilder builder = new UriBuilder + { + Scheme = IgnoranceInternals.Scheme, + Host = serverBindAddress, + Port = port + }; + + return builder.Uri; + } + + public override void Shutdown() + { + // TODO: Nothing needed here? + } + + // Check to ensure channels 0 and 1 mimic LLAPI. Override this at your own risk. + private void OnValidate() + { + if (Channels != null && Channels.Length >= 2) + { + // Check to make sure that Channel 0 and 1 are correct. + if (Channels[0] != IgnoranceChannelTypes.Reliable) + { + Debug.LogWarning("Please do not modify Ignorance Channel 0. The channel will be reset to Reliable delivery. If you need a channel with a different delivery, define and use it instead."); + Channels[0] = IgnoranceChannelTypes.Reliable; + } + if (Channels[1] != IgnoranceChannelTypes.Unreliable) + { + Debug.LogWarning("Please do not modify Ignorance Channel 1. The channel will be reset to Unreliable delivery. If you need a channel with a different delivery, define and use it instead."); + Channels[1] = IgnoranceChannelTypes.Unreliable; + } + } + else + { + Debug.LogWarning("Invalid Channels setting, fixing. If you've just added Ignorance to your NetworkManager GameObject, seeing this message is normal."); + Channels = new IgnoranceChannelTypes[2] + { + + IgnoranceChannelTypes.Reliable, + IgnoranceChannelTypes.Unreliable + }; + } + + // ENet only supports a maximum of 32MB packet size. + if (MaxAllowedPacketSize > 33554432) + MaxAllowedPacketSize = 33554432; + } + + private void InitializeServerBackend() + { + if (Server == null) + { + Debug.LogWarning("IgnoranceServer reference for Server mode was null. This shouldn't happen, but to be safe we'll reinitialize it."); + Server = new IgnoranceServer(); + } + + // Set up the new IgnoranceServer reference. + if (serverBindsAll) + // MacOS is special. It's also a massive thorn in my backside. + Server.BindAddress = IgnoranceInternals.BindAllMacs; + else + // Use the supplied bind address. + Server.BindAddress = serverBindAddress; + + // Sets port, maximum peers, max channels, the server poll time, maximum packet size and verbosity. + Server.BindPort = port; + Server.MaximumPeers = serverMaxPeerCapacity; + Server.MaximumChannels = Channels.Length; + Server.PollTime = serverMaxNativeWaitTime; + Server.MaximumPacketSize = MaxAllowedPacketSize; + Server.Verbosity = (int)LogType; + + // Initializes the packet buffer. + // Allocates once, that's it. + if (InternalPacketBuffer == null) + InternalPacketBuffer = new byte[PacketBufferCapacity]; + } + + private void InitializeClientBackend() + { + if (Client == null) + { + Debug.LogWarning("Ignorance: IgnoranceClient reference for Client mode was null. This shouldn't happen, but to be safe we'll reinitialize it."); + Client = new IgnoranceClient(); + } + + // Sets address, port, channels to expect, verbosity, the server poll time and maximum packet size. + Client.ConnectAddress = cachedConnectionAddress; + Client.ConnectPort = port; + Client.ExpectedChannels = Channels.Length; + Client.PollTime = clientMaxNativeWaitTime; + Client.MaximumPacketSize = MaxAllowedPacketSize; + Client.Verbosity = (int)LogType; + + // Initializes the packet buffer. + // Allocates once, that's it. + if (InternalPacketBuffer == null) + InternalPacketBuffer = new byte[PacketBufferCapacity]; + } + + private void ProcessServerPackets() + { + IgnoranceIncomingPacket incomingPacket; + IgnoranceConnectionEvent connectionEvent; + int adjustedConnectionId; + Packet payload; + + // Incoming connection events. + while (Server.ConnectionEvents.TryDequeue(out connectionEvent)) + { + adjustedConnectionId = (int)connectionEvent.NativePeerId + 1; + + if (LogType == IgnoranceLogType.Verbose) + Debug.Log($"Processing a server connection event from ENet native peer {connectionEvent.NativePeerId}. This peer would be Mirror ConnID {adjustedConnectionId}."); + + // TODO: Investigate ArgumentException: An item with the same key has already been added. Key: + ConnectionLookupDict.Add(adjustedConnectionId, new PeerConnectionData + { + NativePeerId = connectionEvent.NativePeerId, + IP = connectionEvent.IP, + Port = connectionEvent.Port + }); + + OnServerConnected?.Invoke(adjustedConnectionId); + } + + // Handle incoming data packets. + // Console.WriteLine($"Server Incoming Queue is {Server.Incoming.Count}"); + while (Server.Incoming.TryDequeue(out incomingPacket)) + { + adjustedConnectionId = (int)incomingPacket.NativePeerId + 1; + payload = incomingPacket.Payload; + + int length = payload.Length; + ArraySegment dataSegment; + + // Copy to working buffer and dispose of it. + if (length > InternalPacketBuffer.Length) + { + byte[] oneFreshNTastyGcAlloc = new byte[length]; + + payload.CopyTo(oneFreshNTastyGcAlloc); + dataSegment = new ArraySegment(oneFreshNTastyGcAlloc, 0, length); + } + else + { + payload.CopyTo(InternalPacketBuffer); + dataSegment = new ArraySegment(InternalPacketBuffer, 0, length); + } + + payload.Dispose(); + + OnServerDataReceived?.Invoke(adjustedConnectionId, dataSegment, incomingPacket.Channel); + + // Some messages can disable the transport + // If the transport was disabled by any of the messages, we have to break out of the loop and wait until we've been re-enabled. + if (!enabled) + break; + } + + // Disconnection events. + while (Server.DisconnectionEvents.TryDequeue(out IgnoranceConnectionEvent disconnectionEvent)) + { + adjustedConnectionId = (int)disconnectionEvent.NativePeerId + 1; + + if (LogType == IgnoranceLogType.Verbose) + Debug.Log($"ProcessServerPackets fired; handling disconnection event from native peer {disconnectionEvent.NativePeerId}."); + + ConnectionLookupDict.Remove(adjustedConnectionId); + + // Invoke Mirror handler. + OnServerDisconnected?.Invoke(adjustedConnectionId); + } + } + + private void ProcessClientPackets() + { + IgnoranceIncomingPacket incomingPacket; + IgnoranceCommandPacket commandPacket; + IgnoranceClientStats clientStats; + Packet payload; + IgnoranceConnectionEvent connectionEvent; + + // Handle connection events. + while (Client.ConnectionEvents.TryDequeue(out connectionEvent)) + { + if (LogType == IgnoranceLogType.Verbose) + Debug.Log($"ProcessClientConnectionEvents fired: processing a client ConnectionEvents queue item."); + + if (connectionEvent.WasDisconnect) + { + // Disconnected from server. + ClientState = ConnectionState.Disconnected; + + if (LogType != IgnoranceLogType.Nothing) + Debug.Log($"Ignorance Client has been disconnected from server."); + + ignoreDataPackets = true; + OnClientDisconnected?.Invoke(); + } + else + { + // Connected to server. + ClientState = ConnectionState.Connected; + + if (LogType != IgnoranceLogType.Nothing) + Debug.Log($"Ignorance Client successfully connected to server at address {connectionEvent.IP}:{connectionEvent.Port}"); + + ignoreDataPackets = false; + OnClientConnected?.Invoke(); + } + } + + // Now handle the incoming messages. + while (Client.Incoming.TryDequeue(out incomingPacket)) + { + // Temporary fix: if ENet thread is too fast for Mirror, then ignore the packet. + // This is seen sometimes if you stop the client and there's still stuff in the queue. + if (ignoreDataPackets) + { + if (LogType == IgnoranceLogType.Verbose) + Debug.Log("ProcessClientPackets cycle skipped; ignoring data packet"); + break; + } + + + // Otherwise client recieved data, advise Mirror. + // print($"Byte array: {incomingPacket.RentedByteArray.Length}. Packet Length: {incomingPacket.Length}"); + payload = incomingPacket.Payload; + int length = payload.Length; + ArraySegment dataSegment; + + // Copy to working buffer and dispose of it. + if (length > InternalPacketBuffer.Length) + { + // Unity's favourite: A fresh 'n' tasty GC Allocation! + byte[] oneFreshNTastyGcAlloc = new byte[length]; + + payload.CopyTo(oneFreshNTastyGcAlloc); + dataSegment = new ArraySegment(oneFreshNTastyGcAlloc, 0, length); + } + else + { + payload.CopyTo(InternalPacketBuffer); + dataSegment = new ArraySegment(InternalPacketBuffer, 0, length); + } + + payload.Dispose(); + + OnClientDataReceived?.Invoke(dataSegment, incomingPacket.Channel); + + // Some messages can disable the transport + // If the transport was disabled by any of the messages, we have to break out of the loop and wait until we've been re-enabled. + if (!enabled) + break; + } + + // Step 3: Handle other commands. + while (Client.Commands.TryDequeue(out commandPacket)) + { + switch (commandPacket.Type) + { + // ... + default: + break; + } + } + + // Step 4: Handle status updates. + if (Client.StatusUpdates.TryDequeue(out clientStats)) + { + ClientStatistics = clientStats; + } + } + + #region Main Thread Processing and Polling + // Ignorance 1.4.0b5: To use Mirror's polling or not use Mirror's polling, that is up to the developer to decide +#if !IGNORANCE_MIRROR_POLLING + // IMPORTANT: Set Ignorance' execution order before everything else. Yes, that's -32000 !! + // This ensures it has priority over other things. + + // FixedUpdate can be called many times per frame. + // Once we've handled stuff, we set a flag so that we don't poll again for this frame. + + private bool fixedUpdateCompletedWork; + public void FixedUpdate() + { + if (!enabled) return; + if (fixedUpdateCompletedWork) return; + + ProcessAndExecuteAllPackets(); + + // Flip the bool to signal we've done our work. + fixedUpdateCompletedWork = true; + } + + // Normally, Mirror blocks Update() due to poor design decisions... + // But thanks to Vincenzo, we've found a way to bypass that block. + // Update is called once per frame. We don't have to worry about this shit now. + public new void Update() + { + if (!enabled) return; + + // Process what FixedUpdate missed, only if the boolean is not set. + if (!fixedUpdateCompletedWork) + ProcessAndExecuteAllPackets(); + + // Flip back the bool, so it can be reset. + fixedUpdateCompletedWork = false; + } + + // Processes and Executes All Packets. + private void ProcessAndExecuteAllPackets() + { + // Process Server Events... + if (Server.IsAlive) + ProcessServerPackets(); + + // Process Client Events... + if (Client.IsAlive) + { + ProcessClientPackets(); + + if (ClientState == ConnectionState.Connected && clientStatusUpdateInterval > -1) + { + statusUpdateTimer += Time.deltaTime; + + if (statusUpdateTimer >= clientStatusUpdateInterval) + { + Client.Commands.Enqueue(new IgnoranceCommandPacket { Type = IgnoranceCommandType.ClientRequestsStatusUpdate }); + statusUpdateTimer = 0f; + } + } + } + } +#else + // This section will be compiled in instead if you enable IGNORANCE_MIRROR_POLLING. + + public override void ServerEarlyUpdate() { + // This is used by Mirror to consume the incoming server packets. + if (!enabled) return; + + // Process Server Events... + if (Server.IsAlive) + ProcessServerPackets(); + } + + public override void ClientEarlyUpdate() { + // This is used by Mirror to consume the incoming client packets. + if(!enabled) return; + + if(Client.IsAlive) + { + ProcessClientPackets(); + + if (ClientState == ConnectionState.Connected && clientStatusUpdateInterval > -1) + { + statusUpdateTimer += Time.deltaTime; + + if (statusUpdateTimer >= clientStatusUpdateInterval) + { + Client.Commands.Enqueue(new IgnoranceCommandPacket { Type = IgnoranceCommandType.ClientRequestsStatusUpdate }); + statusUpdateTimer = 0f; + } + } + } + + } + + /* + public override void ClientLateUpdate() { + // This is used by Mirror to send out the outgoing client packets. + if (!enabled) return; + } + + public override void ServerLateUpdate() { + // This is used by Mirror to send out the outgoing server packets. + if (!enabled) return; + } + */ +#endif + #endregion + + #region Debug + private void OnGUI() + { + if (DebugDisplay) + GUI.Box(new Rect( + new Vector2(32, Screen.height - 240), new Vector2(200, 160)), + + "-- CLIENT --\n" + + $"State: {ClientState}\n" + + $"Incoming Queue: {Client.Incoming.Count}\n" + + $"Outgoing Queue: {Client.Outgoing.Count}\n\n" + + + "-- SERVER --\n" + + $"Incoming Queue: {Server.Incoming.Count}\n" + + $"Outgoing Queue: {Server.Outgoing.Count}\n" + + $"ConnEvent Queue: {Server.ConnectionEvents.Count}" + ); + } + #endregion + + public override int GetMaxPacketSize(int channelId = 0) => MaxAllowedPacketSize; + + // UDP Recommended Max MTU = 1200. + public override int GetMaxBatchSize(int channelId) { + bool isFragmentedAlready = ((PacketFlags)Channels[channelId] & ReliableOrUnreliableFragmented) > 0; + return isFragmentedAlready ? MaxAllowedPacketSize : 1200; + } + + #region Internals + private bool ignoreDataPackets; + private string cachedConnectionAddress = string.Empty; + private IgnoranceServer Server = new IgnoranceServer(); + private IgnoranceClient Client = new IgnoranceClient(); + private Dictionary ConnectionLookupDict = new Dictionary(); + + private enum ConnectionState { Connecting, Connected, Disconnecting, Disconnected } + private ConnectionState ClientState = ConnectionState.Disconnected; + private byte[] InternalPacketBuffer; + + private const PacketFlags ReliableOrUnreliableFragmented = PacketFlags.Reliable | PacketFlags.UnreliableFragmented; + + private float statusUpdateTimer = 0f; + #endregion + + #region Legacy Overrides +#if !MIRROR_37_0_OR_NEWER + public bool ServerDisconnectLegacy(int connectionId) + { + if (Server == null) + { + Debug.LogError("Cannot enqueue kick packet; our Server object is null. Something has gone wrong."); + // Return here because otherwise we will get a NRE when trying to enqueue the kick packet. + return false; + } + + IgnoranceCommandPacket kickPacket = new IgnoranceCommandPacket + { + Type = IgnoranceCommandType.ServerKickPeer, + PeerId = (uint)connectionId - 1 // ENet's native peer ID will be ConnID - 1 + }; + + // Pass the packet onto the thread for dispatch. + Server.Commands.Enqueue(kickPacket); + return true; + } +#endif + #endregion +#endif + + } +} diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs.meta new file mode 100644 index 0000000..9703c34 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Ignorance.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 872fa23ef6e77334ca452ce16f6cd091 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -32000 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs new file mode 100644 index 0000000..ca677ac --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs @@ -0,0 +1,94 @@ +using System; +using ENet; + +namespace IgnoranceTransport +{ + // Snipped from the transport files, as this will help + // me keep things up to date. + [Serializable] + public enum IgnoranceChannelTypes + { + Reliable = PacketFlags.Reliable, // TCP Emulation. + ReliableUnsequenced = PacketFlags.Reliable | PacketFlags.Unsequenced, // TCP Emulation, but no sequencing. + Unreliable = PacketFlags.Unsequenced, // Pure UDP. + UnreliableFragmented = PacketFlags.UnreliableFragmented, // Pure UDP, but fragmented. + UnreliableSequenced = PacketFlags.None, // Pure UDP, but sequenced. + Unthrottled = PacketFlags.Unthrottled, // Apparently ENet's version of Taco Bell. + } + + public class IgnoranceInternals + { + public const string Version = "1.4.0b6"; + public const string Scheme = "enet"; + public const string BindAllIPv4 = "0.0.0.0"; + public const string BindAllMacs = "::0"; + } + + public enum IgnoranceLogType + { + Nothing, + Standard, + Verbose + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceIncomingPacket + { + public byte Channel; + public uint NativePeerId; + public Packet Payload; + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceOutgoingPacket + { + public byte Channel; + public uint NativePeerId; + public Packet Payload; + } + + // Struct optimized for cache efficiency. (Thanks Vincenzo!) + public struct IgnoranceConnectionEvent + { + public bool WasDisconnect; + public ushort Port; + public uint NativePeerId; + public string IP; + } + + public struct IgnoranceCommandPacket + { + public IgnoranceCommandType Type; + public uint PeerId; + } + + public struct IgnoranceClientStats + { + // Stats only - may not always be used! + public uint RTT; + public ulong BytesReceived; + public ulong BytesSent; + public ulong PacketsReceived; + public ulong PacketsSent; + public ulong PacketsLost; + } + + public enum IgnoranceCommandType + { + // Client + ClientWantsToStop, + ClientRequestsStatusUpdate, + // ENet internal + ResponseToClientStatusRequest, + // Server + ServerKickPeer + } + + // TODO: Optimize struct for Cache performance. + public struct PeerConnectionData + { + public ushort Port; + public uint NativePeerId; + public string IP; + } +} diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs.meta new file mode 100644 index 0000000..444855c --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/IgnoranceDefinitions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b2d1f7f7d9d3d64297755419f6ab925 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins.meta new file mode 100644 index 0000000..def60ed --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e8bd04b9965420e40ac911fbf4294e1c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android.meta new file mode 100644 index 0000000..f51f451 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c90c88052305a054d87177362f63dea8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a.meta new file mode 100644 index 0000000..738b943 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e4a42b5855436864693138f74335c094 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so new file mode 100644 index 0000000..5a48a3b Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so.meta new file mode 100644 index 0000000..63cd799 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/arm64-v8a/libenet.so.meta @@ -0,0 +1,111 @@ +fileFormatVersion: 2 +guid: 4b3abd2268dea254da11190b00d16051 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARM64 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + WebGL: WebGL + second: + enabled: 0 + settings: {} + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a.meta new file mode 100644 index 0000000..bbb65c6 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bfbaf4fbcf8987e4585ca666e28f4871 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so new file mode 100644 index 0000000..e8be734 Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so.meta new file mode 100644 index 0000000..07ea880 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/armeabi-v7a/libenet.so.meta @@ -0,0 +1,106 @@ +fileFormatVersion: 2 +guid: e3ce4b8600e09d74ead46137ba184d01 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86.meta new file mode 100644 index 0000000..4491214 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b3486c84aaebff4489e2e11f5bd3030f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so new file mode 100644 index 0000000..391f83e Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so.meta new file mode 100644 index 0000000..c57aeaa --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Android/x86/libenet.so.meta @@ -0,0 +1,80 @@ +fileFormatVersion: 2 +guid: ba78b07719f786c4cae4c52b9528903f +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: x86 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CPU: AnyCPU + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux.meta new file mode 100644 index 0000000..f1aae5d --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e3ca9b41c9f4064581a6b56ae549a9c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so new file mode 100644 index 0000000..c64bfb7 Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so.meta new file mode 100644 index 0000000..d60a26a --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Linux/libenet.so.meta @@ -0,0 +1,97 @@ +fileFormatVersion: 2 +guid: f2bd341c8082ddd47b4b5cc9bfdf2332 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 0 + Exclude Linux: 1 + Exclude Linux64: 0 + Exclude LinuxUniversal: 0 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 0 + Exclude Win64: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: x86_64 + DefaultValueInitialized: true + OS: Linux + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows.meta new file mode 100644 index 0000000..06c1b96 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8837cb1a7320b8b4f824a02e23f4a545 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt new file mode 100644 index 0000000..1bb2563 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt @@ -0,0 +1,3 @@ +This is a Windows x64 build of ENet-CSharp. + +If you require a version of ENet for 32 Bit computer systems (ie. Windows 7/8/10 32Bit) then please get in touch, or you can install the requirements yourself and compile it using ENet-CSharp's MSBuild-based build system. Get in touch if you want me to compile them for you, but keep in mind that I do not support them when reporting bugs. \ No newline at end of file diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt.meta new file mode 100644 index 0000000..b69d8f0 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/README.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09ee288deb259474c819a5e3daf54b80 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll new file mode 100644 index 0000000..f75351b Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll.meta new file mode 100644 index 0000000..99fefbb --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/Windows/enet.dll.meta @@ -0,0 +1,111 @@ +fileFormatVersion: 2 +guid: cc98033c6bc234a419ccd053e7173781 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 0 + Exclude Linux: 0 + Exclude Linux64: 0 + Exclude LinuxUniversal: 0 + Exclude OSXUniversal: 0 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 0 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 1 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: LinuxUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + WebGL: WebGL + second: + enabled: 0 + settings: {} + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS.meta new file mode 100644 index 0000000..b6beac0 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7edc275f3670f4251b90301cbb9f7413 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a new file mode 100644 index 0000000..0d88385 Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a.meta new file mode 100644 index 0000000..1504880 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-arm64.a.meta @@ -0,0 +1,80 @@ +fileFormatVersion: 2 +guid: 1485de7d76884a64bac00df01454081e +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: ARM64 + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a new file mode 100644 index 0000000..d8b77ba Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a.meta new file mode 100644 index 0000000..aa56177 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-armv7.a.meta @@ -0,0 +1,80 @@ +fileFormatVersion: 2 +guid: fa239cb4c47fc9447816815f80667fea +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: ARMv7 + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a new file mode 100644 index 0000000..e6051c3 Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a.meta new file mode 100644 index 0000000..7106afb --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/iOS/libenet-release-simulator64.a.meta @@ -0,0 +1,80 @@ +fileFormatVersion: 2 +guid: 385bb48fb124b5f40a79bdecf421671f +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CPU: X64 + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS.meta new file mode 100644 index 0000000..b4c703f --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 957ba76da095cd64aaa658f034ab78e5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib new file mode 100644 index 0000000..da377b7 Binary files /dev/null and b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib differ diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib.meta new file mode 100644 index 0000000..92fe418 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/macOS/libenet.dylib.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 5317859893ad2cf48a6df1d585ebdd2c +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt new file mode 100644 index 0000000..66f084a --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt @@ -0,0 +1,35 @@ +ENET Pre-compiled Binary Library Blobs +========================== +This folder contains pre-compiled binaries for a variety of different platforms. + +A brief summary of these folders are as follows: + +- Windows, Mac, Linux +-- 64bit (x64) + +- Android (Kitkat 4.4 minimum target OS) +-- ARMv7 (armeabi-v7a), ARMv8/AArch64 (arm64-v8a) + +- iOS +-- FAT Library (armv7 + arm64). Targeted for iOS 8 minimum. Unsigned library. + +DEBUG VERSIONS +=============== +Debug versions of the libraries can be obtained at https://github.com/SoftwareGuy/ENet-CSharp/releases. +Otherwise you can also compile the library yourself with Debug enabled. + +DOT POINTS +=========== +1. 32bit Support for Ignorance has been removed. Originally, I did not want to support 32bit operating systems, +however due to some countries in the world still stuck in the 32bit era (Brasil, some Russian areas, etc) I added them as a +goodwill gesture. However, since those who needed the libraries have now vanished, I have stopped building 32bit versions of ENet. + +COMPILE THE CODE YOURSELF +========================= +If you don't trust the above binaries then git clone the ENET-CSharp repository (http://github.com/SoftwareGuy/ENet-CSharp) and read the readme. + +EXCLUSION INSTRUCTIONS +====================== +No need, the meta data will cover that for you. + +Still don't know what to do with these? Drop by the Mirror discord and post in the Ignorance channel. \ No newline at end of file diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt.meta new file mode 100644 index 0000000..968eafe --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/Plugins/readme.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a28193472bc84d341ab4aee18c471a93 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt new file mode 100644 index 0000000..e14bdc8 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt @@ -0,0 +1 @@ +1.4.0b6 \ No newline at end of file diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt.meta b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt.meta new file mode 100644 index 0000000..bd4c745 --- /dev/null +++ b/UnityProject/Assets/Mirror/Runtime/Transport/Ignorance/version.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ad80075449f17c548877161f32a9841a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs index 225c75d..cc0381e 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs @@ -23,8 +23,12 @@ namespace LightReflectiveMirror LRMDirectConnectModule directModule; string[] tabs = new string[] { "LRM Settings", "NAT Punch", "Load Balancer", "Other" }; int currentTab = 0; - Type[] supportedTransports = new Type[3] { typeof(KcpTransport), typeof(SimpleWebTransport), typeof(TelepathyTransport) }; +#if !IGNORANCE + Type[] supportedTransports = new Type[3] { typeof(KcpTransport), typeof(SimpleWebTransport), typeof(TelepathyTransport) }; +#else + Type[] supportedTransports = new Type[4] { typeof(KcpTransport), typeof(SimpleWebTransport), typeof(TelepathyTransport), typeof(IgnoranceTransport.Ignorance) }; +#endif public override void OnInspectorGUI() { var lrm = (LightReflectiveMirrorTransport)target; @@ -217,8 +221,6 @@ namespace LightReflectiveMirror case 0: using (var change = new EditorGUI.ChangeCheckScope()) { - - // They are in the LRM Settings tab. if (lrm.useLoadBalancer) { @@ -308,4 +310,4 @@ namespace LightReflectiveMirror } } #endif -} \ No newline at end of file + } \ No newline at end of file diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs index 35d0a5b..bb8fcca 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMDirectConnectModule.cs @@ -65,39 +65,72 @@ public class LRMDirectConnectModule : MonoBehaviour public void SetTransportPort(int port) { +#if !IGNORANCE if (directConnectTransport is kcp2k.KcpTransport kcpTransport) kcpTransport.Port = (ushort)port; else { - throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AT THE MOMENT."); + ThrowIfNotSupported(); } +#else + if (directConnectTransport is kcp2k.KcpTransport kcpTransport) + kcpTransport.Port = (ushort)port; + if (directConnectTransport is IgnoranceTransport.Ignorance ignorance) + ignorance.port = (ushort)port; + else + { + ThrowIfNotSupported(); + } +#endif } public int GetTransportPort() { +#if !IGNORANCE if (directConnectTransport is kcp2k.KcpTransport kcpTransport) return kcpTransport.Port; else { - throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AT THE MOMENT."); + ThrowIfNotSupported(); + return -1; } +#else + if (directConnectTransport is kcp2k.KcpTransport kcpTransport) + return kcpTransport.Port; + if (directConnectTransport is IgnoranceTransport.Ignorance ignorance) + return ignorance.port; + else + { + ThrowIfNotSupported(); + return -1; + } +#endif + } + + private static int ThrowIfNotSupported() + { +#if !IGNORANCE + throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AT THE MOMENT."); +#else + throw new Exception("DIRECT CONNECT MODULE ONLY SUPPORTS KCP AND IGNORANCE"); +#endif } public bool SupportsNATPunch() { +#if !IGNORANCE return directConnectTransport is kcp2k.KcpTransport; +#else + return directConnectTransport is kcp2k.KcpTransport || directConnectTransport is IgnoranceTransport.Ignorance; +#endif } - public bool KickClient(int clientID) + public void KickClient(int clientID) { if (showDebugLogs) Debug.Log("Kicked direct connect client."); -#if MIRROR_37_0_OR_NEWER + directConnectTransport.ServerDisconnect(clientID); - return true; -#else - return directConnectTransport.ServerDisconnect(clientID); -#endif } public void ClientDisconnect() @@ -107,20 +140,12 @@ public class LRMDirectConnectModule : MonoBehaviour public void ServerSend(int clientID, ArraySegment data, int channel) { -#if MIRROR_40_0_OR_NEWER directConnectTransport.ServerSend(clientID, data, channel); -#else - directConnectTransport.ServerSend(clientID, channel, data); -#endif } public void ClientSend(ArraySegment data, int channel) { -#if MIRROR_40_0_OR_NEWER directConnectTransport.ClientSend(data, channel); -#else - directConnectTransport.ClientSend(channel, data); -#endif } #region Transport Callbacks diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportOverrides.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportOverrides.cs index 305701f..a34d7f4 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportOverrides.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportOverrides.cs @@ -86,19 +86,11 @@ namespace LightReflectiveMirror } else { - if (GetLocalIp() == null) - _clientSendBuffer.WriteString(ref pos, "0.0.0.0"); - else - _clientSendBuffer.WriteString(ref pos, GetLocalIp()); + _clientSendBuffer.WriteString(ref pos, GetLocalIp() ?? "0.0.0.0"); } _isClient = true; -#if MIRROR_40_0_OR_NEWER - clientToServerTransport.ClientSend(new System.ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new System.ArraySegment(_clientSendBuffer, 0, pos)); -#endif - + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); } else { @@ -115,23 +107,15 @@ namespace LightReflectiveMirror { int pos = 0; _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.LeaveRoom); -#if MIRROR_40_0_OR_NEWER + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } if (_directConnectModule != null) _directConnectModule.ClientDisconnect(); } -#if MIRROR_40_0_OR_NEWER public override void ClientSend(ArraySegment segment, int channelId) -#else - public override void ClientSend(int channelId, ArraySegment segment) - -#endif { if (_directConnected) { @@ -143,35 +127,11 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.SendData); _clientSendBuffer.WriteBytes(ref pos, segment.Array.Take(segment.Count).ToArray()); _clientSendBuffer.WriteInt(ref pos, 0); -#if MIRROR_40_0_OR_NEWER + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), channelId); -#else - clientToServerTransport.ClientSend(channelId, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } -#if !MIRROR_37_0_OR_NEWER - - public override bool ServerDisconnect(int connectionId) - { - if (_connectedRelayClients.TryGetBySecond(connectionId, out int relayId)) - { - int pos = 0; - _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.KickPlayer); - _clientSendBuffer.WriteInt(ref pos, relayId); - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); - return true; - } - - if (_connectedDirectClients.TryGetBySecond(connectionId, out int directId)) - return _directConnectModule.KickClient(directId); - - return false; - } - -#else - public override void ServerDisconnect(int connectionId) { if (_connectedRelayClients.TryGetBySecond(connectionId, out int relayId)) @@ -187,13 +147,7 @@ namespace LightReflectiveMirror _directConnectModule.KickClient(directId); } -#endif - -#if MIRROR_40_0_OR_NEWER public override void ServerSend(int connectionId, ArraySegment segment, int channelId) -#else - public override void ServerSend(int connectionId, int channelId, ArraySegment segment) -#endif { if (_directConnectModule != null && _connectedDirectClients.TryGetBySecond(connectionId, out int directId)) { @@ -205,11 +159,8 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.SendData); _clientSendBuffer.WriteBytes(ref pos, segment.Array.Take(segment.Count).ToArray()); _clientSendBuffer.WriteInt(ref pos, _connectedRelayClients.GetBySecond(connectionId)); -#if MIRROR_40_0_OR_NEWER + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), channelId); -#else - clientToServerTransport.ClientSend(channelId, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } @@ -242,14 +193,16 @@ namespace LightReflectiveMirror int pos = 0; _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.CreateRoom); + _clientSendBuffer.WriteInt(ref pos, maxServerPlayers); _clientSendBuffer.WriteString(ref pos, serverName); _clientSendBuffer.WriteBool(ref pos, isPublicServer); _clientSendBuffer.WriteString(ref pos, extraServerData); - // If we have direct connect module, and our local IP isnt null, tell server. Only time local IP is null is on cellular networks, such as IOS and Android. - _clientSendBuffer.WriteBool(ref pos, _directConnectModule != null ? GetLocalIp() != null ? true : false : false); - if (_directConnectModule != null && GetLocalIp() != null) + // If we have direct connect module, and our local IP isnt null, tell server. Only time local IP is null is on cellular networks, such as IOS and Android. + _clientSendBuffer.WriteBool(ref pos, _directConnectModule != null ? GetLocalIp() != null : false); + + if (_directConnectModule != null && GetLocalIp() != null && useNATPunch) { _clientSendBuffer.WriteString(ref pos, GetLocalIp()); // Transport port will be NAT port + 1 for the proxy connections. @@ -268,11 +221,8 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteBool(ref pos, false); _clientSendBuffer.WriteInt(ref pos, _directConnectModule == null ? 1 : _directConnectModule.SupportsNATPunch() ? _directConnectModule.GetTransportPort() : 1); } -#if MIRROR_40_0_OR_NEWER + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } public override void ServerStop() @@ -283,11 +233,7 @@ namespace LightReflectiveMirror int pos = 0; _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.LeaveRoom); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif if (_directConnectModule != null) _directConnectModule.StopServer(); diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs index 5ddd899..f805f4e 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs @@ -115,11 +115,7 @@ namespace LightReflectiveMirror _isClient = true; -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new System.ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new System.ArraySegment(_clientSendBuffer, 0, pos)); -#endif } IEnumerator GetServerList(LRMRegions region) diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs index 8b3efc7..5706909 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs @@ -127,14 +127,9 @@ namespace LightReflectiveMirror int pos = 0; _clientSendBuffer.WriteByte(ref pos, 200); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif // If NAT Puncher is initialized, send heartbeat on that as well. - try { if (_NATPuncher != null) @@ -348,11 +343,7 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteBool(ref pos, false); _clientSendBuffer.WriteBool(ref pos, false); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } @@ -368,11 +359,8 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteString(ref pos, newServerData); _clientSendBuffer.WriteBool(ref pos, false); _clientSendBuffer.WriteBool(ref pos, false); -#if MIRROR_40_0_OR_NEWER + clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } @@ -389,11 +377,7 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteBool(ref pos, isPublic); _clientSendBuffer.WriteBool(ref pos, false); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } @@ -410,11 +394,7 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteBool(ref pos, true); _clientSendBuffer.WriteInt(ref pos, maxPlayers); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } } @@ -435,11 +415,7 @@ namespace LightReflectiveMirror _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.AuthenticationResponse); _clientSendBuffer.WriteString(ref pos, authenticationKey); -#if MIRROR_40_0_OR_NEWER clientToServerTransport.ClientSend(new ArraySegment(_clientSendBuffer, 0, pos), 0); -#else - clientToServerTransport.ClientSend(0, new ArraySegment(_clientSendBuffer, 0, pos)); -#endif } public enum OpCodes diff --git a/UnityProject/ProjectSettings/ProjectSettings.asset b/UnityProject/ProjectSettings/ProjectSettings.asset index c0a9369..86fa990 100644 --- a/UnityProject/ProjectSettings/ProjectSettings.asset +++ b/UnityProject/ProjectSettings/ProjectSettings.asset @@ -513,7 +513,7 @@ PlayerSettings: webGLThreadsSupport: 0 webGLWasmStreaming: 0 scriptingDefineSymbols: - 1: MIRROR;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER;MIRROR_30_0_OR_NEWER;MIRROR_30_5_2_OR_NEWER;MIRROR_32_1_2_OR_NEWER;MIRROR_32_1_4_OR_NEWER;MIRROR_35_0_OR_NEWER;MIRROR_35_1_OR_NEWER;MIRROR_37_0_OR_NEWER;MIRROR_38_0_OR_NEWER;MIRROR_39_0_OR_NEWER;MIRROR_40_0_OR_NEWER + 1: MIRROR;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER;MIRROR_30_0_OR_NEWER;MIRROR_30_5_2_OR_NEWER;MIRROR_32_1_2_OR_NEWER;MIRROR_32_1_4_OR_NEWER;MIRROR_35_0_OR_NEWER;MIRROR_35_1_OR_NEWER;MIRROR_37_0_OR_NEWER;MIRROR_38_0_OR_NEWER;MIRROR_39_0_OR_NEWER;MIRROR_40_0_OR_NEWER;IGNORANCE;IGNORANCE_1;IGNORANCE_1_4 13: MIRROR;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER;MIRROR_30_0_OR_NEWER;MIRROR_30_5_2_OR_NEWER;MIRROR_32_1_2_OR_NEWER;MIRROR_32_1_4_OR_NEWER;MIRROR_35_0_OR_NEWER;MIRROR_35_1_OR_NEWER platformArchitecture: {} scriptingBackend: