mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-04-30 03:22:04 -04:00
450 lines
15 KiB
C#
450 lines
15 KiB
C#
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using KfChatDotNetBot.Services;
|
|
|
|
namespace KfChatDotNetBot.Models.DbModels;
|
|
|
|
public class GamblerDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID fo the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// User that this gambler entity is associated with.
|
|
/// A user can have multiple associated gambler entities, but only one should be active
|
|
/// </summary>
|
|
public required UserDbModel User { get; set; }
|
|
/// <summary>
|
|
/// Gambler's balance. It can be negative if an admin has forced them into an overdraft
|
|
/// Values are fractional, it is NOT stored as cents, therefore 100.00 KKK is stored as "100" in the database
|
|
/// </summary>
|
|
public required decimal Balance { get; set; }
|
|
/// <summary>
|
|
/// What state the gambler entity is in
|
|
/// </summary>
|
|
public required GamblerState State { get; set; } = GamblerState.Active;
|
|
/// <summary>
|
|
/// The seed value given to any instance of Random that's associated with the gambler
|
|
/// </summary>
|
|
[MaxLength(256)]
|
|
public required string RandomSeed { get; set; }
|
|
/// <summary>
|
|
/// When the gambler entity was created
|
|
/// </summary>
|
|
public required DateTimeOffset Created { get; set; }
|
|
/// <summary>
|
|
/// Reference value for total wagered during the entity's lifetime
|
|
/// This value is recalculated whenever the bot restarts to ensure integrity
|
|
/// </summary>
|
|
public required decimal TotalWagered { get; set; }
|
|
/// <summary>
|
|
/// Wager requirement for the next VIP level
|
|
/// If TotalWagered reaches this value, it'll trigger the calculation
|
|
/// </summary>
|
|
public required decimal NextVipLevelWagerRequirement { get; set; }
|
|
}
|
|
|
|
public class TransactionDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID fo the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Gambler whose balance was affected by this transaction
|
|
/// </summary>
|
|
public required GamblerDbModel Gambler { get; set; }
|
|
/// <summary>
|
|
/// Source of the transaction event
|
|
/// </summary>
|
|
public required TransactionSourceEventType EventSource { get; set; }
|
|
/// <summary>
|
|
/// Time when the event occurred
|
|
/// </summary>
|
|
public required DateTimeOffset Time { get; set; }
|
|
/// <summary>
|
|
/// Time represented as a 64-bit UNIX epoch
|
|
/// This just exists to make it far more efficient to query a range of txns
|
|
/// as then we can use native SQLite dialect to select e.g. last 24 hours
|
|
/// instead of copying thousands of rows into memory and using LINQ
|
|
/// </summary>
|
|
public required long TimeUnixEpochSeconds { get; set; }
|
|
/// <summary>
|
|
/// Effect of the transaction, plus or minus
|
|
/// </summary>
|
|
public required decimal Effect { get; set; }
|
|
/// <summary>
|
|
/// Optional descriptive comment for the transaction. e.g. "Win from wager [id]", "Balance adjustment by Avenue", "Juicer from Null", etc.
|
|
/// </summary>
|
|
public string? Comment { get; set; } = null;
|
|
/// <summary>
|
|
/// Sender of the transaction in the case of a juicer, null otherwise
|
|
/// </summary>
|
|
public GamblerDbModel? From { get; set; } = null;
|
|
/// <summary>
|
|
/// Snapshot of the gambler's balance after this transaction's effect was applied
|
|
/// </summary>
|
|
public required decimal NewBalance { get; set; }
|
|
}
|
|
|
|
public class WagerDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID fo the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Gambler who wagered
|
|
/// </summary>
|
|
public required GamblerDbModel Gambler { get; set; }
|
|
/// <summary>
|
|
/// Time they wagered
|
|
/// </summary>
|
|
public required DateTimeOffset Time { get; set; }
|
|
/// <summary>
|
|
/// Time represented as a 64-bit UNIX epoch
|
|
/// This just exists to make it far more efficient to query a range of wagers
|
|
/// as then we can use native SQLite dialect to select e.g. last 24 hours
|
|
/// instead of copying thousands of rows into memory and using LINQ
|
|
/// </summary>
|
|
public required long TimeUnixEpochSeconds { get; set; }
|
|
/// <summary>
|
|
/// Amount the gambler wagered
|
|
/// </summary>
|
|
public required decimal WagerAmount { get; set; }
|
|
/// <summary>
|
|
/// Effect of the wager on the gambler's balance
|
|
/// </summary>
|
|
public required decimal WagerEffect { get; set; }
|
|
/// <summary>
|
|
/// Game they played to wager the amount (Note: enum must be extended for any new games.
|
|
/// Don't remove games which are legacy from the enum, just give them the Obsolete attribute)
|
|
/// </summary>
|
|
public required WagerGame Game { get; set; }
|
|
/// <summary>
|
|
/// Multiplier, e.g. 10.5x if a $1 wager paid out $10.50. 0 if it was a complete loss
|
|
/// </summary>
|
|
public required decimal Multiplier { get; set; }
|
|
/// <summary>
|
|
/// An optional field to store serialized information about the game that was played
|
|
/// </summary>
|
|
public string? GameMeta { get; set; } = null;
|
|
/// <summary>
|
|
/// Whether the results of the wager have been realized yet (i.e., is the game 'complete'?)
|
|
/// This is useful for wagers related to bets on the outcome of events
|
|
/// For incomplete bets: set the effect to -wager, subtract it from the user's balance, generate a txn for the wager
|
|
/// Then when the outcome of the bet is fully realized, modify the effect accordingly, generate a new txn for the
|
|
/// payout and set a multiplier based on the win (if any)
|
|
/// </summary>
|
|
public required bool IsComplete { get; set; }
|
|
}
|
|
|
|
public class GamblerExclusionDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID fo the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Gambler who is excluded
|
|
/// </summary>
|
|
public required GamblerDbModel Gambler { get; set; }
|
|
/// <summary>
|
|
/// When the exclusion expires
|
|
/// </summary>
|
|
public required DateTimeOffset Expires { get; set; }
|
|
/// <summary>
|
|
/// When the exclusion was created / began
|
|
/// </summary>
|
|
public required DateTimeOffset Created { get; set; }
|
|
/// <summary>
|
|
/// What triggered the exclusion
|
|
/// </summary>
|
|
public required ExclusionSource Source { get; set; }
|
|
}
|
|
|
|
public class GamblerPerkDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID fo the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Gambler entity the perk is associated with
|
|
/// </summary>
|
|
public required GamblerDbModel Gambler { get; set; }
|
|
/// <summary>
|
|
/// Name of the perk
|
|
/// </summary>
|
|
[MaxLength(256)]
|
|
public required string PerkName { get; set; }
|
|
/// <summary>
|
|
/// Time when the perk was attained
|
|
/// </summary>
|
|
public required DateTimeOffset Time { get; set; }
|
|
/// <summary>
|
|
/// Optional metadata associated with the perk
|
|
/// </summary>
|
|
public string? Metadata { get; set; } = null;
|
|
/// <summary>
|
|
/// What type of perk is this
|
|
/// </summary>
|
|
public required GamblerPerkType PerkType { get; set; }
|
|
/// <summary>
|
|
/// The tier the perk is at.
|
|
/// If tiers are not applicable, set to null
|
|
/// </summary>
|
|
public int? PerkTier { get; set; }
|
|
/// <summary>
|
|
/// The payout from this perk, if any. If none, set to null
|
|
/// </summary>
|
|
public decimal? Payout { get; set; }
|
|
}
|
|
|
|
public class KasinoShopProfileDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID for the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Shop profiles belong to a user, not their gambler ID
|
|
/// they persist even if the user abandons their profile
|
|
/// </summary>
|
|
public required UserDbModel User { get; set; }
|
|
public required List<KasinoShopProfileAssetDbModel> Assets { get; set; }
|
|
public required List<KasinoShopProfileLoanDbModel> Loans { get; set; }
|
|
}
|
|
|
|
public class KasinoShopProfileLoanDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID for the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
// Foreign key that the powers that be told me I need for the fancy navigation property
|
|
public int ProfileId { get; set; }
|
|
/// <summary>
|
|
/// Profile of the user who owns this loan
|
|
/// </summary>
|
|
public required KasinoShopProfileDbModel Profile { get; set; }
|
|
// Foreign key that the powers that be told me I need for the fancy navigation property
|
|
public int PayableToId { get; set; }
|
|
/// <summary>
|
|
/// Profile of the user to whom this loan is owed/payable to
|
|
/// </summary>
|
|
public required KasinoShopProfileDbModel PayableTo { get; set; }
|
|
/// <summary>
|
|
/// Amount loaned
|
|
/// </summary>
|
|
public required decimal Amount { get; set; }
|
|
/// <summary>
|
|
/// Amount to be paid out to the loaner
|
|
/// </summary>
|
|
public required decimal PayoutAmount { get; set; }
|
|
/// <summary>
|
|
/// Date and time loan entry was created
|
|
/// </summary>
|
|
public required DateTimeOffset Created { get; set; }
|
|
}
|
|
|
|
public class KasinoShopProfileAssetDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID for the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Profile of the user who owns this asset
|
|
/// </summary>
|
|
public required KasinoShopProfileDbModel Profile { get; set; }
|
|
/// <summary>
|
|
/// Value of the item at the time of acquisition in Krypto
|
|
/// </summary>
|
|
public required decimal OriginalValue { get; set; }
|
|
/// <summary>
|
|
/// Asset name
|
|
/// </summary>
|
|
public required string Name { get; set; }
|
|
/// <summary>
|
|
/// Asset type
|
|
/// </summary>
|
|
public required AssetType AssetType { get; set; }
|
|
/// <summary>
|
|
/// Date and time the asset was acquired
|
|
/// </summary>
|
|
public required DateTimeOffset Acquired { get; set; }
|
|
/// <summary>
|
|
/// History of value changes (e.g. interest events)
|
|
/// </summary>
|
|
public required List<KasinoShopProfileAssetValueChangeDbModel> ValueChangeReports { get; set; }
|
|
/// <summary>
|
|
/// Serialized JSON for extra information useful for certain assets (e.g. car model)
|
|
/// </summary>
|
|
public string? Extra { get; set; } = null;
|
|
}
|
|
|
|
public class KasinoShopProfileAssetValueChangeDbModel
|
|
{
|
|
/// <summary>
|
|
/// ID for the database row
|
|
/// </summary>
|
|
public int Id { get; set; }
|
|
/// <summary>
|
|
/// Related asset
|
|
/// </summary>
|
|
public required KasinoShopProfileAssetDbModel Asset { get; set; }
|
|
/// <summary>
|
|
/// Effect of the change
|
|
/// </summary>
|
|
public required decimal ValueChangeEffect { get; set; }
|
|
/// <summary>
|
|
/// Change percent as a decimal fraction?
|
|
/// </summary>
|
|
public required decimal ValueChangePercent { get; set; }
|
|
/// <summary>
|
|
/// Descriptive text for the value change (like the source of it)
|
|
/// </summary>
|
|
public required string Description { get; set; }
|
|
}
|
|
|
|
public enum GamblerPerkType
|
|
{
|
|
/// <summary>
|
|
/// For literally anything else, though you should probably just extend this enum
|
|
/// </summary>
|
|
Other = -1,
|
|
/// <summary>
|
|
/// Used for tracking VIP levels attained
|
|
/// </summary>
|
|
[Description("VIP Level")]
|
|
VipLevel
|
|
}
|
|
|
|
public enum ExclusionSource
|
|
{
|
|
/// <summary>
|
|
/// Exclusion as a result of the hostess' action
|
|
/// </summary>
|
|
Hostess,
|
|
/// <summary>
|
|
/// Exclusions placed by administrators
|
|
/// </summary>
|
|
Administrative
|
|
}
|
|
|
|
/// <summary>
|
|
/// What event triggered this transaction
|
|
/// </summary>
|
|
public enum TransactionSourceEventType
|
|
{
|
|
/// <summary>
|
|
/// Generic catch-all type if nothing else suits
|
|
/// </summary>
|
|
Other,
|
|
/// <summary>
|
|
/// Juice from another user. This is only for person to person transactions, use Bonus for kasino rewards
|
|
/// </summary>
|
|
Juicer,
|
|
/// <summary>
|
|
/// Transaction generated from the result of a wager
|
|
/// </summary>
|
|
Gambling,
|
|
/// <summary>
|
|
/// For recording events related to an administrative action. e.g. balance adjustments
|
|
/// </summary>
|
|
Administrative,
|
|
/// <summary>
|
|
/// Some type of bonus, like a VIP level up. Rakeback / reloads have separate enums for this
|
|
/// </summary>
|
|
Bonus,
|
|
/// <summary>
|
|
/// Specifically use for rakeback as we use the delta between last rakeback txn to calculate total wagered
|
|
/// to figure out what the next rakeback should be (if they've wagered enough to be eligible for one)
|
|
/// </summary>
|
|
Rakeback,
|
|
/// <summary>
|
|
/// Use specifically for daily reloads as we use the timing of the last reload txn to figure out if the most
|
|
/// recent reload has been claimed yet or not
|
|
/// </summary>
|
|
Reload,
|
|
/// <summary>
|
|
/// Use this only for hostess juicers as the sum of these juicers in a given day can influence the hostess' behavior
|
|
/// </summary>
|
|
Hostess,
|
|
/// <summary>
|
|
/// Specifically use for lossback as we use the delta between last lossback txn to calculate total lost
|
|
/// to figure out what the next lossback should be. (Basically return a small % of the player's losses
|
|
/// unless the player's actual position is positive during the period, then tell them to fuck off)
|
|
/// </summary>
|
|
Lossback,
|
|
/// <summary>
|
|
/// A specific form of 24 hour time-based reload that has no wager requirement
|
|
/// </summary>
|
|
DailyDollar,
|
|
///<summary>
|
|
///A form of juicer where the value is split among a number of participants
|
|
/// </summary>
|
|
Rain,
|
|
Deposit,
|
|
Withdraw,
|
|
Sponsorship,
|
|
Loan
|
|
}
|
|
|
|
public enum WagerGame
|
|
{
|
|
Limbo,
|
|
Dice,
|
|
Mines,
|
|
Planes,
|
|
[Description("Lambchop")]
|
|
LambChop,
|
|
Keno,
|
|
[Description("Coinflip")]
|
|
CoinFlip,
|
|
/// <summary>
|
|
/// This is for betting pools based on some sort of event or outcome
|
|
/// </summary>
|
|
Event,
|
|
[Description("Guess what number I'm thinking of")]
|
|
GuessWhatNumber,
|
|
Wheel,
|
|
Slots,
|
|
Blackjack,
|
|
[Description("Plinko")]
|
|
Plinko,
|
|
[Description("Roulette but live")]
|
|
Roulette,
|
|
Krash
|
|
}
|
|
|
|
public enum GamblerState
|
|
{
|
|
/// <summary>
|
|
/// Gambler entity is active and user can wager using the profile
|
|
/// </summary>
|
|
Active,
|
|
/// <summary>
|
|
/// Gambler entity has been disabled by an administrator (e.g. due to cheating)
|
|
/// The user will get a new gambler entity when they next interact with the kasino
|
|
/// </summary>
|
|
AdministrativelyDisabled,
|
|
/// <summary>
|
|
/// Gambler entity that was abandoned by the user (e.g. to escape an exclusion or crippling debt)
|
|
/// </summary>
|
|
Abandoned,
|
|
/// <summary>
|
|
/// Entity was permanently banned. This will prevent future gambler entities being created for this user
|
|
/// and will effectively lock them out of the game entirely
|
|
/// </summary>
|
|
PermanentlyBanned,
|
|
/// <summary>
|
|
/// Gambler rendered inactive by the End of Year 2025 Great Reset
|
|
/// This is treated no different to abandonment, state exists for
|
|
/// the purposes of tracking statistics later to see how much KKK
|
|
/// was erased by this event
|
|
/// </summary>
|
|
EndOfYear2025Liquidated
|
|
} |