You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
10 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Epic.OnlineServices;
using Epic.OnlineServices.Auth;
using Epic.OnlineServices.Connect;
using Epic.OnlineServices.Lobby;
using Epic.OnlineServices.Logging;
using Epic.OnlineServices.Platform;
using Epic.OnlineServices.RTC;
using Epic.OnlineServices.RTCAudio;
using UnityEngine;
using Credentials = Epic.OnlineServices.Auth.Credentials;
using LoginCallbackInfo = Epic.OnlineServices.Auth.LoginCallbackInfo;
using LoginOptions = Epic.OnlineServices.Auth.LoginOptions;
public class MagnificentVoiceChat : MonoBehaviour
{
private const string DebugLobbyId = "a0f6a51f-6b61-4c95-9ed8-a1d508fe4eb6";
private const string DebugBucketId = "foobar";
private readonly StringBuilder status = new StringBuilder("Status:\n");
private PlatformInterface platformInterface;
private AuthInterface authInterface;
private ConnectInterface connectInterface;
private LobbyInterface lobbyInterface;
private RTCInterface rtcInterface;
private RTCAudioInterface audioInterface;
private EpicAccountId localEpicAccountId;
private ProductUserId localProductUserId;
private EOSVoiceChat voiceChat;
private string XAudio29DllPath =>
#if UNITY_EDITOR
Path.Combine(Application.dataPath, @"Plugins\EpicOnlineServices\Bin\x64\xaudio2_9redist.dll");
#else
Path.Combine(Application.dataPath, @"Plugins\x86_64\xaudio2_9redist.dll");
#endif
void Start()
{
#if UNITY_EDITOR
LoadLibrary();
#endif
var result = PlatformInterface.Initialize(new InitializeOptions
{
ProductName = "WW1 Test",
ProductVersion = "0.1",
});
if (result != Result.Success)
{
Debug.LogError("Failed to initialize EOS, result = " + result);
return;
}
LoggingInterface.SetLogLevel(LogCategory.AllCategories, LogLevel.Warning);
LoggingInterface.SetCallback(OnEOSLogMessage);
var options = new WindowsOptions // Okay so this will need to be platform-specific
{
ProductId = "b21a28c2c5404c8099d72f5a28c59c16",
SandboxId = "b630f2c3933a4838a971ce53d5b0db3b",
DeploymentId = "9a36f589572c492fbee14bd299173c12",
ClientCredentials = new ClientCredentials
{
ClientId = "xyza7891UOFoUhfvfbKgO2xRCIiuAIjH",
ClientSecret = "NArwIQT1laFfsS7fdcN1MKDdgwy490w9MBJsAlHN4QI",
},
Flags = PlatformFlags.DisableOverlay,
CacheDirectory = null,
EncryptionKey = null,
IsServer = false,
RTCOptions = new WindowsRTCOptions // This is also platform-specific
{
PlatformSpecificOptions = new WindowsRTCOptionsPlatformSpecificOptions
{
XAudio29DllPath = XAudio29DllPath
}
},
};
Debug.Log("XAudio library path: " + XAudio29DllPath);
platformInterface = PlatformInterface.Create(options);
if (platformInterface == null)
{
Debug.LogError("Failed to create EOS platform interface");
status.AppendLine("Failed to create EOS platform interface");
return;
}
Debug.Log("EOS platform interface successfully created!");
status.AppendLine("EOS platform interface created");
authInterface = platformInterface.GetAuthInterface();
status.AppendLine("Auth interface: " + authInterface);
connectInterface = platformInterface.GetConnectInterface();
status.AppendLine("Connect interface: " + connectInterface);
lobbyInterface = platformInterface.GetLobbyInterface();
status.AppendLine("Lobby interface: " + lobbyInterface);
rtcInterface = platformInterface.GetRTCInterface(); // Real-time communication, needed for audio
status.AppendLine("RTC interface: " + rtcInterface);
audioInterface = rtcInterface.GetAudioInterface();
status.AppendLine("Audio interface: " + audioInterface);
authInterface.Login(new LoginOptions
{
Credentials = GetEpicCredentials(),
ScopeFlags = AuthScopeFlags.BasicProfile,
}, null, HandleLoginResult);
voiceChat = new EOSVoiceChat(lobbyInterface, rtcInterface, audioInterface, () => localProductUserId);
voiceChat.OnChatConnected += () => status.AppendLine("Chat lobby successfully connected!");
voiceChat.OnChatConnectionFailed += () => status.AppendLine("Chat lobby connection failed...");
voiceChat.OnChatDisconnected += () => status.AppendLine("Chat lobby disconnected");
voiceChat.OnChatUserJoined += userId => status.AppendLine($"Chat user {userId} joined");
voiceChat.OnChatUserLeft += userId => status.AppendLine($"Chat user {userId} left");
}
private Credentials GetEpicCredentials() // This is platform-specific
{
return new Credentials
{
// Type = LoginCredentialType.AccountPortal, // Use ExternalAuth on console platform
Id = "192.168.1.100:8888",
Type = LoginCredentialType.Developer,
Token = SystemInfo.deviceName,
};
}
private void HandleLoginResult(LoginCallbackInfo data)
{
switch (data.ResultCode)
{
case Result.Success:
localEpicAccountId = data.LocalUserId;
Debug.Log("EOS login successful: " + localEpicAccountId);
status.AppendLine("EOS login successful: " + localEpicAccountId);
authInterface.CopyUserAuthToken(new CopyUserAuthTokenOptions(), localEpicAccountId, out Token token);
connectInterface.Login(new Epic.OnlineServices.Connect.LoginOptions
{
Credentials = new Epic.OnlineServices.Connect.Credentials
{
Type = ExternalCredentialType.Epic, // Can be XSTS or PSN ID as well, platform-specific
Token = token.AccessToken,
},
}, null, HandleConnectResult);
break;
default:
Debug.Log("EOS login failed, result code = " + data.ResultCode);
status.AppendLine("EOS login failed");
break;
}
}
private void HandleConnectResult(Epic.OnlineServices.Connect.LoginCallbackInfo data)
{
switch (data.ResultCode)
{
case Result.Success:
localProductUserId = data.LocalUserId;
Debug.Log("Connect successful: " + localProductUserId);
status.AppendLine("Connect successful: " + localProductUserId);
CreateOrJoinVoiceLobby();
break;
case Result.InvalidUser:
Debug.Log("Invalid user, creating user...");
status.AppendLine("Invalid user, creating user...");
connectInterface.CreateUser(new CreateUserOptions
{
ContinuanceToken = data.ContinuanceToken,
}, null, HandleUserCreated);
break;
default:
Debug.Log("Connect failed, result code = " + data.ResultCode);
status.AppendLine("Connect failed");
break;
}
}
private void HandleUserCreated(CreateUserCallbackInfo data)
{
switch (data.ResultCode)
{
case Result.Success:
localProductUserId = data.LocalUserId;
Debug.Log("User creation successful: " + localProductUserId);
status.AppendLine("User creation successful: " + localProductUserId);
CreateOrJoinVoiceLobby();
break;
default:
Debug.Log("User creation failed, result code = " + data.ResultCode);
status.AppendLine("User creation failed");
break;
}
}
private void CreateOrJoinVoiceLobby()
{
voiceChat.ConnectToChat(DebugLobbyId);
}
void Update()
{
platformInterface.Tick();
}
private void OnDestroy()
{
if (voiceChat != null)
{
voiceChat.Dispose();
voiceChat = null;
}
if (platformInterface != null)
{
platformInterface.Release();
platformInterface = null;
}
PlatformInterface.Shutdown();
#if UNITY_EDITOR
UnloadLibrary();
#endif
}
#if UNITY_EDITOR
private IntPtr eosLbraryHandle;
private void LoadLibrary()
{
eosLbraryHandle = SystemLibrary.LoadLibrary($@"Assets\Plugins\EpicOnlineServices\Bin\{Config.LibraryName}.dll");
if (eosLbraryHandle == IntPtr.Zero)
{
throw new Exception("Could not load EOS library!");
}
Bindings.Hook(eosLbraryHandle, SystemLibrary.GetProcAddress);
Debug.Log("Hooked EOS library bindings");
status.AppendLine("Hooked EOS library bindings");
}
private void UnloadLibrary()
{
Debug.Log("Unhooking EOS library bindings");
Bindings.Unhook();
if (eosLbraryHandle != IntPtr.Zero)
{
SystemLibrary.FreeLibrary(eosLbraryHandle);
eosLbraryHandle = IntPtr.Zero;
}
}
#endif
private void OnEOSLogMessage(LogMessage message)
{
switch (message.Level)
{
case LogLevel.Fatal:
case LogLevel.Error:
Debug.LogError(message.Message);
break;
case LogLevel.Warning:
Debug.LogWarning(message.Message);
break;
default:
Debug.Log(message.Message);
break;
}
}
private void OnGUI()
{
GUI.matrix = Matrix4x4.Scale(new Vector3(2, 2, 1));
GUILayout.Label(status.ToString());
}
}