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()); } }