Пример #1
0
        public static async Task <PatchData> DownloadFromUrl(string url)
        {
            UnityWebRequest request = await FinalPatchUtility.WebRequestGet(url);

            if (request == null)
            {
                return(null);
            }

            try
            {
                PatchData patchData = null;
                using (MemoryStream ms = new MemoryStream(request.downloadHandler.data))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(PatchData));
                    patchData = serializer.Deserialize(ms) as PatchData;
                }
                return(patchData);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                return(null);
            }
        }
Пример #2
0
        private void CopyToStreamingAssets(BuildVersion buildVersion)
        {
            m_outputPlatformPath = string.Format($"{FinalPatchConst.ROOT_PATH}/{buildVersion.name}");
            m_outputFullPath     = FinalPatchUtility.GetOutputFullPath(m_outputPlatformPath, buildVersion.version);
            // copy asset bundles
            foreach (var file in Directory.GetFiles(m_outputFullPath, "*", SearchOption.AllDirectories))
            {
                string fileName = Path.GetFileName(file);
                if (fileName == FinalPatchConst.PATCH_DATA_FILE_NAME)
                {
                    continue;
                }

                string toPath = $"Assets/StreamingAssets/{FinalPatchConst.ASSET_BUNDLE_SUBDIRECTORY_NAME}{file.Remove(0, m_outputFullPath.Length)}";
                string toDir  = Path.GetDirectoryName(toPath);
                if (!Directory.Exists(toDir))
                {
                    Directory.CreateDirectory(toDir);
                }

                File.Copy(file, toPath, true);
            }

            PatchData patchData = PatchData.LoadAtPath(FinalPatchUtility.GetFullPatchDataFilePath(m_outputPlatformPath, buildVersion.version));

            patchData.SaveToStreamingAssets();
            AssetDatabase.Refresh();
        }
Пример #3
0
        private static async Task <bool> DownloadBundle(PatchReport patchReport, BundleData bundleData)
        {
            string url = $"{patchReport.ChannelData.URL}/{patchReport.ChannelData.Build}/{bundleData.Version}/{bundleData.Name}";

            Debug.Log($"Downloading Bundle:'{url}'");
            UnityWebRequest request = await FinalPatchUtility.WebRequestGet(url);

            if (request == null)
            {
                return(false);
            }

            //Save
            string path          = FinalPatchUtility.GetPersistentBundlePath(bundleData.Name);
            string saveDirectory = Path.GetDirectoryName(path);

            if (!Directory.Exists(saveDirectory))
            {
                Directory.CreateDirectory(saveDirectory);
            }
            using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                fs.Write(request.downloadHandler.data, 0, request.downloadHandler.data.Length);
            }
            patchReport.PatchedSize += bundleData.Size;
            patchReport.ClientData.UpdateBundle(bundleData.Name);
            return(true);
        }
Пример #4
0
        private void Build(BuildVersion buildVersion, int newVersion)
        {
            m_outputPlatformPath = string.Format($"{FinalPatchConst.ROOT_PATH}/{buildVersion.name}");
            m_outputFullPath     = FinalPatchUtility.GetOutputFullPath(m_outputPlatformPath, newVersion);
            m_outputPackagePath  = FinalPatchUtility.GetOutputPackagePath(m_outputPlatformPath, newVersion);
            if (Validate(newVersion))
            {
                AssetDatabase.SaveAssets();
                IBuildEditorCallback callback = CreateBuildCallback();
                BuildBundles(buildVersion, newVersion);
                callback?.OnBuildFullFinished(buildVersion);

                if (newVersion == 1)
                {
                    BuildFullPackage(newVersion);
                }
                else
                {
                    BuildIncrementalPackage(newVersion);
                }
                callback?.OnBuildPackageFinished(buildVersion);

                Debug.Log(Localization.GetString("msg_build_success"));
            }
        }
Пример #5
0
        public static ClientData GetOrCreate(bool allowObsolete)
        {
            ClientData clientData = ClientData.LoadAtPath(FinalPatchUtility.GetPersistentClientDataPath());

            if (clientData != null && (allowObsolete || !clientData.IsObsolete))
            {
                return(clientData);
            }

            return(new ClientData());
        }
Пример #6
0
        private bool Validate(int version)
        {
            bool validation = true;

            if (version > 1)
            {
                // check previous version file
                string previousVersionPath = $"{FinalPatchUtility.GetFullPatchDataFilePath(m_outputPlatformPath, version - 1)}";
                if (!File.Exists(previousVersionPath))
                {
                    Debug.LogError(Localization.GetString("msg_build_failure_no_previous_patch_data"));
                    validation = false;
                }
            }

            if (!validation)
            {
                m_managerWindow.ShowNotification(new GUIContent(Localization.GetString("msg_build_failure_notification")));
            }
            return(validation);
        }
Пример #7
0
        private static async Task <DeployData> DownloadDeployData()
        {
            UnityWebRequest request = await FinalPatchUtility.WebRequestGet(s_deployDataUrl);

            if (request == null)
            {
                return(null);
            }

            try
            {
                using (MemoryStream ms = new MemoryStream(request.downloadHandler.data))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(DeployData));
                    return(serializer.Deserialize(ms) as DeployData);
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                return(null);
            }
        }
Пример #8
0
        private void BuildIncrementalPackage(int version)
        {
            if (Directory.Exists(m_outputPackagePath))
            {
                Directory.Delete(m_outputPackagePath, true);
            }
            Directory.CreateDirectory(m_outputPackagePath);

            // copy current version bundle files
            foreach (var bundle in PatchData.LoadAtPath($"{FinalPatchUtility.GetFullPatchDataFilePath(m_outputPlatformPath, version)}").Bundles)
            {
                if (bundle.Version != version)
                {
                    continue;
                }

                string fromPath = $"{m_outputFullPath}/{bundle.Name}";
                string toPath   = $"{m_outputPackagePath}/{bundle.Name}";
                CopyBundle(fromPath, toPath);
            }

            // copy patch data
            File.Copy($"{m_outputFullPath}/{FinalPatchConst.PATCH_DATA_FILE_NAME}", $"{m_outputPackagePath}/{FinalPatchConst.PATCH_DATA_FILE_NAME}", true);
        }
Пример #9
0
 public void SaveToPersistent()
 {
     Save(FinalPatchUtility.GetPersistentPatchDataPath());
 }
Пример #10
0
 public void SaveToStreamingAssets()
 {
     Save(FinalPatchUtility.GetStreamingAssetsPatchDataPath());
 }
Пример #11
0
        public static async Task <PatchReport> Collect()
        {
            PatchReport patchReport = new PatchReport();

            if (s_data.applyEditorMode)
            {
                Debug.Log("Patched in Editor Mode");
                patchReport.Result = PatchResult.Success;
                return(patchReport);
            }

            DeployData deployData = await DownloadDeployData();

            if (deployData == null)
            {
                Debug.LogErrorFormat("Deploy Data Not Found");
                patchReport.Result = PatchResult.Failure_NotFoundDeployData;
                return(patchReport);
            }

            ChannelData channelData = deployData.Channels.Find(c => c.Name == s_channel);

            if (channelData == null)
            {
                Debug.LogErrorFormat("Channel Not Found:'{0}'", s_channel);
                patchReport.Result = PatchResult.Failure_NotFoundChannel;
                return(patchReport);
            }

            if (channelData.Version == 0)
            {
                Debug.Log("No patch released");
                patchReport.Result = PatchResult.Success;
                return(patchReport);
            }

            string    patchDataUrl    = $"{channelData.URL}/{channelData.Build}/{channelData.Version}/{FinalPatchConst.PATCH_DATA_FILE_NAME}";
            PatchData serverPatchData = await PatchData.DownloadFromUrl(patchDataUrl);

            if (serverPatchData == null)
            {
                Debug.LogErrorFormat("Patch Data Not Found:'{0}'", patchDataUrl);
                patchReport.Result = PatchResult.Failure_NotFoundServerPatchData;
                return(patchReport);
            }

            PatchData persistentPatchData = PatchData.LoadAtPath(FinalPatchUtility.GetPersistentPatchDataPath());
            PatchData packagePatchData    = PatchData.LoadAtPath(FinalPatchUtility.GetStreamingAssetsPatchDataPath());

            if (packagePatchData?.Hash == serverPatchData.Hash)
            {
                // use package bundles
                Debug.LogFormat("Newest Package Version:'{0}[{1}]'", channelData.Build, channelData.Version);
                if (persistentPatchData != null)
                {
                    // reset build
                    persistentPatchData.Build = null;
                    persistentPatchData.SaveToPersistent();

                    // set client data obsolete
                    ClientData persistentClientData = ClientData.LoadAtPath(FinalPatchUtility.GetPersistentClientDataPath());
                    persistentClientData.IsObsolete = true;
                    persistentClientData.SaveToPersistent();
                }
                patchReport.Result = PatchResult.Success;
                return(patchReport);
            }

            if (persistentPatchData != null)
            {
                if (persistentPatchData.Build == null)
                {
                    persistentPatchData.Build = channelData.Build;
                }

                if (persistentPatchData.Build != channelData.Build)
                {
                    Debug.LogErrorFormat("Current Build Is Out Of Date:'{0}[{1}]'", persistentPatchData.Build, channelData.Version);
                    patchReport.Result = PatchResult.Failure_OutOfDate;
                    return(patchReport);
                }
            }

            ClientData clientData = ClientData.GetOrCreate(true);

            if (persistentPatchData?.Hash == serverPatchData.Hash)
            {
                Debug.LogFormat("Newest Version:'{0}[{1}]'", channelData.Build, channelData.Version);
                if (clientData.IsObsolete)
                {
                    clientData.IsObsolete = false;
                    clientData.SaveToPersistent();
                }
                patchReport.Result = PatchResult.Success;
                return(patchReport);
            }

            patchReport.PatchBundles = new List <BundleData>();
            foreach (var serverBundle in serverPatchData.Bundles)
            {
                BundleData packageBundle = packagePatchData?.Bundles?.Find((bundle) => bundle.Name == serverBundle.Name);

                if (packageBundle?.Hash == serverBundle.Hash)
                {
                    continue;
                }

                BundleData persistentBundle = persistentPatchData?.Bundles?.Find((bundle) => bundle.Name == serverBundle.Name);
                if (persistentBundle?.Hash != serverBundle.Hash)
                {
                    patchReport.PatchBundles.Add(serverBundle);
                    patchReport.TotalSize += serverBundle.Size;
                }
                persistentPatchData?.Bundles?.Remove(persistentBundle);
            }

            patchReport.DeleteBundles = new List <BundleData>();
            if (persistentPatchData != null)
            {
                foreach (var persistentBundle in persistentPatchData.Bundles)
                {
                    patchReport.DeleteBundles.Add(persistentBundle);
                }
            }

            patchReport.ServerPatchData = serverPatchData;
            patchReport.ClientData      = clientData;
            patchReport.ChannelData     = channelData;
            patchReport.Result          = PatchResult.Collected;
            return(patchReport);
        }
Пример #12
0
        private PatchData SavePatchData(string build, int version)
        {
            var bundleFiles = Directory.GetFiles(m_outputFullPath, "*", SearchOption.AllDirectories);

            PatchData currentPatchData = new PatchData
            {
                Build   = build,
                Bundles = new List <BundleData>()
            };

            SHA1 hashAlgorithm = SHA1.Create();

            foreach (var file in bundleFiles)
            {
                string generalFile = file.Replace('\\', '/');
                string bundleName  = generalFile.Remove(0, m_outputFullPath.Length + 1);
                string hash        = null;
                long   size        = 0;
                try
                {
                    using (FileStream fs = File.Open(generalFile, FileMode.Open, FileAccess.Read))
                    {
                        hash = BitConverter.ToString(hashAlgorithm.ComputeHash(fs)).Replace("-", string.Empty);
                        size = fs.Length;
                    }
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    continue;
                }

                BundleData bundleData = new BundleData()
                {
                    Name    = bundleName,
                    Hash    = hash.ToString(),
                    Size    = size,
                    Version = version,
                };
                currentPatchData.Bundles.Add(bundleData);
            }

            // calc bundle version
            PatchData prevPatchData = PatchData.LoadAtPath($"{FinalPatchUtility.GetFullPatchDataFilePath(m_outputPlatformPath, version - 1)}");

            if (prevPatchData != null)
            {
                foreach (var currentBundle in currentPatchData.Bundles)
                {
                    BundleData prevBundle = prevPatchData.Bundles.Find((bundle) => bundle.Name == currentBundle.Name);
                    if (prevBundle == null)
                    {
                        continue;
                    }

                    if (currentBundle.Hash == prevBundle.Hash)
                    {
                        currentBundle.Version = prevBundle.Version;
                    }
                }
            }

            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(ms, currentPatchData);
                ms.Seek(0, SeekOrigin.Begin);
                currentPatchData.Hash = BitConverter.ToString(hashAlgorithm.ComputeHash(ms)).Replace("-", string.Empty);
            }
            currentPatchData.Save($"{FinalPatchUtility.GetFullPatchDataFilePath(m_outputPlatformPath, version)}");
            return(currentPatchData);
        }