Ejemplo n.º 1
0
        public override IEnumerator DownLoad()
        {
            // Check fatal
            if (States != EWebRequestStates.None)
            {
                throw new Exception($"{nameof(WebFileRequest)} is downloading yet : {URL}");
            }

            States = EWebRequestStates.Loading;

            // 下载文件
            CacheRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET);
            DownloadHandlerFile handler = new DownloadHandlerFile(SavePath);

            handler.removeFileOnAbort    = true;
            CacheRequest.downloadHandler = handler;
            CacheRequest.disposeDownloadHandlerOnDispose = true;
            CacheRequest.timeout = Timeout;
            yield return(CacheRequest.SendWebRequest());

            // Check error
            if (CacheRequest.isNetworkError || CacheRequest.isHttpError)
            {
                MotionLog.Log(ELogLevel.Warning, $"Failed to download web file : {URL} Error : {CacheRequest.error}");
                States = EWebRequestStates.Fail;
            }
            else
            {
                States = EWebRequestStates.Success;
            }
        }
Ejemplo n.º 2
0
        private void GetDownloadList()
        {
            // 获取游戏启动时的下载列表
            var downloadList = _patcher.GetAutoPatchDownloadList();

            // 如果下载列表为空
            if (downloadList.Count == 0)
            {
                MotionLog.Log("Not found update web files.");
                _patcher.Switch(EPatchStates.DownloadOver.ToString());
            }
            else
            {
                MotionLog.Log($"Found update web files : {downloadList.Count}");

                // 创建补丁下载器
                _patcher.CreateInternalDownloader(downloadList);

                // 发现新更新文件后,挂起流程系统
                // 注意:开发者需要在下载前检测磁盘空间不足
                int  totalDownloadCount = _patcher.InternalDownloader.TotalDownloadCount;
                long totalDownloadBytes = _patcher.InternalDownloader.TotalDownloadBytes;
                PatchEventDispatcher.SendFoundUpdateFilesMsg(totalDownloadCount, totalDownloadBytes);
            }
        }
Ejemplo n.º 3
0
        private void Handle_Completed(AssetOperationHandle obj)
        {
            try
            {
                TextAsset txt = _handle.AssetObject as TextAsset;
                if (txt != null)
                {
                    // 解析数据
                    ParseDataInternal(txt.bytes);
                }
            }
            catch (Exception ex)
            {
                MotionLog.Log(ELogLevel.Error, $"Failed to parse config {Location}. Error : {ex.ToString()}");
            }

            // 注意:为了节省内存这里立即释放了资源
            if (_assetRef != null)
            {
                _assetRef.Release();
                _assetRef = null;
            }

            IsPrepare = true;
            _userCallback?.Invoke(this);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 处理沙盒被污染
        /// 注意:在覆盖安装的时候,会保留沙盒目录里的文件,所以需要强制清空。
        /// </summary>
        private void ProcessSandboxDirty()
        {
            string appVersion = PatchManager.Instance.GetAPPVersion();
            string filePath   = PatchHelper.GetSandboxStaticFilePath();

            // 如果是首次打开,记录APP版本信息
            if (PatchHelper.CheckSandboxStaticFileExist() == false)
            {
                MotionLog.Log($"Create sandbox static file : {filePath}");
                FileUtility.CreateFile(filePath, appVersion);
                return;
            }

            // 每次启动时比对APP版本号是否一致
            string recordVersion = FileUtility.ReadFile(filePath);

            // 如果记录的版本号不一致
            if (recordVersion != appVersion)
            {
                MotionLog.Warning($"Sandbox is dirty, Record version is {recordVersion}, APP version is {appVersion}");
                MotionLog.Warning("Clear all sandbox files.");
                PatchHelper.ClearSandbox();

                // 重新写入最新的APP版本信息
                MotionLog.Log($"Recreate sandbox static file : {filePath}");
                FileUtility.CreateFile(filePath, appVersion);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 处理连接请求
        /// </summary>
        private void ProcessConnected(object obj)
        {
            SocketAsyncEventArgs e     = obj as SocketAsyncEventArgs;
            UserToken            token = (UserToken)e.UserToken;

            if (e.SocketError == SocketError.Success)
            {
                if (_channel != null)
                {
                    throw new Exception("TcpClient channel is created.");
                }

                // 创建频道
                _channel = new TcpChannel();
                _channel.InitChannel(e.ConnectSocket, _packageCoderType, _packageMaxSize);
            }
            else
            {
                MotionLog.Log(ELogLevel.Error, $"ProcessConnected error : {e.SocketError}");
            }

            // 回调函数
            if (token.Callback != null)
            {
                token.Callback.Invoke(e.SocketError);
            }
        }
        public IEnumerator Download()
        {
            // 请求游戏版本
            string webURL      = _patcher.GetWebServerURL();
            string postContent = _patcher.GetWebPostContent();

            MotionLog.Log($"Beginning to request from web : {webURL}");
            MotionLog.Log($"Web post content : {postContent}");
            WebPostRequest download = new WebPostRequest(webURL);

            download.SendRequest(postContent);
            yield return(download);

            // Check fatal
            if (download.HasError())
            {
                download.ReportError();
                download.Dispose();
                PatchEventDispatcher.SendGameVersionRequestFailedMsg();
                yield break;
            }

            string responseContent = download.GetResponse();

            MotionLog.Log($"Succeed get response from web : {responseContent}");
            download.Dispose();
            _patcher.ParseResponseContent(responseContent);
            _patcher.SwitchNext();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 转换节点
        /// </summary>
        public void Transition(string nodeName)
        {
            if (string.IsNullOrEmpty(nodeName))
            {
                throw new ArgumentNullException();
            }

            IFsmNode node = GetNode(nodeName);

            if (node == null)
            {
                MotionLog.Error($"Can not found node {nodeName}");
                return;
            }

            // 检测转换关系
            if (Graph != null)
            {
                if (Graph.CanTransition(_curNode.Name, node.Name) == false)
                {
                    MotionLog.Error($"Can not transition {_curNode} to {node}");
                    return;
                }
            }

            MotionLog.Log($"Transition {_curNode.Name} to {node.Name}");
            _preNode = _curNode;
            _curNode.OnExit();
            _curNode = node;
            _curNode.OnEnter();
        }
Ejemplo n.º 8
0
 /// <summary>
 /// 捕获异常错误
 /// </summary>
 public void HandleError(bool isDispose, string error)
 {
     MotionLog.Log(ELogLevel.Error, error);
     if (isDispose)
     {
         Dispose();
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// 保存缓存文件
        /// </summary>
        public void SaveCache()
        {
            MotionLog.Log("Save cache to disk.");
            string filePath = PatchHelper.GetSandboxCacheFilePath();
            string jsonData = JsonUtility.ToJson(this);

            FileUtility.CreateFile(filePath, jsonData);
        }
Ejemplo n.º 10
0
        public void SaveRemotePatchManifest()
        {
            // 注意:这里会覆盖掉沙盒内的补丁清单文件
            MotionLog.Log("Save remote patch manifest.");
            string savePath = AssetPathHelper.MakePersistentLoadPath(PatchDefine.PatchManifestFileName);

            PatchManifest.Serialize(savePath, _localPatchManifest);
        }
 /// <summary>
 /// 创建指定资源的游戏对象池
 /// </summary>
 public void CreatePool(string location, int capacity = 0)
 {
     if (_collectors.ContainsKey(location))
     {
         MotionLog.Log(ELogLevel.Warning, $"Asset is already existed : {location}");
         return;
     }
     CreatePoolInternal(location, capacity);
 }
Ejemplo n.º 12
0
        /// <summary>
        /// 开始下载
        /// </summary>
        public void Download()
        {
            if (DownloadStates != EDownloaderStates.None)
            {
                throw new System.Exception($"{nameof(PatchDownloader)} is already running.");
            }

            MotionLog.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes");
            DownloadStates = EDownloaderStates.Loading;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// 获取配表
        /// </summary>
        /// <param name="configName">配表文件名称</param>
        public AssetConfig GetConfig(string configName)
        {
            if (_configs.ContainsKey(configName))
            {
                return(_configs[configName]);
            }

            MotionLog.Log(ELogLevel.Error, $"Not found config {configName}");
            return(null);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// 注册变体规则
        /// </summary>
        /// <param name="variantGroup">变体组</param>
        /// <param name="targetVariant">目标变体</param>
        public void RegisterVariantRule(List <string> variantGroup, string targetVariant)
        {
            if (variantGroup == null || variantGroup.Count == 0)
            {
                throw new Exception("VariantGroup is null or empty.");
            }
            if (string.IsNullOrEmpty(targetVariant))
            {
                throw new Exception("TargetVariant is invalid.");
            }

            // 需要包含点前缀
            for (int i = 0; i < variantGroup.Count; i++)
            {
                string variant = variantGroup[i];
                if (variant.Contains(".") == false)
                {
                    variantGroup[i] = $".{variant}";
                }
            }
            if (targetVariant.Contains(".") == false)
            {
                targetVariant = $".{targetVariant}";
            }

            // 目标变体需要在变体组列表里
            if (variantGroup.Contains(targetVariant) == false)
            {
                throw new Exception($"Variant group not contains target variant : {targetVariant} ");
            }

            // 转换为小写形式
            targetVariant = targetVariant.ToLower();
            for (int i = 0; i < variantGroup.Count; i++)
            {
                variantGroup[i] = variantGroup[i].ToLower();
            }

            foreach (var variant in variantGroup)
            {
                if (variant == targetVariant)
                {
                    continue;
                }
                if (_variantRuleCollection.ContainsKey(variant) == false)
                {
                    _variantRuleCollection.Add(variant, targetVariant);
                }
                else
                {
                    MotionLog.Log(ELogLevel.Warning, $"Variant key {variant} is already existed.");
                }
            }
        }
Ejemplo n.º 15
0
 /// <summary>
 /// 运行流程系统
 /// </summary>
 public void Run()
 {
     if (_nodeNames.Count > 0)
     {
         _fsm.Run(_nodeNames[0]);
     }
     else
     {
         MotionLog.Log(ELogLevel.Warning, "Procedure system dont has any node.");
     }
 }
Ejemplo n.º 16
0
        public void CacheDownloadPatchFiles(List <PatchBundle> downloadList)
        {
            List <string> hashList = new List <string>(downloadList.Count);

            foreach (var patchBundle in downloadList)
            {
                MotionLog.Log($"Cache download web file : {patchBundle.BundleName} Version : {patchBundle.Version} Hash : {patchBundle.Hash}");
                hashList.Add(patchBundle.Hash);
            }
            _cache.CacheDownloadPatchFiles(hashList);
        }
Ejemplo n.º 17
0
        public void CacheDownloadPatchFiles(List <PatchElement> downloadList)
        {
            List <string> hashList = new List <string>(downloadList.Count);

            foreach (var element in downloadList)
            {
                MotionLog.Log($"Cache download file : {element.BundleName} : {element.Version}");
                hashList.Add(element.MD5);
            }
            _cache.CacheDownloadPatchFiles(hashList);
        }
Ejemplo n.º 18
0
 // 缓存系统相关
 public void CacheDownloadPatchFile(string bundleName)
 {
     if (_localPatchManifest.Elements.TryGetValue(bundleName, out PatchElement element))
     {
         MotionLog.Log($"Cache download file : {element.BundleName} : {element.Version}");
         _cache.CacheDownloadPatchFile(element.MD5);
     }
     else
     {
         MotionLog.Warning($"Not found cache content file in local patch manifest : {bundleName}");
     }
 }
Ejemplo n.º 19
0
 /// <summary>
 /// 获取数据,如果不存在报警告
 /// </summary>
 public ConfigTable GetTable(int key)
 {
     if (_tables.ContainsKey(key))
     {
         return(_tables[key]);
     }
     else
     {
         MotionLog.Log(ELogLevel.Warning, $"Faild to get tab. File is {Location}, key is {key}");
         return(null);
     }
 }
Ejemplo n.º 20
0
        /// <summary>
        /// 开启更新
        /// </summary>
        public void Download()
        {
            MotionLog.Log("Begin to run patch procedure.");

            // 注意:按照先后顺序添加流程节点
            _procedure.AddNode(new FsmRequestGameVersion(this));
            _procedure.AddNode(new FsmGetWebPatchManifest(this));
            _procedure.AddNode(new FsmGetDonwloadList(this));
            _procedure.AddNode(new FsmDownloadWebFiles(this));
            _procedure.AddNode(new FsmDownloadOver(this));
            _procedure.Run();
        }
Ejemplo n.º 21
0
 // 缓存系统相关
 public void CacheDownloadPatchFile(string bundleName)
 {
     if (_localPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle patchBundle))
     {
         MotionLog.Log($"Cache download web file : {patchBundle.BundleName} Version : {patchBundle.Version} Hash : {patchBundle.Hash}");
         _cache.CacheDownloadPatchFile(patchBundle.Hash);
     }
     else
     {
         MotionLog.Warning($"Not found bundle in local patch manifest : {bundleName}");
     }
 }
Ejemplo n.º 22
0
        /// <summary>
        /// 发送网络消息
        /// </summary>
        public void SendMessage(INetworkPackage package)
        {
            if (States != ENetworkStates.Connected)
            {
                MotionLog.Log(ELogLevel.Warning, "Network is not connected.");
                return;
            }

            if (_client != null)
            {
                _client.SendPackage(package);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 切换至上个流程节点
        /// </summary>
        public void SwitchLast()
        {
            int index = _nodeNames.IndexOf(_fsm.CurrentNodeName);

            if (index <= 0)
            {
                MotionLog.Log(ELogLevel.Warning, $"Current node {_fsm.CurrentNodeName} is begin node.");
            }
            else
            {
                Switch(_nodeNames[index - 1]);
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// 切换至下个流程节点
        /// </summary>
        public void SwitchNext()
        {
            int index = _nodeNames.IndexOf(_fsm.CurrentNodeName);

            if (index >= _nodeNames.Count - 1)
            {
                MotionLog.Log(ELogLevel.Warning, $"Current node {_fsm.CurrentNodeName} is end node.");
            }
            else
            {
                Switch(_nodeNames[index + 1]);
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// 读取缓存文件
        /// </summary>
        public static PatchCache LoadCache()
        {
            if (PatchHelper.CheckSandboxCacheFileExist() == false)
            {
                return(new PatchCache());
            }

            MotionLog.Log("Load cache from disk.");
            string filePath = PatchHelper.GetSandboxCacheFilePath();
            string jsonData = FileUtility.ReadFile(filePath);

            return(JsonUtility.FromJson <PatchCache>(jsonData));
        }
Ejemplo n.º 26
0
        /// <summary>
        /// 获取配表
        /// </summary>
        public T GetConfig <T>() where T : AssetConfig
        {
            System.Type type = typeof(T);
            foreach (var pair in _configs)
            {
                if (pair.Value.GetType() == type)
                {
                    return(pair.Value as T);
                }
            }

            MotionLog.Log(ELogLevel.Error, $"Not found config {type}");
            return(null);
        }
        public IEnumerator Download()
        {
            // 获取最新的游戏版本号
            {
                string url  = _patcher.GetWebServerIP();
                string post = _patcher.GetWebPostData();
                MotionLog.Log($"Beginning to request from web : {url} {post}");
                WebPostRequest download = new WebPostRequest(url, post);
                download.DownLoad();
                yield return(download);

                //Check fatal
                if (download.HasError())
                {
                    download.ReportError();
                    download.Dispose();
                    PatchEventDispatcher.SendGameVersionRequestFailedMsg();
                    yield break;
                }

                string response = download.GetResponse();
                MotionLog.Log($"Succeed get response from web : {url} {response}");
                _patcher.ParseWebResponseData(response);
                download.Dispose();
            }

            // 检测强更安装包
            if (_patcher.ForceInstall)
            {
                string requestedGameVersion = _patcher.RequestedGameVersion.ToString();
                MotionLog.Log($"Found new APP can be install : {requestedGameVersion}");
                PatchEventDispatcher.SendFoundForceInstallAPPMsg(requestedGameVersion, _patcher.AppURL);
                yield break;
            }

            // 检测资源版本是否变化
            int newResourceVersion = _patcher.RequestedResourceVersion;
            int oldResourceVersion = _patcher.LocalResourceVersion;

            if (newResourceVersion == oldResourceVersion)
            {
                MotionLog.Log($"Resource version is not change.");
                _patcher.Switch(EPatchStates.DownloadOver.ToString());
            }
            else
            {
                MotionLog.Log($"Resource version is change : {oldResourceVersion} -> {newResourceVersion}");
                _patcher.SwitchNext();
            }
        }
Ejemplo n.º 28
0
 private void OnConnectServer(SocketError error)
 {
     MotionLog.Log($"Server connect result : {error}");
     if (error == SocketError.Success)
     {
         States = ENetworkStates.Connected;
         NetworkEventDispatcher.SendConnectSuccessMsg();
     }
     else
     {
         States = ENetworkStates.Disconnect;
         NetworkEventDispatcher.SendConnectFailMsg(error.ToString());
     }
 }
Ejemplo n.º 29
0
        public void UnLoad()
        {
            if (_handle != null)
            {
                MotionLog.Log($"Begin to unload scene : {Location}");
                _finishCallback    = null;
                _progressCallback  = null;
                _lastProgressValue = 0;

                // 异步卸载场景
                _handle.UnloadAsync();
                _handle = null;
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// 启动状态机
        /// </summary>
        /// <param name="entryNode">入口节点</param>
        public void Run(string entryNode)
        {
            _curNode = GetNode(entryNode);
            _preNode = GetNode(entryNode);

            if (_curNode != null)
            {
                _curNode.OnEnter();
            }
            else
            {
                MotionLog.Log(ELogLevel.Error, $"Not found entry node : {entryNode}");
            }
        }