Currency Raffle almost done.
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
using NadekoBot.Core.Services;
|
||||
using Discord;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Core.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -8,33 +11,24 @@ namespace NadekoBot.Core.Modules.Gambling.Common
|
||||
{
|
||||
public class CurrencyRaffleGame
|
||||
{
|
||||
private readonly HashSet<(string, ulong)> _users = new HashSet<(string, ulong)>();
|
||||
private readonly HashSet<IUser> _users = new HashSet<IUser>();
|
||||
public IEnumerable<IUser> Users => _users;
|
||||
private readonly int _amount;
|
||||
private readonly CurrencyService _cs;
|
||||
private readonly DbService _db;
|
||||
private bool running;
|
||||
|
||||
public CurrencyRaffleGame(int amount, CurrencyService cs, DbService db)
|
||||
public CurrencyRaffleGame(int amount)
|
||||
{
|
||||
if (amount < 1)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
_amount = amount;
|
||||
_cs = cs;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public async Task<bool> AddUser(string username, ulong userId)
|
||||
public bool AddUser(IUser usr)
|
||||
{
|
||||
if (!_users.Add(usr))
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public void ForceStop()
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
using NadekoBot.Common.Attributes;
|
||||
using NadekoBot.Core.Modules.Gambling.Services;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using System;
|
||||
using NadekoBot.Core.Services;
|
||||
using NadekoBot.Extensions;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
@ -8,13 +12,34 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
public class CurrencyRaffleCommands : NadekoSubmodule<CurrencyRaffleService>
|
||||
{
|
||||
private readonly IBotConfigProvider _bc;
|
||||
|
||||
public CurrencyRaffleCommands(IBotConfigProvider bc)
|
||||
{
|
||||
_bc = bc;
|
||||
}
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
public async Task RaffleCur(int amount)
|
||||
{
|
||||
if (_service.Games.TryAdd(Context.Channel.Id,
|
||||
))
|
||||
async Task OnEnded(IUser arg, int won)
|
||||
{
|
||||
await ReplyConfirmLocalized("rafflecur_ended", _bc.BotConfig.CurrencyName, Format.Bold(arg.ToString()), won + _bc.BotConfig.CurrencySign);
|
||||
}
|
||||
var res = await _service.JoinOrCreateGame(Context.Channel.Id,
|
||||
Context.User, amount, OnEnded)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (res.Item1 != null)
|
||||
{
|
||||
await Context.Channel.SendConfirmAsync(GetText("rafflecur_joined", Context.User.ToString()),
|
||||
string.Join("\n", res.Item1.Users)).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Item2 == CurrencyRaffleService.JoinErrorType.AlreadyJoined)
|
||||
await ReplyErrorLocalized("rafflecur_already_joined").ConfigureAwait(false);
|
||||
else if (res.Item2 == CurrencyRaffleService.JoinErrorType.NotEnoughCurrency)
|
||||
await ReplyErrorLocalized("not_enough").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,86 @@
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Core.Services;
|
||||
using System.Collections.Concurrent;
|
||||
using NadekoBot.Core.Modules.Gambling.Common;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
using NadekoBot.Common;
|
||||
using System.Collections.Generic;
|
||||
using Discord;
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Core.Modules.Gambling.Services
|
||||
{
|
||||
public class CurrencyRaffleService : INService
|
||||
{
|
||||
public enum JoinErrorType {
|
||||
NotEnoughCurrency,
|
||||
AlreadyJoined
|
||||
}
|
||||
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
||||
private readonly DbService _db;
|
||||
private readonly CurrencyService _cs;
|
||||
|
||||
public ConcurrentDictionary<ulong, CurrencyRaffleGame> Games { get; }
|
||||
public Dictionary<ulong, CurrencyRaffleGame> Games { get; } = new Dictionary<ulong, CurrencyRaffleGame>();
|
||||
|
||||
public CurrencyRaffleService(DbService db)
|
||||
public CurrencyRaffleService(DbService db, CurrencyService cs)
|
||||
{
|
||||
_db = db;
|
||||
_cs = cs;
|
||||
}
|
||||
|
||||
public async Task JoinOrCreateGame(ulong channelId, string username,
|
||||
ulong userId)
|
||||
public async Task<(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, 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(amount);
|
||||
}
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
//remove money
|
||||
if (!await _cs.RemoveAsync(userId, "Currency Raffle Join", _amount).ConfigureAwait(false))
|
||||
return false;
|
||||
}
|
||||
//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);
|
||||
}
|
||||
|
||||
//add to to list
|
||||
if (_users.Add((username, userId)))
|
||||
return false;
|
||||
return true;
|
||||
if (!crg.AddUser(user))
|
||||
{
|
||||
await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false);
|
||||
return (null, JoinErrorType.AlreadyJoined);
|
||||
}
|
||||
}
|
||||
if (newGame)
|
||||
{
|
||||
var _t = new Timer(async state =>
|
||||
{
|
||||
await _locker.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var users = crg.Users.ToArray();
|
||||
var rng = new NadekoRandom();
|
||||
var usr = users[rng.Next(0, users.Length)];
|
||||
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
await _cs.AddAsync(usr.Id, "Currency Raffle Win",
|
||||
amount * users.Length, uow);
|
||||
}
|
||||
Games.Remove(channelId, out _);
|
||||
var oe = onEnded(usr, users.Length * amount);
|
||||
}
|
||||
catch { }
|
||||
finally { _locker.Release(); }
|
||||
|
||||
}, null, 30000, Timeout.Infinite);
|
||||
}
|
||||
return (crg, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
Reference in New Issue
Block a user