Пример #1
0
 /// <summary>
 /// 根据AppResConfig进行更新
 /// </summary>
 public void UpdateByAppResConfig(ResConfigFile _appConfig)
 {
     if (_appConfig.ResVersion < ResVersion)
     {
         return;
     }
     for (Int32 i = 0; i < _appConfig.m_assets.Count; ++i)
     {
         ResInfo localResInfo;
         var     appResInfo = _appConfig.m_assets[i];
         if (ResDictionary.TryGetValue(appResInfo.Name, out localResInfo))
         {
             if (appResInfo.Version > localResInfo.Version)
             {
                 appResInfo.CopyTo(localResInfo);
                 localResInfo.Location = AssetLocation.StreamingPath;
             }
         }
         else
         {
             localResInfo          = appResInfo.Clone();
             localResInfo.Location = AssetLocation.StreamingPath;
             m_assets.Add(localResInfo);
             ResDictionary.Add(localResInfo.Name, localResInfo);
         }
     }
     Save();
 }
Пример #2
0
        public Boolean BuilderMergeOld(ResConfigFile _old_file)
        {
            Boolean found = false;

            for (Int32 i = 0; i < m_assets.Count; ++i)
            {
                ResInfo old_res_info;
                if (!_old_file.TryGetAssetInfo(m_assets[i].Name, out old_res_info))
                {
                    found = true;
                    Log.Info("[New]: {0}", m_assets[i].Name);
                    continue;
                }
                if (m_assets[i].ResType == ResourceType.AssetBundle && m_assets[i].AssetBundleTypeTreeHash.Equals(old_res_info.AssetBundleTypeTreeHash))
                {
                    m_assets[i] = old_res_info;
                    ResDictionary[old_res_info.Name] = old_res_info;
                    continue;
                }
                if (!old_res_info.NeedUpdate(m_assets[i]))
                {
                    m_assets[i] = old_res_info;
                    ResDictionary[old_res_info.Name] = old_res_info;
                    continue;
                }
                Log.Info("[Modify]: {0}", m_assets[i].Name);
                found = true;
            }
            return(found);
        }
Пример #3
0
        public void UpdateRes(Action <Boolean> _onCompleted)
        {
            Log.Debug("开始资源更新准备工作");
            mOnUpdateCompleted = _onCompleted;
            var appConfigAb = AssetBundle.LoadFromFile(
                ResInfo.GetSystemApiLoadPath("res_config.grt", AssetLocation.StreamingPath));

            if (appConfigAb == null)
            {
                Log.Critical(eLogType.Resources, "加载 In App res config 失败!!!");
                appConfigAb.Unload(true);
                return;
            }

            mInAppConfig = ResConfigFile.Create(appConfigAb.LoadAsset <TextAsset>("res_config").bytes);
            if (appConfigAb == null)
            {
                Log.Critical(eLogType.Resources, "解析 In App res config 失败!!!");
                appConfigAb.Unload(true);
                return;
            }
            appConfigAb.Unload(true);
            mLocalConfig = ResConfigFile.Create(ResInfo.GetSystemApiLoadPath("res_config", AssetLocation.PersistentPath), true);

            if (mLocalConfig == null)
            {
                Log.Critical(eLogType.Resources, "创建 Local res config 失败!!!");
                return;
            }

            StartCoroutine(checkUpdate());
        }
Пример #4
0
        private IEnumerator checkUpdate()
        {
            Log.Debug("开始检查资源更新");
            using (UnityWebRequest uwr = UnityWebRequest.GetAssetBundle(ResUtility.ResConfigDownloadUrl))
            {
                yield return(uwr.Send());

                if (uwr.isError)
                {
                    Debug.Log(uwr.error);
                    showCheckUpdateFailTip();
                    yield break;
                }
                else
                {
                    AssetBundle srvConfigAb = ((DownloadHandlerAssetBundle)uwr.downloadHandler).assetBundle;
                    if (srvConfigAb == null)
                    {
                        showCheckUpdateFailTip();
                        yield break;
                    }
                    TextAsset asset = srvConfigAb.LoadAsset <TextAsset>("res_config");
                    if (asset == null)
                    {
                        showCheckUpdateFailTip();
                        srvConfigAb.Unload(true);
                        yield break;
                    }
                    mServerConfig = ResConfigFile.Create(asset.bytes);
                    srvConfigAb.Unload(true);
                    if (mServerConfig == null)
                    {
                        showCheckUpdateFailTip();
                        yield break;
                    }
                }
            }

            // 处理更新列表
            Boolean localResConfigUpdated;

            mUpdateTotalSize = mLocalConfig.GetUpdateList(mInAppConfig, mServerConfig, out mUpdateList, out localResConfigUpdated);
            if (mUpdateTotalSize == 0)
            {
                mOnUpdateCompleted(localResConfigUpdated);
            }
            else
            {
                showUpdateTip();
            }
        }
Пример #5
0
        /// <summary>
        /// 获取更新列表
        /// </summary>
        /// <param name="_appConfig"></param>
        /// <param name="_serverConfig"></param>
        /// <param name="_updateList"></param>
        /// <returns>更新文件大小(字节)</returns>
        public Int64 GetUpdateList(ResConfigFile _appConfig, ResConfigFile _serverConfig, out LinkedList <ResInfo> _updateList, out Boolean _localConfigUpdated)
        {
            _localConfigUpdated = false;
            Int64 updateSize = 0;

            _updateList = new LinkedList <ResInfo>();
            for (Int32 i = 0; i < _serverConfig.m_assets.Count; ++i)
            {
                var     srvResInfo = _serverConfig.m_assets[i];
                ResInfo localResInfo;
                ResDictionary.TryGetValue(srvResInfo.Name, out localResInfo);
                ResInfo appResInfo;
                _appConfig.ResDictionary.TryGetValue(srvResInfo.Name, out appResInfo);

                // 无需更新
                if (localResInfo != null && !localResInfo.NeedUpdate(srvResInfo))
                {
                    continue;
                }

                if (appResInfo != null && !appResInfo.NeedUpdate(srvResInfo))
                {
                    localResInfo          = appResInfo.Clone();
                    localResInfo.Location = AssetLocation.StreamingPath;
                    AddOrUpdateResInfo(localResInfo);
                    Save();
                    _localConfigUpdated = true;
                }
                else
                {
                    localResInfo          = srvResInfo.Clone();
                    localResInfo.Location = AssetLocation.PersistentPath;
                    _updateList.AddLast(localResInfo);
                    updateSize += localResInfo.Size;
                }
            }
            return(updateSize);
        }
Пример #6
0
        /// <summary>
        /// 加载一个最新的package
        /// </summary>
        /// <returns></returns>
        public static ResUpdatePkg LoadLastPkg()
        {
            var          resConfigPath = String.Concat(OUTPUT_ROOT, "/res_config.grt");
            ResUpdatePkg pkg           = new ResUpdatePkg();

            if (!File.Exists(resConfigPath))
            {
                Log.Info("没有更新包!");
                return(null);
            }
            else
            {
                // 直接读取txt
                pkg.m_res_config = ResConfigFile.Create(String.Concat(OUTPUT_ROOT, "/res_config.txt"), false);
                pkg.Version      = pkg.m_res_config.ResVersion;
                if (pkg.m_res_config == null)
                {
                    Log.Error("读取最新更新包失败!");
                    return(null);
                }
            }
            return(pkg);
        }
Пример #7
0
        /// <summary>
        /// 从AssetsConfig中删除资源
        /// </summary>
        /// <param name="_srv_config"></param>
        /// <returns>是否有删除到东西</returns>
        public Boolean DeleteRes(ResConfigFile _srv_config)
        {
            Boolean found = false;

            for (int i = 0; i < m_assets.Count; i++)
            {
                if (!_srv_config.ContainAsset(m_assets[i].Name))
                {
                    m_assets[i] = null;
                    if (m_asset_dictionary != null)                      // 直接重建好了
                    {
                        m_asset_dictionary = null;
                    }
                    found = true;
                }
            }
            if (!found)
            {
                return(false);
            }
            m_assets.RemoveNull();
            return(true);
        }
Пример #8
0
        /// <summary>
        /// 初始化ResourceManager, 加载包内和包外的res_config
        /// </summary>
        /// <param name="_action_initialized"></param>
        /// <returns></returns>
        private IEnumerator _asyncInitialize(Action <Boolean> _action_initialized)
        {
            String app_res_config_path = ResInfo.GetWWWLoadPath("res_config", AssetLocation.StreamingPath);

            Log.Debug(eLogType.Resources, app_res_config_path);
            using (WWW www = new WWW(app_res_config_path))
            {
                yield return(www);

                if (!String.IsNullOrEmpty(www.error))                    // 加载错误
                {
                    Log.Error(eLogType.Resources, "[ResourceManager]: In App res_config assetbundle 加载失败!: {0}", www.error);
                    _action_initialized(false);
                    yield break;
                }


                ResConfigFile app_res_config = ResConfigFile.Create(www.bytes);
                if (app_res_config == null)                  // 解析错误
                {
                    Log.Error(eLogType.Resources, "[ResourceManager]: In App res_config 解析错误!");
                    _action_initialized(false);
                    yield break;
                }

                mLoadResConfig = ResConfigFile.Create(ResUtility.LocalResConfigPath, true);
                if (mLoadResConfig == null)                  // 保存用assetsconfig 创建或读取错误
                {
                    app_res_config = null;
                    Log.Error(eLogType.Resources, "[ResouceManager]: Saved res_config file 创建或解析错误!");
                    _action_initialized(false);
                    yield break;
                }
                _action_initialized(true);
            }
        }
Пример #9
0
        /// <summary>
        /// 初始化资源管理器
        /// </summary>
        /// <param name="_updateByAppConfig">是否使用app内config更新列表,在更新完成之后重新初始化时不需要更新</param>
        /// <returns></returns>
        public Boolean Initialize(Boolean _updateByAppConfig)
        {
            String appResConfigPath        = String.Concat(Application.streamingAssetsPath, "/res/res_config.grt");
            var    assetbundleAppResConfig = AssetBundle.LoadFromFile(appResConfigPath);

            if (assetbundleAppResConfig == null)
            {
                Log.Critical("[ResourceManager.Initialize]:读取inapp res config 失败! assetbundle 加载失败!");
                return(false);
            }

            var appResConfigBytes = assetbundleAppResConfig.LoadAsset <TextAsset>("res_config");

            if (appResConfigBytes == null)
            {
                Log.Critical("[ResourceManager.Initialize]:读取inapp res config 失败! TextAsset加载失败");
                assetbundleAppResConfig.Unload(true);
                return(false);
            }
            var appResConfig = ResConfigFile.Create(appResConfigBytes.bytes);

            if (appResConfig == null)
            {
                Log.Critical(eLogType.Resources, "[ResourceManager.Initialize]: 读取inapp res config 失败! 解析失败!");
                assetbundleAppResConfig.Unload(true);
                return(false);
            }
            assetbundleAppResConfig.Unload(true);


            mLoadResConfig = ResConfigFile.Create(ResUtility.LocalResConfigPath, true);
            if (mLoadResConfig == null)
            {
                Log.Error(eLogType.Resources, "[ResouceManager]: Local res config file 创建失败!");
                return(false);
            }

            // 首次初始化时执行
            if (_updateByAppConfig)
            {
                mLoadResConfig.UpdateByAppResConfig(appResConfig);
            }


            mLoadResConfig.TraverseAssets(_info => {
                m_res_dictionary.Add(_info.Name, _createResourceData(_info));
            });

            // 读取依赖
            var assetbundleManifest      = AssetBundle.LoadFromFile(GetResource("res.grt").ResouceInfo.SystemApiLoadingPath);
            AssetBundleManifest manifest = assetbundleManifest.LoadAsset <AssetBundleManifest>("AssetBundleManifest");

            foreach (Resource_Base res in m_res_dictionary.Values)
            {
                if (res.ResouceInfo.ResType != ResourceType.AssetBundle)
                {
                    continue;
                }
                Resource_Assetbundle resAssetbundle = res as Resource_Assetbundle;
                var dependenciesName = manifest.GetDirectDependencies(res.Name);
                for (int i = 0; i < dependenciesName.Length; i++)
                {
                    Resource_Assetbundle dependency = GetResource <Resource_Assetbundle>(dependenciesName[i]);
                    if (dependency == null)
                    {
                        Log.Critical(eLogType.Resources, "[ResourceManager.Initialize]: {0}的依赖资源: {1}没有在ResourceConfig中找到! 请尝试重新打包!", res.Name, dependenciesName[i]);
                        return(false);
                    }
                    resAssetbundle.AddDependencies(dependency);
                }
            }
            assetbundleManifest.Unload(true);

            Log.Debug(eLogType.Resources, "ResourceManager Initialized Done!");
            return(true);
        }
Пример #10
0
        public static void BuildNew(ResUpdatePkg _old_pkg)
        {
            //AssetBundle bundle = AssetBundle.LoadFromFile( String.Concat( OUTPUT_TMP, "/data/global_configtest" ) );
            //TextAsset g = bundle.LoadAsset<TextAsset>( "global_configtest" );
            ////TextAsset r = bundle.LoadAsset<TextAsset>( "rookie_config" );
            //bundle.Unload( true );
            ////AssetBundle bundle = AssetBundle.LoadFromFile( String.Concat( OUTPUT_TMP, "/ui/ui_main.ui" ) );
            //return;
            FileHelper.DeleteDirectory(OUTPUT_TMP, true);
            FileHelper.CreateDirectory(OUTPUT_TMP);

            // 打包Assetbundle
            BuildPipeline.BuildAssetBundles(OUTPUT_TMP, BUILD_OPTIONS, BUILD_TARGET);
            AssetBundle assetbundleManifest = null;

            assetbundleManifest = AssetBundle.LoadFromFile(String.Concat(OUTPUT_TMP, "/res"));
            AssetBundleManifest manifest = assetbundleManifest.LoadAsset <AssetBundleManifest>("AssetBundleManifest");

            String[] allAssetBundles = manifest.GetAllAssetBundles();

            // 添加Assetbundle到config
            var newPkg = new ResUpdatePkg {
                Version = _old_pkg == null ? 1 : _old_pkg.Version + 1, m_pre_version = _old_pkg
            };

            newPkg.m_res_config = ResConfigFile.Create(String.Concat(OUTPUT_TMP, "/res_config.txt"), true);

            foreach (String assetBundle in allAssetBundles)
            {
                newPkg.m_res_config.BuidlerAndResInfo(OUTPUT_TMP, assetBundle, newPkg.Version);
            }

            assetbundleManifest.Unload(true);

            File.Move(String.Concat(OUTPUT_TMP, "/res"), String.Concat(OUTPUT_TMP, "/res.grt"));
            newPkg.m_res_config.BuidlerAndResInfo(OUTPUT_TMP, "res.grt", newPkg.Version);

            // 打包lua文件
            GrtFileEditor.Pack("Assets/res/lua", OUTPUT_TMP, "scripts/ui.grt");
            newPkg.m_res_config.BuidlerAndResInfo(OUTPUT_TMP, "scripts/ui.grt", newPkg.Version);

            Boolean hasNewRes = true;

            // 处理res_config
            if (newPkg.m_pre_version != null)
            {
                hasNewRes = newPkg.m_res_config.BuilderMergeOld(_old_pkg.m_res_config);
            }

            if (!hasNewRes)
            {
                EditorUtility.DisplayDialog("", "资源无更新!", "确定");
                return;
            }

            // 保存到版本目录
            String version_root = String.Concat(OUTPUT_ROOT, "/", newPkg.Version.ToString());

            FileHelper.CreateDirectory(version_root);

            // 临时保存到Assets下以便打包
            newPkg.m_res_config.SaveAs("Assets/res_config.txt", true);
            File.Copy("Assets/res_config.txt", String.Concat(version_root, "/res_config.txt"), true);
            File.Copy("Assets/res_config.txt", String.Concat(OUTPUT_ROOT, "/res_config.txt"), true);

            AssetDatabase.Refresh();
            BuildPipeline.BuildAssetBundles(
                OUTPUT_ROOT,
                new AssetBundleBuild[] { new AssetBundleBuild()
                                         {
                                             assetBundleName = "res_config.grt", assetNames = new[] { "Assets/res_config.txt" }
                                         } },
                BUILD_OPTIONS,
                BUILD_TARGET
                );

            AssetDatabase.Refresh();
            File.Copy(String.Concat(OUTPUT_ROOT, "/res_config.grt"), String.Concat(version_root, "/res_config.grt"), true);


            // 保存的根目录
            //new_pkg.m_res_config.SaveAs( String.Concat( OUTPUT_ROOT, "/res_config" ), true );

            FileHelper.CreateDirectory(version_root);
            // copy main assetbundle manifest
            //File.Copy( String.Concat( OUTPUT_TMP, "/res" ), String.Concat( version_root, "/res" ), true );

            newPkg.m_res_config.TraverseAssets(
                _info => {
                if (_info.Version != newPkg.Version)
                {
                    return;
                }
                String dest = String.Concat(version_root, "/", _info.Name);
                FileHelper.CreateDirectoryByFilePath(dest);
                File.Copy(String.Concat(OUTPUT_TMP, "/", _info.Name), dest, true);
            });

            // 删除指定Assetbundle打包后生成的信息文件(没用)
            File.Delete(String.Concat(OUTPUT_ROOT, "/update_pkg"));
            File.Delete(String.Concat(OUTPUT_ROOT, "/update_pkg.manifest"));

            File.Delete("Assets/res_config.txt");
            File.Delete("Assets/res_config.grt");

            AssetDatabase.Refresh();


            EditorUtility.DisplayDialog("成功", "打包完成!", "确定");
        }
Пример #11
0
        /// <summary>
        /// 反序列化ResouceConfigFile
        /// </summary>
        /// <param name="_file_path"></param>
        /// <param name="_bytes"></param>
        /// <param name="_create_if_err"></param>
        /// <returns></returns>
        private static ResConfigFile _deserialize(String _file_path, Byte[] _bytes, Boolean _create_if_err)
        {
            ResConfigFile res_config = new ResConfigFile()
            {
                m_file_path = _file_path
            };

            try
            {
                using (MemoryStream memory_stream = new MemoryStream(_bytes))
                {
                    using (StreamReader reader = new StreamReader(memory_stream, Encoding.UTF8))
                    {
                        if (!Equals(Encoding.UTF8, reader.CurrentEncoding))
                        {
                            throw new ConfigFileNotUTF8("AssetsConfig file with {0} encoding not UTF-8!", reader.CurrentEncoding.EncodingName);
                        }

                        if (reader.EndOfStream)
                        {
                            return(res_config);
                        }
                        Int32 line_count = 0;
                        while (!reader.EndOfStream)
                        {
                            String line = reader.ReadLine();
                            if (String.IsNullOrEmpty(line))
                            {
                                continue;
                            }
                            line_count++;
                            String[] parts = line.Split('\t');
//#if UNITY_EDITOR
//							if( parts.Length != 8 && parts.Length != 9 )
//#else
//							if( parts.Length != 8 )
//#endif
//								throw new Exception( "Assetsinfo size error" );

                            String        name          = parts[0];
                            Int64         size          = Int64.Parse(parts[1], NumberStyles.None);
                            Int32         version       = Int32.Parse(parts[2]);
                            AssetLocation location      = Configuration.ParseEnum <AssetLocation>(parts[3]);
                            String        sha1          = parts[4];
                            String        md5           = parts[5];
                            UInt32        crc32         = UInt32.Parse(parts[6], NumberStyles.None);
                            ResourceType  resource_type = Configuration.ParseEnum <ResourceType>(parts[7]);
                            ResInfo       res           = new ResInfo(name, size, version, sha1, md5, crc32, location, resource_type);
#if UNITY_EDITOR
                            if (parts.Length == 9)
                            {
                                res.AssetBundleTypeTreeHash = parts[8];
                            }
#endif
                            // 处理版本号
                            if (version > res_config.ResVersion)
                            {
                                res_config.ResVersion = version;
                            }
                            res_config.m_assets.Add(res);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (_create_if_err)
                {
                    Log.Error("解析 AssetsConfig 文件失败!  创建新文件");
                    return(new ResConfigFile()
                    {
                        m_file_path = _file_path
                    });
                }
                Log.Error("解析 AssetsConfig 文件失败!\tMessage: {0}\nStackTrace: {1} {2}", e.Message, e.StackTrace, e.ToString());
                res_config = null;
            }
            return(res_config);
        }