Exemple #1
0
        /// <summary>
        /// Operation extracts an asset from the loaded bundle
        /// </summary>
        /// <param name="asyncOperation"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async UniTask <T> GetAssetComponentAsync <T>(AssetBundleRequest asyncOperation, IProgress <float> progress,
                                                             CancellationToken cancellationToken) where T : UnityEngine.Object
        {
            while (!asyncOperation.isDone)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

                //Supressing this so it doesnt step over GetBundleFromStreamingAssetsAsync or GetBundleFromWebOrCacheAsync
                //progress?.Report(asyncOperation.progress);
                Logger.Log($"GetAssetComponentAsync {Bundle.name} progress: {asyncOperation.progress * 100f}%", Colors.LightSalmon);
            }

            if (!asyncOperation.asset)
            {
                throw new Exception("RunAssetBundleRequestOperation: Error getting bundle.");
            }

            //Current use case returns the component, if this changes then deal with it downstream but for now this should be ok
            var go = asyncOperation.asset as GameObject;

            return(go.GetComponent <T>());
        }
Exemple #2
0
        /// <summary>
        /// Saves data into a file.
        /// </summary>
        /// <param name="data"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async UniTask Save <T>(T data) where T : IStorable
        {
            await Task.Run(() =>
            {
                if (data is MonoBehaviour)
                {
                    Logger.LogError($"Persistent Data Service: Monobehaviours cannot be serialized. Aborting.");
                    return;
                }

                var filename = data.FileName + _configuration.DataFileExtension;

                try
                {
                    using (var file = File.Open(_dataDirectory + "/" + filename, FileMode.Create))
                    {
                        var bf = new BinaryFormatter();
                        bf.Serialize(file, data); //todo: need to find an async way of doing this

                        file.Flush();
                        file.Close();

                        Logger.Log($"Persistent Data Service: Saving to - {_dataDirectory + "/" + filename}", Colors.LightPink);
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError($"Persistent Data Service: error saving to - {_dataDirectory + "/" + filename}, {e.Message}");
                }
            });
        }
Exemple #3
0
        /// <summary>
        /// Loads serialized data into an object
        /// </summary>
        /// <param name="filename"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async UniTask <T> Load <T>(string filename) where T : IStorable
        {
            return(await Task.Run(() =>
            {
                filename += _configuration.DataFileExtension;
                if (!File.Exists(_dataDirectory + "/" + filename))
                {
                    Logger.LogWarning($"Persistent Data Service: File {_dataDirectory + "/" + filename} does not exists.");
                    return default(T);
                }

                try
                {
                    using (var file = File.Open(_dataDirectory + "/" + filename, FileMode.Open))
                    {
                        var bf = new BinaryFormatter();
                        var data = (T)bf.Deserialize(file);  //todo: need to find an async way of doing this
                        file.Close();

                        Logger.Log($"Persistent Data Service: Reading from - {_dataDirectory + "/" + filename}", Colors.LightPink);

                        return data;
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError($"Persistent Data Service: Error - {e.Message}");
                }

                return default(T);
            }));
        }
        /// <summary>
        /// Utility method to request multiple assets.
        /// </summary>
        /// <param name="requests">Bundle requests</param>
        /// <param name="progress">Reports loading progress percentage</param>
        /// <param name="forceLoadFromStreamingAssets"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask <Dictionary <string, LoadedBundle> > LoadMultipleBundles(List <BundleRequest> requests,
                                                                                      bool forceLoadFromStreamingAssets = false, IProgress <float> progress = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var tempCount = 0;
            var total     = requests.Count;
            var bundles   = new Dictionary <string, LoadedBundle>();

            foreach (var request in requests)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

                var bundle = await _assetBundlebundleLoader.LoadBundle(request, forceLoadFromStreamingAssets, cancellationToken : cancellationToken);

                bundles.Add(request.BundleName, bundle);

                tempCount++;
                progress?.Report(tempCount * 100 / total);

                Logger.Log($"LoadMultipleAssets: {tempCount} of {total} | {tempCount * 100 / total}%", Colors.Aquamarine);
            }

            return(bundles);
        }
Exemple #5
0
        public override void InstallBindings()
        {
            //Initialize SignalBus
            SignalBusInstaller.Install(Container); //This allows SignalBus to be injected in any class instantiated here, or any of its children.

            //Add Game Scoped Signals
            Container.DeclareSignal <OnGameStartedSignal>().OptionalSubscriber();
            Container.DeclareSignal <OnGamePaused>().OptionalSubscriber();
            Container.DeclareSignal <OnGameResumed>().OptionalSubscriber();
            Container.DeclareSignal <OnGameGotFocus>().OptionalSubscriber();
            Container.DeclareSignal <OnGameLostFocus>().OptionalSubscriber();
            Container.DeclareSignal <OnGameQuit>().OptionalSubscriber();

            Logger.Log($"Binding {coreSystems.Count} systems", Colors.Lime);

            //Create system objects and bind them
            foreach (var prefab in coreSystems)
            {
                Container.Bind(prefab.GetType())
                .FromComponentInNewPrefab(prefab)
                .AsSingle()
                .OnInstantiated((InjectContext context, ICoreSystem system) =>
                {
                    if (system is FactoryCoreSystem factory)
                    {
                        factory.SetDiContainer(Container);
                    }
                })
                .NonLazy();

                Logger.Log($"----{prefab.name}", Colors.Lime);
            }

            Logger.Log("GameConfiguration: Service binding complete", Colors.Lime);
        }
        public async UniTask <T> OpenUI <T>(UIElement window, IProgress <float> progress = null,
                                            CancellationToken cancellationToken          = default(CancellationToken)) where T : UIElement
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(null);
            }

            var obj = _factoryService.Instantiate(window, DetermineRenderPriorityCanvas(window.UIType));

            obj.name = window.name;

            obj.OnClosed().Subscribe(x => { UIElementClosed(x).Run(); });

            if (!_activeUIElements.ContainsKey(obj.name))
            {
                _activeUIElements.Add(obj.name, obj);
            }

            if (obj.PauseGameWhenOpen)
            {
                PauseResume(true);
            }

            Logger.Log($"UI Service: Loaded window - {obj.name}", Colors.LightBlue);
            await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

            return(obj as T);
        }
Exemple #7
0
        private void OnServerTick(uint deltaTick)
        {
            try
            {
                if (!_serverCachedPackets.IsEmpty)
                {
                    var command = _serverCachedPackets.PopFront();

                    if (_currentCommand == null)
                    {
                        _currentCommand = command;
                    }

                    if (_currentCommand.Tick > command.Tick)
                    {
                        _serverCachedPackets.PushBack(command);
                    }

                    _currentCommand = command;

                    var vector = new Vector3(_currentCommand.Position.x, 0, _currentCommand.Position.y);
                    _moveVector = vector;
                }
            }
            catch (Exception e)
            {
                Logger.LogError(e);
            }
        }
Exemple #8
0
        /// <summary>
        /// Loads a component from a prefab AssetReference.
        /// Use this when a component is needed from a prefab. (Particle System, Canvas, Image, etc)
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async UniTask <T> LoadPrefabAssetFromReferenceAsync <T>(AssetReference reference, IProgress <float> progress = null, CancellationToken cancellationToken = default) where T : UnityEngine.Object
        {
            var asset = await LoadAssetFromReferenceAsync <GameObject>(reference, progress, cancellationToken);

            Logger.Log($"Loaded component: {asset.name}".ColoredLog(Colors.Pink));
            return(asset.GetComponent <T>());
        }
        /// <summary>
        /// Facilitates communication with Put and Get requests from server API.
        /// </summary>
        /// <param name="observer"></param>
        /// <param name="requestType"></param>
        /// <param name="uri"></param>
        /// <param name="putData"></param>
        /// <returns></returns>
        private static IEnumerator RequestAsync(IObserver <string> observer, RequestType requestType, string uri, string putData)
        {
            var request = CreateRequest(requestType, uri, putData);

            request.SetRequestHeader("poop", "pappa");

            yield return(request.SendWebRequest());

            if (IsError(request, out var error))
            {
                observer.OnError(new Exception(error));
            }
            else
            {
                if (requestType == RequestType.Put)
                {
                    Logger.Log($"{uri} | ".ColoredLog(Colors.Aqua) + $"{putData} | {request.downloadHandler.text}".ColoredLog(Colors.Coral));
                }
                else
                {
                    Logger.Log($"{uri} | ".ColoredLog(Colors.Aqua) + $"{request.downloadHandler.text}".Colored(Colors.Coral));
                }

                observer.OnNext(request.downloadHandler.text);
                observer.OnCompleted();
            }
        }
Exemple #10
0
        /// <summary>
        /// Loads an asset from an AssetReference. Textures, Materials, Sound Clips, etc.
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async UniTask <T> LoadAssetFromReferenceAsync <T>(AssetReference reference, IProgress <float> progress = null, CancellationToken cancellationToken = default) where T : UnityEngine.Object
        {
            var asyncOperation = reference.LoadAssetAsync <T>();
            var asset          = await GetAsyncOperationResultAsync(asyncOperation, progress, cancellationToken);

            Logger.Log($"Loaded asset: {asset.name}".ColoredLog(Colors.Pink));
            return(asset);
        }
Exemple #11
0
        /// <summary>
        /// Unload scene.
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        public async UniTask UnLoadScene(string scene)
        {
            await SceneManager.UnloadSceneAsync(scene);

            await _assetService.UnloadAsset(scene, true);

            Logger.Log(("SceneLoaderService: Unloaded scene - " + scene), Colors.LightBlue);
        }
        public override void InstallBindings()
        {
            Logger.LogLevel = debugLevel;

            //Initialize SignalBus
            SignalBusInstaller.Install(Container); //This allows SignalBus to be injected in any class instantiated here, or any of its children.

            //Add Game Scoped Signals
            Container.DeclareSignal <OnGameStartedSignal>().OptionalSubscriber();
            Container.DeclareSignal <OnGamePaused>().OptionalSubscriber();
            Container.DeclareSignal <OnGameResumed>().OptionalSubscriber();
            Container.DeclareSignal <OnGameGotFocus>().OptionalSubscriber();
            Container.DeclareSignal <OnGameLostFocus>().OptionalSubscriber();
            Container.DeclareSignal <OnGameQuit>().OptionalSubscriber();

            Logger.Log("GameConfiguration: Starting Services", Colors.Lime);
            foreach (var service in services)
            {
                Logger.Log($"--- Starting: {service.name}", Colors.Cyan);
                if (service is AssetServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <AssetService>().AsSingle().WithArguments(service).NonLazy();

                    Container.Bind <AssetServiceConfiguration>().AsSingle().NonLazy();
                    Container.Bind <AssetBundleLoader>().AsSingle().NonLazy();
                }
                else if (service is SceneLoaderServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <SceneLoaderService>().AsSingle().WithArguments(service).NonLazy();
                    Container.Bind <SceneLoaderServiceConfiguration>().AsSingle().NonLazy();
                }
                else if (service is UIServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <UIService>().AsSingle().WithArguments(service).NonLazy();
                    Container.Bind <UIServiceConfiguration>().AsSingle().NonLazy();
                }
                else if (service is FactoryServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <FactoryService>().AsSingle().WithArguments(service, Container).NonLazy();
                    Container.Bind <FactoryServiceConfiguration>().AsSingle().NonLazy();
                }
                else if (service is AudioServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <AudioService>().AsSingle().WithArguments(service).NonLazy();
                    Container.Bind <AudioServiceConfiguration>().AsSingle().NonLazy();
                }
                else if (service is SocialServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <SocialService>().AsSingle().WithArguments(service).NonLazy();
                    Container.Bind <SocialServiceConfiguration>().AsSingle().NonLazy();
                }
                else if (service is PersistentDataServiceConfiguration)
                {
                    Container.BindInterfacesAndSelfTo <PersistentDataService>().AsSingle().WithArguments(service).NonLazy();
                    Container.Bind <PersistentDataServiceConfiguration>().AsSingle().NonLazy();
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Loads a scene from an AssetReference
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="loadSceneMode"></param>
        /// <param name="activateOnLoad"></param>
        /// <param name="priority"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask <Scene> LoadSceneFromReferenceAsync(AssetReference reference, LoadSceneMode loadSceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100, IProgress <float> progress = null, CancellationToken cancellationToken = default)
        {
            var asyncOperation = Addressables.LoadSceneAsync(reference, loadSceneMode, activateOnLoad, priority);
            var sceneInstance  = await GetAsyncOperationResultAsync(asyncOperation, progress, cancellationToken);

            Logger.Log($"Loaded Scene: {sceneInstance.Scene.name}".ColoredLog(Colors.Pink));

            return(sceneInstance.Scene);
        }
            static Startup()
            {
                if (EditorPreferences.EditorprefFirstTimeUse)
                {
                    Logger.Log("First time use. Enabling asset bundle simulation mode.", Colors.Yellow);

                    EditorPreferences.EditorprefSimulateAssetBundles = true;
                    EditorPreferences.EditorprefFirstTimeUse         = false;
                }
            }
 public override void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
 {
     if (messageType == UnconnectedMessageType.Broadcast)
     {
         Logger.Log("[SERVER] Received discovery request. Send discovery response".ColoredLog(Colors.Yellow));
         var resp = new NetDataWriter();
         resp.Put(1);
         SendUnconnectedMessage(resp, remoteEndPoint);
     }
 }
        /// <summary>
        /// Method attemps to get a bundle from the web/cloud
        /// </summary>
        /// <param name="bundleRequest">Bundle to request</param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        private async UniTask <AssetBundle> GetBundleFromWebOrCacheAsync(BundleRequest bundleRequest,
                                                                         IProgress <float> progress, CancellationToken cancellationToken)
        {
            var uwr = new UnityWebRequest();

            Logger.Log($"AssetBundleLoader:  {_assetService.AssetCacheState}  | Requesting:  {bundleRequest.AssetName}  {bundleRequest.BundleName}", Colors.Aqua);
            if (_assetService.CloudBuildManifest != null && _assetService.AssetCacheState == AssetCacheState.Cache)
            {
                //cache bundles by using Unity Cloud Build manifest
                uint buildNumber = 0;
                buildNumber = Convert.ToUInt32(_assetService.CloudBuildManifest.buildNumber);
                uwr         = UnityWebRequestAssetBundle.GetAssetBundle(bundleRequest.GetAssetPath(_assetService.Configuration), buildNumber, 0);
            }
            else if (_assetService.CloudBuildManifest == null || _assetService.AssetCacheState == AssetCacheState.NoCache)
            {
                if (_assetService.AssetCacheState == AssetCacheState.Cache)
                {
                    Logger.Log("AssetBundleLoader:  Caching is enabled, but Unity Cloud Build Manifest was missing, bundle was not cached.", Colors.Aqua);
                }

                //No caching, just get the bundle
                uwr = UnityWebRequestAssetBundle.GetAssetBundle(bundleRequest.GetAssetPath(_assetService.Configuration));
            }

            //Wait until uwr is done.
            var asyncOperation = uwr.SendWebRequest();

            while (!asyncOperation.isDone)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

                progress?.Report(asyncOperation.progress);
                Logger.Log($"GetBundleFromWebOrCacheAsync {bundleRequest.BundleName} progress: {asyncOperation.progress * 100f}%", Colors.LightSalmon);
            }

            //get bundle
            var bundle = DownloadHandlerAssetBundle.GetContent(uwr);

            if (uwr.isNetworkError)
            {
                throw new System.Exception($"AssetBundleLoader:  {uwr.error}");
            }

            uwr.Dispose();

            return(bundle);
        }
        public override void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
        {
            if (!ServerNetworkEntities.ContainsKey((ushort)peer.Id))
            {
                return;
            }

            var entity = ServerNetworkEntities[(ushort)peer.Id];

            ServerNetworkEntities.Remove(entity.PeerId);
            _onPeerDisconnected.OnNext(entity.PeerId);
            Logger.Log($"[SERVER] Peer {entity.PeerId} disconnected because {disconnectInfo.Reason}".ColoredLog(Colors.Yellow));
        }
        private async void LoadBuildManifestAsync()
        {
            var cloudManifest = await UnityCloufBuildManifestLoader.LoadBuildManifest();

            if (cloudManifest != null)
            {
                Logger.Log(("---- AssetService: Unity Cloud Build Manifest present. Build Version: " + cloudManifest.buildNumber), Colors.Aqua);
                _cloudBuildManifest = cloudManifest;
            }
            else
            {
                Logger.Log("---- AssetService: Unity Cloud Build Manifest missing. This is ok. Ignoring.", Colors.Aqua);
            }
        }
        private async UniTask UIElementClosed(UIElement window)
        {
            Logger.Log(("UI Service: Closed window - " + window.name), Colors.LightBlue);

            _activeUIElements.Remove(window.name);

            await _assetService.UnloadAsset(window.name, true);

            if (window.PauseGameWhenOpen)
            {
                PauseResume(false);
            }

            UnityEngine.Object.Destroy(window.gameObject);
        }
        private void OnNetworkEntityJoined(NetworkEntityJoinedGamePacket packet)
        {
            CreateEntity(packet.PeerId, packet.NetworkObjectId);

            //Send network objects
            if (IsHost)
            {
                foreach (var key in _serverInstantiatedObjects.Keys)
                {
                    InstantiateNetworkObject(packet.PeerId, _serverInstantiatedObjects[key].PeerId, _serverInstantiatedObjects[key].NetworkObjectId, "");
                }
            }

            _onPlayerJoined.OnNext(Unit.Default);
            Logger.Log($"[CLIENT] Player Joined!! {packet.PeerId}".ColoredLog(Colors.HotPink));
        }
Exemple #21
0
        /// <summary>
        /// Loads an asset inside this bundle
        /// </summary>
        /// <param name="name"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask <T> LoadAssetAsync <T>(string name, IProgress <float> progress,
                                                    CancellationToken cancellationToken) where T : UnityEngine.Object
        {
#if UNITY_EDITOR
            if (EditorPreferences.EditorprefSimulateAssetBundles)
            {
                Logger.Log(("LoadAssetAsync Simulated: loading asset: " + name), Colors.Yellow);
                var comp = _simulatedAsset.GetComponent <T>();
                await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

                return(comp);
            }
#endif

            Logger.Log(("LoadAssetAsync: loading asset: " + name), Colors.Yellow);
            return(await GetAssetComponentAsync <T>(Bundle.LoadAssetAsync(name), progress, cancellationToken));
        }
        private static bool IsError(UnityWebRequest request, out string error, bool isBinary = false)
        {
            if (!isBinary && request.downloadHandler.text.Contains("error"))
            {
                Logger.LogError($"URI: {request.uri} | {request.downloadHandler.text}".ColoredLog(Colors.Red));
                error = $"URI: {request.uri} - {request.downloadHandler.text}";
                return(true);
            }

            if (request.isNetworkError || request.error != null)
            {
                Logger.LogError($"URI: {request.uri} | {request.error}".ColoredLog(Colors.Red));
                error = request.error;
                return(true);
            }

            error = string.Empty;
            return(false);
        }
        private void OnPlayerJoinRequestAccepted(PlayerJoinRequestAcceptedPacket packet)
        {
            CreateEntity(packet.PeerId, packet.NetworkObjectId, true);
            PeerId = packet.PeerId;
            Client.SyncTick(packet.Tick);
            foreach (var peer in packet.CurrentPeers)
            {
                if (!Client.ConnectedPeers.ContainsKey(peer.PeerId))
                {
                    CreateEntity(peer.PeerId, peer.NetworkObjectId);
                }
            }

            if (IsHost)
            {
                InstantiateNetworkObject(PeerId, PeerId, GetNewNetworkObjectId(), "");
            }

            Logger.Log($"[CLIENT] We joined. Id: {packet.PeerId} Existing players: {packet.CurrentPeers.Length}".ColoredLog(Colors.HotPink));
        }
Exemple #24
0
        /// <summary>
        /// Gets a scene from an asset bundle
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="mode"> </param>
        /// <param name="forceLoadFromStreamingAssets"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async UniTask <UnityEngine.Object> GetScene(string scene, LoadSceneMode mode,
                                                            bool forceLoadFromStreamingAssets, IProgress <float> progress,
                                                            CancellationToken cancellationToken)
        {
            if (_assetService.GetLoadedBundle(scene))
            {
                throw new Exception("Scene " + scene + " is already loaded and open. Opening the same scene twice is not supported.");
            }

            var sceneObject = await _assetService.GetScene(new BundleRequest(AssetCategoryRoot.Scenes, scene, scene),
                                                           forceLoadFromStreamingAssets, progress, cancellationToken);

            if (sceneObject && !cancellationToken.IsCancellationRequested)
            {
                Logger.Log(("SceneLoaderService: Loaded scene - " + scene), Colors.LightBlue);

                await SceneManager.LoadSceneAsync(scene, mode);

                Logger.Log(("SceneLoaderService: Opened scene - " + scene), Colors.LightBlue);
            }

            return(sceneObject);
        }
        /// <summary>
        /// Gets bundle from streaming assets directory
        /// </summary>
        /// <param name="bundleRequest"> Bundle to request </param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        private async UniTask <AssetBundle> GetBundleFromStreamingAssetsAsync(BundleRequest bundleRequest,
                                                                              IProgress <float> progress, CancellationToken cancellationToken)
        {
            Logger.Log($"AssetBundleLoader: Using StreamingAssets -  Requesting: {bundleRequest.AssetCategory}  {bundleRequest.BundleName}", Colors.Aqua);
            var path = Path.Combine(Application.streamingAssetsPath, bundleRequest.AssetPathFromLocalStreamingAssets);

            var asyncOperation = AssetBundle.LoadFromFileAsync(path);

            while (!asyncOperation.isDone)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);

                progress?.Report(asyncOperation.progress);
                Logger.Log($"GetBundleFromStreamingAssetsAsync {bundleRequest.BundleName} progress: {asyncOperation.progress * 100f}%", Colors.LightSalmon);
            }

            return(asyncOperation.assetBundle);
        }
 /// <summary>
 /// Observable wrapper for RequestAsync
 /// </summary>
 /// <param name="requestType"></param>
 /// <param name="uri"></param>
 /// <param name="putData"></param>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public static IObservable <T> Request <T>(RequestType requestType, string uri, string putData = "")
 {
     return(Observable.Create(
                (IObserver <T> requestObserver) =>
     {
         return Observable.FromCoroutine <string>(observer =>
                                                  RequestAsync(observer, requestType, uri, putData))
         .CatchIgnore((Exception ex) => { requestObserver.OnError(ex); })
         .Subscribe(json =>
         {
             try
             {
                 requestObserver.OnNext(JsonUtility.FromJson <T>(json));
                 requestObserver.OnCompleted();
             }
             catch (Exception e)
             {
                 Logger.LogError(e);
                 throw e;
             }
         });
     }));
 }
        /// <summary>
        /// Saves data into a file.
        /// </summary>
        /// <param name="data"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public void Save <T>(T data) where T : IStorable
        {
            //TODO: improve this with async https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/using-async-for-file-access
            if (data is MonoBehaviour)
            {
                throw new Exception($"Persistent Data Service: Monobehaviours cannot be serialized. Aborting.");
            }

            var filename = data.FileName + dataFileExtension;
            var file     = File.Open(_dataDirectory + "/" + filename, FileMode.Create);

            try
            {
                var bf = new BinaryFormatter();
                bf.Serialize(file, data); //todo: need to find an async way of doing this
                file.Flush();
                file.Close();
                Logger.Log($"Persistent Data Service: Saving to - {_dataDirectory + "/" + filename}", Colors.LightPink);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// Loads serialized data into an object
        /// </summary>
        /// <param name="filename"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private async UniTask <T> Load <T>(string filename) where T : IStorable
        {
            filename += dataFileExtension;
            if (!File.Exists(_dataDirectory + "/" + filename))
            {
                throw new Exception($"Persistent Data Service: File {_dataDirectory + "/" + filename} does not exists.");
            }

            var file = File.Open(_dataDirectory + "/" + filename, FileMode.Open);

            try
            {
                var bf   = new BinaryFormatter();
                var data = (T)bf.Deserialize(file);  //todo: need to find an async way of doing this

                Logger.Log($"Persistent Data Service: Reading from - {_dataDirectory + "/" + filename}", Colors.LightPink);

                return(data);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
 public override void OnPeerConnected(NetPeer peer)
 {
     Logger.Log($"[SERVER] Client connected: {peer.Id}".ColoredLog(Colors.Yellow));
 }
 public override void OnNetworkError(IPEndPoint endPoint, SocketError socketError)
 {
     Logger.Log($"[SERVER] received error {socketError}".ColoredLog(Colors.Yellow));
 }