Currency Raffle almost done.
This commit is contained in:
parent
fa0b9e4f80
commit
cfee252ce3
@ -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
|
||||
{
|
||||
|
@ -884,5 +884,8 @@
|
||||
"administration_restarting": "Restarting.",
|
||||
"customreactions_edit_fail": "Custom reaction with that ID does not exist.",
|
||||
"searches_streaming": "Streaming",
|
||||
"searches_followers": "Followers"
|
||||
"searches_followers": "Followers",
|
||||
"gambling_rafflecur_joined": "User {0} joined the raffle!",
|
||||
"gambling_rafflecur_already_joined": "You have already joined this raffle.",
|
||||
"gambling_rafflecur_ended": "{0} raffle ended. {1} won {2}!"
|
||||
}
|
@ -3037,5 +3037,12 @@
|
||||
"usage": [
|
||||
"{0}execsql UPDATE Currency SET Amount=Amount+1234"
|
||||
]
|
||||
},
|
||||
"rafflecur": {
|
||||
"cmd": "rafflecur",
|
||||
"desc": "Starts a currency raffle with a specified amount. Users who join the raffle will lose the amount of currency specified and add it to the pot. After 30 seconds, random winner will be selected who will receive the whole pot.",
|
||||
"usage": [
|
||||
"{0}rafflecur 20"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user