public string GetMapContents(string Package, byte[] Key, int BeatmapID)
        {
            string             contents = null;
            UpdateResponseCode code     = DoMapPackageActionSafe(
                (M) =>
            {
                string filename = M.GetMapByID(BeatmapID);
                if (filename == string.Empty)
                {
                    return(UpdateResponseCode.FileDoesNotExist);
                }

                using (StreamReader reader = new StreamReader(M.GetFile(filename)))
                    contents = reader.ReadToEnd();

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(Convert.ToString((int)code));
            }

            return(contents);
        }
        public string GetFileInfoList(string Package, byte[] Key)
        {
            StringBuilder      fileInfoList = new StringBuilder(20 * (15 + 8 + 6 + 16 * 2));
            UpdateResponseCode code         = DoMapPackageActionSafe(
                (M) =>
            {
                List <FileInfo> list = M.GetFileInfo();
                foreach (FileInfo info in list)
                {
                    fileInfoList.AppendFormat("{0}:{1}:{2}:{3}:{4}:{5}|", info.Filename, info.Offset,
                                              info.Length, BitConverter.ToString(info.Hash).Replace("-", ""), info.CreationTime.ToBinary(),
                                              info.ModifiedTime.ToBinary());
                }
                fileInfoList.Remove(fileInfoList.Length - 1, 1);
                fileInfoList.AppendLine().Append(Convert.ToString(M.DataOffset));

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (fileInfoList.Length == 0)
            {
                return(null);
            }

            return(fileInfoList.ToString());
        }
        public int PatchMappackageWithKey(string Package, byte[] Key = null)
        {
            string Osz2PatchFilename = s3getToTemp("working/" + Package.Replace(".osz2", ".patch"), true);

            if (Osz2PatchFilename == null)
            {
                return((int)UpdateResponseCode.FileDoesNotExist);
            }

            string Osz2Filename = s3getToTemp("osz2/" + Package);

            if (Osz2Filename == null)
            {
                return((int)UpdateResponseCode.FileDoesNotExist);
            }

            string Osz2FilenameTemp = Osz2Filename + ".temp";

            if (!MapPackage.UpdateFromPatch(Osz2Filename, Osz2PatchFilename, Osz2FilenameTemp))
            {
                File.Delete(Osz2PatchFilename);
                File.Delete(Osz2FilenameTemp);
                return((int)UpdateResponseCode.UnknownError);
            }

            File.Delete(Osz2Filename);
            File.Move(Osz2FilenameTemp, Osz2Filename);

            //check if updated mappackage is valid
            UpdateResponseCode code = DoMapPackageActionSafe((M) => { return(UpdateResponseCode.UpdateSuccessful); }, Osz2Filename, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return((int)code);
            }

            //copy patched file back to the original
            try
            {
                //when replacing failed it will automaticaly be restored to the previous version
                s3putFile("osz2/" + Package, Osz2Filename);
            }
            catch (Exception e)
            {
                log(e);
                //todo add logger here
                code = UpdateResponseCode.CopyingFailed;
            }
            finally
            {
                File.Delete(Osz2PatchFilename);
            }

            return((int)code);
        }
        public byte[] GetRawOsz2Header(string Package, byte[] Key)
        {
            byte[]             header = null;
            UpdateResponseCode code   = DoMapPackageActionSafe(
                (M) =>
            {
                header = M.getRawHeader();
                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            return(header);
        }
        public byte[] GetCachedFileMd5(string Package, byte[] key, string Filename)
        {
            byte[]             hash = null;
            UpdateResponseCode code = DoMapPackageActionSafe(
                (M) =>
            {
                hash = M.GetCachedFileHash(Filename);
                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, key, false, false);

            return(hash);
        }
        public bool HasVideoData(string Package, byte[] Key)
        {
            bool hasVideo           = false;
            UpdateResponseCode code = DoMapPackageActionSafe(
                (M) =>
            {
                int offset, length;
                M.getVideoOffset(out offset, out length);
                hasVideo = offset != -1;

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            return(hasVideo);
        }
        public byte[][] GetHashes(string Package, byte[] Key)
        {
            byte[][]           hashes = new byte[2][];
            UpdateResponseCode code   = DoMapPackageActionSafe(
                (M) =>
            {
                hashes[0] = M.hash_body;
                hashes[1] = M.hash_meta;
                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, true);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(null);
            }

            return(hashes);
        }
        public int GetFilePartCount(string Package, byte[] Key, string Filename)
        {
            int count = 0;
            UpdateResponseCode code = DoMapPackageActionSafe(
                (M) =>
            {
                using (Stream file = M.GetFile(Filename, false))
                    count = (int)((file.Length - 1) / PartSize) + 1;

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return((int)code);
            }

            return(count);
        }
        public string ExtractFile(string Package, byte[] Key, string Filename)
        {
            string             newFile = String.Empty;
            UpdateResponseCode code    = DoMapPackageActionSafe(
                (M) =>
            {
                if (!M.FileExists(Filename))
                {
                    return(UpdateResponseCode.FileDoesNotExist);
                }

                int bufferSize = 1048576;
                int count;

                newFile = Package + "_" + Filename;

                using (Stream file = M.GetFile(Filename))
                    using (FileStream output = File.Open(newFile, FileMode.Create))
                    {
                        byte[] buffer = new byte[bufferSize];
                        while ((count = file.Read(buffer, 0, bufferSize)) > 0)
                        {
                            output.Write(buffer, 0, count);
                        }

                        output.Close();
                    }

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(Convert.ToString((int)code));
            }

            string filename = Path.GetFileName(newFile);

            s3putFile(@"working/" + filename, newFile, true);

            return(filename);
        }
        public string GetVideoInfo(string Package, byte[] Key)
        {
            string             videoInfo = null;
            UpdateResponseCode code      = DoMapPackageActionSafe(
                (M) =>
            {
                int offset, length;
                string name = String.Empty;
                M.getVideoOffset(out offset, out length);
                if (offset == -1)
                {
                    return(UpdateResponseCode.UpdateSuccessful);
                }

                name      = M.GetFileInfo().Find((F) => MapPackage.IsVideoFile(F.Filename)).Filename;
                videoInfo = String.Format("{0},{1},{2}", name, length, offset);

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            return(videoInfo);
        }
        public string GetMapName(string Package, byte[] Key, int BeatmapID)
        {
            string             filename = null;
            UpdateResponseCode code     = DoMapPackageActionSafe(
                (M) =>
            {
                filename = M.GetMapByID(BeatmapID);
                if (filename == string.Empty)
                {
                    return(UpdateResponseCode.FileDoesNotExist);
                }

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, true);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(null);
            }

            return(filename);
        }
        public byte[] GetMapMd5(string Package, byte[] Key, int BeatmapID)
        {
            byte[]             hash = null;
            UpdateResponseCode code = DoMapPackageActionSafe(
                (M) =>
            {
                string filename = M.GetMapByID(BeatmapID);
                if (filename == string.Empty)
                {
                    return(UpdateResponseCode.FileDoesNotExist);
                }

                hash = M.GetMapHash(filename);
                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(null);
            }

            return(hash);
        }
        public byte[] GetFileContents(string Package, byte[] Key, string Filename, int Part, bool Raw)
        {
            byte[]             chunk = null;
            UpdateResponseCode code  = DoMapPackageActionSafe(
                (M) =>
            {
                using (Stream file = M.GetFile(Filename, Raw))
                {
                    int partCount = (int)((file.Length - 1) / PartSize) + 1;
                    if (Part >= partCount)
                    {
                        return(UpdateResponseCode.PartIsOutOfBounds);
                    }

                    int partLength = (int)Math.Min((file.Length - Part * PartSize), PartSize);
                    chunk          = new byte[partLength];
                    file.Position += Part * PartSize;
                    file.Read(chunk, 0, (int)partLength);
                }
                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            return(chunk);
        }
        public string GetMapContentsByName(string Package, byte[] Key, string Filename)
        {
            string             contents = null;
            UpdateResponseCode code     = DoMapPackageActionSafe(
                (M) =>
            {
                if (!M.FileExists(Filename))
                {
                    return(UpdateResponseCode.FileDoesNotExist);
                }

                using (StreamReader reader = new StreamReader(M.GetFile(Filename)))
                    contents = reader.ReadToEnd();

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            if (code != UpdateResponseCode.UpdateSuccessful)
            {
                return(Convert.ToString((int)code));
            }

            return(contents);
        }
        public string ConvertToOsz(string Package, byte[] Key)
        {
            string tempFolder = Path.GetTempPath() + Path.GetFileNameWithoutExtension(Package) + "-" + DateTime.Now.Ticks;

            log("Converting {0} from osz2 to osz", Package);

            UpdateResponseCode code = DoMapPackageActionSafe(
                (M) =>
            {
                try
                {
                    List <FileInfo> files = M.GetFileInfo();
                    foreach (FileInfo fileInfo in files)
                    {
                        string file = fileInfo.Filename;

                        string fullPath = Path.Combine(tempFolder, file);
                        string dirName  = Path.GetDirectoryName(fullPath);

                        if (!Directory.Exists(dirName))
                        {
                            Directory.CreateDirectory(dirName);
                        }

                        DateTime fileOverrideLastWrite = File.GetLastWriteTimeUtc(fullPath);
                        System.IO.FileInfo curFileInfo = new System.IO.FileInfo(fullPath);

                        long fileOverriddenFileTime = 0;
                        long fileBaseFileTime       = 0;

                        try
                        {
                            fileOverriddenFileTime = fileOverrideLastWrite.ToFileTime();
                            fileBaseFileTime       = fileInfo.ModifiedTime.ToFileTime();
                        }
                        catch {
                        }

                        //within 4 second accuracy
                        if (Math.Abs(fileBaseFileTime - fileOverriddenFileTime) < 200000000 && curFileInfo.Length == fileInfo.Length - 4)
                        {
                            continue;
                        }

                        using (Stream fileP = M.GetFile(file))
                            using (FileStream fileC = File.Create(fullPath, (int)fileP.Length, FileOptions.WriteThrough))
                            {
                                byte[] buffer = new byte[fileP.Length];
                                fileP.Read(buffer, 0, buffer.Length);
                                fileC.Write(buffer, 0, buffer.Length);
                                fileC.Flush();
                            }

                        try
                        {
                            File.SetCreationTimeUtc(fullPath, fileInfo.CreationTime);
                            File.SetLastWriteTimeUtc(fullPath, fileInfo.ModifiedTime);
                        }
                        catch (Exception e)
                        {
                            log(e);
                            //may fail on non-existent timestamps
                        }
                    }
                }
                catch (Exception e)
                {
                    log(e);
                }

                return(UpdateResponseCode.UpdateSuccessful);
            }, Package, Key, false, false);

            string oszFilename = Package.Replace(".osz2", ".osz");

            string oszTempPath = Path.Combine(Path.GetTempPath(), oszFilename);

            File.Delete(oszTempPath);

            ZipConstants.DefaultCodePage = 932;
            FastZip fz = new FastZip();

            fz.CreateZip(oszTempPath, tempFolder, true, ".*");

            try { Directory.Delete(tempFolder, true); }
            catch (Exception e)
            {
                log(e);
            }

            s3putFile("osz/" + oszFilename, oszTempPath, true);

            return(oszFilename);
        }