Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Badge trading #231

Open
wants to merge 21 commits into
base: badge-trading
Choose a base branch
from

Conversation

Mogiiii
Copy link
Contributor

@Mogiiii Mogiiii commented Apr 26, 2021

WIP pull request for badge trading and updates to badges in general.

int amount = amountOpt.Map(i => i.Number).OrElse(1);
int form = PkmnForms.pokemonHasForms(species) ? 0 : 1; // default to the first listed form if form is unspecified
bool shiny = shinyOpt.IsPresent ? shinyOpt.Value : false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be condensed to shinyOpt.OrElse(false)

Copy link
Member

@Felk Felk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very neat so far! You have written few TODOs, but I also don't mind merging an intermediate state as long the commands aren't hooked up yet and therefore aren't part of production code

TPP.Persistence.MongoDB/Repos/BadgeBuyOfferRepo.cs Outdated Show resolved Hide resolved
TPP.Persistence.MongoDB/Repos/BadgeRepo.cs Show resolved Hide resolved
@@ -64,26 +68,55 @@ private void InitIndexes()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(above here, can't comment on the correct line).
Please add indexes for the new filterable fields.
Nitpick: Also this is fine for now, but I suspect filtering for "!= true" for the shiny field might not work properly for the index. Maybe it does, but it's something you can test if you're still motivated. E.g. by enabling profiling level 2, issuing a query, and looking at the execution plan.

TPP.Core/Commands/Definitions/OperatorCommands.cs Outdated Show resolved Hide resolved
TPP.Core/Commands/Definitions/BadgeCommands.cs Outdated Show resolved Hide resolved
TPP.Core/Commands/Definitions/BadgeCommands.cs Outdated Show resolved Hide resolved
TPP.Core/Commands/Definitions/BadgeCommands.cs Outdated Show resolved Hide resolved
TPP.Core.Tests/Commands/Definitions/BadgeCommandsTest.cs Outdated Show resolved Hide resolved
TPP.Common/PkmnForms.cs Outdated Show resolved Hide resolved
TPP.ArgsParsing/TypeParsers/ShinyParser.cs Outdated Show resolved Hide resolved
@Mogiiii Mogiiii requested a review from Felk September 17, 2021 07:34
Comment on lines 107 to 110
Badge.BadgeSource? source = sourceOpt.IsPresent ? sourceOpt.Value : null;
string? form = formOpt.IsPresent ? formOpt.Value.Name : null;
bool? shiny = shinyOpt.IsPresent ? shinyOpt.Value : false;
return (source, form, shiny);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks equivalent to

return (sourceOpt.OrElse(null), formOpt.OrElse(null), shinyOpt.OrElse(false));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also is defaulting to shiny=false correct? It's still nullable, which indicates to me you wanted it to be kind of a tri-state of "yes", "no" and "don't care whether shiny or not"

TPP.Core/Commands/Definitions/BadgeCommands.cs Outdated Show resolved Hide resolved
TPP.Core/Setups.cs Outdated Show resolved Hide resolved
TPP.Model/BadgeBuyOffer.cs Show resolved Hide resolved
TPP.Model/BadgeBuyOffer.cs Show resolved Hide resolved
Comment on lines +73 to +90
public async Task<List<BadgeBuyOffer>> FindAllBuyOffers(string? userId, PkmnSpecies species, string? form, Badge.BadgeSource? source, bool? shiny)
{
FilterDefinition<BadgeBuyOffer> filter = Builders<BadgeBuyOffer>.Filter.Empty;
if (userId != null)
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.UserId, userId);
if (species != null)
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Species, species);
if (form != null)
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Form, form);
if (source != null)
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Source, source);
if (shiny == true)
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Shiny, true);
else
filter &= Builders<BadgeBuyOffer>.Filter.Ne(b => b.Shiny, true);

return await BuyOfferCollection.Find(filter).ToListAsync();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm not sure how I feel about this duplicate code. Especially since it is a bit finnicky in regards to the shiny filter requiring to filter for "!= true". If this is equal to the variant in BadgeRepo, can it be extracted as a utility method somewhere that builds a FilterDefinition<T>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is something like a static method in Badge class what you had in mind?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like that, yeah. Just somewhere where it's namespaced somewhat sensibly

Badge badgeBForSale = new Badge("B", userId, species, source, after, form, shiny) { SellPrice = price };
List<Badge> notForSale = new List<Badge> { badgeA, badgeB };

_mockBadgeRepo.Setup(m => m.FindAllNotForSaleByCustom(userId, species, form, source, shiny)).Returns(Task.FromResult(notForSale));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc there's a ReturnsAsync that removes the need to wrap the result in Task.FromResult(...)

Comment on lines +22 to +27
internal class MockClock : IClock
{
public Instant FixedCurrentInstant = Instant.FromUnixTimeSeconds(1234567890);
public Instant GetCurrentInstant() => FixedCurrentInstant;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why I used this class somewhere in the first place. I believe it is redundant because Moq mocks should work fine

Comment on lines +186 to +190
new Transaction<User>(buyer, -1 * offer.Price, "BadgePurchase"),
new Transaction<User>(seller, offer.Price, "BadgeSale")
}
);
await _badgeRepo.TransferBadges(new List<Badge> { badge }.ToImmutableList(), buyer.Id, "BadgeSale", new Dictionary<string, object?>() { });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please put these transaction types in TransactionType

/// Sorts badges according to the priority in which they should be sold.
/// Current sorting rule: prioritize keeping 1 of each form, then sell newer badges first. Top priority badge will be selected for sale when fufilling offers.
/// </summary>
private static List<Badge> SortBySpecialness(IEnumerable<Badge> toSort)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bunch of stuff, including this, probably needs more unit tests. Maybe you'll even have to make this sorter its own thing for that to be easier

@Mogiiii Mogiiii closed this Dec 21, 2022
@m4-used-rollout m4-used-rollout changed the base branch from master to badge-trading December 21, 2022 22:10
@Mogiiii Mogiiii marked this pull request as ready for review December 21, 2022 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants