Пример #1
0
        public FileInfo Download(ChildrenBeatmap beatmap)
        {
            var req = new FileWebRequest(
                _tmpStorage.GetFullPath(beatmap.BeatmapId.ToString(), true),
                $"https://osu.ppy.sh/osu/{beatmap.BeatmapId}");

            _limiter.Limit();

            req.Perform();

            FileInfo info;

            using (var f = _tmpStorage.GetStream(beatmap.BeatmapId.ToString(), FileAccess.Read, FileMode.Open))
                using (var db = _cache.GetForWrite())
                {
                    info = _store.Add(f);

                    if (db.Context.CacheBeatmaps.Any(bm => bm.BeatmapId == beatmap.BeatmapId))
                    {
                        db.Context.CacheBeatmaps.Update(new Beatmap {
                            BeatmapId = beatmap.BeatmapId, Hash = info.Hash, FileMd5 = f.ComputeMD5Hash()
                        });
                    }
                    else
                    {
                        db.Context.CacheBeatmaps.Add(new Beatmap {
                            BeatmapId = beatmap.BeatmapId, Hash = info.Hash, FileMd5 = f.ComputeMD5Hash()
                        });
                    }
                }

            _tmpStorage.Delete(beatmap.BeatmapId.ToString());

            return(info);
        }
Пример #2
0
        private static void Populate(FileStore <ExampleProduct> store, int n)
        {
            for (int i = 0; i < n; ++i)
            {
                var product = new ExampleProduct
                {
                    Id    = Guid.NewGuid(),
                    Name  = "Whatever",
                    Price = 12.00M
                };

                store.Add(product);
            }
        }
Пример #3
0
        /// <summary>
        /// Create all required <see cref="FileInfo"/>s for the provided archive, adding them to the global file store.
        /// </summary>
        private List <TFileModel> createFileInfos(ArchiveReader reader, FileStore files)
        {
            var fileInfos = new List <TFileModel>();

            // import files to manager
            foreach (string file in reader.Filenames)
            {
                using (Stream s = reader.GetStream(file))
                    fileInfos.Add(new TFileModel
                    {
                        Filename = FileSafety.PathStandardise(file),
                        FileInfo = files.Add(s)
                    });
            }

            return(fileInfos);
        }
Пример #4
0
        /// <summary>
        /// Create all required <see cref="FileInfo"/>s for the provided archive, adding them to the global file store.
        /// </summary>
        private List <BeatmapSetFileInfo> createFileInfos(ArchiveReader reader, FileStore files)
        {
            List <BeatmapSetFileInfo> fileInfos = new List <BeatmapSetFileInfo>();

            // import files to manager
            foreach (string file in reader.Filenames)
            {
                using (Stream s = reader.GetStream(file))
                    fileInfos.Add(new BeatmapSetFileInfo
                    {
                        Filename = file,
                        FileInfo = files.Add(s)
                    });
            }

            return(fileInfos);
        }
Пример #5
0
        public static void Main(string[] args)
        {
            var store = new FileStore <ExampleProduct>();

            Console.Write($"Populating store with {N} objects... ");
            Console.WriteLine("{0}ms", BenchmarkMs(() => Populate(store, N)));

            Console.Write($"Saving store with {N} objects to disk... ");
            Console.WriteLine("{0}ms", BenchmarkMs(store.Save));

            Console.Write($"Clearing store with {N} objects from disk... ");
            Console.WriteLine("{0}ms", BenchmarkMs(store.ClearAndSave));

            Console.Write($"Saving store with {N} objects to disk (on each add)... ");
            store.FileAdded += (s, e) => store.Save(); // VERY SLOW
            Console.WriteLine("{0}ms", BenchmarkMs(() => Populate(store, N)));

            Console.Write($"Searching store with {N} objects... ");
            store.Add(new ExampleProduct
            {
                Id    = Guid.NewGuid(),
                Name  = "WhateverCheaper",
                Price = 11.00M // will be the last (!) and only product with this price
            });
            ExampleProduct foundProduct = null;

            Console.Write("{0}ms - ", BenchmarkMs(()
                                                  => foundProduct = store.Where(p => p.Price == 11.00M).FirstOrDefault()));
            Console.WriteLine(foundProduct);

            var store2 = new FileStore <ExampleProduct>(); // uses the same file on disk

            Console.Write($"Loading store with {N} objects from disk... ");
            Console.WriteLine("{0}ms", BenchmarkMs(store2.Load));

            Console.Write($"Removing last file from store with {N} objects... ");
            store2.FileRemoved += (s, e) => store2.Save();
            Console.WriteLine("{0}ms", BenchmarkMs(() => store2.Remove(foundProduct)));
        }
Пример #6
0
 public void Save()
 {
     if (!StringUtility.IsNullOrEmpty(this.StorageRoot))
     {
         try
         {
             using (var fileStream = new FileStream(this._filePath, FileMode.Create))
             {
                 if (this != null)
                 {
                     lock (this._bindingSync)
                     {
                         FileStore store = new FileStore();
                         foreach (BindingLease lease in this._assignedTable.Values)
                         {
                             FileStore item = new FileStore();
                             item.ClientId   = lease.ClientId;
                             item.Owner      = lease.Owner.ToArray();
                             item.Address    = lease.Address.ToArray();
                             item.HostName   = lease.HostName;
                             item.Expiration = lease.Expiration;
                             item.SessionId  = lease.SessionId;
                             item.State      = lease.State;
                             store.Add(item);
                         }
                         byte[] serializedData = Reflection.Serialize(store, typeof(FileStore));
                         fileStream.Write(serializedData, 0, serializedData.Length);
                         fileStream.Close();
                     }
                 }
             }
         }
         catch (Exception ex)
         {
             Logger.WriteError(this, "Error Message:" + ex.Message.ToString(), ex);
         }
     }
 }
Пример #7
0
        /// <summary>
        /// Import a beamap into our local <see cref="FileStore"/> storage.
        /// If the beatmap is already imported, the existing instance will be returned.
        /// </summary>
        /// <param name="files">The store to import beatmap files to.</param>
        /// <param name="beatmaps">The store to import beatmaps to.</param>
        /// <param name="reader">The beatmap archive to be read.</param>
        /// <returns>The imported beatmap, or an existing instance if it is already present.</returns>
        private BeatmapSetInfo importToStorage(FileStore files, BeatmapStore beatmaps, ArchiveReader reader)
        {
            // let's make sure there are actually .osu files to import.
            string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));

            if (string.IsNullOrEmpty(mapName))
            {
                throw new InvalidOperationException("No beatmap files found in the map folder.");
            }

            // for now, concatenate all .osu files in the set to create a unique hash.
            MemoryStream hashable = new MemoryStream();

            foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
            {
                using (Stream s = reader.GetStream(file))
                    s.CopyTo(hashable);
            }

            var hash = hashable.ComputeSHA2Hash();

            // check if this beatmap has already been imported and exit early if so.
            var beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.Hash == hash);

            if (beatmapSet != null)
            {
                undelete(beatmaps, files, beatmapSet);

                // ensure all files are present and accessible
                foreach (var f in beatmapSet.Files)
                {
                    if (!storage.Exists(f.FileInfo.StoragePath))
                    {
                        using (Stream s = reader.GetStream(f.Filename))
                            files.Add(s, false);
                    }
                }

                // todo: delete any files which shouldn't exist any more.

                return(beatmapSet);
            }

            List <BeatmapSetFileInfo> fileInfos = new List <BeatmapSetFileInfo>();

            // import files to manager
            foreach (string file in reader.Filenames)
            {
                using (Stream s = reader.GetStream(file))
                    fileInfos.Add(new BeatmapSetFileInfo
                    {
                        Filename = file,
                        FileInfo = files.Add(s)
                    });
            }

            BeatmapMetadata metadata;

            using (var stream = new StreamReader(reader.GetStream(mapName)))
                metadata = Decoder.GetDecoder(stream).DecodeBeatmap(stream).Metadata;


            // check if a set already exists with the same online id.
            if (metadata.OnlineBeatmapSetID != null)
            {
                beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.OnlineBeatmapSetID == metadata.OnlineBeatmapSetID);
            }

            if (beatmapSet == null)
            {
                beatmapSet = new BeatmapSetInfo
                {
                    OnlineBeatmapSetID = metadata.OnlineBeatmapSetID,
                    Beatmaps           = new List <BeatmapInfo>(),
                    Hash     = hash,
                    Files    = fileInfos,
                    Metadata = metadata
                }
            }
            ;


            var mapNames = reader.Filenames.Where(f => f.EndsWith(".osu"));

            foreach (var name in mapNames)
            {
                using (var raw = reader.GetStream(name))
                    using (var ms = new MemoryStream()) //we need a memory stream so we can seek and shit
                        using (var sr = new StreamReader(ms))
                        {
                            raw.CopyTo(ms);
                            ms.Position = 0;

                            var     decoder = Decoder.GetDecoder(sr);
                            Beatmap beatmap = decoder.DecodeBeatmap(sr);

                            beatmap.BeatmapInfo.Path    = name;
                            beatmap.BeatmapInfo.Hash    = ms.ComputeSHA2Hash();
                            beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();

                            var existing = beatmaps.Beatmaps.FirstOrDefault(b => b.Hash == beatmap.BeatmapInfo.Hash || beatmap.BeatmapInfo.OnlineBeatmapID != null && b.OnlineBeatmapID == beatmap.BeatmapInfo.OnlineBeatmapID);

                            if (existing == null)
                            {
                                // Exclude beatmap-metadata if it's equal to beatmapset-metadata
                                if (metadata.Equals(beatmap.Metadata))
                                {
                                    beatmap.BeatmapInfo.Metadata = null;
                                }

                                RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);

                                // TODO: this should be done in a better place once we actually need to dynamically update it.
                                beatmap.BeatmapInfo.Ruleset        = ruleset;
                                beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;

                                beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
                            }
                        }
            }

            return(beatmapSet);
        }
Пример #8
0
        /// <summary>
        /// Import a beamap into our local <see cref="FileStore"/> storage.
        /// If the beatmap is already imported, the existing instance will be returned.
        /// </summary>
        /// <param name="reader">The beatmap archive to be read.</param>
        /// <returns>The imported beatmap, or an existing instance if it is already present.</returns>
        private BeatmapSetInfo importToStorage(ArchiveReader reader)
        {
            // let's make sure there are actually .osu files to import.
            string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));

            if (string.IsNullOrEmpty(mapName))
            {
                throw new InvalidOperationException("No beatmap files found in the map folder.");
            }

            // for now, concatenate all .osu files in the set to create a unique hash.
            MemoryStream hashable = new MemoryStream();

            foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
            {
                using (Stream s = reader.GetStream(file))
                    s.CopyTo(hashable);
            }

            var hash = hashable.ComputeSHA2Hash();

            // check if this beatmap has already been imported and exit early if so.
            BeatmapSetInfo beatmapSet;

            lock (beatmaps)
                beatmapSet = beatmaps.QueryAndPopulate <BeatmapSetInfo>(b => b.Hash == hash).FirstOrDefault();

            if (beatmapSet != null)
            {
                Undelete(beatmapSet);
                return(beatmapSet);
            }

            List <BeatmapSetFileInfo> fileInfos = new List <BeatmapSetFileInfo>();

            // import files to manager
            foreach (string file in reader.Filenames)
            {
                using (Stream s = reader.GetStream(file))
                    fileInfos.Add(new BeatmapSetFileInfo
                    {
                        Filename = file,
                        FileInfo = files.Add(s)
                    });
            }

            BeatmapMetadata metadata;

            using (var stream = new StreamReader(reader.GetStream(mapName)))
                metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;

            beatmapSet = new BeatmapSetInfo
            {
                OnlineBeatmapSetID = metadata.OnlineBeatmapSetID,
                Beatmaps           = new List <BeatmapInfo>(),
                Hash     = hash,
                Files    = fileInfos,
                Metadata = metadata
            };

            var mapNames = reader.Filenames.Where(f => f.EndsWith(".osu"));

            foreach (var name in mapNames)
            {
                using (var raw = reader.GetStream(name))
                    using (var ms = new MemoryStream()) //we need a memory stream so we can seek and shit
                        using (var sr = new StreamReader(ms))
                        {
                            raw.CopyTo(ms);
                            ms.Position = 0;

                            var     decoder = BeatmapDecoder.GetDecoder(sr);
                            Beatmap beatmap = decoder.Decode(sr);

                            beatmap.BeatmapInfo.Path    = name;
                            beatmap.BeatmapInfo.Hash    = ms.ComputeSHA2Hash();
                            beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();

                            // TODO: Diff beatmap metadata with set metadata and leave it here if necessary
                            beatmap.BeatmapInfo.Metadata = null;

                            // TODO: this should be done in a better place once we actually need to dynamically update it.
                            beatmap.BeatmapInfo.Ruleset        = rulesets.Query <RulesetInfo>().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID);
                            beatmap.BeatmapInfo.StarDifficulty = rulesets.Query <RulesetInfo>().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID)?.CreateInstance()?.CreateDifficultyCalculator(beatmap)
                                                                 .Calculate() ?? 0;

                            beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
                        }
            }

            return(beatmapSet);
        }
Пример #9
0
 public void Save()
 {
     if (!StringUtility.IsNullOrEmpty(this.StorageRoot))
     {
         try
         {
             using (var fileStream = new FileStream(this._filePath, FileMode.Create))
             {
                 if (this != null)
                 {
                     lock (this._bindingSync)
                     {
                         FileStore store = new FileStore();
                         foreach (BindingLease lease in this._assignedTable.Values)
                         {
                             FileStore item = new FileStore();
                             item.ClientId = lease.ClientId;
                             item.Owner = lease.Owner.ToArray();
                             item.Address = lease.Address.ToArray();
                             item.HostName = lease.HostName;
                             item.Expiration = lease.Expiration;
                             item.SessionId = lease.SessionId;
                             item.State = lease.State;
                             store.Add(item);
                         }
                         byte[] serializedData = Reflection.Serialize(store, typeof(FileStore));
                         fileStream.Write(serializedData, 0, serializedData.Length);
                         fileStream.Close();
                     }
                 }
             }
         }
         catch (Exception ex)
         {
             Logger.WriteError(this, "Error Message:" + ex.Message.ToString(), ex);
         }
     }
 }