97 lines
3.5 KiB
C#
97 lines
3.5 KiB
C#
using System.Threading.Tasks;
|
|
using NadekoBot.Core.Services;
|
|
using NadekoBot.Core.Modules.Gambling.Common;
|
|
using System.Threading;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using Discord;
|
|
using System;
|
|
|
|
namespace NadekoBot.Core.Modules.Gambling.Services
|
|
{
|
|
public class CurrencyRaffleService : INService
|
|
{
|
|
public enum JoinErrorType
|
|
{
|
|
NotEnoughCurrency,
|
|
AlreadyJoinedOrInvalidAmount
|
|
}
|
|
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
|
private readonly DbService _db;
|
|
private readonly CurrencyService _cs;
|
|
|
|
public Dictionary<ulong, CurrencyRaffleGame> Games { get; } = new Dictionary<ulong, CurrencyRaffleGame>();
|
|
|
|
public CurrencyRaffleService(DbService db, CurrencyService cs)
|
|
{
|
|
_db = db;
|
|
_cs = cs;
|
|
}
|
|
|
|
public async Task<(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, bool mixed, Func<IUser, int, Task> onEnded)
|
|
{
|
|
await _locker.WaitAsync().ConfigureAwait(false);
|
|
try
|
|
{
|
|
var newGame = false;
|
|
if (!Games.TryGetValue(channelId, out var crg))
|
|
{
|
|
newGame = true;
|
|
crg = new CurrencyRaffleGame(mixed
|
|
? CurrencyRaffleGame.Type.Mixed
|
|
: CurrencyRaffleGame.Type.Normal);
|
|
Games.Add(channelId, crg);
|
|
}
|
|
using (var uow = _db.UnitOfWork)
|
|
{
|
|
//remove money, and stop the game if this
|
|
// user created it and doesn't have the money
|
|
if (!await _cs.RemoveAsync(user.Id, "Currency Raffle Join", amount, uow).ConfigureAwait(false))
|
|
{
|
|
if (newGame)
|
|
Games.Remove(channelId);
|
|
return (null, JoinErrorType.NotEnoughCurrency);
|
|
}
|
|
|
|
if (!crg.AddUser(user, amount))
|
|
{
|
|
await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false);
|
|
return (null, JoinErrorType.AlreadyJoinedOrInvalidAmount);
|
|
}
|
|
|
|
uow.Complete();
|
|
}
|
|
if (newGame)
|
|
{
|
|
var _t = Task.Run(async () =>
|
|
{
|
|
await Task.Delay(60000).ConfigureAwait(false);
|
|
await _locker.WaitAsync().ConfigureAwait(false);
|
|
try
|
|
{
|
|
var winner = crg.GetWinner();
|
|
var won = crg.Users.Sum(x => x.Amount);
|
|
|
|
using (var uow = _db.UnitOfWork)
|
|
{
|
|
await _cs.AddAsync(winner.DiscordUser.Id, "Currency Raffle Win",
|
|
won, uow);
|
|
|
|
uow.Complete();
|
|
}
|
|
Games.Remove(channelId, out _);
|
|
var oe = onEnded(winner.DiscordUser, won);
|
|
}
|
|
catch { }
|
|
finally { _locker.Release(); }
|
|
});
|
|
}
|
|
return (crg, null);
|
|
}
|
|
finally
|
|
{
|
|
_locker.Release();
|
|
}
|
|
}
|
|
}
|
|
} |