/// <summary>
        /// 初始化.
        /// </summary>
        /// <param name="iTarget">下载目标.</param>
        /// <param name="iOnStart">开始事件委托.</param>
        /// <param name="iOnSuccessed">成功事件委托.</param>
        /// <param name="iOnFailed">失败事件委托.</param>
        /// <param name="iLocalSave">本地保存标志位.</param>
        /// <param name="iType">下载对象类型.</param>
        public void Init(
            DownloadTargetInfo iTarget, OnStart iOnStart,
            OnSuccessed iOnSuccessed, OnFailed iOnFailed)
        {
            this._target         = iTarget;
            this.DownloadBaseUrl = ServersConf.GetBundleDownloadBaseURL(iTarget);
            this.FileName        = UploadList.GetLocalBundleFileName(iTarget.ID, iTarget.FileType);
            this.FullFileName    = string.Format("{0}/{1}", this.DownloadDir, this.FileName);

            this.onStart     = iOnStart;
            this.onSuccessed = iOnSuccessed;
            this.onFailed    = iOnFailed;
            this.Retries     = ServersConf.GetInstance().NetRetries;
            this.TimeOut     = ServersConf.GetInstance().NetTimeOut * 1000;

            if (TBundleType.Scene != iTarget.BundleType)
            {
                this.TargetType = TargetType.BundleOfNormal;
            }
            else
            {
                this.TargetType = TargetType.BundleOfScenes;
            }

            // 检查目录
            if (Directory.Exists(this.DownloadDir) == false)
            {
                Directory.CreateDirectory(this.DownloadDir);
            }
        }
        /// <summary>
        /// 创建下载器.
        /// </summary>
        /// <returns>下载器.</returns>
        /// <param name="iTarget">目标信息.</param>
        private DownloaderBase CreateDownloader(DownloadTargetInfo iTarget)
        {
            DownloaderBase downloader  = null;
            TDownloadWay   downloadWay = ServersConf.GetInstance().DownloadWay;

            switch (downloadWay)
            {
            case TDownloadWay.WWW:
            {
                downloader = WWWDownloader.Create(
                    iTarget, OnStartDownload, OnDownloadSuccessed, OnDownloadFail);
            }
            break;

            case TDownloadWay.None:
            case TDownloadWay.Http:
            default:
            {
                downloader = HttpDownloader.Create(
                    iTarget, OnStartDownload, OnDownloadSuccessed, OnDownloadFail);
            }
            break;
            }
            return(downloader);
        }
        /// <summary>
        /// 初始化.
        /// </summary>
        /// <param name="iDownloadUrl">下载Url.</param>
        /// <param name="iOnStart">开始事件委托.</param>
        /// <param name="iOnSuccessed">成功事件委托.</param>
        /// <param name="iOnFailed">失败事件委托.</param>
        /// <param name="iType">下载对象类型.</param>
        public void Init(
            string iDownloadUrl, OnStart iOnStart,
            OnSuccessedByUrl iOnSuccessed, OnFailedByUrl iOnFailed, TargetType iType = TargetType.Bundle)
        {
            string urlTmp    = iDownloadUrl;
            int    lastIndex = urlTmp.LastIndexOf("/");

            this.DownloadBaseUrl = urlTmp.Substring(0, lastIndex);
            this.FileName        = urlTmp.Substring(lastIndex + 1);
            int index = this.FileName.IndexOf("?");

            if (-1 != index)
            {
                this.FileName     = this.FileName.Substring(0, index);
                this.FullFileName = string.Format("{0}/{1}", this.DownloadDir, this.FileName);
            }

            this.onStart          = iOnStart;
            this.onSuccessedByUrl = iOnSuccessed;
            this.onFailedByUrl    = iOnFailed;
            this.Retries          = ServersConf.GetInstance().NetRetries;
            this.TimeOut          = ServersConf.GetInstance().NetTimeOut * 1000;

            this.TargetType = iType;

            if (Directory.Exists(this.DownloadDir) == false)
            {
                Directory.CreateDirectory(this.DownloadDir);
            }
        }
        /// <summary>
        /// 创建下载器(Url).
        /// </summary>
        /// <returns>The downloader by URL.</returns>
        /// <param name="iDownloadUrl">下载Url.</param>
        /// <param name="iOnStart">开始事件委托.</param>
        /// <param name="iOnSuccessed">成功事件委托.</param>
        /// <param name="iOnFailed">失败事件委托.</param>
        /// <param name="iType">下载对象类型.</param>
        public static DownloaderBase CreateDownloaderByUrl(string iUrl,
                                                           OnStart iOnStart, OnSuccessedByUrl iOnSuccessed, OnFailedByUrl iOnFailed,
                                                           TargetType iType)
        {
            DownloaderBase downloader  = null;
            TDownloadWay   downloadWay = ServersConf.GetInstance().DownloadWay;

            switch (downloadWay)
            {
            case TDownloadWay.WWW:
            {
                downloader = WWWDownloader.Create(
                    iUrl, iOnStart, iOnSuccessed, iOnFailed, iType);
            }
            break;

            case TDownloadWay.None:
            case TDownloadWay.Http:
            default:
            {
                downloader = HttpDownloader.Create(
                    iUrl, iOnStart, iOnSuccessed, iOnFailed, iType);
            }
            break;
            }
            return(downloader);
        }
        /// <summary>
        /// 清空.
        /// </summary>
        /// <param name="iForceClear">强力清除标识位(删除Json文件).</param>
        protected override void Clear(bool iForceClear = false)
        {
            if (null == this._assetSetting)
            {
                return;
            }
            ServersConf.GetInstance();
#if UNITY_EDITOR
            if (true == iForceClear)
            {
                this._assetSetting.Clear(true);
                this._assetSetting.ExportToJsonFile();
            }
            else
            {
                this._assetSetting.Clear(false);
            }
#endif
            if (true == iForceClear)
            {
                this._assetSetting.Clear(true, ServersConf.BundlesDir);
                this._assetSetting.ExportToJsonFile(ServersConf.BundlesDir);
            }
            else
            {
                this._assetSetting.Clear(false);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// 检测服务器上Dir信息.
        /// </summary>
        /// <returns><c>true</c>, 成功, <c>false</c> 失败.</returns>
        /// <param name="iServer">服务器信息.</param>
        /// <param name="iParentUrl">上一层Url.</param>
        /// <param name="iCheckDir">欲检测的文件夹的相对路径.</param>
        /// <param name="iCreatedDir">已创建的相对目录.</param>
        private bool CheckDirOnServer(
            UploadServerInfo iServer, string iParentUrl,
            string iCheckDir, ref string iCreatedDir)
        {
            if (string.IsNullOrEmpty(iCreatedDir) == true)
            {
                iCreatedDir = iCheckDir;
            }
            else
            {
                iCreatedDir = string.Format("{0}/{1}", iCreatedDir, iCheckDir);
            }

            // 已经在服务器上创建
            if (ServersConf.GetInstance().isDirCreatedOnServerByLocal(iServer.ID, iCreatedDir) == true)
            {
                return(true);
            }

            // 检测目录
            if (this.CheckDirOnServer(iServer, iParentUrl, iCheckDir) == true)
            {
                ServersConf.GetInstance().AddCreatedDir(iServer.ID, iCreatedDir);
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// 下载上传列表.
        /// </summary>
        private IEnumerator DownloadUploadlist()
        {
            string         downloadUrl = ServersConf.GetInstance().GetDownloadUrlOfUploadList();
            DownloaderBase downloader  = this.CreateDownloader(downloadUrl);

            if (downloader != null)
            {
                downloader.ThreadDownLoadByUrl();
                yield return(new WaitUntil(() => (TRunState.Completed == downloader.State)));

                downloader.Dispose();
            }
            yield return(null);
        }
Esempio n. 8
0
        /// <summary>
        /// 初始化上传队列.
        /// </summary>
        private IEnumerator InitUploadQueue()
        {
            this._isCompleted = false;

            // 初始化上传信息队列
            List <UploadItem> targets = UploadList.GetInstance().Targets;

            if (this.UploadQueue != null)
            {
                UploadItem[] uploadTargets = targets.
                                             Where(o => (
                                                       (false == o.Uploaded) &&
                                                       (false == o.Scraped)))
                                             .OrderBy(o => o.No)
                                             .ToArray();
                if ((uploadTargets == null) || (uploadTargets.Length <= 0))
                {
                    this._State = TRunState.NoUploadTarget;
                    UtilsLog.Warning("InitUploadQueue", "There is no target to upload!!!");
                }
                yield return(new WaitForEndOfFrame());

                if (TRunState.OK == this._State)
                {
                    this.UploaderCount = 0;
                    int targetsCount = uploadTargets.Length;
                    int maxCount     = ServersConf.GetInstance().ThreadMaxCount;
                    this.UploaderMaxCount = (targetsCount > maxCount) ? maxCount : targetsCount;

                    foreach (UploadItem loop in uploadTargets)
                    {
                        if (loop == null)
                        {
                            continue;
                        }
                        Uploader uploader = Uploader.Create(loop,
                                                            this.OnUploadStart,
                                                            this.OnUploadFailed,
                                                            this.OnUploadSuccessed);
                        if (uploader != null)
                        {
                            this.UploadQueue.Enqueue(uploader);
                        }
                    }
                    yield return(new WaitForEndOfFrame());
                }
            }
            yield return(null);
        }
        /// <summary>
        /// 下载(WWW).
        /// </summary>
        /// <param name="iDownloadPreCheck">下载预检查.</param>
        public void DownloadByWWW(bool iDownloadPreCheck = false)
        {
            // 打断当前线程并停止所有协同进程
            isCanceled = true;
            this.StopAllCoroutines();

            // 重置开始完成标志位
            this._isCompleted = false;
            this.isStarted    = false;

            // 指定下载方式
            ServersConf.GetInstance().DownloadWay = TDownloadWay.WWW;

            // 点击事件
            this.DownloadStart(iDownloadPreCheck);
        }
        /// <summary>
        /// 开始下载.
        /// </summary>
        private IEnumerator DownloadFiles()
        {
            TDownloadWay downloadWay = ServersConf.GetInstance().DownloadWay;

            while (this.DownloadQueue.Count > 0)
            {
                // 下载器个数控制
                if (this.DownloaderCount >= this.DownloaderMaxCount)
                {
                    yield return(new WaitForSeconds(1.0f));
                }

                // 下载出错则停止
                if (TRunState.OK != this._State)
                {
                    this.Error("DownloadFiles()::Download Failed!!! State:{0}", this._State.ToString());
                    // 取消现有下载线程
                    isCanceled = true;
                    yield break;
                }

                DownloaderBase downloader = this.DownloadQueue.Dequeue();
                if (downloader == null)
                {
                    continue;
                }
                // Bundle文件
                if (TDownloadWay.WWW == downloadWay)
                {
                    yield return(downloader.AsynDownLoadTarget());
                }
                else
                {
                    downloader.ThreadDownLoadTarget();
                }
                yield return(new WaitForEndOfFrame());

                // 下载出错则停止
                if (TRunState.OK != this._State)
                {
                    this.Error("DownloadFiles()::Download Failed!!! State:{0}", this._State.ToString());
                    // 取消现有下载线程
                    isCanceled = true;
                    yield break;
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// 上传.
        /// </summary>
        private IEnumerator UploadFiles(TUploadWay iUploadWay = TUploadWay.Default)
        {
            UploadServerInfo server = ServersConf.GetInstance().GetUploadServerInfo();

            if (server == null)
            {
                yield return(null);
            }
            while (this.UploadQueue.Count > 0)
            {
                if (this.UploaderCount >= this.UploaderMaxCount)
                {
                    yield return(new WaitForSeconds(1.0f));
                }

                // 上传出错则停止
                if (TRunState.OK != this._State)
                {
                    UtilsLog.Error("UploadFiles", "Failed!!! State:{0} Detail:{1}",
                                   this._State.ToString(), this._errors.ToString());
                    // 取消现有上传线程
                    isCanceled = true;
                    break;
                }

                Uploader uploader = this.UploadQueue.Dequeue();
                if (uploader == null)
                {
                    continue;
                }
                yield return(uploader.UploadFile());

                yield return(new WaitForEndOfFrame());

                // 上传出错则停止
                if (TRunState.OK != this._State)
                {
                    UtilsLog.Error("UploadFiles", "Failed!!! State:{0} Detail:{1}",
                                   this._State.ToString(), this._errors.ToString());
                    // 取消现有上传线程
                    isCanceled = true;
                    break;
                }
            }

            yield return(null);
        }
Esempio n. 12
0
        static void Clear()
        {
            DownloadList list = DownloadList.GetInstance();

            if (list != null)
            {
                ServersConf.GetInstance();
#if UNITY_EDITOR
                list.Clear();
                list.ExportToJsonFile();
#endif
                list.Clear(true, ServersConf.BundlesDir);
                list.ExportToJsonFile(ServersConf.BundlesDir);
            }

            UtilsAsset.AssetsRefresh();
        }
Esempio n. 13
0
        private IEnumerator UpdateTips()
        {
            if (this._tipText == null)
            {
                yield return(null);
            }

            while (true)
            {
                string tip = ServersConf.GetInstance().GetProgressTipByRandom();
                if (string.IsNullOrEmpty(tip) == true)
                {
                    break;
                }
                this._tipText.text = tip;
                yield return(new WaitForSeconds(ServersConf.GetInstance().ProgressTips.Interval));
            }
            yield return(null);
        }
Esempio n. 14
0
        /// <summary>
        /// 开始上传.
        /// </summary>
        /// <param name="iUploadWay">上传方式.</param>
        public void StartUpload(TUploadWay iUploadWay = TUploadWay.Default)
        {
            this._uploadWay = iUploadWay;
            this.isStarted  = true;
            isCanceled      = false;

            // 开始下载初始化状态:OK
            this._State = TRunState.OK;

            if (this._uploadBar != null)
            {
                this._uploadBar.Init();
            }

            ServersConf.GetInstance().ClearCreatedDir();

            // 检测上传
            StartCoroutine(UploadCheck());
        }
Esempio n. 15
0
        /// <summary>
        /// 初始化.
        /// </summary>
        /// <param name="iTarget">上传目标.</param>
        /// <param name="iOnStart">开始上传委托.</param>
        /// <param name="iOnFailed">上传失败委托.</param>
        /// <param name="iOnSuccessed">上传成功委托.</param>
        /// <param name="iUploadWay">上传方式.</param>
        private void Init(
            UploadItem iTarget,
            OnStart iOnStart,
            OnFailed iOnFailed,
            OnSuccessed iOnSuccessed,
            TUploadWay iUploadWay = TUploadWay.Ftp)
        {
            this._target      = iTarget;
            this._onStart     = iOnStart;
            this._onFailed    = iOnFailed;
            this._onSuccessed = iOnSuccessed;
            this._uploadWay   = iUploadWay;
            this.Retries      = ServersConf.GetInstance().NetRetries;

            if (this._server == null)
            {
                this._server = ServersConf.GetInstance().UploadServer;
            }
            this.UploadBaseUrl = ServersConf.GetBundleUploadBaseURL(this._server, this._target);
            this.FileName      = UploadList.GetLocalBundleFileName(this._target.ID, this._target.FileType);
        }
Esempio n. 16
0
        /// <summary>
        /// 向服务器更新最新状态.
        /// </summary>
        private IEnumerator UpdateInfoToServer()
        {
            UploadServerInfo server = ServersConf.GetInstance().UploadServer;

            // 备份本地文件
            if (true == ServersConf.GetInstance().AssetBundlesBackUp)
            {
                this.BackUpBundleFiles();
            }
            yield return(new WaitForEndOfFrame());

            // 开始上传Bunlde包依赖信息文件(Json文件)
            string bundlesMapFilePath = this.UploadBundlesMapFile(server);

            yield return(new WaitForEndOfFrame());

            // 备份文件
            this.BackupFile(bundlesMapFilePath);
            yield return(new WaitForEndOfFrame());

            // 开始上传Bundles列表信息(Json文件)
            string uploadListFilePath = this.UploadUploadListFile(server);

            yield return(new WaitForEndOfFrame());

            // 备份文件
            this.BackupFile(uploadListFilePath);
            yield return(new WaitForEndOfFrame());

            // 清空本地文件
            AssetBundles.Common.ClearStreamingAssets();
            yield return(new WaitForEndOfFrame());

            if ((this._uploadEvents != null) && (this._uploadEvents.OnCompletedNotification != null))
            {
                this._uploadEvents.OnCompletedNotification.Invoke();
            }
            yield return(null);
        }
        /// <summary>
        /// 初始化下载队列.
        /// </summary>
        private IEnumerator initDownloadQueue()
        {
            // 初始化清空
            this.DownloadQueue.Clear();

            List <DownloadTargetInfo> targets = DownloadList.GetInstance().Targets;

            DownloadTargetInfo[] downloadTargets = targets
                                                   .Where(o => (false == o.Downloaded))
                                                   .ToArray();
            if ((downloadTargets == null) || (downloadTargets.Length <= 0))
            {
                this._State = TRunState.NoDownloadTarget;
                this.Warning("initDownloadQueue()::There is no target to download!!!");
            }
            yield return(new WaitForEndOfFrame());

            if (TRunState.OK == this._State)
            {
                this.DownloaderCount = 0;
                int targetsCount = downloadTargets.Length;
                int maxCount     = ServersConf.GetInstance().ThreadMaxCount;
                this.DownloaderMaxCount = (targetsCount > maxCount) ? maxCount : targetsCount;
                // 遍历下载列表,并压进下载队列
                foreach (DownloadTargetInfo loop in downloadTargets)
                {
                    if (loop == null)
                    {
                        continue;
                    }

                    DownloaderBase downloader = CreateDownloader(loop);
                    if (downloader != null)
                    {
                        this.DownloadQueue.Enqueue(downloader);
                    }
                }
            }
        }
Esempio n. 18
0
        /// <summary>
        /// 初始化信息.
        /// </summary>
        /// <returns><c>true</c>, OK, <c>false</c> NG.</returns>
        private bool InitInfo()
        {
            // 超时状态
            this._timeoutMaxValue = ServersConf.GetInstance().NetTimeOut;

            // 状态
            this.LastState = IAPState.None;
            this.State     = IAPState.None;

            this.ActiveStep          = IAPActionStep.None;
            this.ActiveIAPItem       = default(T1);
            this.ActiveProductID     = null;
            this.ActiveQuantity      = 0;
            this.ActiveOrderID       = null;
            this.ActiveTransactionID = null;
            this.ActiveReceipt       = null;

            // 错误信息
            this.ErrorCode       = IAPErrorCode.None;
            this.ErrorDetailCode = -1;
            this.ErrorDetail     = null;

            return(true);
        }
Esempio n. 19
0
        /// <summary>
        /// 设定打包信息
        /// </summary>
        private static void SetBuildInfoFromParameters()
        {
            // 平台类型
            TPlatformType platformType = BuildParameters.PlatformType;

            if (TPlatformType.None != platformType)
            {
                BuildInfo.GetInstance().PlatformType = platformType;
            }

            // 工程名
            string projectName = BuildParameters.ProjectName;

            if (false == string.IsNullOrEmpty(projectName))
            {
                BuildInfo.GetInstance().BuildName = projectName;
            }

            // 打包ID
            string buildID = BuildParameters.BuildId;

            if (false == string.IsNullOrEmpty(buildID))
            {
                BuildInfo.GetInstance().BuildID = buildID;
            }

            // 打包模式
            TBuildMode buildMode = BuildParameters.BuildMode;

            if (TBuildMode.None != buildMode)
            {
                BuildInfo.GetInstance().BuildMode = buildMode;
            }

            // 版本号
            string buildVersion = BuildParameters.BuildVersion;

            if (false == string.IsNullOrEmpty(buildVersion))
            {
                BuildInfo.GetInstance().BuildVersion = buildVersion;
            }

            // VersionCode
            int buildVersionCode = BuildParameters.BuildVersionCode;

            if (-1 != buildVersionCode)
            {
                BuildInfo.GetInstance().BuildVersionCode = buildVersionCode;
            }

            // 中心服务器版本号
            string centerVersion = BuildParameters.CenterVersion;

            if (false == string.IsNullOrEmpty(centerVersion))
            {
                BuildInfo.GetInstance().CenterVersion = centerVersion;
            }

            // 打包号
            int buildNumber = BuildParameters.BuildNumber;

            if (-1 < buildNumber)
            {
                BuildInfo.GetInstance().BuildNumber = buildNumber;
            }

            // 是否跳过下载
            bool isSkipDownload = BuildParameters.IsSkipDownload;

            ServersConf.GetInstance().SkipDownload = isSkipDownload;
        }
 /// <summary>
 /// 重置.
 /// </summary>
 public void Reset()
 {
     this.Retries = ServersConf.GetInstance().NetRetries;
 }
Esempio n. 21
0
        /// <summary>
        /// 检测服务器上得各个路径.
        /// </summary>
        /// <returns><c>true</c>, OK, <c>false</c> NG.</returns>
        private IEnumerator CheckDirsOnServer()
        {
            string buildName = BuildInfo.GetInstance().BuildName;

            // 上传服务器信息
            UploadServerInfo server = ServersConf.GetInstance().UploadServer;

            if (server == null)
            {
                this._State = TRunState.GetServerInfoFailed;
                yield return(null);
            }

            // 取得上传URL
            string uploadBaseUrl = ServersConf.GetUploadBaseURL(server);

            int    startIndex = uploadBaseUrl.IndexOf(buildName);
            string dirsInfo   = uploadBaseUrl.Substring(startIndex);

            string[] dirNames = dirsInfo.Split('/');

            string curUrl     = uploadBaseUrl.Substring(0, startIndex - 1);
            string createdDir = null;

            for (int i = 0; i < dirNames.Length; ++i)
            {
                if (this.CheckDirOnServer(server, curUrl, dirNames [i], ref createdDir) == true)
                {
                    curUrl = string.Format("{0}/{1}", curUrl, dirNames [i]);
                    yield return(new WaitForEndOfFrame());
                }
                else
                {
                    this._State = TRunState.CheckDirFailed;
                    yield return(null);
                }
            }

            // 检测目录
            // Url:<ParentUrl>/bundles
            if (this.CheckDirOnServer(server, curUrl, "bundles", ref createdDir) == true)
            {
                curUrl = string.Format("{0}/{1}", curUrl, "bundles");
                yield return(new WaitForEndOfFrame());
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                yield return(null);
            }

            // Url:<ParentUrl>/<BuildTarget>
            string buildTarget = UploadList.GetInstance().BuildTarget;

            if (this.CheckDirOnServer(server, curUrl, buildTarget, ref createdDir) == true)
            {
                curUrl = string.Format("{0}/{1}", curUrl, buildTarget);
                yield return(new WaitForEndOfFrame());
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                yield return(null);
            }

            // Url:<ParentUrl>/<AppVersion>
            string appVersion = UploadList.GetInstance().AppVersion;

            if (this.CheckDirOnServer(server, curUrl, appVersion, ref createdDir) == true)
            {
                curUrl = string.Format("{0}/{1}", curUrl, appVersion);
                yield return(new WaitForEndOfFrame());
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                yield return(null);
            }

            // Url:<ParentUrl>/Normal
            string subUrlTmp        = curUrl;
            string subCreatedDirTmp = createdDir;

            if (this.CheckDirOnServer(server, subUrlTmp,
                                      UploadList.AssetBundleDirNameOfNormal, ref subCreatedDirTmp) == true)
            {
                subUrlTmp = string.Format("{0}/{1}", subUrlTmp, UploadList.AssetBundleDirNameOfNormal);
                yield return(new WaitForEndOfFrame());
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                yield return(null);
            }

            // Url:<ParentUrl>/Scene
            subUrlTmp        = curUrl;
            subCreatedDirTmp = createdDir;
            if (this.CheckDirOnServer(server, subUrlTmp,
                                      UploadList.AssetBundleDirNameOfScenes, ref subCreatedDirTmp) == true)
            {
                subUrlTmp = string.Format("{0}/{1}", subUrlTmp, UploadList.AssetBundleDirNameOfScenes);
                yield return(new WaitForEndOfFrame());
            }
            else
            {
                this._State = TRunState.CheckDirFailed;
                yield return(null);
            }

            yield return(null);
        }
Esempio n. 22
0
        static void CreateUploadShell()
        {
            const string funcBlock = "AssetBundlesBuild.CreateUploadShell()";

            BuildLogger.OpenBlock(funcBlock);

            string filePath = string.Format("{0}/../Shell/Upload.sh", Application.dataPath);

            if (File.Exists(filePath) == true)
            {
                File.Delete(filePath);
            }
            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);

            if (null == fs)
            {
                return;
            }
            StreamWriter sw = new StreamWriter(fs);

            if (null == sw)
            {
                if (null != fs)
                {
                    fs.Flush();
                    fs.Close();
                    fs.Dispose();
                }
                return;
            }

            // 写入文件头
            sw.WriteLine("#!/bin/bash");
            sw.Flush();

            sw.WriteLine("");
            sw.Flush();

            // 设定变量
            sw.WriteLine("# 上传根目录");
            sw.WriteLine("ROOT_DIR=bundles");
            sw.Flush();
            sw.WriteLine("# 本地上传路径");
            sw.WriteLine(string.Format("UPLOAD_FROM_ROOT_DIR={0}/StreamingAssets", Application.dataPath));
            sw.WriteLine("");
            sw.Flush();
            sw.WriteLine("# 上传目标平台");
            sw.WriteLine(string.Format("BUILD_TARGET={0}", UploadList.GetInstance().BuildTarget));
            sw.Flush();
            sw.WriteLine("# App Version");
            sw.WriteLine(string.Format("APP_VERSION={0}", UploadList.GetInstance().AppVersion));
            sw.Flush();
            sw.WriteLine("# Center Version");
            sw.WriteLine(string.Format("CENTER_VERSION={0}", UploadList.GetInstance().CenterVersion));
            sw.WriteLine("");
            sw.Flush();

            UploadServerInfo uploadServer = ServersConf.GetInstance().UploadServer;

            sw.WriteLine("# 检测上传目录");
            sw.WriteLine("# $1 上传目录");
            sw.WriteLine("checkUploadDir()");
            sw.WriteLine("{");
            sw.WriteLine("ftp -n<<!");
            sw.WriteLine(string.Format("open {0} {1}", uploadServer.IpAddresss, uploadServer.PortNo));
            sw.WriteLine(string.Format("user {0} {1}", uploadServer.AccountId, uploadServer.Pwd));
            sw.WriteLine("binary");
            sw.WriteLine("pwd");
            sw.WriteLine("if [ ! -d \"$1\" ]; then");
            sw.WriteLine("  mkdir \"$1\"");
            sw.WriteLine("fi");
            sw.WriteLine("prompt");
//			sw.WriteLine("ls -l");
            sw.WriteLine("close");
            sw.WriteLine("bye");
            sw.WriteLine("!");
            sw.WriteLine("}");
            sw.WriteLine("");
            sw.Flush();

            sw.WriteLine("# 文件上传函数");
            sw.WriteLine("# $1 本地上传目录");
            sw.WriteLine("# $2 上传目标目录");
            sw.WriteLine("# $3 上传目标文件");
            sw.WriteLine("upload()");
            sw.WriteLine("{");
            sw.WriteLine("ftp -n<<!");
            sw.WriteLine(string.Format("open {0} {1}", uploadServer.IpAddresss, uploadServer.PortNo));
            sw.WriteLine(string.Format("user {0} {1}", uploadServer.AccountId, uploadServer.Pwd));
            sw.WriteLine("binary");
            sw.WriteLine("cd \"$2\"");
            sw.WriteLine("lcd \"$1\"");
            sw.WriteLine("pwd");
            sw.WriteLine("prompt");
            sw.WriteLine("put \"$3\"");
//			sw.WriteLine("ls -l");
            sw.WriteLine("close");
            sw.WriteLine("bye");
            sw.WriteLine("!");
            sw.WriteLine("}");
            sw.WriteLine("");
            sw.Flush();


            sw.WriteLine("# 检测目录");
            sw.WriteLine("checkUploadDir $ROOT_DIR");
            sw.WriteLine("checkUploadDir $ROOT_DIR/$BUILD_TARGET");
            sw.WriteLine("checkUploadDir $ROOT_DIR/$BUILD_TARGET/$APP_VERSION");
            sw.WriteLine("");
            sw.Flush();

            sw.WriteLine("# 上传资源文件");
            List <UploadItem> Targets = UploadList.GetInstance().Targets;

            UploadItem[] _normals = Targets
                                    .Where(o => (TBundleType.Normal == o.BundleType))
                                    .OrderBy(o => o.No)
                                    .ToArray();
            if (0 < _normals.Length)
            {
                sw.WriteLine("# 检测一般文件目录");
                sw.WriteLine(string.Format("checkUploadDir $ROOT_DIR/$BUILD_TARGET/$APP_VERSION/{0}", TBundleType.Normal.ToString()));

                sw.WriteLine("# 一般文件");
                foreach (UploadItem loop in _normals)
                {
                    string fileName = UploadList.GetLocalBundleFileName(loop.ID, loop.FileType);
                    sw.WriteLine(string.Format("upload $UPLOAD_FROM_ROOT_DIR/{0} $ROOT_DIR/$BUILD_TARGET/$APP_VERSION/{0} {1}",
                                               TBundleType.Normal.ToString(), fileName));
                }
                sw.WriteLine("");
                sw.Flush();
            }

            UploadItem[] _scenes = Targets
                                   .Where(o => (TBundleType.Scene == o.BundleType))
                                   .OrderBy(o => o.No)
                                   .ToArray();
            if (0 < _scenes.Length)
            {
                sw.WriteLine("# 检测场景文件目录");
                sw.WriteLine(string.Format("checkUploadDir $ROOT_DIR/$BUILD_TARGET/$APP_VERSION/{0}", TBundleType.Scene.ToString()));
                sw.WriteLine("# 场景文件");
                foreach (UploadItem loop in _scenes)
                {
                    string fileName = UploadList.GetLocalBundleFileName(loop.ID, loop.FileType);
                    sw.WriteLine(string.Format("upload $UPLOAD_FROM_ROOT_DIR/{0} $ROOT_DIR/$BUILD_TARGET/$APP_VERSION/{0} {1}",
                                               TBundleType.Scene.ToString(), fileName));
                }
                sw.WriteLine("");
                sw.Flush();
            }

            // 导出依赖文件
            BundlesMap.GetInstance().ExportToJsonFile(string.Format("{0}/StreamingAssets", Application.dataPath));
            sw.WriteLine("# 上传依赖文件");
            sw.WriteLine("upload $UPLOAD_FROM_ROOT_DIR $ROOT_DIR/$BUILD_TARGET/$APP_VERSION BundlesMapData.json");

            // 导出上传列表文件
            UploadList.GetInstance().ExportToJsonFile(string.Format("{0}/StreamingAssets", Application.dataPath));
            sw.WriteLine("# 上传上传列表文件");
            sw.WriteLine("upload $UPLOAD_FROM_ROOT_DIR $ROOT_DIR/$BUILD_TARGET/$APP_VERSION UploadListData.json");

            if (0 < Targets.Count)
            {
                sw.WriteLine("# 清空上传文件");
                sw.WriteLine(string.Format("rm -rfv $UPLOAD_FROM_ROOT_DIR", TBundleType.Normal.ToString()));
                sw.WriteLine("");
                sw.Flush();
            }

            sw.WriteLine("");
            sw.Flush();

            if (null != fs)
            {
                fs.Flush();
                fs.Close();
                fs.Dispose();
            }

            if (null != sw)
            {
                sw.Flush();
                sw.Close();
                sw.Dispose();
            }

            BuildLogger.CloseBlock();
        }