public int ChangeKey(string SourcePackage, string TargetPackage, byte[] OldKey, byte[] NewKey)
        {
            log("Changing key for {0} / {1}", SourcePackage, TargetPackage);

            string osz2FilenameOld = s3getToTemp("osz2/" + SourcePackage);
            string osz2FilenameNew = osz2FilenameOld + ".new";

            try
            {
                //ensure an existing new file doesn't existing exist.
                File.Delete(osz2FilenameNew);

                if (!File.Exists(osz2FilenameOld))
                {
                    log("couldn't find local file {0}", osz2FilenameOld);
                    return((int)UpdateResponseCode.FileDoesNotExist);
                }

                using (MapPackage oldPackage = new MapPackage(osz2FilenameOld, OldKey, false, false))
                    using (MapPackage newPackage = new MapPackage(osz2FilenameNew, NewKey, true, false))
                    {
                        Dictionary <MapMetaType, string> metaData = oldPackage.GetAllMetadata();

                        foreach (KeyValuePair <MapMetaType, string> mapMeta in metaData)
                        {
                            newPackage.AddMetadata(mapMeta.Key, mapMeta.Value);
                        }

                        List <FileInfo> fileInfo = oldPackage.GetFileInfo();
                        foreach (FileInfo fo in fileInfo)
                        {
                            using (var br = new BinaryReader(oldPackage.GetFile(fo.Filename)))
                            {
                                newPackage.AddFile(fo.Filename, br.ReadBytes((int)br.BaseStream.Length),
                                                   fo.CreationTime, fo.ModifiedTime);
                            }
                        }

                        newPackage.Save();
                    }

                s3putFile("osz2/" + TargetPackage, osz2FilenameNew);
                File.Delete(osz2FilenameNew);
            }
            catch (Exception e)
            {
                File.Delete(osz2FilenameOld);
                File.Delete(osz2FilenameNew);
                log(e);
            }

            return((int)UpdateResponseCode.UpdateSuccessful);
        }
        /// <summary>
        ///  Calls a MapPackageAction in a safe environment by catching all the exceptions
        ///  and translating them to appropiate responsecodes.
        /// </summary>
        /// <param name="Action">A MapPackageAction which updates the osz2 file in the save environment</param>
        /// <param name="MappackageFile">Path to the osz2 fileparam>
        /// <param name="Key">The key used to decrypt or encrypt the mappackage</param>
        /// <param name="SaveData">Whether to save the data after using the custom defined action on the beatmap</param>
        /// <returns>the UpdateResponseCode of the custom defined action when no exception has occured
        ///  while loading the beatmap(osz2) file, or a failed UpdateResponseCode when there has.</returns>
        private UpdateResponseCode DoMapPackageActionSafe(MapPackageAction Action, string MappackageFile, byte[] Key, bool SaveData, bool MetadataOnly)
        {
            string originalPath = MappackageFile;

            if (!File.Exists(MappackageFile))
            {
                MappackageFile = s3getToTemp("osz2/" + MappackageFile);
            }
            else
            {
                originalPath = Path.GetFileName(originalPath);
            }

            UpdateResponseCode CustomResponseCode;

            if (!File.Exists(MappackageFile))
            {
                return(UpdateResponseCode.FileDoesNotExist);
            }
            try
            {
                using (MapPackage Osz2Beatmap = new MapPackage(MappackageFile, Key, false, MetadataOnly))
                {
                    CustomResponseCode = Action(Osz2Beatmap);
                    if (CustomResponseCode == UpdateResponseCode.UpdateSuccessful && SaveData)
                    {
                        Osz2Beatmap.Save();
                    }
                    Osz2Beatmap.Close();
                }

                if (CustomResponseCode == UpdateResponseCode.UpdateSuccessful && SaveData)
                {
                    s3putFile("osz2/" + originalPath, MappackageFile);
                }
            }
            catch (IOException e)
            {
                log(e);
                return(UpdateResponseCode.Osz2Corrupted);
            }
            catch (Exception e)
            {
                log(e);
                return(UpdateResponseCode.UnknownError);
            }
            finally
            {
            }

            return(CustomResponseCode);
        }
Example #3
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);
                });
            }
            //});
        }
Example #4
0
        private static void writePackage(string oscFilename, string osz2Filename, string audioFilename, List <BeatmapDifficulty> difficulties, List <string> ordered)
        {
            bool isPreview = osz2Filename.Contains("_preview");

            int hitObjectCutoff = 0;

            using (StreamWriter output = new StreamWriter(oscFilename))
            {
                //write headers first (use first difficulty as arbitrary source)
                foreach (string l in headerContent)
                {
                    if (isPreview)
                    {
                        if (l.StartsWith("Bookmarks:") && osz2Filename.Contains("_preview"))
                        {
                            //may need to double up on bookmarks if they don't occur often often

                            List <int> switchPoints = Player.Beatmap.StreamSwitchPoints;

                            if (switchPoints.Count < 10 || switchPoints[9] > 60000)
                            {
                                string switchString = "Bookmarks:";

                                foreach (int s in switchPoints)
                                {
                                    switchString += s.ToString(nfi) + ",";
                                    switchString += s.ToString(nfi) + ","; //double bookmark hack for previews
                                }

                                output.WriteLine(switchString.Trim(','));

                                hitObjectCutoff = switchPoints.Count < 10 ? switchPoints[4] : switchPoints[9];
                                continue;
                            }
                        }
                    }

                    output.WriteLine(l);
                }

                //keep track of how many hitObject lines are remaining for each difficulty
                int[] linesRemaining = new int[difficulties.Count];
                for (int i = 0; i < difficulties.Count; i++)
                {
                    linesRemaining[i] = difficulties[i] == null ? 0 : difficulties[i].HitObjectLines.Count;
                }

                int currentTime = 0;

                while (!linesRemaining.All(i => i == 0))
                {
                    int           bestMatchDifficulty = -1;
                    HitObjectLine bestMatchLine       = null;

                    for (int i = 0; i < difficulties.Count; i++)
                    {
                        if (linesRemaining[i] == 0)
                        {
                            continue;
                        }

                        int holOffset = difficulties[i].HitObjectLines.Count - linesRemaining[i];

                        HitObjectLine line = difficulties[i].HitObjectLines[holOffset];

                        if (isPreview && hitObjectCutoff > 0 && line.Time > hitObjectCutoff)
                        {
                            linesRemaining[i]--;
                            continue;
                        }

                        if (line.Time >= currentTime && (bestMatchLine == null || line.Time < bestMatchLine.Time))
                        {
                            bestMatchDifficulty = i;
                            bestMatchLine       = line;
                        }
                    }

                    if (bestMatchLine != null)
                    {
                        output.WriteLine(bestMatchDifficulty + "," + bestMatchLine.StringRepresentation);
                        linesRemaining[bestMatchDifficulty]--;
                    }
                }
            }

            using (MapPackage package = new MapPackage(osz2Filename, true))
            {
                package.AddMetadata(MapMetaType.BeatmapSetID, "0");

                string versionsAvailable = "";
                if (ordered[0] != null)
                {
                    versionsAvailable += "|Easy";
                }
                if (ordered[1] != null)
                {
                    versionsAvailable += "|Normal";
                }
                if (ordered[2] != null)
                {
                    versionsAvailable += "|Hard";
                }
                if (ordered[3] != null)
                {
                    versionsAvailable += "|Expert";
                }
                package.AddMetadata(MapMetaType.Version, versionsAvailable.Trim('|'));

                if (string.IsNullOrEmpty(audioFilename))
                {
                    throw new Exception("FATAL ERROR: audio file not found");
                }

                package.AddFile(Path.GetFileName(oscFilename), oscFilename, DateTime.MinValue, DateTime.MinValue);
                if (isPreview)
                {
                    if (!File.Exists(audioFilename.Replace(".m4a", "_lq.m4a")))
                    {
                        Console.WriteLine("WARNING: missing preview audio file (_lq.m4a)");
                        return;
                    }

                    package.AddFile("audio.m4a", audioFilename.Replace(".m4a", "_lq.m4a"), DateTime.MinValue, DateTime.MinValue);
                }
                else
                {
                    package.AddFile(audioFilename.EndsWith(".m4a") ? "audio.m4a" : "audio.mp3", audioFilename, DateTime.MinValue, DateTime.MinValue);
                }

                string dir = Path.GetDirectoryName(audioFilename);

                string metadata = dir + "\\metadata.txt";
                if (File.Exists(metadata))
                {
                    foreach (string line in File.ReadAllLines(metadata))
                    {
                        if (line.Length == 0)
                        {
                            continue;
                        }

                        string[] var = line.Split(':');
                        string   key = string.Empty;
                        string   val = string.Empty;
                        if (var.Length > 1)
                        {
                            key = line.Substring(0, line.IndexOf(':'));
                            val = line.Substring(line.IndexOf(':') + 1).Trim();

                            MapMetaType t = (MapMetaType)Enum.Parse(typeof(MapMetaType), key, true);
                            package.AddMetadata(t, val);
                        }
                    }
                }

                if (isPreview)
                {
                    package.AddMetadata(MapMetaType.Revision, "preview");
                }

                string thumb = dir + "\\thumb-128.jpg";
                if (File.Exists(thumb))
                {
                    package.AddFile("thumb-128.jpg", thumb, DateTime.MinValue, DateTime.MinValue);
                }

                thumb = Path.GetDirectoryName(audioFilename) + "\\thumb-256.jpg";
                if (File.Exists(thumb))
                {
                    package.AddFile("thumb-256.jpg", thumb, DateTime.MinValue, DateTime.MinValue);
                }

                thumb = Path.GetDirectoryName(audioFilename) + "\\thumb-512.jpg";
                if (File.Exists(thumb))
                {
                    package.AddFile("thumb-512.jpg", thumb, DateTime.MinValue, DateTime.MinValue);
                }

                package.Save();
            }
        }