reformat code

This commit is contained in:
JohnCorby 2022-02-05 20:17:08 -08:00
parent e7accbdf17
commit c9f9ba0801
10 changed files with 1562 additions and 1278 deletions

View File

@ -50,9 +50,10 @@ using System.Collections.Generic;
/// MIT License
/// </summary>
namespace EpicTransport {
public class BidirectionalDictionary<T1, T2> : IEnumerable {
namespace EpicTransport
{
public class BidirectionalDictionary<T1, T2> : IEnumerable
{
private Dictionary<T1, T2> t1ToT2Dict = new Dictionary<T1, T2>();
private Dictionary<T2, T1> t2ToT1Dict = new Dictionary<T2, T1>();
@ -63,12 +64,14 @@ namespace EpicTransport {
public int Count => t1ToT2Dict.Count;
public void Add(T1 key, T2 value) {
public void Add(T1 key, T2 value)
{
t1ToT2Dict[key] = value;
t2ToT1Dict[value] = key;
}
public void Add(T2 key, T1 value) {
public void Add(T2 key, T1 value)
{
t2ToT1Dict[key] = value;
t1ToT2Dict[value] = key;
}
@ -85,36 +88,44 @@ namespace EpicTransport {
public bool Contains(T2 key) => t2ToT1Dict.ContainsKey(key);
public void Remove(T1 key) {
if (Contains(key)) {
public void Remove(T1 key)
{
if (Contains(key))
{
T2 val = t1ToT2Dict[key];
t1ToT2Dict.Remove(key);
t2ToT1Dict.Remove(val);
}
}
public void Remove(T2 key) {
if (Contains(key)) {
public void Remove(T2 key)
{
if (Contains(key))
{
T1 val = t2ToT1Dict[key];
t1ToT2Dict.Remove(val);
t2ToT1Dict.Remove(key);
}
}
public T1 this[T2 key] {
public T1 this[T2 key]
{
get => t2ToT1Dict[key];
set {
set
{
t2ToT1Dict[key] = value;
t1ToT2Dict[value] = key;
}
}
public T2 this[T1 key] {
public T2 this[T1 key]
{
get => t1ToT2Dict[key];
set {
set
{
t1ToT2Dict[key] = value;
t2ToT1Dict[value] = key;
}
}
}
}

View File

@ -6,9 +6,10 @@ using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace EpicTransport {
public class Client : Common {
namespace EpicTransport
{
public class Client : Common
{
public SocketId socketId;
public ProductUserId serverId;
@ -27,11 +28,13 @@ namespace EpicTransport {
private TaskCompletionSource<Task> connectedComplete;
private CancellationTokenSource cancelToken;
private Client(EosTransport transport) : base(transport) {
private Client(EosTransport transport) : base(transport)
{
ConnectionTimeout = TimeSpan.FromSeconds(Math.Max(1, transport.timeout));
}
public static Client CreateClient(EosTransport transport, string host) {
public static Client CreateClient(EosTransport transport, string host)
{
Client c = new Client(transport);
c.hostAddress = host;
@ -44,10 +47,12 @@ namespace EpicTransport {
return c;
}
public async void Connect(string host) {
public async void Connect(string host)
{
cancelToken = new CancellationTokenSource();
try {
try
{
hostProductId = ProductUserId.FromString(host);
serverId = hostProductId;
connectedComplete = new TaskCompletionSource<Task>();
@ -58,35 +63,46 @@ namespace EpicTransport {
Task connectedCompleteTask = connectedComplete.Task;
if (await Task.WhenAny(connectedCompleteTask, Task.Delay(ConnectionTimeout/*, cancelToken.Token*/)) != connectedCompleteTask) {
if (await Task.WhenAny(connectedCompleteTask, Task.Delay(ConnectionTimeout /*, cancelToken.Token*/)) != connectedCompleteTask)
{
Debug.LogError($"Connection to {host} timed out.");
OnConnected -= SetConnectedComplete;
OnConnectionFailed(hostProductId);
}
OnConnected -= SetConnectedComplete;
} catch (FormatException) {
}
catch (FormatException)
{
Debug.LogError($"Connection string was not in the right format. Did you enter a ProductId?");
Error = true;
OnConnectionFailed(hostProductId);
} catch (Exception ex) {
}
catch (Exception ex)
{
Debug.LogError(ex.Message);
Error = true;
OnConnectionFailed(hostProductId);
} finally {
if (Error) {
}
finally
{
if (Error)
{
OnConnectionFailed(null);
}
}
}
public void Disconnect() {
if (serverId != null) {
public void Disconnect()
{
if (serverId != null)
{
CloseP2PSessionWithUser(serverId, socketId);
serverId = null;
} else {
}
else
{
return;
}
@ -100,12 +116,15 @@ namespace EpicTransport {
private void SetConnectedComplete() => connectedComplete.SetResult(connectedComplete.Task);
protected override void OnReceiveData(byte[] data, ProductUserId clientUserId, int channel) {
if (ignoreAllMessages) {
protected override void OnReceiveData(byte[] data, ProductUserId clientUserId, int channel)
{
if (ignoreAllMessages)
{
return;
}
if (clientUserId != hostProductId) {
if (clientUserId != hostProductId)
{
Debug.LogError("Received a message from an unknown");
return;
}
@ -113,34 +132,44 @@ namespace EpicTransport {
OnReceivedData.Invoke(data, channel);
}
protected override void OnNewConnection(OnIncomingConnectionRequestInfo result) {
if (ignoreAllMessages) {
protected override void OnNewConnection(OnIncomingConnectionRequestInfo result)
{
if (ignoreAllMessages)
{
return;
}
if (deadSockets.Contains(result.SocketId.SocketName)) {
if (deadSockets.Contains(result.SocketId.SocketName))
{
Debug.LogError("Received incoming connection request from dead socket");
return;
}
if (hostProductId == result.RemoteUserId) {
if (hostProductId == result.RemoteUserId)
{
EOSSDKComponent.GetP2PInterface().AcceptConnection(
new AcceptConnectionOptions() {
new AcceptConnectionOptions()
{
LocalUserId = EOSSDKComponent.LocalUserProductId,
RemoteUserId = result.RemoteUserId,
SocketId = result.SocketId
});
} else {
}
else
{
Debug.LogError("P2P Acceptance Request from unknown host ID.");
}
}
protected override void OnReceiveInternalData(InternalMessages type, ProductUserId clientUserId, SocketId socketId) {
if (ignoreAllMessages) {
protected override void OnReceiveInternalData(InternalMessages type, ProductUserId clientUserId, SocketId socketId)
{
if (ignoreAllMessages)
{
return;
}
switch (type) {
switch (type)
{
case InternalMessages.ACCEPT_CONNECT:
Connected = true;
OnConnected.Invoke();
@ -158,7 +187,7 @@ namespace EpicTransport {
}
}
public void Send(byte[] data, int channelId) => Send(hostProductId, socketId, data, (byte) channelId);
public void Send(byte[] data, int channelId) => Send(hostProductId, socketId, data, (byte)channelId);
protected override void OnConnectionFailed(ProductUserId remoteId) => OnDisconnected.Invoke();
public void EosNotInitialized() => OnDisconnected.Invoke();

View File

@ -1,24 +1,26 @@

using Epic.OnlineServices;
using Epic.OnlineServices;
using Epic.OnlineServices.P2P;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EpicTransport {
public abstract class Common {
namespace EpicTransport
{
public abstract class Common
{
private PacketReliability[] channels;
private int internal_ch => channels.Length;
protected enum InternalMessages : byte {
protected enum InternalMessages : byte
{
CONNECT,
ACCEPT_CONNECT,
DISCONNECT
}
protected struct PacketKey {
protected struct PacketKey
{
public ProductUserId productUserId;
public byte channel;
}
@ -36,7 +38,8 @@ namespace EpicTransport {
// Mapping from PacketKey to a List of Packet Lists
protected Dictionary<PacketKey, List<List<Packet>>> incomingPackets = new Dictionary<PacketKey, List<List<Packet>>>();
protected Common(EosTransport transport) {
protected Common(EosTransport transport)
{
channels = transport.Channels;
deadSockets = new List<string>();
@ -58,17 +61,18 @@ namespace EpicTransport {
outgoingNotificationId = EOSSDKComponent.GetP2PInterface().AddNotifyPeerConnectionClosed(addNotifyPeerConnectionClosedOptions,
null, OnRemoteConnectionClosed);
if (outgoingNotificationId == 0 || incomingNotificationId == 0) {
if (outgoingNotificationId == 0 || incomingNotificationId == 0)
{
Debug.LogError("Couldn't bind notifications with P2P interface");
}
incomingPackets = new Dictionary<PacketKey, List<List<Packet>>>();
this.transport = transport;
}
protected void Dispose() {
protected void Dispose()
{
EOSSDKComponent.GetP2PInterface().RemoveNotifyPeerConnectionRequest(incomingNotificationId);
EOSSDKComponent.GetP2PInterface().RemoveNotifyPeerConnectionClosed(outgoingNotificationId);
@ -77,14 +81,17 @@ namespace EpicTransport {
protected abstract void OnNewConnection(OnIncomingConnectionRequestInfo result);
private void OnConnectFail(OnRemoteConnectionClosedInfo result) {
if (ignoreAllMessages) {
private void OnConnectFail(OnRemoteConnectionClosedInfo result)
{
if (ignoreAllMessages)
{
return;
}
OnConnectionFailed(result.RemoteUserId);
switch (result.Reason) {
switch (result.Reason)
{
case ConnectionClosedReason.ClosedByLocalUser:
throw new Exception("Connection cLosed: The Connection was gracecfully closed by the local user.");
case ConnectionClosedReason.ClosedByPeer:
@ -111,11 +118,13 @@ namespace EpicTransport {
}
}
protected void SendInternal(ProductUserId target, SocketId socketId, InternalMessages type) {
EOSSDKComponent.GetP2PInterface().SendPacket(new SendPacketOptions() {
protected void SendInternal(ProductUserId target, SocketId socketId, InternalMessages type)
{
EOSSDKComponent.GetP2PInterface().SendPacket(new SendPacketOptions()
{
AllowDelayedDelivery = true,
Channel = (byte) internal_ch,
Data = new byte[] { (byte) type },
Channel = (byte)internal_ch,
Data = new byte[] { (byte)type },
LocalUserId = EOSSDKComponent.LocalUserProductId,
Reliability = PacketReliability.ReliableOrdered,
RemoteUserId = target,
@ -123,9 +132,10 @@ namespace EpicTransport {
});
}
protected void Send(ProductUserId host, SocketId socketId, byte[] msgBuffer, byte channel) {
Result result = EOSSDKComponent.GetP2PInterface().SendPacket(new SendPacketOptions() {
protected void Send(ProductUserId host, SocketId socketId, byte[] msgBuffer, byte channel)
{
Result result = EOSSDKComponent.GetP2PInterface().SendPacket(new SendPacketOptions()
{
AllowDelayedDelivery = true,
Channel = channel,
Data = msgBuffer,
@ -135,19 +145,23 @@ namespace EpicTransport {
SocketId = socketId
});
if(result != Result.Success) {
if (result != Result.Success)
{
Debug.LogError("Send failed " + result);
}
}
private bool Receive(out ProductUserId clientProductUserId, out SocketId socketId, out byte[] receiveBuffer, byte channel) {
Result result = EOSSDKComponent.GetP2PInterface().ReceivePacket(new ReceivePacketOptions() {
private bool Receive(out ProductUserId clientProductUserId, out SocketId socketId, out byte[] receiveBuffer, byte channel)
{
Result result = EOSSDKComponent.GetP2PInterface().ReceivePacket(new ReceivePacketOptions()
{
LocalUserId = EOSSDKComponent.LocalUserProductId,
MaxDataSizeBytes = P2PInterface.MaxPacketSize,
RequestedChannel = channel
}, out clientProductUserId, out socketId, out channel, out receiveBuffer);
if (result == Result.Success) {
if (result == Result.Success)
{
return true;
}
@ -156,47 +170,62 @@ namespace EpicTransport {
return false;
}
protected virtual void CloseP2PSessionWithUser(ProductUserId clientUserID, SocketId socketId) {
if (socketId == null) {
protected virtual void CloseP2PSessionWithUser(ProductUserId clientUserID, SocketId socketId)
{
if (socketId == null)
{
Debug.LogWarning("Socket ID == null | " + ignoreAllMessages);
return;
}
if (deadSockets == null) {
if (deadSockets == null)
{
Debug.LogWarning("DeadSockets == null");
return;
}
if (deadSockets.Contains(socketId.SocketName)) {
if (deadSockets.Contains(socketId.SocketName))
{
return;
} else {
}
else
{
deadSockets.Add(socketId.SocketName);
}
}
protected void WaitForClose(ProductUserId clientUserID, SocketId socketId) => transport.StartCoroutine(DelayedClose(clientUserID, socketId));
private IEnumerator DelayedClose(ProductUserId clientUserID, SocketId socketId) {
private IEnumerator DelayedClose(ProductUserId clientUserID, SocketId socketId)
{
yield return null;
CloseP2PSessionWithUser(clientUserID, socketId);
}
public void ReceiveData() {
try {
public void ReceiveData()
{
try
{
// Internal Channel, no fragmentation here
SocketId socketId = new SocketId();
while (transport.enabled && Receive(out ProductUserId clientUserID, out socketId, out byte[] internalMessage, (byte) internal_ch)) {
if (internalMessage.Length == 1) {
OnReceiveInternalData((InternalMessages) internalMessage[0], clientUserID, socketId);
while (transport.enabled && Receive(out ProductUserId clientUserID, out socketId, out byte[] internalMessage, (byte)internal_ch))
{
if (internalMessage.Length == 1)
{
OnReceiveInternalData((InternalMessages)internalMessage[0], clientUserID, socketId);
return; // Wait one frame
} else {
}
else
{
Debug.Log("Incorrect package length on internal channel.");
}
}
// Insert new packet at the correct location in the incoming queue
for (int chNum = 0; chNum < channels.Length; chNum++) {
while (transport.enabled && Receive(out ProductUserId clientUserID, out socketId, out byte[] receiveBuffer, (byte) chNum)) {
for (int chNum = 0; chNum < channels.Length; chNum++)
{
while (transport.enabled && Receive(out ProductUserId clientUserID, out socketId, out byte[] receiveBuffer, (byte)chNum))
{
PacketKey incomingPacketKey = new PacketKey();
incomingPacketKey.productUserId = clientUserID;
incomingPacketKey.channel = (byte)chNum;
@ -204,34 +233,43 @@ namespace EpicTransport {
Packet packet = new Packet();
packet.FromBytes(receiveBuffer);
if (!incomingPackets.ContainsKey(incomingPacketKey)) {
if (!incomingPackets.ContainsKey(incomingPacketKey))
{
incomingPackets.Add(incomingPacketKey, new List<List<Packet>>());
}
int packetListIndex = incomingPackets[incomingPacketKey].Count;
for(int i = 0; i < incomingPackets[incomingPacketKey].Count; i++) {
if(incomingPackets[incomingPacketKey][i][0].id == packet.id) {
for (int i = 0; i < incomingPackets[incomingPacketKey].Count; i++)
{
if (incomingPackets[incomingPacketKey][i][0].id == packet.id)
{
packetListIndex = i;
break;
}
}
if (packetListIndex == incomingPackets[incomingPacketKey].Count) {
if (packetListIndex == incomingPackets[incomingPacketKey].Count)
{
incomingPackets[incomingPacketKey].Add(new List<Packet>());
}
int insertionIndex = -1;
for (int i = 0; i < incomingPackets[incomingPacketKey][packetListIndex].Count; i++) {
if (incomingPackets[incomingPacketKey][packetListIndex][i].fragment > packet.fragment) {
for (int i = 0; i < incomingPackets[incomingPacketKey][packetListIndex].Count; i++)
{
if (incomingPackets[incomingPacketKey][packetListIndex][i].fragment > packet.fragment)
{
insertionIndex = i;
break;
}
}
if (insertionIndex >= 0) {
if (insertionIndex >= 0)
{
incomingPackets[incomingPacketKey][packetListIndex].Insert(insertionIndex, packet);
} else {
}
else
{
incomingPackets[incomingPacketKey][packetListIndex].Add(packet);
}
}
@ -239,24 +277,32 @@ namespace EpicTransport {
// Find fully received packets
List<List<Packet>> emptyPacketLists = new List<List<Packet>>();
foreach(KeyValuePair<PacketKey, List<List<Packet>>> keyValuePair in incomingPackets) {
for(int packetList = 0; packetList < keyValuePair.Value.Count; packetList++) {
foreach (KeyValuePair<PacketKey, List<List<Packet>>> keyValuePair in incomingPackets)
{
for (int packetList = 0; packetList < keyValuePair.Value.Count; packetList++)
{
bool packetReady = true;
int packetLength = 0;
for (int packet = 0; packet < keyValuePair.Value[packetList].Count; packet++) {
for (int packet = 0; packet < keyValuePair.Value[packetList].Count; packet++)
{
Packet tempPacket = keyValuePair.Value[packetList][packet];
if (tempPacket.fragment != packet || (packet == keyValuePair.Value[packetList].Count - 1 && tempPacket.moreFragments)) {
if (tempPacket.fragment != packet || (packet == keyValuePair.Value[packetList].Count - 1 && tempPacket.moreFragments))
{
packetReady = false;
} else {
}
else
{
packetLength += tempPacket.data.Length;
}
}
if (packetReady) {
if (packetReady)
{
byte[] data = new byte[packetLength];
int dataIndex = 0;
for (int packet = 0; packet < keyValuePair.Value[packetList].Count; packet++) {
for (int packet = 0; packet < keyValuePair.Value[packetList].Count; packet++)
{
Array.Copy(keyValuePair.Value[packetList][packet].data, 0, data, dataIndex, keyValuePair.Value[packetList][packet].data.Length);
dataIndex += keyValuePair.Value[packetList][packet].data.Length;
}
@ -268,15 +314,16 @@ namespace EpicTransport {
}
}
for (int i = 0; i < emptyPacketLists.Count; i++) {
for (int i = 0; i < emptyPacketLists.Count; i++)
{
keyValuePair.Value.Remove(emptyPacketLists[i]);
}
emptyPacketLists.Clear();
}
} catch (Exception e) {
}
catch (Exception e)
{
Debug.LogException(e);
}
}

View File

@ -1,10 +1,8 @@
using Epic.OnlineServices;
using Epic.OnlineServices.Logging;
using Epic.OnlineServices.Platform;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
/// <summary>
@ -14,10 +12,11 @@ using UnityEngine;
/// after releasing the SDK the game has to be restarted in order to initialize the SDK again.
/// In the unity editor the OnDestroy function will not run so that we dont have to restart the editor after play.
/// </summary>
namespace EpicTransport {
namespace EpicTransport
{
[DefaultExecutionOrder(-32000)]
public class EOSSDKComponent : MonoBehaviour {
public class EOSSDKComponent : MonoBehaviour
{
// Unity Inspector shown variables
[SerializeField]
@ -31,11 +30,14 @@ namespace EpicTransport {
public Epic.OnlineServices.ExternalCredentialType connectInterfaceCredentialType = Epic.OnlineServices.ExternalCredentialType.DeviceidAccessToken;
public string deviceModel = "PC Windows 64bit";
[SerializeField] private string displayName = "User";
public static string DisplayName {
get {
public static string DisplayName
{
get
{
return Instance.displayName;
}
set {
set
{
Instance.displayName = value;
}
}
@ -45,8 +47,10 @@ namespace EpicTransport {
[SerializeField]
public bool collectPlayerMetrics = true;
public static bool CollectPlayerMetrics {
get {
public static bool CollectPlayerMetrics
{
get
{
return Instance.collectPlayerMetrics;
}
}
@ -61,7 +65,6 @@ namespace EpicTransport {
private ulong authExpirationHandle;
private string authInterfaceLoginCredentialId = null;
public static void SetAuthInterfaceLoginCredentialId(string credentialId) => Instance.authInterfaceLoginCredentialId = credentialId;
private string authInterfaceCredentialToken = null;
@ -89,61 +92,78 @@ namespace EpicTransport {
public static Epic.OnlineServices.UI.UIInterface GetUIInterface() => Instance.EOS.GetUIInterface();
public static Epic.OnlineServices.UserInfo.UserInfoInterface GetUserInfoInterface() => Instance.EOS.GetUserInfoInterface();
protected EpicAccountId localUserAccountId;
public static EpicAccountId LocalUserAccountId {
get {
public static EpicAccountId LocalUserAccountId
{
get
{
return Instance.localUserAccountId;
}
}
protected string localUserAccountIdString;
public static string LocalUserAccountIdString {
get {
public static string LocalUserAccountIdString
{
get
{
return Instance.localUserAccountIdString;
}
}
protected ProductUserId localUserProductId;
public static ProductUserId LocalUserProductId {
get {
public static ProductUserId LocalUserProductId
{
get
{
return Instance.localUserProductId;
}
}
protected string localUserProductIdString;
public static string LocalUserProductIdString {
get {
public static string LocalUserProductIdString
{
get
{
return Instance.localUserProductIdString;
}
}
protected bool initialized;
public static bool Initialized {
get {
public static bool Initialized
{
get
{
return Instance.initialized;
}
}
protected bool isConnecting;
public static bool IsConnecting {
get {
public static bool IsConnecting
{
get
{
return Instance.isConnecting;
}
}
protected static EOSSDKComponent instance;
protected static EOSSDKComponent Instance {
get {
if (instance == null) {
protected static EOSSDKComponent Instance
{
get
{
if (instance == null)
{
return new GameObject("EOSSDKComponent").AddComponent<EOSSDKComponent>();
} else {
}
else
{
return instance;
}
}
}
public static void Tick() {
public static void Tick()
{
instance.platformTickTimer -= Time.deltaTime;
instance.EOS.Tick();
}
@ -189,7 +209,8 @@ namespace EpicTransport {
private IntPtr libraryPointer;
#endif
private void Awake() {
private void Awake()
{
// Initialize Java version of the SDK with a reference to the VM with JNI
// See https://eoshelp.epicgames.com/s/question/0D54z00006ufJBNCA2/cant-get-createdeviceid-to-work-in-unity-android-c-sdk?language=en_US
if (Application.platform == RuntimePlatform.Android)
@ -202,10 +223,12 @@ namespace EpicTransport {
}
// Prevent multiple instances
if (instance != null) {
if (instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
#if UNITY_EDITOR
@ -219,15 +242,18 @@ namespace EpicTransport {
Bindings.Hook(libraryPointer, GetProcAddress);
#endif
if (!delayedInitialization) {
if (!delayedInitialization)
{
Initialize();
}
}
protected void InitializeImplementation() {
protected void InitializeImplementation()
{
isConnecting = true;
var initializeOptions = new InitializeOptions() {
var initializeOptions = new InitializeOptions()
{
ProductName = apiKeys.epicProductName,
ProductVersion = apiKeys.epicProductVersion
};
@ -236,7 +262,8 @@ namespace EpicTransport {
// This code is called each time the game is run in the editor, so we catch the case where the SDK has already been initialized in the editor.
var isAlreadyConfiguredInEditor = Application.isEditor && initializeResult == Result.AlreadyConfigured;
if (initializeResult != Result.Success && !isAlreadyConfiguredInEditor) {
if (initializeResult != Result.Success && !isAlreadyConfiguredInEditor)
{
throw new System.Exception("Failed to initialize platform: " + initializeResult);
}
@ -245,11 +272,13 @@ namespace EpicTransport {
LoggingInterface.SetLogLevel(LogCategory.AllCategories, epicLoggerLevel);
LoggingInterface.SetCallback(message => Logger.EpicDebugLog(message));
var options = new Options() {
var options = new Options()
{
ProductId = apiKeys.epicProductId,
SandboxId = apiKeys.epicSandboxId,
DeploymentId = apiKeys.epicDeploymentId,
ClientCredentials = new ClientCredentials() {
ClientCredentials = new ClientCredentials()
{
ClientId = apiKeys.epicClientId,
ClientSecret = apiKeys.epicClientSecret
},
@ -257,18 +286,21 @@ namespace EpicTransport {
};
EOS = PlatformInterface.Create(options);
if (EOS == null) {
if (EOS == null)
{
throw new System.Exception("Failed to create platform");
}
if (checkForEpicLauncherAndRestart) {
if (checkForEpicLauncherAndRestart)
{
Result result = EOS.CheckForLauncherAndRestart();
// If not started through epic launcher the app will be restarted and we can quit
if (result != Result.NoChange) {
if (result != Result.NoChange)
{
// Log error if launcher check failed, but still quit to prevent hacking
if (result == Result.UnexpectedError) {
if (result == Result.UnexpectedError)
{
Debug.LogError("Unexpected Error while checking if app was started through epic launcher");
}
@ -278,15 +310,19 @@ namespace EpicTransport {
// If we use the Auth interface then only login into the Connect interface after finishing the auth interface login
// If we don't use the Auth interface we can directly login to the Connect interface
if (authInterfaceLogin) {
if (authInterfaceCredentialType == Epic.OnlineServices.Auth.LoginCredentialType.Developer) {
if (authInterfaceLogin)
{
if (authInterfaceCredentialType == Epic.OnlineServices.Auth.LoginCredentialType.Developer)
{
authInterfaceLoginCredentialId = "localhost:" + devAuthToolPort;
authInterfaceCredentialToken = devAuthToolCredentialName;
}
// Login to Auth Interface
Epic.OnlineServices.Auth.LoginOptions loginOptions = new Epic.OnlineServices.Auth.LoginOptions() {
Credentials = new Epic.OnlineServices.Auth.Credentials() {
Epic.OnlineServices.Auth.LoginOptions loginOptions = new Epic.OnlineServices.Auth.LoginOptions()
{
Credentials = new Epic.OnlineServices.Auth.Credentials()
{
Type = authInterfaceCredentialType,
Id = authInterfaceLoginCredentialId,
Token = authInterfaceCredentialToken
@ -295,33 +331,43 @@ namespace EpicTransport {
};
EOS.GetAuthInterface().Login(loginOptions, null, OnAuthInterfaceLogin);
} else {
}
else
{
// Login to Connect Interface
if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.DeviceidAccessToken) {
if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.DeviceidAccessToken)
{
Epic.OnlineServices.Connect.CreateDeviceIdOptions createDeviceIdOptions = new Epic.OnlineServices.Connect.CreateDeviceIdOptions();
createDeviceIdOptions.DeviceModel = deviceModel;
EOS.GetConnectInterface().CreateDeviceId(createDeviceIdOptions, null, OnCreateDeviceId);
} else {
}
else
{
ConnectInterfaceLogin();
}
}
}
public static void Initialize() {
if (Instance.initialized || Instance.isConnecting) {
public static void Initialize()
{
if (Instance.initialized || Instance.isConnecting)
{
return;
}
Instance.InitializeImplementation();
}
private void OnAuthInterfaceLogin(Epic.OnlineServices.Auth.LoginCallbackInfo loginCallbackInfo) {
if (loginCallbackInfo.ResultCode == Result.Success) {
private void OnAuthInterfaceLogin(Epic.OnlineServices.Auth.LoginCallbackInfo loginCallbackInfo)
{
if (loginCallbackInfo.ResultCode == Result.Success)
{
Debug.Log("Auth Interface Login succeeded");
string accountIdString;
Result result = loginCallbackInfo.LocalUserId.ToString(out accountIdString);
if (Result.Success == result) {
if (Result.Success == result)
{
Debug.Log("EOS User ID:" + accountIdString);
localUserAccountIdString = accountIdString;
@ -329,32 +375,45 @@ namespace EpicTransport {
}
ConnectInterfaceLogin();
} else if(Epic.OnlineServices.Common.IsOperationComplete(loginCallbackInfo.ResultCode)){
}
else if (Epic.OnlineServices.Common.IsOperationComplete(loginCallbackInfo.ResultCode))
{
Debug.Log("Login returned " + loginCallbackInfo.ResultCode);
}
}
private void OnCreateDeviceId(Epic.OnlineServices.Connect.CreateDeviceIdCallbackInfo createDeviceIdCallbackInfo) {
if (createDeviceIdCallbackInfo.ResultCode == Result.Success || createDeviceIdCallbackInfo.ResultCode == Result.DuplicateNotAllowed) {
private void OnCreateDeviceId(Epic.OnlineServices.Connect.CreateDeviceIdCallbackInfo createDeviceIdCallbackInfo)
{
if (createDeviceIdCallbackInfo.ResultCode == Result.Success || createDeviceIdCallbackInfo.ResultCode == Result.DuplicateNotAllowed)
{
ConnectInterfaceLogin();
} else if(Epic.OnlineServices.Common.IsOperationComplete(createDeviceIdCallbackInfo.ResultCode)) {
}
else if (Epic.OnlineServices.Common.IsOperationComplete(createDeviceIdCallbackInfo.ResultCode))
{
Debug.Log("Device ID creation returned " + createDeviceIdCallbackInfo.ResultCode);
}
}
private void ConnectInterfaceLogin() {
private void ConnectInterfaceLogin()
{
var loginOptions = new Epic.OnlineServices.Connect.LoginOptions();
if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.Epic) {
if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.Epic)
{
Epic.OnlineServices.Auth.Token token;
Result result = EOS.GetAuthInterface().CopyUserAuthToken(new Epic.OnlineServices.Auth.CopyUserAuthTokenOptions(), localUserAccountId, out token);
if (result == Result.Success) {
if (result == Result.Success)
{
connectInterfaceCredentialToken = token.AccessToken;
} else {
}
else
{
Debug.LogError("Failed to retrieve User Auth Token");
}
} else if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.DeviceidAccessToken) {
}
else if (connectInterfaceCredentialType == Epic.OnlineServices.ExternalCredentialType.DeviceidAccessToken)
{
loginOptions.UserLoginInfo = new Epic.OnlineServices.Connect.UserLoginInfo();
loginOptions.UserLoginInfo.DisplayName = displayName;
}
@ -366,13 +425,16 @@ namespace EpicTransport {
EOS.GetConnectInterface().Login(loginOptions, null, OnConnectInterfaceLogin);
}
private void OnConnectInterfaceLogin(Epic.OnlineServices.Connect.LoginCallbackInfo loginCallbackInfo) {
if (loginCallbackInfo.ResultCode == Result.Success) {
private void OnConnectInterfaceLogin(Epic.OnlineServices.Connect.LoginCallbackInfo loginCallbackInfo)
{
if (loginCallbackInfo.ResultCode == Result.Success)
{
Debug.Log("Connect Interface Login succeeded");
string productIdString;
Result result = loginCallbackInfo.LocalUserId.ToString(out productIdString);
if (Result.Success == result) {
if (Result.Success == result)
{
Debug.Log("EOS User Product ID:" + productIdString);
localUserProductIdString = productIdString;
@ -384,36 +446,50 @@ namespace EpicTransport {
var authExpirationOptions = new Epic.OnlineServices.Connect.AddNotifyAuthExpirationOptions();
authExpirationHandle = EOS.GetConnectInterface().AddNotifyAuthExpiration(authExpirationOptions, null, OnAuthExpiration);
} else if (Epic.OnlineServices.Common.IsOperationComplete(loginCallbackInfo.ResultCode)) {
}
else if (Epic.OnlineServices.Common.IsOperationComplete(loginCallbackInfo.ResultCode))
{
Debug.Log("Login returned " + loginCallbackInfo.ResultCode + "\nRetrying...");
EOS.GetConnectInterface().CreateUser(new Epic.OnlineServices.Connect.CreateUserOptions() { ContinuanceToken = loginCallbackInfo.ContinuanceToken }, null, (Epic.OnlineServices.Connect.CreateUserCallbackInfo cb) => {
if (cb.ResultCode != Result.Success) { Debug.Log(cb.ResultCode); return; }
EOS.GetConnectInterface().CreateUser(new Epic.OnlineServices.Connect.CreateUserOptions() { ContinuanceToken = loginCallbackInfo.ContinuanceToken }, null, (Epic.OnlineServices.Connect.CreateUserCallbackInfo cb) =>
{
if (cb.ResultCode != Result.Success)
{
Debug.Log(cb.ResultCode);
return;
}
localUserProductId = cb.LocalUserId;
ConnectInterfaceLogin();
});
}
}
private void OnAuthExpiration(Epic.OnlineServices.Connect.AuthExpirationCallbackInfo authExpirationCallbackInfo) {
private void OnAuthExpiration(Epic.OnlineServices.Connect.AuthExpirationCallbackInfo authExpirationCallbackInfo)
{
Debug.Log("AuthExpiration callback");
EOS.GetConnectInterface().RemoveNotifyAuthExpiration(authExpirationHandle);
ConnectInterfaceLogin();
}
// Calling tick on a regular interval is required for callbacks to work.
private void LateUpdate() {
if (EOS != null) {
private void LateUpdate()
{
if (EOS != null)
{
platformTickTimer += Time.deltaTime;
if (platformTickTimer >= platformTickIntervalInSeconds) {
if (platformTickTimer >= platformTickIntervalInSeconds)
{
platformTickTimer = 0;
EOS.Tick();
}
}
}
private void OnApplicationQuit() {
if (EOS != null) {
private void OnApplicationQuit()
{
if (EOS != null)
{
EOS.Release();
EOS = null;
PlatformInterface.Shutdown();

View File

@ -10,9 +10,9 @@ using UnityEngine;
/// Create -> EOS -> API Key
/// in order to create an instance of this scriptable object
/// </summary>
[CreateAssetMenu(fileName = "EosApiKey", menuName = "EOS/API Key", order = 1)]
public class EosApiKey : ScriptableObject {
public class EosApiKey : ScriptableObject
{
public string epicProductName = "MyApplication";
public string epicProductVersion = "1.0";
public string epicProductId = "";

View File

@ -8,12 +8,13 @@ using Mirror;
using Epic.OnlineServices.Metrics;
using System.Collections;
namespace EpicTransport {
namespace EpicTransport
{
/// <summary>
/// EOS Transport following the Mirror transport standard
/// </summary>
public class EosTransport : Transport {
public class EosTransport : Transport
{
private const string EPIC_SCHEME = "epic";
private Client client;
@ -41,14 +42,18 @@ namespace EpicTransport {
private int packetId = 0;
private void Awake() {
private void Awake()
{
Debug.Assert(Channels != null && Channels.Length > 0, "No channel configured for EOS Transport.");
Debug.Assert(Channels.Length < byte.MaxValue, "Too many channels configured for EOS Transport");
if(Channels[0] != PacketReliability.ReliableOrdered) {
if (Channels[0] != PacketReliability.ReliableOrdered)
{
Debug.LogWarning("EOS Transport Channel[0] is not ReliableOrdered, Mirror expects Channel 0 to be ReliableOrdered, only change this if you know what you are doing.");
}
if (Channels[1] != PacketReliability.UnreliableUnordered) {
if (Channels[1] != PacketReliability.UnreliableUnordered)
{
Debug.LogWarning("EOS Transport Channel[1] is not UnreliableUnordered, Mirror expects Channel 1 to be UnreliableUnordered, only change this if you know what you are doing.");
}
@ -56,59 +61,79 @@ namespace EpicTransport {
StartCoroutine("ChangeRelayStatus");
}
public override void ClientEarlyUpdate() {
public override void ClientEarlyUpdate()
{
EOSSDKComponent.Tick();
if (activeNode != null) {
if (activeNode != null)
{
ignoreCachedMessagesTimer += Time.deltaTime;
if (ignoreCachedMessagesTimer <= ignoreCachedMessagesAtStartUpInSeconds) {
if (ignoreCachedMessagesTimer <= ignoreCachedMessagesAtStartUpInSeconds)
{
activeNode.ignoreAllMessages = true;
} else {
}
else
{
activeNode.ignoreAllMessages = false;
if (client != null && !client.isConnecting) {
if (EOSSDKComponent.Initialized) {
if (client != null && !client.isConnecting)
{
if (EOSSDKComponent.Initialized)
{
client.Connect(client.hostAddress);
} else {
}
else
{
Debug.LogError("EOS not initialized");
client.EosNotInitialized();
}
client.isConnecting = true;
}
}
}
if (enabled) {
if (enabled)
{
activeNode?.ReceiveData();
}
}
public override void ClientLateUpdate() {}
public override void ClientLateUpdate() { }
public override void ServerEarlyUpdate() {
public override void ServerEarlyUpdate()
{
EOSSDKComponent.Tick();
if (activeNode != null) {
if (activeNode != null)
{
ignoreCachedMessagesTimer += Time.deltaTime;
if (ignoreCachedMessagesTimer <= ignoreCachedMessagesAtStartUpInSeconds) {
if (ignoreCachedMessagesTimer <= ignoreCachedMessagesAtStartUpInSeconds)
{
activeNode.ignoreAllMessages = true;
} else {
}
else
{
activeNode.ignoreAllMessages = false;
}
}
if (enabled) {
if (enabled)
{
activeNode?.ReceiveData();
}
}
public override void ServerLateUpdate() {}
public override void ServerLateUpdate() { }
public override bool ClientConnected() => ClientActive() && client.Connected;
public override void ClientConnect(string address) {
if (!EOSSDKComponent.Initialized) {
public override void ClientConnect(string address)
{
if (!EOSSDKComponent.Initialized)
{
Debug.LogError("EOS not initialized. Client could not be started.");
OnClientDisconnected.Invoke();
return;
@ -116,18 +141,21 @@ namespace EpicTransport {
StartCoroutine("FetchEpicAccountId");
if (ServerActive()) {
if (ServerActive())
{
Debug.LogError("Transport already running as server!");
return;
}
if (!ClientActive() || client.Error) {
if (!ClientActive() || client.Error)
{
Debug.Log($"Starting client, target address {address}.");
client = Client.CreateClient(this, address);
activeNode = client;
if (EOSSDKComponent.CollectPlayerMetrics) {
if (EOSSDKComponent.CollectPlayerMetrics)
{
// Start Metrics colletion session
BeginPlayerSessionOptions sessionOptions = new BeginPlayerSessionOptions();
sessionOptions.AccountId = EOSSDKComponent.LocalUserAccountId;
@ -137,55 +165,68 @@ namespace EpicTransport {
sessionOptions.ServerIp = null;
Result result = EOSSDKComponent.GetMetricsInterface().BeginPlayerSession(sessionOptions);
if(result == Result.Success) {
if (result == Result.Success)
{
Debug.Log("Started Metric Session");
}
}
} else {
}
else
{
Debug.LogError("Client already running!");
}
}
public override void ClientConnect(Uri uri) {
public override void ClientConnect(Uri uri)
{
if (uri.Scheme != EPIC_SCHEME)
throw new ArgumentException($"Invalid url {uri}, use {EPIC_SCHEME}://EpicAccountId instead", nameof(uri));
ClientConnect(uri.Host);
}
public override void ClientSend(ArraySegment<byte> segment, int channelId) {
public override void ClientSend(ArraySegment<byte> segment, int channelId)
{
Send(channelId, segment);
}
public override void ClientDisconnect() {
if (ClientActive()) {
public override void ClientDisconnect()
{
if (ClientActive())
{
Shutdown();
}
}
public bool ClientActive() => client != null;
public override bool ServerActive() => server != null;
public override void ServerStart() {
if (!EOSSDKComponent.Initialized) {
public override void ServerStart()
{
if (!EOSSDKComponent.Initialized)
{
Debug.LogError("EOS not initialized. Server could not be started.");
return;
}
StartCoroutine("FetchEpicAccountId");
if (ClientActive()) {
if (ClientActive())
{
Debug.LogError("Transport already running as client!");
return;
}
if (!ServerActive()) {
if (!ServerActive())
{
Debug.Log("Starting server.");
server = Server.CreateServer(this, NetworkManager.singleton.maxConnections);
activeNode = server;
if (EOSSDKComponent.CollectPlayerMetrics) {
if (EOSSDKComponent.CollectPlayerMetrics)
{
// Start Metrics colletion session
BeginPlayerSessionOptions sessionOptions = new BeginPlayerSessionOptions();
sessionOptions.AccountId = EOSSDKComponent.LocalUserAccountId;
@ -195,17 +236,22 @@ namespace EpicTransport {
sessionOptions.ServerIp = null;
Result result = EOSSDKComponent.GetMetricsInterface().BeginPlayerSession(sessionOptions);
if (result == Result.Success) {
if (result == Result.Success)
{
Debug.Log("Started Metric Session");
}
}
} else {
}
else
{
Debug.LogError("Server already started!");
}
}
public override Uri ServerUri() {
UriBuilder epicBuilder = new UriBuilder {
public override Uri ServerUri()
{
UriBuilder epicBuilder = new UriBuilder
{
Scheme = EPIC_SCHEME,
Host = EOSSDKComponent.LocalUserProductIdString
};
@ -213,26 +259,37 @@ namespace EpicTransport {
return epicBuilder.Uri;
}
public override void ServerSend(int connectionId, ArraySegment<byte> segment, int channelId) {
if (ServerActive()) {
Send( channelId, segment, connectionId);
public override void ServerSend(int connectionId, ArraySegment<byte> segment, int channelId)
{
if (ServerActive())
{
Send(channelId, segment, connectionId);
}
}
public override void ServerDisconnect(int connectionId) => server.Disconnect(connectionId);
public override string ServerGetClientAddress(int connectionId) => ServerActive() ? server.ServerGetClientAddress(connectionId) : string.Empty;
public override void ServerStop() {
if (ServerActive()) {
public override void ServerStop()
{
if (ServerActive())
{
Shutdown();
}
}
private void Send(int channelId, ArraySegment<byte> segment, int connectionId = int.MinValue) {
private void Send(int channelId, ArraySegment<byte> segment, int connectionId = int.MinValue)
{
Packet[] packets = GetPacketArray(channelId, segment);
for(int i = 0; i < packets.Length; i++) {
if (connectionId == int.MinValue) {
for (int i = 0; i < packets.Length; i++)
{
if (connectionId == int.MinValue)
{
client.Send(packets[i].ToBytes(), channelId);
} else {
}
else
{
server.SendAll(connectionId, packets[i].ToBytes(), channelId);
}
}
@ -240,11 +297,13 @@ namespace EpicTransport {
packetId++;
}
private Packet[] GetPacketArray(int channelId, ArraySegment<byte> segment) {
int packetCount = Mathf.CeilToInt((float) segment.Count / (float)GetMaxSinglePacketSize(channelId));
private Packet[] GetPacketArray(int channelId, ArraySegment<byte> segment)
{
int packetCount = Mathf.CeilToInt((float)segment.Count / (float)GetMaxSinglePacketSize(channelId));
Packet[] packets = new Packet[packetCount];
for (int i = 0; i < segment.Count; i += GetMaxSinglePacketSize(channelId)) {
for (int i = 0; i < segment.Count; i += GetMaxSinglePacketSize(channelId))
{
int fragment = i / GetMaxSinglePacketSize(channelId);
packets[fragment] = new Packet();
@ -258,14 +317,17 @@ namespace EpicTransport {
return packets;
}
public override void Shutdown() {
if (EOSSDKComponent.CollectPlayerMetrics) {
public override void Shutdown()
{
if (EOSSDKComponent.CollectPlayerMetrics)
{
// Stop Metrics collection session
EndPlayerSessionOptions endSessionOptions = new EndPlayerSessionOptions();
endSessionOptions.AccountId = EOSSDKComponent.LocalUserAccountId;
Result result = EOSSDKComponent.GetMetricsInterface().EndPlayerSession(endSessionOptions);
if (result == Result.Success) {
if (result == Result.Success)
{
Debug.LogError("Stopped Metric Session");
}
}
@ -285,24 +347,32 @@ namespace EpicTransport {
public override int GetBatchThreshold(int channelId) => P2PInterface.MaxPacketSize; // Use P2PInterface.MaxPacketSize as everything above will get fragmentated and will be counter effective to batching
public override bool Available() {
try {
public override bool Available()
{
try
{
return EOSSDKComponent.Initialized;
} catch {
}
catch
{
return false;
}
}
private IEnumerator FetchEpicAccountId() {
while (!EOSSDKComponent.Initialized) {
private IEnumerator FetchEpicAccountId()
{
while (!EOSSDKComponent.Initialized)
{
yield return null;
}
productUserId = EOSSDKComponent.LocalUserProductId;
}
private IEnumerator ChangeRelayStatus() {
while (!EOSSDKComponent.Initialized) {
private IEnumerator ChangeRelayStatus()
{
while (!EOSSDKComponent.Initialized)
{
yield return null;
}
@ -312,12 +382,15 @@ namespace EpicTransport {
EOSSDKComponent.GetP2PInterface().SetRelayControl(setRelayControlOptions);
}
public void ResetIgnoreMessagesAtStartUpTimer() {
public void ResetIgnoreMessagesAtStartUpTimer()
{
ignoreCachedMessagesTimer = 0;
}
private void OnDestroy() {
if (activeNode != null) {
private void OnDestroy()
{
if (activeNode != null)
{
Shutdown();
}
}

View File

@ -4,11 +4,14 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EpicTransport {
public static class Logger {
public static void EpicDebugLog(LogMessage message) {
switch (message.Level) {
namespace EpicTransport
{
public static class Logger
{
public static void EpicDebugLog(LogMessage message)
{
switch (message.Level)
{
case LogLevel.Info:
Debug.Log($"Epic Manager: Category - {message.Category} Message - {message.Message}");
break;

View File

@ -1,7 +1,9 @@
using System;
namespace EpicTransport {
public struct Packet {
namespace EpicTransport
{
public struct Packet
{
public const int headerSize = sizeof(uint) + sizeof(uint) + 1;
public int size => headerSize + data.Length;
@ -13,20 +15,21 @@ namespace EpicTransport {
// body
public byte[] data;
public byte[] ToBytes() {
public byte[] ToBytes()
{
byte[] array = new byte[size];
// Copy id
array[0] = (byte) id;
array[1] = (byte) (id >> 8);
array[2] = (byte) (id >> 0x10);
array[3] = (byte) (id >> 0x18);
array[0] = (byte)id;
array[1] = (byte)(id >> 8);
array[2] = (byte)(id >> 0x10);
array[3] = (byte)(id >> 0x18);
// Copy fragment
array[4] = (byte) fragment;
array[5] = (byte) (fragment >> 8);
array[6] = (byte) (fragment >> 0x10);
array[7] = (byte) (fragment >> 0x18);
array[4] = (byte)fragment;
array[5] = (byte)(fragment >> 8);
array[6] = (byte)(fragment >> 0x10);
array[7] = (byte)(fragment >> 0x18);
array[8] = moreFragments ? (byte)1 : (byte)0;
@ -35,7 +38,8 @@ namespace EpicTransport {
return array;
}
public void FromBytes(byte[] array) {
public void FromBytes(byte[] array)
{
id = BitConverter.ToInt32(array, 0);
fragment = BitConverter.ToInt32(array, 4);
moreFragments = array[8] == 1;

View File

@ -1,10 +1,11 @@
using System;
using System.Text;
public class RandomString {
public class RandomString
{
// Generates a random string with a given size.
public static string Generate(int size) {
public static string Generate(int size)
{
var builder = new StringBuilder(size);
Random random = new Random();
@ -19,15 +20,19 @@ public class RandomString {
char offsetUpperCase = 'A';
const int lettersOffset = 26; // A...Z or a..z: length=26
for (var i = 0; i < size; i++) {
for (var i = 0; i < size; i++)
{
char offset;
if(random.Next(0,2) == 0) {
if (random.Next(0, 2) == 0)
{
offset = offsetLowerCase;
} else {
}
else
{
offset = offsetUpperCase;
}
var @char = (char) random.Next(offset, offset + lettersOffset);
var @char = (char)random.Next(offset, offset + lettersOffset);
builder.Append(@char);
}

View File

@ -4,8 +4,10 @@ using System;
using System.Collections.Generic;
using UnityEngine;
namespace EpicTransport {
public class Server : Common {
namespace EpicTransport
{
public class Server : Common
{
private event Action<int> OnConnected;
private event Action<int, byte[], int> OnReceivedData;
private event Action<int> OnDisconnected;
@ -16,7 +18,8 @@ namespace EpicTransport {
private int maxConnections;
private int nextConnectionID;
public static Server CreateServer(EosTransport transport, int maxConnections) {
public static Server CreateServer(EosTransport transport, int maxConnections)
{
Server s = new Server(transport, maxConnections);
s.OnConnected += (id) => transport.OnServerConnected.Invoke(id);
@ -24,46 +27,56 @@ namespace EpicTransport {
s.OnReceivedData += (id, data, channel) => transport.OnServerDataReceived.Invoke(id, new ArraySegment<byte>(data), channel);
s.OnReceivedError += (id, exception) => transport.OnServerError.Invoke(id, exception);
if (!EOSSDKComponent.Initialized) {
if (!EOSSDKComponent.Initialized)
{
Debug.LogError("EOS not initialized.");
}
return s;
}
private Server(EosTransport transport, int maxConnections) : base(transport) {
private Server(EosTransport transport, int maxConnections) : base(transport)
{
this.maxConnections = maxConnections;
epicToMirrorIds = new BidirectionalDictionary<ProductUserId, int>();
epicToSocketIds = new Dictionary<ProductUserId, SocketId>();
nextConnectionID = 1;
}
protected override void OnNewConnection(OnIncomingConnectionRequestInfo result) {
if (ignoreAllMessages) {
protected override void OnNewConnection(OnIncomingConnectionRequestInfo result)
{
if (ignoreAllMessages)
{
return;
}
if (deadSockets.Contains(result.SocketId.SocketName)) {
if (deadSockets.Contains(result.SocketId.SocketName))
{
Debug.LogError("Received incoming connection request from dead socket");
return;
}
EOSSDKComponent.GetP2PInterface().AcceptConnection(
new AcceptConnectionOptions() {
new AcceptConnectionOptions()
{
LocalUserId = EOSSDKComponent.LocalUserProductId,
RemoteUserId = result.RemoteUserId,
SocketId = result.SocketId
});
}
protected override void OnReceiveInternalData(InternalMessages type, ProductUserId clientUserId, SocketId socketId) {
if (ignoreAllMessages) {
protected override void OnReceiveInternalData(InternalMessages type, ProductUserId clientUserId, SocketId socketId)
{
if (ignoreAllMessages)
{
return;
}
switch (type) {
switch (type)
{
case InternalMessages.CONNECT:
if (epicToMirrorIds.Count >= maxConnections) {
if (epicToMirrorIds.Count >= maxConnections)
{
Debug.LogError("Reached max connections");
//CloseP2PSessionWithUser(clientUserId, socketId);
SendInternal(clientUserId, socketId, InternalMessages.DISCONNECT);
@ -82,13 +95,16 @@ namespace EpicTransport {
Debug.Log($"Client with Product User ID {clientUserIdString} connected. Assigning connection id {connectionId}");
break;
case InternalMessages.DISCONNECT:
if (epicToMirrorIds.TryGetValue(clientUserId, out int connId)) {
if (epicToMirrorIds.TryGetValue(clientUserId, out int connId))
{
OnDisconnected.Invoke(connId);
//CloseP2PSessionWithUser(clientUserId, socketId);
epicToMirrorIds.Remove(clientUserId);
epicToSocketIds.Remove(clientUserId);
Debug.Log($"Client with Product User ID {clientUserId} disconnected.");
} else {
}
else
{
OnReceivedError.Invoke(-1, new Exception("ERROR Unknown Product User ID"));
}
@ -99,14 +115,19 @@ namespace EpicTransport {
}
}
protected override void OnReceiveData(byte[] data, ProductUserId clientUserId, int channel) {
if (ignoreAllMessages) {
protected override void OnReceiveData(byte[] data, ProductUserId clientUserId, int channel)
{
if (ignoreAllMessages)
{
return;
}
if (epicToMirrorIds.TryGetValue(clientUserId, out int connectionId)) {
if (epicToMirrorIds.TryGetValue(clientUserId, out int connectionId))
{
OnReceivedData.Invoke(connectionId, data, channel);
} else {
}
else
{
SocketId socketId;
epicToSocketIds.TryGetValue(clientUserId, out socketId);
CloseP2PSessionWithUser(clientUserId, socketId);
@ -119,20 +140,26 @@ namespace EpicTransport {
}
}
public void Disconnect(int connectionId) {
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId)) {
public void Disconnect(int connectionId)
{
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId))
{
SocketId socketId;
epicToSocketIds.TryGetValue(userId, out socketId);
SendInternal(userId, socketId, InternalMessages.DISCONNECT);
epicToMirrorIds.Remove(userId);
epicToSocketIds.Remove(userId);
} else {
}
else
{
Debug.LogWarning("Trying to disconnect unknown connection id: " + connectionId);
}
}
public void Shutdown() {
foreach (KeyValuePair<ProductUserId, int> client in epicToMirrorIds) {
public void Shutdown()
{
foreach (KeyValuePair<ProductUserId, int> client in epicToMirrorIds)
{
Disconnect(client.Value);
SocketId socketId;
epicToSocketIds.TryGetValue(client.Key, out socketId);
@ -145,32 +172,41 @@ namespace EpicTransport {
Dispose();
}
public void SendAll(int connectionId, byte[] data, int channelId) {
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId)) {
public void SendAll(int connectionId, byte[] data, int channelId)
{
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId))
{
SocketId socketId;
epicToSocketIds.TryGetValue(userId, out socketId);
Send(userId, socketId, data, (byte)channelId);
} else {
}
else
{
Debug.LogError("Trying to send on unknown connection: " + connectionId);
OnReceivedError.Invoke(connectionId, new Exception("ERROR Unknown Connection"));
}
}
public string ServerGetClientAddress(int connectionId) {
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId)) {
public string ServerGetClientAddress(int connectionId)
{
if (epicToMirrorIds.TryGetValue(connectionId, out ProductUserId userId))
{
string userIdString;
userId.ToString(out userIdString);
return userIdString;
} else {
}
else
{
Debug.LogError("Trying to get info on unknown connection: " + connectionId);
OnReceivedError.Invoke(connectionId, new Exception("ERROR Unknown Connection"));
return string.Empty;
}
}
protected override void OnConnectionFailed(ProductUserId remoteId) {
if (ignoreAllMessages) {
protected override void OnConnectionFailed(ProductUserId remoteId)
{
if (ignoreAllMessages)
{
return;
}