Exemplo n.º 1
0
        //A temporary replacement for p2p updating
        private void updateOsz2Container()
        {
            Beatmap b = BeatmapManager.Current;

            if (b.Package == null)
            {
                throw new Exception("Can only update osz2 Packages.");
            }

            //todo: disable update button here
            AudioEngine.Stop();
            AudioEngine.FreeMusic();



            //ThreadPool.QueueUserWorkItem((o) =>
            {
                List <osu_common.Libraries.Osz2.FileInfo> fileInfoCurrent = b.Package.GetFileInfo();
                //b.Package.Close();
                MapPackage currentPackage = b.Package;
#if P2P
                if (!currentPackage.AcquireLock(20, true))
                {
                    String message = "Failed to update: Mappackage seems to be already in use.";
                    GameBase.Scheduler.Add
                        (() => NotificationManager.ShowMessage(message, Color.Cyan, 3000));
                    return;
                }
#endif

                pWebRequest getFileInfo = new pWebRequest(String.Format(Urls.OSZ2_GET_FILE_INFO,
                                                                        ConfigManager.sUsername, ConfigManager.sPassword, b.BeatmapSetId));

                status.SetStatus("Dowloading package version information");
                string fileInfoEncoded = null;
                getFileInfo.Finished += (r, exc) => { if (exc == null)
                                                      {
                                                          fileInfoEncoded = r.ResponseString;
                                                      }
                };
                try
                {
                    getFileInfo.BlockingPerform();
                }
                catch { }

                if (fileInfoEncoded == null || fileInfoEncoded.Trim() == "" || fileInfoEncoded.StartsWith("5\n"))
                {
#if P2P
                    currentPackage.Unlock();
#endif
                    String message = "Failed to update: Could not connect to the update service";
                    GameBase.Scheduler.AddDelayed
                        (() => NotificationManager.ShowMessage(message, Color.Cyan, 3000), 100);
                    return;
                }
                //decode string to FileInfo list
                string[] DatanList          = fileInfoEncoded.Split('\n');
                string[] fileInfoCollection = DatanList[0].Split('|');
                List <osu_common.Libraries.Osz2.FileInfo> fileInfoNew =
                    new List <osu_common.Libraries.Osz2.FileInfo>(fileInfoCollection.Length);

                status.SetStatus("Cross-referencing version information");
                foreach (string fileInfoEnc in fileInfoCollection)
                {
                    string[] fileInfoItems = fileInfoEnc.Split(':');
                    string   filename      = fileInfoItems[0];
                    int      offset        = Convert.ToInt32(fileInfoItems[1]);
                    int      length        = Convert.ToInt32(fileInfoItems[2]);
                    byte[]   hash          = GeneralHelper.StringToByteArray(fileInfoItems[3]);
                    DateTime dateCreated   = DateTime.FromBinary(Convert.ToInt64(fileInfoItems[4]));
                    DateTime dateModified  = DateTime.FromBinary(Convert.ToInt64(fileInfoItems[5]));
                    osu_common.Libraries.Osz2.FileInfo infoDecoded;
                    infoDecoded = new osu_common.Libraries.Osz2.FileInfo(filename, offset, length, hash, dateCreated, dateModified);

                    fileInfoNew.Add(infoDecoded);
                }


                status.SetStatus("Downloading and updating files:");
                //update all files that needs to be updated
                foreach (var fiNew in fileInfoNew)
                {
                    //if already uptodate continue
                    if (fileInfoCurrent.FindIndex((f) => f.Filename == fiNew.Filename)
                        //&& MonoTorrent.Common.Toolbox.ByteMatch(f.Hash, fiNew.Hash))
                        != -1)
                    {
                        continue;
                    }

                    //if this file is a video and this package is a no-videoversion
                    if (currentPackage.NoVideoVersion && MapPackage.IsVideoFile(fiNew.Filename))
                    {
                        continue;
                    }

                    status.SetStatus("Updating " + fiNew.Filename + "...");

                    //download the file:
                    string url = String.Format(Urls.OSZ2_GET_FILE_CONTENTS, ConfigManager.sUsername, ConfigManager.sPassword,
                                               b.BeatmapSetId, fiNew.Filename);

                    byte[]      fileContents    = null;
                    pWebRequest getFileContents = new pWebRequest(url);
                    getFileContents.Finished += (r, exc) => { if (exc == null)
                                                              {
                                                                  fileContents = r.ResponseData;
                                                              }
                    };
                    try
                    {
                        getFileContents.Perform();
                    }
                    catch { }

                    if (fileContents == null)
                    {
                        String message = String.Format("Failed to update: Dowloading {0} failed.", fiNew.Filename);
                        GameBase.Scheduler.Add
                            (() => NotificationManager.ShowMessage(message, Color.Cyan, 3300));
                        return;
                    }

                    currentPackage.AddFile(fiNew.Filename, fileContents, fiNew.CreationTime, fiNew.ModifiedTime, true);
                }

                status.SetStatus("Saving changes...");
                currentPackage.Save(true);
                Osz2Factory.CloseMapPackage(currentPackage);

                status.SetStatus("Updating metadata...");

                //get the new fileheader and replace the old
                string getHeaderUrl = String.Format(Urls.OSZ2_GET_RAW_HEADER, ConfigManager.sUsername, ConfigManager.sPassword,
                                                    b.BeatmapSetId);
                byte[]      rawHeader    = null;
                pWebRequest getHeaderRaw = new pWebRequest(getHeaderUrl);
                getHeaderRaw.Finished += (r, exc) => { if (exc == null)
                                                       {
                                                           rawHeader = r.ResponseData;
                                                       }
                };
                getHeaderRaw.Perform();

                if (rawHeader == null || rawHeader.Length < 60)
                {
                    String message = "Failed to update: recieving header failed, please try to redownload.";
                    GameBase.Scheduler.Add
                        (() => NotificationManager.ShowMessage(message, Color.Cyan, 3300));
                    return;
                }

                int dataOffset = Convert.ToInt32(DatanList[1]);
                int dataSize   = 0;
                //reorder all files to their new positions.
                fileInfoNew.ForEach((f) => { dataSize += f.Offset; });

                MapPackage.Pad(b.ContainingFolderAbsolute, fileInfoNew, dataOffset, dataOffset + dataSize);
                //write received reader
                using (FileStream osz2Package = File.Open(b.ContainingFolderAbsolute, FileMode.Open, FileAccess.Write))
                    osz2Package.Write(rawHeader, 0, rawHeader.Length);


                GameBase.Scheduler.Add(() =>
                {
                    //open package again.
                    //_package = Osz2Factory.TryOpen(ContainingFolder);
                    BeatmapImport.SignalBeatmapCheck(true);
                    BeatmapManager.ChangedPackages.Add(Path.GetFullPath(b.ContainingFolderAbsolute));
                    //BeatmapManager.CheckAndProcess(false);
                    //GameBase.ChangeModeInstant(OsuModes.BeatmapImport, false);
                });
            }
            //});
        }