Пример #1
0
        public async Task <bool> AddAsync(SporeServerAsset asset, SporeServerUser author, string comment)
        {
            try
            {
                var assetComment = new SporeServerAssetComment()
                {
                    Author = author,
                    Asset  = asset,
                    // comments on your own creations are automatically approved
                    Approved  = (author.Id == asset.AuthorId),
                    Timestamp = DateTime.Now,
                    Comment   = comment
                };

                await _context.AssetComments.AddAsync(assetComment);

                await _context.SaveChangesAsync();

                _logger.LogInformation($"AddAsync: Added Comment {assetComment.CommentId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"AddAsync: Failed To Add Comment For {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #2
0
        public async Task <bool> ReserveAsync(SporeServerUser user)
        {
            try
            {
                // create new empty asset
                var asset = new SporeServerAsset()
                {
                    Used   = false,
                    Author = user
                };

                // add it to assets
                await _context.Assets.AddAsync(asset);

                await _context.SaveChangesAsync();

                // update user
                user.NextAssetId = asset.AssetId;
                await _userManager.UpdateAsync(user);

                _logger.LogInformation($"ReserveAsync: Reserved Asset {asset.AssetId} For User {user.Id}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"ReserveAsync: Failed To Reserve Asset For User {user.Id}: {e}");
                return(false);
            }
        }
Пример #3
0
        public async Task <bool> AddAsync(SporeServerUser author, SporeServerAsset asset, bool rating)
        {
            try
            {
                var assetRating = new SporeServerRating()
                {
                    Author    = author,
                    Asset     = asset,
                    Timestamp = DateTime.Now,
                    Rating    = rating
                };

                await _context.AssetRatings.AddAsync(assetRating);

                await _context.SaveChangesAsync();

                // update asset rating
                await UpdateAssetRatingAsync(asset);

                _logger.LogInformation($"AddAsync: Added Rating {assetRating.RatingId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"AddAsync: Failed To Add Rating For {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #4
0
        public async Task <bool> DeleteAsync(SporeServerAsset asset)
        {
            try
            {
                var files = GetAssetFiles(asset.AssetId);

                // delete files
                foreach (string file in new string[] { files.ModelFile,
                                                       files.ThumbFile,
                                                       files.ImageFile,
                                                       files.ImageFile2,
                                                       files.ImageFile3,
                                                       files.ImageFile4 })
                {
                    if (File.Exists(file))
                    {
                        File.Delete(file);
                    }
                }

                // update database
                _context.Assets.Remove(asset);
                await _context.SaveChangesAsync();

                _logger.LogInformation($"DeleteAsync: Deleted Asset {asset.AssetId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"DeleteAsync: Failed To Delete Asset {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #5
0
        /// <summary>
        ///     Updates asset rating
        /// </summary>
        /// <param name="asset"></param>
        /// <returns></returns>
        private async Task <bool> UpdateAssetRatingAsync(SporeServerAsset asset)
        {
            try
            {
                var assetRatings = await FindAllByAssetAsync(asset);

                // only update asset rating,
                // when we have more than 1 rating
                if (assetRatings != null &&
                    assetRatings.Length > 1)
                {
                    // so we calculate the rating like this:
                    // get the percentage of the positive votes,
                    // then make sure the maximum value is 10.0
                    // and the minimum is -10.0
                    int   positiveRatingCount = assetRatings.Where(r => r.Rating).Count();
                    float positivePercentage  = positiveRatingCount / (float)assetRatings.Length * 100f;
                    asset.Rating = (positivePercentage / 5) - 10;

                    // update asset
                    await _assetManager.UpdateAsync(asset);
                }

                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"UpdateAssetRatingAsync: Failed To Update Asset Rating For {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #6
0
        public async Task <bool> AddAsync(SporeServerAsset adventureAsset, SporeServerAsset captainAsset,
                                          Int32 percentageCompleted, Int32 timeInMilliseconds,
                                          SporeServerUser author)
        {
            try
            {
                var entry = new SporeServerLeaderboardEntry()
                {
                    Asset               = adventureAsset,
                    Author              = author,
                    Timestamp           = DateTime.Now,
                    PercentageCompleted = percentageCompleted,
                    TimeInMilliseconds  = timeInMilliseconds,
                    Captain             = captainAsset
                };

                await _context.LeaderboardEntries.AddAsync(entry);

                await _context.SaveChangesAsync();

                _logger.LogInformation($"AddAsync: Added Leaderboard Entry {entry.EntryId} For {entry.AuthorId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"AddAsync: Failed To Add Leaderboard Entry: {e}");
                return(false);
            }
        }
Пример #7
0
 public async Task <SporeServerRating[]> FindAllByAssetAsync(SporeServerAsset asset)
 {
     try
     {
         return(await _context.AssetRatings
                .Where(r => r.AssetId == asset.AssetId)
                .ToArrayAsync());
     }
     catch (Exception e)
     {
         _logger.LogError($"FindAllByAssetAsync: Failed To Find Ratings For {asset.AssetId}: {e}");
         return(null);
     }
 }
Пример #8
0
        public async Task <SporeServerAsset[]> GetRandomAssetsAsync(Int64 authorId, SporeModelType type)
        {
            try
            {
                // maximum of 5 assets per request
                int amountOfItems = GetRandomNumber(0, 5);

                // find only used assets which don't have the author specified by author id
                // and make sure it's the type we want
                var assets = await _context.Assets
                             .Include(a => a.Author)
                             .Where(a => a.Used &&
                                    a.AuthorId != authorId &&
                                    a.ModelType == type)
                             .ToArrayAsync();

                int assetsCount = assets.Length;

                // make sure we find some assets
                if (assetsCount == 0)
                {
                    return(null);
                }

                // adjust amountOfItems as needed
                if (assetsCount < amountOfItems)
                {
                    amountOfItems = assetsCount;
                }

                var retAssets = new SporeServerAsset[amountOfItems];

                for (int i = 0; i < amountOfItems; i++)
                {
                    int randomIndex = GetRandomNumber(0, assetsCount);
                    retAssets[i] = assets.ElementAt(randomIndex);
                }

                return(retAssets);
            }
            catch (Exception e)
            {
                _logger.LogError($"GetRandomAssets: Failed To Get random Assets: {e}");
                return(null);
            }
        }
Пример #9
0
        public async Task <bool> UpdateAsync(SporeServerAsset asset)
        {
            try
            {
                // update asset in database
                _context.Assets.Update(asset);
                await _context.SaveChangesAsync();

                _logger.LogInformation($"UpdateAsync: Updated Asset {asset.AssetId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"UpdateAsync: Failed To Update Asset {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #10
0
 public async Task <SporeServerRating> FindAsync(SporeServerUser author, SporeServerAsset asset)
 {
     try
     {
         return(await _context.AssetRatings
                .Include(r => r.Asset)
                .Where(r =>
                       r.AuthorId == author.Id &&
                       r.AssetId == asset.AssetId)
                .FirstOrDefaultAsync());
     }
     catch (Exception e)
     {
         _logger.LogError($"FindAsync: Failed To Find Rating For {asset.AssetId}: {e}");
         return(null);
     }
 }
Пример #11
0
 public async Task <SporeServerAssetComment[]> FindAllApprovedByAssetAsync(SporeServerAsset asset)
 {
     try
     {
         return(await _context.AssetComments
                .Include(c => c.Author)
                .Where(c =>
                       c.AssetId == asset.AssetId &&
                       c.Approved)
                .OrderByDescending(c => c.Timestamp)
                .Take(10)
                .ToArrayAsync());
     }
     catch (Exception e)
     {
         _logger.LogError($"FindAllApprovedByAssetAsync: Failed To Find Approved Comments For {asset.AssetId}: {e}");
         return(null);
     }
 }
        public async Task <IActionResult> AssetUploadServlet([FromForm] AssetUploadForm formAsset)
        {
            Console.WriteLine($"/pollinator/public-interface/AssetUploadServlet{Request.QueryString}");

            // the game client always sends the slurp query
            // and it's always either 0 or 1
            if (!Request.Query.ContainsKey("slurp") ||
                !int.TryParse(Request.Query["slurp"], out int slurpValue) ||
                (slurpValue != 0 && slurpValue != 1))
            {
                return(Ok());
            }

            Int64 parentId = 0;

            // the game sometimes sends a parent id,
            // make sure we can parse it
            if (Request.Query.ContainsKey("parent") &&
                !Int64.TryParse(Request.Query["parent"], out parentId))
            {
                return(Ok());
            }

            SporeServerAsset parentAsset = null;

            // when parentId is not 0,
            // try to find parent asset
            if (parentId != 0)
            {
                parentAsset = await _assetManager.FindByIdAsync(parentId);
            }

            // the game always sends the type id
            // make sure we can parse it
            // and that's it a valid id
            if (!Int64.TryParse(formAsset.TypeId.TrimStart('0', 'x'),
                                NumberStyles.HexNumber,
                                null,
                                out Int64 typeId) ||
                !Enum.IsDefined(typeof(SporeAssetType), typeId))
            {
                Console.WriteLine($"invalid type id: {typeId}");
                return(Ok());
            }

            var user = await _userManager.GetUserAsync(User);

            // make sure the requested assetId is the user's nextAssetId
            if (user.NextAssetId != formAsset.AssetId)
            {
                return(Ok());
            }

            var asset = await _assetManager.FindByIdAsync(formAsset.AssetId);

            // make sure the asset exists and
            // make sure it isn't already used
            if (asset == null ||
                asset.Used)
            {
                return(Ok());
            }

            // make sure the asset doesn't go over any limits
            if ((formAsset.Description != null &&
                 formAsset.Description.Length > 256) ||
                (formAsset.ModelData != null &&
                 formAsset.ModelData.FileName.Length > 32) ||
                (formAsset.Tags != null &&
                 formAsset.Tags.Length > 256))
            {
                return(Ok());
            }

            // save the asset
            if (!await _assetManager.AddAsync(formAsset,
                                              asset,
                                              parentAsset,
                                              (slurpValue == 1),
                                              (SporeAssetType)typeId))
            {
                return(StatusCode(500));
            }

            return(Ok());
        }
Пример #13
0
        public async Task <bool> AddAsync(AssetUploadForm form, SporeServerAsset asset, SporeServerAsset parentAsset, bool slurped, SporeAssetType type)
        {
            try
            {
                var files = GetAssetFiles(form.AssetId);

                // load, validate & deserialize SporeModel
                SporeModel model    = null;
                string     modelXml = null;
                using (Stream modelStream = OpenFormFileStream(form.ModelData))
                {
                    if (!LoadSporeModel(modelStream, out model))
                    {
                        throw new Exception("LoadSporeModel Failed");
                    }
                    if (!ValidateSporeModel(model))
                    {
                        throw new Exception("ValidateSporeModel Failed");
                    }
                    if (!DeserializeSporeModel(model, out modelXml))
                    {
                        throw new Exception("DeserializeSporeModel Failed");
                    }
                }

                // save files
                File.WriteAllText(files.ModelFile, modelXml);
                await SaveFormFile(form.ThumbnailData, files.ThumbFile);

                if (form.ImageData != null)
                {
                    await SaveFormFile(form.ImageData, files.ImageFile);
                }
                if (form.ImageData_2 != null)
                {
                    await SaveFormFile(form.ImageData_2, files.ImageFile2);
                }
                if (form.ImageData_3 != null)
                {
                    await SaveFormFile(form.ImageData_3, files.ImageFile3);
                }
                if (form.ImageData_4 != null)
                {
                    await SaveFormFile(form.ImageData_4, files.ImageFile4);
                }

                // update database
                asset.Used            = true;
                asset.Timestamp       = DateTime.Now;
                asset.OriginalAssetId = 0;
                asset.ParentAssetId   = 0;
                if (parentAsset != null)
                {
                    // when original asset id of parent is 0,
                    // the parent id is the original asset id
                    // else follow the original asset id specified
                    if (parentAsset.OriginalAssetId == 0)
                    {
                        asset.OriginalAssetId = parentAsset.AssetId;
                    }
                    else
                    {
                        asset.OriginalAssetId = parentAsset.OriginalAssetId;
                    }
                    asset.ParentAssetId = parentAsset.AssetId;
                }
                asset.Name = form.ModelData.FileName;

                var tags = new List <SporeServerAssetTag>();
                if (form.Tags != null)
                {
                    foreach (string tagString in form.Tags.Split(","))
                    {
                        string trimmedTagString = tagString.TrimStart().TrimEnd();

                        tags.Add(new SporeServerAssetTag()
                        {
                            Asset = asset,
                            Tag   = trimmedTagString
                        });
                    }
                }
                asset.Tags = tags;

                var traits = new List <SporeServerAssetTrait>();
                if (form.TraitGuids != null)
                {
                    foreach (string traitString in form.TraitGuids.Split(","))
                    {
                        string trimmedTraitString = traitString.TrimStart()
                                                    .TrimStart('0', 'x')
                                                    .TrimEnd();

                        Int64 traitType = Int64.Parse(trimmedTraitString, NumberStyles.HexNumber);

                        // make sure the trait id is valid
                        if (!Enum.IsDefined(typeof(SporeAssetTraitType), traitType))
                        {
                            throw new Exception($"Invalid Trait Id: {traitType}");
                        }

                        traits.Add(new SporeServerAssetTrait()
                        {
                            Asset     = asset,
                            TraitType = (SporeAssetTraitType)traitType
                        });
                    }
                }
                asset.Traits = traits;

                asset.Description = form.Description;
                asset.Size        = form.ThumbnailData.Length;
                asset.Slurped     = slurped;
                // TODO, put this in a struct or whatever?
                asset.ModelFileUrl  = GetRelativeUrlFromPath(files.ModelFile);
                asset.ThumbFileUrl  = GetRelativeUrlFromPath(files.ThumbFile);
                asset.ImageFileUrl  = GetRelativeUrlFromPath(files.ImageFile);
                asset.ImageFile2Url = GetRelativeUrlFromPath(files.ImageFile2);
                asset.ImageFile3Url = GetRelativeUrlFromPath(files.ImageFile3);
                asset.ImageFile4Url = GetRelativeUrlFromPath(files.ImageFile4);
                asset.ModelType     = (SporeModelType)model.Properties.ModelType;
                asset.Type          = type;
                _context.Assets.Update(asset);
                await _context.SaveChangesAsync();

                _logger.LogInformation($"AddAsync: Added Asset {asset.AssetId}");
                return(true);
            }
            catch (Exception e)
            {
                _logger.LogError($"AddAsync: Failed To Add Asset {asset.AssetId}: {e}");
                return(false);
            }
        }
Пример #14
0
        /// <summary>
        ///     Creates an ATOM feed entry for the given asset
        /// </summary>
        /// <param name="document"></param>
        /// <param name="asset"></param>
        public static void AddAssetFeedEntry(XmlDocument document, SporeServerAsset asset)
        {
            // <entry />
            //
            var entryFeed = AtomFeedBuilder.AddFeedEntry(document,
                                                         id: $"tag:spore.com,2006:asset/{asset.AssetId}",
                                                         title: $"{asset.Name}",
                                                         updated: asset.Timestamp,
                                                         subtitle: null,
                                                         authorName: $"{asset.Author.UserName}",
                                                         authorUri: $"{asset.Author.Id}",
                                                         subCount: null,
                                                         link: null);

            // <locale />
            // TODO
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "locale", "en_US");
            // <modeltype />
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "modeltype", $"0x{((Int64)asset.ModelType):x2}");

            // <sp:stats />
            // TODO
            if (asset.Type == SporeAssetType.Adventure)
            {
                var statsElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:stats");

                // <sp:stat name="playcount" />
                var statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "playcount");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
                // <sp:stat name="difficulty" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "difficulty");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
                // <sp:stat name="rating" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", $"{asset.Rating}");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "rating");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "float");
                // <sp:stat name="pointvalue" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "pointvalue");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
            }

            // <sp:images />
            //
            if (asset.Type == SporeAssetType.Adventure)
            {
                var imagesElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:images", null);

                // <sp:image_1 />
                if (asset.ImageFileUrl != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_1",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFileUrl}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_2 />
                if (asset.ImageFile2Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_2",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile2Url}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_3 />
                if (asset.ImageFile3Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_3",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile3Url}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_4 />
                if (asset.ImageFile4Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_4",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile4Url}",
                                                   type: "image/png",
                                                   length: null);
                }
            }

            // <sp:ownership />
            //
            var ownershipElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:ownership");
            // <sp:original />
            var originalElement = AtomFeedBuilder.AddCustomElement(document, ownershipElement, "sp:original", $"{asset.OriginalAssetId}");

            AtomFeedBuilder.AddCustomAttribute(document, originalElement, "name", "id");
            AtomFeedBuilder.AddCustomAttribute(document, originalElement, "type", "int");
            // <sp:parent />
            var parentElement = AtomFeedBuilder.AddCustomElement(document, ownershipElement, "sp:parent", $"{asset.ParentAssetId}");

            AtomFeedBuilder.AddCustomAttribute(document, parentElement, "name", "id");
            AtomFeedBuilder.AddCustomAttribute(document, parentElement, "type", "int");

            // <content />
            //
            var contentElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "content");

            AtomFeedBuilder.AddCustomAttribute(document, contentElement, "type", "html");
            // <img />
            var imgElement = AtomFeedBuilder.AddCustomElement(document, contentElement, "img");

            AtomFeedBuilder.AddCustomAttribute(document, imgElement, "src", $"https://static.spore.com/{asset.ThumbFileUrl}");

            // <link />
            //
            AtomFeedBuilder.AddLinkElement(document, entryFeed,
                                           rel: "enclosure",
                                           url: $"https://static.spore.com/{asset.ThumbFileUrl}",
                                           type: "image/png",
                                           length: $"{asset.Size}");

            // <link />
            //
            AtomFeedBuilder.AddLinkElement(document, entryFeed,
                                           rel: "enclosure",
                                           url: $"https://static.spore.com/{asset.ModelFileUrl}",
                                           type: $"application/x-{asset.Type.ToString().ToLower()}+xml",
                                           length: null);

            // <summary />
            //
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "summary", $"{asset.Description}");

            // <category />
            //
            if (asset.Tags != null)
            {
                for (int i = 0; i < asset.Tags.Count; i++)
                {
                    // <category scheme="tag" term="tag1" />
                    // <category scheme="tag" term=" tag2" />
                    var tag             = asset.Tags.ElementAt(i);
                    var categoryElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "category");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "scheme", "tag");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "term", $"{(i == 0 ? "" : " ")}{tag.Tag}");
                }
            }
            if (asset.Traits != null)
            {
                foreach (var trait in asset.Traits)
                {
                    // <category scheme="consequence" term="0x2b35f523" />
                    var categoryElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "category");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "scheme", "consequence");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "term", $"0x{(Int64)trait.TraitType:x}");
                }
            }
        }