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); }
//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); }); } //}); }
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(); } }