md5文件比对 unity3d_unity3d md5 - CSDN
  • 在之前的文章中,我们提到了用ulua的热更新框架,其中最后提及了通过文件MD5比对来判断文件是否更新,假如MD5码不一致则可以判定文件发生了变化,所以需要进行更新。因此,我们需要为那些能够进行热更新的文件生成...

            在之前的文章中,我们提到了用ulua的热更新框架,其中最后提及了通过文件MD5码比对来判断文件是否更新,假如MD5码不一致则可以判定文件发生了变化,所以需要进行更新。因此,我们需要为那些能够进行热更新的文件生成对应的MD5码,每个文件都对应唯一的一个MD5码

            生成步骤:

    1.读取文件流

    2.读取文件流中的字节数据

    3.通过MD5接口生成MD5码(获得的是一个Hash字节数组)

    4.将步骤3获得的Hash字节数组转换为字符串


    关键代码如下:

            public static string getFileHash(string filePath)
            {           
                try
                {
                    FileStream fs = new FileStream(filePath, FileMode.Open);
                    int len = (int)fs.Length;
                    byte[] data = new byte[len];
                    fs.Read(data, 0, len);
                    fs.Close();
                    MD5 md5 = new MD5CryptoServiceProvider();
                    byte[] result = md5.ComputeHash(data);
                    string fileMD5 = "";
                    foreach (byte b in result)
                    {
                        fileMD5 += Convert.ToString(b, 16);
                    }
                    return fileMD5;   
                }
                catch (FileNotFoundException e)
                {
                    Console.WriteLine(e.Message);
                    return "";
                }                                 
            }
            调用的时候通过填写制定文件的完整目录,即可获得对应文件的MD5码:

             string md5 = getFileHash("E:\\MyPro\\cubetest.unity3d");

            将所有文件的MD5码都写到一个文本.txt文件中,此即为热更新文件的配置文件,每次上传新版本到服务器时,将这份文件也存放到服务器中。


            游戏检查更新的具体步骤如下:

    1.通过请求服务器获取到服务器的MD5码配置文件

    2.获取本地的MD5码配置文件

    3.逐个比对每个文件的MD5码

    4.统计MD5码不一致的文件列表

    5.从服务器下载更新文件列表中包含的文件




    展开全文
  • ///文件路径  public string GetFileHash(string filePath)  {  如果(!IsFileExist(文件路径))  {  返回””;  }  尝试  {  by...
    1. ///文件路径   
      public string GetFileHash(string filePath)
              {
                  如果(!IsFileExist(文件路径))
                  {
                      返回””;
                  }
      
                  尝试
                  {
                      byte [] data = readFile(AssetBundleReader.mWritablePath + filePath);
                      return getDataHash(data);
                  }
                  catch(FileNotFoundException e)
                      返回NULL;
                  }
              }
      

       

    1. ///文件
       public string GetDataHash(byte [] data)
              {
                  尝试
                  {
                      MD5 md5 = new MD5CryptoServiceProvider();
                      byte [] result = md5.ComputeHash(data);
                      string fileMD5 =“”;
                      的foreach(结果中的字节b)中
                      {
                          fileMD5 + = System.Convert.ToString(b,16).PadLeft(2,'0');
                      }
                      return fileMD5;
                  }
                  catch(FileNotFoundException e)
                  {
                      return null;
                  }
              }

       

       //字符串
      public string Md5Sum(string input)
        {
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));//大  "X2",小"x2"  
            }
            return sb.ToString();
          
        }
    

     

    展开全文
  • AssetBundle打包写入MD5待更新文件 using UnityEngine; using UnityEditor; using System.IO; using System.Text; using System.Collections.Generic; using LitJson; public class EditorCreateBundle : Editor ...

    AssetBundle打包写入MD5待更新文件

    using UnityEngine;
    using UnityEditor;
    using System.IO;
    using System.Text;
    using System.Collections.Generic;
    using LitJson;
    
    public class EditorCreateBundle : Editor
    {
        public static string m_BundleDirectory = Application.dataPath + "/AssetBundle/";
      
        [MenuItem("Tools/Bundle/IOS打Bundle")]
        static void BuildReleaseIOSBundle()
        {
    
            BuildBundleTest(BuildTarget.iOS);
        }
    
        [MenuItem("Tools/Bundle/Android打Bundle")]
        static void BuildReleaseAndroidBundle()
        {
           
            BuildBundleTest(BuildTarget.Android);
        }
    
        [MenuItem("Tools/Bundle/Windows64打Bundle")]
        static void BuildReleaseWindowsBundle()
        {
    
            BuildBundleTest(BuildTarget.StandaloneWindows64);
        }
    
        static void BuildBundleTest(BuildTarget target)
        {
            Caching.ClearCache();
            string[] filePaths = Directory.GetDirectories(m_BundleDirectory, "*.*", SearchOption.TopDirectoryOnly);
            string path = GetTempPath(target);
            DeleteTempBundles(target);
            SetAssetBundleName(filePaths);
            BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.ChunkBasedCompression, target);
            CreateBundleVersionNumber(path, target);
            AssetDatabase.Refresh();
        }
    
        private static Dictionary<string, string> m_BundleMD5Map = new Dictionary<string, string>();
       /// <summary>
       /// 删除目标文件夹下的所有文件
       /// </summary>
       /// <param name="target"></param>
        static void DeleteTempBundles(BuildTarget target)
        {
            string[] bundleFiles = GetAllFilesFromBundleDirectory(target);
            foreach (string s in bundleFiles)
            {
                File.Delete(s);
            }
        }
    
        static string[] GetAllFilesFromBundleDirectory(BuildTarget target)
        {
            string path = GetTempPath(target);
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            string[] bundleFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
    
            return bundleFiles;
        }
    
        static void SetAssetBundleName(string[] topDirectories)
        {
            foreach (string path in topDirectories)
            {
                string[] childPaths = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
                string childPathName, extension, directoryName;
                foreach (string childPath in childPaths)
                {
                    extension = Path.GetExtension(childPath);
                    if (extension != ".meta" && extension != ".DS_Store")
                    {
                        childPathName = Path.GetFileNameWithoutExtension(childPath);
                        directoryName = Path.GetDirectoryName(childPath).Replace("\\", "/");
    
                        AssetImporter temp = AssetImporter.GetAtPath(childPath.Replace(Application.dataPath, "Assets"));
                        temp.assetBundleName = null;
    
                        if (directoryName.ToLower().IndexOf("sprite") >= 0)
                        {
                            AssetImporter ai = AssetImporter.GetAtPath(directoryName.Replace(Application.dataPath, "Assets"));
                            ai.assetBundleName = directoryName.Replace(m_BundleDirectory, "");
                        }
                        else
                            temp.assetBundleName = directoryName.Replace(m_BundleDirectory, "") + "/" + childPathName;
                    }
                }
            }
        }
     /// <summary>获取文件的md5校验码</summary>
            static string GetMD5HashFromFile(string fileName)
            {
    
                if (File.Exists(fileName))
                {
                    FileStream file = new FileStream(fileName, FileMode.Open);
                    MD5 md5 = new MD5CryptoServiceProvider();
                    byte[] retVal = md5.ComputeHash(file);
                    file.Close();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < retVal.Length; i++)
                        sb.Append(retVal[i].ToString("x2"));
                    return sb.ToString();
                }
                return null;
            }
        static void CreateBundleVersionNumber(string bundlePath, BuildTarget target)
        {
            JsonData serverJson = new JsonData();
            string[] contents = Directory.GetFiles(bundlePath, "*.*", SearchOption.AllDirectories);
            string extension;
            string fileName = "";
            string fileMD5 = "";
            long allLength = 0;
            int fileLen;
            m_BundleMD5Map.Clear();
            for (int i = 0; i < contents.Length; i++)
            {
                fileName = contents[i].Replace(GetTempPath(target), "").Replace("\\", "/");
                extension = Path.GetExtension(contents[i]);
                if (extension != ".meta")
                {
                    fileMD5 = GetMD5HashFromFile(contents[i]);
                    fileLen = File.ReadAllBytes(contents[i]).Length;
                    allLength += fileLen;
                    m_BundleMD5Map.Add(fileName, fileMD5 + "+" + fileLen);
                }
            }
    
            JsonData files = new JsonData();
            foreach (KeyValuePair<string, string> kv in m_BundleMD5Map)
            {
                JsonData jd = new JsonData();
                jd["file"] = kv.Key;
                string[] nAndL = kv.Value.Split('+');
                jd["md5"] = nAndL[0];
                jd["fileLength"] = nAndL[1];
                files.Add(jd);
            }
            serverJson["length"] = allLength;
            serverJson["files"] = files;
    
            File.WriteAllText(GetTempPath(target) + "Bundle.txt", serverJson.ToJson());
    
            m_BundleMD5Map.Clear();
            //MiscUtils.CopyDirectory(Application.streamingAssetsPath + "/AssetBundle", Application.dataPath.Replace("Assets", ""), "*.*", true);
            //Directory.Delete(Application.streamingAssetsPath + "/AssetBundle", true);
        }
    
        static string GetTempPath(BuildTarget target)
        {
                return Application.streamingAssetsPath + "/";
        }
    }
    
    

    服务端比对版本更新

      /// <summary>
            /// 版本更新
            /// </summary>
            /// <returns></returns>
            IEnumerator VersionUpdate()
            {
    
                WWW www = new WWW(ConstantUtils.HttpDownLoadUrl + "Bundle.txt");
                yield return www;
    
                if (www.isDone && string.IsNullOrEmpty(www.error))
                {
                    List<BundleInfo> bims = new List<BundleInfo>();
                    JsonData data = JsonMapper.ToObject(www.text);
                    string md5, file, path;
                    int lenth;
                    for (int i = 0; i < data["files"].Count; i++)
                    {
                        JsonData jd = data["files"][i];
                        file = jd.TryGetstring("file");
                        path = ConstantUtils.PathUrl(file);
                        md5 = GetMD5HashFromFile(path);
                        if (string.IsNullOrEmpty(md5) || md5 != jd.TryGetstring("md5"))
                        {
                            bims.Add(new BundleInfo()
                            {
                               
                                Url = ConstantUtils.HttpDownLoadUrl +file,
                                Path = path
                            });
                            lenth = int.Parse(jd.TryGetstring("fileLength"));
                            allfilesLength += lenth;
                        }
                    }
                    if (bims.Count > 0)
                    {
                        GameObject.Find("Canvas").transform.Find("LoadPage").gameObject.SetActive(true);
                        StartCoroutine(DownLoadBundleFiles(bims, (progress) => {
                            OpenLodingShow("自动更新中...", progress, allfilesLength);
                        }, (isfinish) => {
                            if (isfinish)
                                StartCoroutine(VersionUpdateFinish());
                            else
                            {
                                LoadingPage.Instance.GetMyEvent.Invoke("部分文件更新失败,正在准备重试...");
                                StartCoroutine(VersionUpdate());
                            }
                        }));
                    }
                    else
                    {
                        //Debug.Log(ConstantUtils.DataPath("common/luascript/XLuaScript.lua.txt", _pathinfo.streamingAssetsPath));
                        StartCoroutine(VersionUpdateFinish());
                    }
                }
            }
     /// <summary>获取文件的md5校验码</summary>
            public static string GetMD5HashFromFile(string fileName)
            {
    
                if (File.Exists(fileName))
                {
                    FileStream file = new FileStream(fileName, FileMode.Open);
                    MD5 md5 = new MD5CryptoServiceProvider();
                    byte[] retVal = md5.ComputeHash(file);
                    file.Close();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < retVal.Length; i++)
                        sb.Append(retVal[i].ToString("x2"));
                    return sb.ToString();
                }
                return null;
            }
     public LuaEnv LuaEnvt { get; private set; }
           
            Action StartLua;
            Action UpdateLua;
            Action DestoryLua;
      IEnumerator VersionUpdateFinish()
            {
               // LoadingNode.instance.Close();
                GameObject.Find("Canvas").transform.Find("LoadPage").gameObject.SetActive(false);
    //登录验证...执行lua文件
                 LuaEnvt = new LuaEnv();
                TextAsset texts = Singleton<UIManager>.singleton.GetBundleFile<TextAsset>("Lua/FirstLua.lua", "FirstLua.lua");
                LuaEnvt.DoString(texts.text);
                StartLua = LuaEnvt.Global.Get<Action>("start");
    
                UpdateLua = LuaEnvt.Global.Get<Action>("update");
                DestoryLua = LuaEnvt.Global.Get<Action>("ondestroy");
                yield return new WaitForEndOfFrame();
                if (StartLua != null)
                    StartLua();
                
            }
      /// <summary>
            /// 路径比对
            /// </summary>
            /// <param name="infos"></param>
            /// <param name="LoopCallBack"></param>
            /// <param name="CallBack"></param>
            /// <returns></returns>
            public IEnumerator DownLoadBundleFiles(List<BundleInfo> infos, Action<float> LoopCallBack = null, Action<bool> CallBack = null)
            {
                int num = 0;
                string dir;
                for (int i = 0; i < infos.Count; i++)
                {
                    BundleInfo info = infos[i];
                    WWW www = new WWW(info.Url);
                    yield return www;
                    if (www.isDone && string.IsNullOrEmpty(www.error))
                    {
                        try
                        {
                            string filepath = info.Path;
                            dir = Path.GetDirectoryName(filepath);
                            if (!Directory.Exists(dir))
                                Directory.CreateDirectory(dir);
                            File.WriteAllBytes(filepath, www.bytes);
                            num++;
                            if (LoopCallBack != null)
                                LoopCallBack.Invoke((float)num / infos.Count);
                        }
                        catch (Exception e)
                        {
                            Debug.Log("下载失败pp");
    
                        }
                    }
                    else
                    {
                        Debug.Log("没有进去");
    
                    }
                }
                if (CallBack != null)
                    CallBack.Invoke(num == infos.Count);
            }
            /// <summary>
            /// 记录信息
            /// </summary>
            public struct BundleInfo
            {
                public string Path { get; set; }
                public string Url { get; set; }
                public override bool Equals(object obj)
                {
                    return obj is BundleInfo && Url == ((BundleInfo)obj).Url;
                }
                public override int GetHashCode()
                {
                    return Url.GetHashCode();
                }
            }
            /// <summary>
            /// loadpage展示
            /// </summary>
            /// <param name="text"></param>
            /// <param name="progress"></param>
            /// <param name="filealllength"></param>
            public static void OpenLodingShow(string text = null, float progress = 0, long filealllength = 0)
            {
                string allLength = ConstantUtils.GetMillionFromByte(filealllength).ToString("F2");
                string currlength = ConstantUtils.GetMillionFromByte((long)(filealllength * progress)).ToString("F2");
                LoadingPage.Instance.PrograssText.text = "<color=#8CF976FF>" + currlength + "MB</color>/<color=#FEE646FF>" + allLength + "MB</color>";
                LoadingPage.Instance.imagePrograss.DOFillAmount(progress, 0.5f);
                if (!string.IsNullOrEmpty(text))
                    LoadingPage.Instance.LodingDes.text = text;
                else
                    LoadingPage.Instance.LodingDes.text = text;
            }
     void Update() {
                if (UpdateLua != null)
                {
                    UpdateLua.Invoke();
                }
                if (LuaEnvt != null)
                    LuaEnvt.Tick();
            }
     
            private void OnDestroy()
            {
                if (DestoryLua != null)
                    DestoryLua();
                UpdateLua = null;
                DestoryLua = null;
                StartLua = null;
               // LuaEnvt.Dispose();
    
            }

     

    展开全文
  • Unity 打包AssetBundle文件MD5值变化问题 https://www.jianshu.com/p/a6d357cc11f7 之前打包的时候,一直没有注意,后来发现2个问题 不同电脑从SVN上更新下来同一工程,同一版本,打出的的AssetBundle文件,...

    Unity 打包AssetBundle文件的MD5值变化问题

    https://www.jianshu.com/p/a6d357cc11f7

    之前打包的时候,一直没有注意,后来发现2个问题


    • 不同电脑从SVN上更新下来同一工程,同一版本,打出的的AssetBundle文件,大量的文件Hash值和MD5值都不一致。
    • 就算是同一台电脑,有的时候场景文件(scene)的MD5值也会变,但是HASH不变。

    针对这2个问题我研究了块2个星期了。终于根据这个文章的说法:
    https://answer.uwa4d.com/question/58dd17434e69b5ed22e68ad1
    手动设置GraphicsSettings的Shader stripping 且同步了所有文件的Meta到SVN上。然后再用多台电脑,多个版本打包测试,结果是除了lua等特殊文件外,所有普通的资源文件的MD5值比较稳定,反倒是hash值在不同电脑上还是会有少量不一致的情况。
    其中同步meta这一步需要注意的是,有时候本地工程修改了meta文件,直接从SVN上更新是不会发现差异的,需要还原成SVN上的版本,或者直接把本地的修改提交。



    作者:灰的狼
    链接:https://www.jianshu.com/p/a6d357cc11f7
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

     

     

     

     

    展开全文
  • unity MD5加密

    2019-06-15 19:16:06
    不是的,它是一种信息摘要算法,它可以从一个字符串或一个文件中按照一定的规则生成一个特殊的字符串(这个特殊的字符串就被称之为摘要,我理解就是从文件中摘一些信息片段加工而来),并且一个文件所对应的MD5摘要...
  • 【参考原文】河乐不为-Unity3D 学习笔记7 —— 获取热更新资源文件MD5码 概要 在热更新时通过文件MD5比对来判断文件是否更新,假如MD5码不一致则可以判定文件发生了变化,所以需要进行更新。因此,需要为...
  • 文件MD5值是独一无二的,所以当MD5值改变时说明文件改变了 近期做移动端的断点续传正是运用到这一特性。using UnityEngine; using System.Collections; using System.Net.NetworkInformation; using System.IO; ...
  • Unity使用MD5加密

    2017-04-27 18:33:45
    使用MD5可以为任何文件产生一个独一无二的“指纹”且加密不可逆这里结合Unity使用MD5加密游戏的分数直接上代码:using UnityEngine; using System.Collections;public class scoreHandler : MonoBeha
  • UnityC# MD5验证

    2015-07-03 00:28:43
    孙广东 2014.6.24 数据经网络传输后会变得非常不安全,最简单有效的解决方案是给数据加一个密钥,使用MD5 算法算出校验码,服务器收到数据和校验码后在进行比较校验码是否正确,以此来判断数据是否修改过。...
  • 这个工具呢,博主在Unity3D游戏开发之反编译AssetBundle提取游戏资源这篇文章中其实已经提到过了,不过因为有些朋友对如何使用这个工具依然存在问题,所以博主决定特地写一篇文章来讲解如何使用disunity来提取Unity...
  • 文件格式大全 http://www.moon-soft.com/program/FORMAT/ .psd(支持alpha通道) photoshop导出和打开 .png 图片(支持alpha通道) T....1.标签图像文件格式(Tagged Image File Format,简写为TIFF) 2.
  • 很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,...
  • 美术想要一个把unity中*.asset的模型导出来,导成3D Max可以打开的模式,fbx或obj. 需要导出的格式: 图1 也就是需要一个工具,个人觉得这个问题,肯定之前Unity的前辈就有解决方法了。于是乎网上一通下载和...
  • 这里结合实际开发,记录下Unity3d中的.gitignore的配置。我们每次开一个工程的时候都需要有这样一个.gitignore文件,慢慢我们会发现这个配置文件的内容是比较固定的。比如在Unity中,我们通常会忽略掉根目录的...
  • Unity3D机器学习之环境搭建。原文链接: https://unity3d.college/2017/10/25/machine-learning-in-unity3d
  • Sqlite的应用场景 在判断是否使用存储格式为Sqlite模式的标准,我们的标准是内容只读。也就是说,除非发布者修改Sqlite内容,玩家...对于如何使用Sqlite,请参考我的另外一篇文章《Unity本地数据存储---Sqlite和JSON
  • 注意:PC端导出后不能把exe文件和相关的数据文件夹拷贝到带中文的文件目录下,不然无法加载要加载的文件Unity3D的路径问题。我们常用的是以下四个路径: Application.dataPath  Application....
  • Unity3D之如何将包大小减少到极致,图片是游戏app里最最占空间的资源,所以请各位还没有理解u3d对图片文件存储方式理解的请看《unity3d-texture图片空间和内存占用分析》。因为u3d对资源的压缩并不阐述的十分详细,...
  • Unity3D 热更新 知识

    2018-05-28 11:48:40
    373人阅读 什么是热更新呢?首先需要了解移动程序的发布流程:将程序进行打包成相应平台的程序包,就拿Appsrote平台来说,需要将程序打包成xcarchive,打包好后,上传苹果商店,上传之后,苹果商店需要进行审核...
  • 本课程是 Unity 3D 系列教程,目标是带领读者搭建一个商业游戏的网络架构设计,该架构设计是游戏的核心技术,将采用 Unity 2017.2 最新版本作为开发工具。内容分为 UI 架构、技能架构、服务器和网络同步四大部分,共...
1 2 3 4 5 ... 20
收藏数 648
精华内容 259
关键字:

md5文件比对 unity3d