Gonna move to server authority

This commit is contained in:
2022-01-31 17:27:38 +05:30
parent f3d21f4ec6
commit 7368968176
1354 changed files with 107808 additions and 80043 deletions

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: e03829cb9e647274db0f6a7b8b1b757b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e03829cb9e647274db0f6a7b8b1b757b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,296 +1,351 @@
// 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<IgnoranceIncomingPacket> Incoming = new ConcurrentQueue<IgnoranceIncomingPacket>();
public ConcurrentQueue<IgnoranceOutgoingPacket> Outgoing = new ConcurrentQueue<IgnoranceOutgoingPacket>();
public ConcurrentQueue<IgnoranceCommandPacket> Commands = new ConcurrentQueue<IgnoranceCommandPacket>();
public ConcurrentQueue<IgnoranceConnectionEvent> ConnectionEvents = new ConcurrentQueue<IgnoranceConnectionEvent>();
public ConcurrentQueue<IgnoranceClientStats> StatusUpdates = new ConcurrentQueue<IgnoranceClientStats>();
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;
}
}
}
// Ignorance 1.4.x LTS (Long Term Support)
// https://github.com/SoftwareGuy/Ignorance
// -----------------
// Copyright (c) 2019 - 2021 Matt Coburn (SoftwareGuy/Coburn64)
// Ignorance is licensed under the MIT license. Refer
// to the LICENSE file for more information.
using System;
using System.Collections.Concurrent;
using System.Threading;
using ENet;
using IgnoranceThirdparty;
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 IgnoranceCore
{
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;
// Maximum ring buffer capacity.
public int IncomingOutgoingBufferSize = 5000;
public int ConnectionEventBufferSize = 100;
// Queues
public RingBuffer<IgnoranceIncomingPacket> Incoming;
public RingBuffer<IgnoranceOutgoingPacket> Outgoing;
public RingBuffer<IgnoranceCommandPacket> Commands;
public RingBuffer<IgnoranceConnectionEvent> ConnectionEvents;
public RingBuffer<IgnoranceClientStats> StatusUpdates;
public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive;
private volatile bool CeaseOperation = false;
private Thread WorkerThread;
public void Start()
{
if (WorkerThread != null && WorkerThread.IsAlive)
{
// Cannot do that.
Debug.LogError("Ignorance Client: A worker thread is already running. Cannot start another.");
return;
}
// Setup the ring buffers.
SetupRingBuffersIfNull();
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("Ignorance Client: Dispatched worker thread.");
}
public void Stop()
{
if (WorkerThread != null && !CeaseOperation)
{
Debug.Log("Ignorance Client: Stop acknowledged. This may take a while depending on network load...");
CeaseOperation = true;
}
}
#region The meat and potatoes.
// 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; // The peer object that represents the client's connection.
Host clientHost; // NOT related to Mirror "Client Host". This is the client's ENet Host Object.
Event clientEvent; // Used when clients get events on the network.
IgnoranceClientStats icsu = default;
bool alreadyNotifiedAboutDisconnect = false;
// 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 Native successfully initialized.");
else
{
Debug.LogError("Ignorance Client: Failed to initialize ENet Native. Aborting.");
return;
}
// Attempt to connect to our target.
clientAddress.SetHost(setupInfo.Address);
clientAddress.Port = (ushort)setupInfo.Port;
using (clientHost = new Host())
{
try
{
clientHost.Create();
clientPeer = clientHost.Connect(clientAddress, setupInfo.Channels);
}
catch (Exception ex)
{
// Oops, something failed.
Debug.LogError($"Ignorance Client: Looks like something went wrong. While attempting to create client object, we caught an exception:\n{ex.Message}");
Debug.LogError($"You could try the debug-enabled version of the native ENet library which creates a logfile, or alternatively you could try restart " +
$"your device to ensure jank is cleared out of memory. If problems persist, please file a support ticket explaining what happened.");
Library.Deinitialize();
return;
}
// Process network events as long as we're not ceasing operation.
while (!CeaseOperation)
{
bool pollComplete = false;
while (Commands.TryDequeue(out IgnoranceCommandPacket ignoranceCommandPacket))
{
switch (ignoranceCommandPacket.Type)
{
case IgnoranceCommandType.ClientStatusRequest:
// Respond with statistics so far.
if (!clientPeer.IsSet)
break;
icsu.RTT = clientPeer.RoundTripTime;
icsu.BytesReceived = clientPeer.BytesReceived;
icsu.BytesSent = clientPeer.BytesSent;
icsu.PacketsReceived = clientHost.PacketsReceived;
icsu.PacketsSent = clientPeer.PacketsSent;
icsu.PacketsLost = clientPeer.PacketsLost;
StatusUpdates.Enqueue(icsu);
break;
case IgnoranceCommandType.ClientWantsToStop:
CeaseOperation = true;
break;
}
}
// If something outside the thread has told us to stop execution, then we need to break out of this while loop.
if (CeaseOperation)
break;
// Step 1: 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 {ret} while sending packet to Server via Peer {outgoingPacket.NativePeerId}.");
}
// If something outside the thread has told us to stop execution, then we need to break out of this while loop.
// while loop to break out of is while(!CeaseOperation).
if (CeaseOperation)
break;
// 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 (clientHost.CheckEvents(out clientEvent) <= 0)
{
// If service time is met, break out of it.
if (clientHost.Service(setupInfo.PollTime, out clientEvent) <= 0) break;
// Poll is done.
pollComplete = true;
}
// Setup the packet references.
incomingPeer = clientEvent.Peer;
// Now, let's handle those events.
switch (clientEvent.Type)
{
case EventType.None:
default:
break;
case EventType.Connect:
if (setupInfo.Verbosity > 0)
Debug.Log("Ignorance Client: ENet has connected to the server.");
ConnectionEvents.Enqueue(new IgnoranceConnectionEvent
{
EventType = 0x00,
NativePeerId = incomingPeer.ID,
IP = incomingPeer.IP,
Port = incomingPeer.Port
});
break;
case EventType.Disconnect:
case EventType.Timeout:
if (setupInfo.Verbosity > 0)
Debug.Log("Ignorance Client: ENet has been disconnected from the server.");
ConnectionEvents.Enqueue(new IgnoranceConnectionEvent { EventType = 0x01 });
CeaseOperation = true;
alreadyNotifiedAboutDisconnect = true;
break;
case EventType.Receive:
// Receive event type usually includes a packet; so cache its reference.
incomingPacket = clientEvent.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 = clientEvent.ChannelID,
NativePeerId = incomingPeer.ID,
Payload = incomingPacket
};
Incoming.Enqueue(incomingQueuePacket);
break;
}
}
// If something outside the thread has told us to stop execution, then we need to break out of this while loop.
// while loop to break out of is while(!CeaseOperation).
if (CeaseOperation)
break;
}
Debug.Log("Ignorance Client: Thread shutdown commencing. Disconnecting and flushing connection.");
// Flush the client and disconnect.
clientPeer.Disconnect(0);
clientHost.Flush();
// Fix for client stuck in limbo, since the disconnection event may not be fired until next loop.
if (!alreadyNotifiedAboutDisconnect)
{
ConnectionEvents.Enqueue(new IgnoranceConnectionEvent { EventType = 0x01 });
alreadyNotifiedAboutDisconnect = true;
}
}
// Fix for client stuck in limbo, since the disconnection event may not be fired until next loop, again.
if (!alreadyNotifiedAboutDisconnect)
ConnectionEvents.Enqueue(new IgnoranceConnectionEvent { EventType = 0x01 });
// Deinitialize
Library.Deinitialize();
if (setupInfo.Verbosity > 0)
Debug.Log("Ignorance Client: Shutdown complete.");
}
#endregion
private void SetupRingBuffersIfNull()
{
Debug.Log($"Ignorance: Setting up ring buffers if they're not already created. " +
$"If they are already, this step will be skipped.");
if (Incoming == null)
Incoming = new RingBuffer<IgnoranceIncomingPacket>(IncomingOutgoingBufferSize);
if (Outgoing == null)
Outgoing = new RingBuffer<IgnoranceOutgoingPacket>(IncomingOutgoingBufferSize);
if (Commands == null)
Commands = new RingBuffer<IgnoranceCommandPacket>(100);
if (ConnectionEvents == null)
ConnectionEvents = new RingBuffer<IgnoranceConnectionEvent>(ConnectionEventBufferSize);
if (StatusUpdates == null)
StatusUpdates = new RingBuffer<IgnoranceClientStats>(10);
}
private struct ThreadParamInfo
{
public int Channels;
public int PollTime;
public int Port;
public int PacketSizeLimit;
public int Verbosity;
public string Address;
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: b7b9e2c091c3d42439840a02fe700252
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b7b9e2c091c3d42439840a02fe700252
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,328 +1,411 @@
// 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<IgnoranceIncomingPacket> Incoming = new ConcurrentQueue<IgnoranceIncomingPacket>();
public ConcurrentQueue<IgnoranceOutgoingPacket> Outgoing = new ConcurrentQueue<IgnoranceOutgoingPacket>();
public ConcurrentQueue<IgnoranceCommandPacket> Commands = new ConcurrentQueue<IgnoranceCommandPacket>();
public ConcurrentQueue<IgnoranceConnectionEvent> ConnectionEvents = new ConcurrentQueue<IgnoranceConnectionEvent>();
public ConcurrentQueue<IgnoranceConnectionEvent> DisconnectionEvents = new ConcurrentQueue<IgnoranceConnectionEvent>();
// 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;
}
}
}
// Ignorance 1.4.x LTS (Long Term Support)
// https://github.com/SoftwareGuy/Ignorance
// -----------------
// Copyright (c) 2019 - 2021 Matt Coburn (SoftwareGuy/Coburn64)
// Ignorance is licensed under the MIT license. Refer
// to the LICENSE file for more information.
using System;
using System.Collections.Generic;
using System.Threading;
using ENet;
using IgnoranceThirdparty;
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 IgnoranceCore
{
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;
// - Verbosity.
public int Verbosity = 1;
// - Queue Sizing
public int IncomingOutgoingBufferSize = 5000;
public int ConnectionEventBufferSize = 100;
public bool IsAlive => WorkerThread != null && WorkerThread.IsAlive;
private volatile bool CeaseOperation = false;
// Queues
// v1.4.0b9: Replace the queues with RingBuffers.
public RingBuffer<IgnoranceIncomingPacket> Incoming;
public RingBuffer<IgnoranceOutgoingPacket> Outgoing;
public RingBuffer<IgnoranceCommandPacket> Commands;
public RingBuffer<IgnoranceConnectionEvent> ConnectionEvents;
public RingBuffer<IgnoranceConnectionEvent> DisconnectionEvents;
public RingBuffer<IgnoranceServerStats> StatusUpdates;
public RingBuffer<IgnoranceServerStats> RecycledServerStatBlocks = new RingBuffer<IgnoranceServerStats>(100);
// Thread
private Thread WorkerThread;
public void Start()
{
if (WorkerThread != null && WorkerThread.IsAlive)
{
// Cannot do that.
Debug.LogError("Ignorance Server: A worker thread is already running. Cannot start another.");
return;
}
// Setup the ring buffers.
SetupRingBuffersIfNull();
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 _)) ;
if (StatusUpdates != null) while (StatusUpdates.TryDequeue(out _)) ;
WorkerThread = new Thread(ThreadWorker);
WorkerThread.Start(threadParams);
// Announce
if (Verbosity > 0)
Debug.Log("Ignorance Server: Dispatched worker thread.");
}
public void Stop()
{
// v1.4.0b7: Mirror may call this; if the worker thread isn't alive then don't announce it.
if (WorkerThread != null && WorkerThread.IsAlive)
{
if (Verbosity > 0)
Debug.Log("Ignorance Server: Server stop acknowledged. Depending on network load, this may take a moment or two...");
CeaseOperation = true;
}
}
#region The meat and potatoes.
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;
IgnoranceClientStats peerStats = default;
// 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 Native successfully initialized.");
}
else
{
Debug.LogError("Ignorance Server: Failed to initialize ENet Native. Aborting.");
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.
try
{
serverENetHost.Create(serverAddress, setupInfo.Peers, setupInfo.Channels);
}
catch (Exception ex)
{
Debug.LogError($"Ignorance Server: While attempting to create server host object, we caught an exception:\n{ex.Message}");
Debug.LogError($"If you are getting a \"Host creation call failed\" exception, please ensure you don't have a server already running on the same IP and Port.\n" +
$"Multiple server instances running on the same port are not supported. Also check to see if ports are not in-use by another application. In the worse case scenario, " +
$"restart your device to ensure no random background ENet threads are active that haven't been cleaned up correctly. If problems persist, please file a support ticket.");
Library.Deinitialize();
return;
}
// 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");
IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent
{
EventType = 0x01,
NativePeerId = targetPeer
};
DisconnectionEvents.Enqueue(iced);
// Disconnect and reset the peer array's entry for that peer.
serverPeerArray[targetPeer].DisconnectNow(0);
serverPeerArray[targetPeer] = default;
break;
case IgnoranceCommandType.ServerStatusRequest:
IgnoranceServerStats serverStats;
if (!RecycledServerStatBlocks.TryDequeue(out serverStats))
serverStats.PeerStats = new Dictionary<int, IgnoranceClientStats>(setupInfo.Peers);
serverStats.PeerStats.Clear();
serverStats.BytesReceived = serverENetHost.BytesReceived;
serverStats.BytesSent = serverENetHost.BytesSent;
serverStats.PacketsReceived = serverENetHost.PacketsReceived;
serverStats.PacketsSent = serverENetHost.PacketsSent;
serverStats.PeersCount = serverENetHost.PeersCount;
for (int i = 0; i < serverPeerArray.Length; i++)
{
if (!serverPeerArray[i].IsSet) continue;
peerStats.RTT = serverPeerArray[i].RoundTripTime;
peerStats.BytesReceived = serverPeerArray[i].BytesReceived;
peerStats.BytesSent = serverPeerArray[i].BytesSent;
peerStats.PacketsSent = serverPeerArray[i].PacketsSent;
peerStats.PacketsLost = serverPeerArray[i].PacketsLost;
serverStats.PeerStats.Add(i, peerStats);
}
StatusUpdates.Enqueue(serverStats);
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 {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;
// What type are you?
switch (serverENetEvent.Type)
{
// Idle.
case EventType.None:
default:
break;
// Connection Event.
case EventType.Connect:
if (setupInfo.Verbosity > 1)
Debug.Log($"Ignorance Server: Peer ID {incomingPeer.ID} says Hi.");
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 {incomingPeer.ID} has disconnected.");
IgnoranceConnectionEvent iced = new IgnoranceConnectionEvent
{
EventType = 0x01,
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: Thread 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);
}
}
if (setupInfo.Verbosity > 0)
Debug.Log("Ignorance Server: Shutdown complete.");
Library.Deinitialize();
}
#endregion
private void SetupRingBuffersIfNull()
{
Debug.Log($"Ignorance: Setting up ring buffers if they're not already created. " +
$"If they are already, this step will be skipped.");
if (Incoming == null)
Incoming = new RingBuffer<IgnoranceIncomingPacket>(IncomingOutgoingBufferSize);
if (Outgoing == null)
Outgoing = new RingBuffer<IgnoranceOutgoingPacket>(IncomingOutgoingBufferSize);
if (Commands == null)
Commands = new RingBuffer<IgnoranceCommandPacket>(100);
if (ConnectionEvents == null)
ConnectionEvents = new RingBuffer<IgnoranceConnectionEvent>(ConnectionEventBufferSize);
if (DisconnectionEvents == null)
DisconnectionEvents = new RingBuffer<IgnoranceConnectionEvent>(ConnectionEventBufferSize);
if (StatusUpdates == null)
StatusUpdates = new RingBuffer<IgnoranceServerStats>(10);
}
private struct ThreadParamInfo
{
public int Channels;
public int Peers;
public int PollTime;
public int Port;
public int PacketSizeLimit;
public int Verbosity;
public string Address;
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 1069f42b88a4adb4ab1990cec4949343
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1069f42b88a4adb4ab1990cec4949343
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 12f903db684732e45b130ad56f7c86c1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 12f903db684732e45b130ad56f7c86c1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 12a7875e95f5ebb4a9b58390441dd933
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 12a7875e95f5ebb4a9b58390441dd933
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,279 @@
// The following dependency was taken from https://github.com/dave-hillier/disruptor-unity3d
// The Apache License 2.0 this dependency follows is located at https://github.com/dave-hillier/disruptor-unity3d/blob/master/LICENSE.
// Modifications were made by SoftwareGuy (Coburn).
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
namespace IgnoranceThirdparty
{
/// <summary>
/// Implementation of the Disruptor pattern
/// </summary>
/// <typeparam name="T">the type of item to be stored</typeparam>
public class RingBuffer<T>
{
private readonly T[] _entries;
private readonly int _modMask;
private Volatile.PaddedLong _consumerCursor = new Volatile.PaddedLong();
private Volatile.PaddedLong _producerCursor = new Volatile.PaddedLong();
/// <summary>
/// Creates a new RingBuffer with the given capacity
/// </summary>
/// <param name="capacity">The capacity of the buffer</param>
/// <remarks>Only a single thread may attempt to consume at any one time</remarks>
public RingBuffer(int capacity)
{
capacity = NextPowerOfTwo(capacity);
_modMask = capacity - 1;
_entries = new T[capacity];
}
/// <summary>
/// The maximum number of items that can be stored
/// </summary>
public int Capacity
{
get { return _entries.Length; }
}
public T this[long index]
{
get { unchecked { return _entries[index & _modMask]; } }
set { unchecked { _entries[index & _modMask] = value; } }
}
/// <summary>
/// Removes an item from the buffer.
/// </summary>
/// <returns>The next available item</returns>
public T Dequeue()
{
var next = _consumerCursor.ReadAcquireFence() + 1;
while (_producerCursor.ReadAcquireFence() < next) // makes sure we read the data from _entries after we have read the producer cursor
{
Thread.SpinWait(1);
}
var result = this[next];
_consumerCursor.WriteReleaseFence(next); // makes sure we read the data from _entries before we update the consumer cursor
return result;
}
/// <summary>
/// Attempts to remove an items from the queue
/// </summary>
/// <param name="obj">the items</param>
/// <returns>True if successful</returns>
public bool TryDequeue(out T obj)
{
var next = _consumerCursor.ReadAcquireFence() + 1;
if (_producerCursor.ReadAcquireFence() < next)
{
obj = default(T);
return false;
}
obj = Dequeue();
return true;
}
/// <summary>
/// Add an item to the buffer
/// </summary>
/// <param name="item"></param>
public void Enqueue(T item)
{
var next = _producerCursor.ReadAcquireFence() + 1;
long wrapPoint = next - _entries.Length;
long min = _consumerCursor.ReadAcquireFence();
while (wrapPoint > min)
{
min = _consumerCursor.ReadAcquireFence();
Thread.SpinWait(1);
}
this[next] = item;
_producerCursor.WriteReleaseFence(next); // makes sure we write the data in _entries before we update the producer cursor
}
/// <summary>
/// The number of items in the buffer
/// </summary>
/// <remarks>for indicative purposes only, may contain stale data</remarks>
public int Count { get { return (int)(_producerCursor.ReadFullFence() - _consumerCursor.ReadFullFence()); } }
private static int NextPowerOfTwo(int x)
{
var result = 2;
while (result < x)
{
result <<= 1;
}
return result;
}
}
public static class Volatile
{
private const int CacheLineSize = 64;
[StructLayout(LayoutKind.Explicit, Size = CacheLineSize * 2)]
public struct PaddedLong
{
[FieldOffset(CacheLineSize)]
private long _value;
/// <summary>
/// Create a new <see cref="PaddedLong"/> with the given initial value.
/// </summary>
/// <param name="value">Initial value</param>
public PaddedLong(long value)
{
_value = value;
}
/// <summary>
/// Read the value without applying any fence
/// </summary>
/// <returns>The current value</returns>
public long ReadUnfenced()
{
return _value;
}
/// <summary>
/// Read the value applying acquire fence semantic
/// </summary>
/// <returns>The current value</returns>
public long ReadAcquireFence()
{
var value = _value;
Thread.MemoryBarrier();
return value;
}
/// <summary>
/// Read the value applying full fence semantic
/// </summary>
/// <returns>The current value</returns>
public long ReadFullFence()
{
Thread.MemoryBarrier();
return _value;
}
/// <summary>
/// Read the value applying a compiler only fence, no CPU fence is applied
/// </summary>
/// <returns>The current value</returns>
[MethodImpl(MethodImplOptions.NoOptimization)]
public long ReadCompilerOnlyFence()
{
return _value;
}
/// <summary>
/// Write the value applying release fence semantic
/// </summary>
/// <param name="newValue">The new value</param>
public void WriteReleaseFence(long newValue)
{
Thread.MemoryBarrier();
_value = newValue;
}
/// <summary>
/// Write the value applying full fence semantic
/// </summary>
/// <param name="newValue">The new value</param>
public void WriteFullFence(long newValue)
{
Thread.MemoryBarrier();
_value = newValue;
}
/// <summary>
/// Write the value applying a compiler fence only, no CPU fence is applied
/// </summary>
/// <param name="newValue">The new value</param>
[MethodImpl(MethodImplOptions.NoOptimization)]
public void WriteCompilerOnlyFence(long newValue)
{
_value = newValue;
}
/// <summary>
/// Write without applying any fence
/// </summary>
/// <param name="newValue">The new value</param>
public void WriteUnfenced(long newValue)
{
_value = newValue;
}
/// <summary>
/// Atomically set the value to the given updated value if the current value equals the comparand
/// </summary>
/// <param name="newValue">The new value</param>
/// <param name="comparand">The comparand (expected value)</param>
/// <returns></returns>
public bool AtomicCompareExchange(long newValue, long comparand)
{
return Interlocked.CompareExchange(ref _value, newValue, comparand) == comparand;
}
/// <summary>
/// Atomically set the value to the given updated value
/// </summary>
/// <param name="newValue">The new value</param>
/// <returns>The original value</returns>
public long AtomicExchange(long newValue)
{
return Interlocked.Exchange(ref _value, newValue);
}
/// <summary>
/// Atomically add the given value to the current value and return the sum
/// </summary>
/// <param name="delta">The value to be added</param>
/// <returns>The sum of the current value and the given value</returns>
public long AtomicAddAndGet(long delta)
{
return Interlocked.Add(ref _value, delta);
}
/// <summary>
/// Atomically increment the current value and return the new value
/// </summary>
/// <returns>The incremented value.</returns>
public long AtomicIncrementAndGet()
{
return Interlocked.Increment(ref _value);
}
/// <summary>
/// Atomically increment the current value and return the new value
/// </summary>
/// <returns>The decremented value.</returns>
public long AtomicDecrementAndGet()
{
return Interlocked.Decrement(ref _value);
}
/// <summary>
/// Returns the string representation of the current value.
/// </summary>
/// <returns>the string representation of the current value.</returns>
public override string ToString()
{
var value = ReadFullFence();
return value.ToString();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f0c413335c890f4a87e1a9dbe32bd68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 0995e08af14888348b42ecaa6eb21544
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 0995e08af14888348b42ecaa6eb21544
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,83 +1,102 @@
#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace IgnoranceTransport
{
/// <summary>
/// Adds the given define symbols to PlayerSettings define symbols.
/// Just add your own define symbols to the Symbols property at the below.
/// </summary>
[InitializeOnLoad]
public class AddIgnoranceDefine : Editor
{
private static string existingDefines = string.Empty;
/// <summary>
/// Symbols that will be added to the editor
/// </summary>
public static readonly string[] Symbols = new string[] {
"IGNORANCE", // Ignorance exists
"IGNORANCE_1", // Major version
"IGNORANCE_1_4" // Major and minor version
};
/// <summary>
/// Do not remove these symbols
/// </summary>
public static readonly string[] DoNotRemoveTheseSymbols = new string[]
{
"IGNORANCE_NO_UPNP",
"IGNORANCE_MIRROR_POLLING"
};
/// <summary>
/// Add define symbols as soon as Unity gets done compiling.
/// </summary>
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<string> 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
// Ignorance 1.4.x LTS (Long Term Support)
// https://github.com/SoftwareGuy/Ignorance
// -----------------
// Copyright (c) 2019 - 2021 Matt Coburn (SoftwareGuy/Coburn64)
// Ignorance is licensed under the MIT license. Refer
// to the LICENSE file for more information.
#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace IgnoranceTransport
{
/// <summary>
/// Adds the given define symbols to PlayerSettings define symbols.
/// Just add your own define symbols to the Symbols property at the below.
/// </summary>
[InitializeOnLoad]
public class AddIgnoranceDefine : Editor
{
private static bool debugMode = false;
private static string existingDefines = string.Empty;
/// <summary>
/// Symbols that will be added to the editor
/// </summary>
public static readonly string[] Symbols = new string[] {
"IGNORANCE", // Ignorance exists
"IGNORANCE_1", // Major version
"IGNORANCE_1_4" // Major and minor version
};
/// <summary>
/// Do not remove these symbols
/// </summary>
public static readonly string[] DoNotRemoveTheseSymbols = new string[]
{
"IGNORANCE",
"IGNORANCE_1",
"IGNORANCE_1_4",
"IGNORANCE_MIRROR_POLLING"
};
/// <summary>
/// Add define symbols as soon as Unity gets done compiling.
/// </summary>
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<string> 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(debugMode)
UnityEngine.Debug.Log($"{s.Trim()} matches blacklist");
if (s == symbol.Trim()) return true;
}
return false;
}
static bool IsSafeToRemove (string input)
{
if (input.StartsWith("IGNORANCE") && !DoesSymbolExistInBlacklist(input))
{
if (debugMode)
UnityEngine.Debug.Log($"{input.Trim()} is safe to remove");
return true;
}
return false;
}
}
}
#endif

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: ed8acbde141f2d8469baf2142712de9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: ed8acbde141f2d8469baf2142712de9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,44 +0,0 @@
#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

View File

@@ -0,0 +1,43 @@
// Ignorance 1.4.x LTS (Long Term Support)
// https://github.com/SoftwareGuy/Ignorance
// -----------------
// Copyright (c) 2019 - 2021 Matt Coburn (SoftwareGuy/Coburn64)
// Ignorance is licensed under the MIT license. Refer
// to the LICENSE file for more information.
#if UNITY_EDITOR
using UnityEditor;
namespace IgnoranceTransport
{
public class Toolbox
{
#pragma warning disable IDE0051
[MenuItem("Ignorance/Debug/Native Library Name")]
public static void RevealEnetLibraryName()
{
EditorUtility.DisplayDialog("ENet Library Name", $"Your platform expects the native library to be called: {ENet.Native.nativeLibraryName}.\n\n" +
$"This info is very useful when trying to diagnose issues with DLL loading.", "Got it");
}
[MenuItem("Ignorance/RTFM/Github Repo")]
private static void LaunchGithubRepo()
{
UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/Ignorance");
}
[MenuItem("Ignorance/RTFM/Issue Tracker")]
private static void LaunchGithubIssueTracker()
{
UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/Ignorance/issues");
}
[MenuItem("Ignorance/RTFM/ENet-C# Repo")]
private static void LaunchENetCSharpForkRepo()
{
UnityEngine.Application.OpenURL("https://github.com/SoftwareGuy/ENet-CSharp");
}
#pragma warning restore
}
}
#endif

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 1fdecc996313d614ca16214d4e2b9162
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1fdecc996313d614ca16214d4e2b9162
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 872fa23ef6e77334ca452ce16f6cd091
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -32000
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 872fa23ef6e77334ca452ce16f6cd091
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -32000
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,94 +1,109 @@
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;
}
}
// Ignorance 1.4.x LTS (Long Term Support)
// https://github.com/SoftwareGuy/Ignorance
// -----------------
// Copyright (c) 2019 - 2021 Matt Coburn (SoftwareGuy/Coburn64)
// Ignorance is licensed under the MIT license. Refer
// to the LICENSE file for more information.
using System;
using System.Collections.Generic;
using ENet;
namespace IgnoranceCore
{
// Snipped from the transport files, as this will help
// me keep things up to date.
[Serializable]
public enum IgnoranceChannelTypes
{
Reliable = PacketFlags.Reliable, // Reliable UDP (TCP-like emulation)
ReliableUnsequenced = PacketFlags.Reliable | PacketFlags.Unsequenced, // Reliable UDP (TCP-like emulation w/o sequencing)
Unreliable = PacketFlags.Unsequenced, // Pure UDP, high velocity packet action.
UnreliableFragmented = PacketFlags.UnreliableFragmented, // Pure UDP, but fragmented.
UnreliableSequenced = PacketFlags.None, // Pure UDP, but sequenced.
Unthrottled = PacketFlags.Unthrottled, // Pure UDP. Literally turbo mode.
}
public class IgnoranceInternals
{
public const string Version = "1.4.0r0 (LTS)";
public const string Scheme = "enet";
public const string BindAnyAddress = "::0";
}
public enum IgnoranceLogType
{
Nothing,
Standard,
Verbose
}
public struct IgnoranceIncomingPacket
{
public byte Channel;
public uint NativePeerId;
public Packet Payload;
}
public struct IgnoranceOutgoingPacket
{
public byte Channel;
public uint NativePeerId;
public Packet Payload;
}
public struct IgnoranceConnectionEvent
{
public byte EventType;
public ushort Port;
public uint NativePeerId;
public string IP;
}
public struct IgnoranceCommandPacket
{
public IgnoranceCommandType Type;
public uint PeerId;
}
// Stats only - may not always be used!
public struct IgnoranceClientStats
{
public uint RTT;
public ulong BytesReceived;
public ulong BytesSent;
public ulong PacketsReceived;
public ulong PacketsSent;
public ulong PacketsLost;
}
public enum IgnoranceCommandType
{
// Client
ClientWantsToStop,
ClientStatusRequest,
// Server
ServerKickPeer,
ServerStatusRequest
}
// Stats only - may not always be used!
public struct IgnoranceServerStats
{
public ulong BytesReceived;
public ulong BytesSent;
public ulong PacketsReceived;
public ulong PacketsSent;
public ulong PeersCount;
public Dictionary<int, IgnoranceClientStats> PeerStats;
}
public struct PeerConnectionData
{
public ushort Port;
public uint NativePeerId;
public string IP;
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 3b2d1f7f7d9d3d64297755419f6ab925
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 3b2d1f7f7d9d3d64297755419f6ab925
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: e8bd04b9965420e40ac911fbf4294e1c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e8bd04b9965420e40ac911fbf4294e1c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: c90c88052305a054d87177362f63dea8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c90c88052305a054d87177362f63dea8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: e4a42b5855436864693138f74335c094
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e4a42b5855436864693138f74335c094
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,111 +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:
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:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: bfbaf4fbcf8987e4585ca666e28f4871
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: bfbaf4fbcf8987e4585ca666e28f4871
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,106 +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:
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:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: b3486c84aaebff4489e2e11f5bd3030f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b3486c84aaebff4489e2e11f5bd3030f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,80 +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:
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:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 8e3ca9b41c9f4064581a6b56ae549a9c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8e3ca9b41c9f4064581a6b56ae549a9c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
Rename this debug library without the "_debug" suffix and replace (maybe backup the original first) the library.
For example, to replace the x64 ENet Library with the Debug version, you'd first backup/move "libenet.so", then extract and rename "libenet_debug.so" to "libenet.so".
If you have trouble, file a GitHub support ticket at https://github.com/SoftwareGuy/Ignorance.
- Coburn

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 765c88bc8183ed44cb51a5529d8f743e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,97 +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:
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:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c7482955b4ae93c4081db9ddd04cae47
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 8837cb1a7320b8b4f824a02e23f4a545
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8837cb1a7320b8b4f824a02e23f4a545
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,3 +1,3 @@
This is a Windows x64 build of ENet-CSharp.
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.

View File

@@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 09ee288deb259474c819a5e3daf54b80
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 09ee288deb259474c819a5e3daf54b80
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,111 +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:
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:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 7edc275f3670f4251b90301cbb9f7413
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7edc275f3670f4251b90301cbb9f7413
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,80 +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:
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:

View File

@@ -1,80 +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:
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:

View File

@@ -1,80 +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:
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:

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 957ba76da095cd64aaa658f034ab78e5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 957ba76da095cd64aaa658f034ab78e5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,32 +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:
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:

View File

@@ -1,35 +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.
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.

View File

@@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: a28193472bc84d341ab4aee18c471a93
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: a28193472bc84d341ab4aee18c471a93
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1 +1 @@
1.4.0b6
1.4.0r0 LTS

View File

@@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: ad80075449f17c548877161f32a9841a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: ad80075449f17c548877161f32a9841a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: