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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -8,33 +11,24 @@ namespace NadekoBot.Core.Modules.Gambling.Common
|
|||||||
{
|
{
|
||||||
public class CurrencyRaffleGame
|
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 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)
|
if (amount < 1)
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
_amount = amount;
|
_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;
|
||||||
|
|
||||||
}
|
return true;
|
||||||
|
|
||||||
public void ForceStop()
|
|
||||||
{
|
|
||||||
lock (_locker)
|
|
||||||
{
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
using NadekoBot.Common.Attributes;
|
using NadekoBot.Common.Attributes;
|
||||||
using NadekoBot.Core.Modules.Gambling.Services;
|
using NadekoBot.Core.Modules.Gambling.Services;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Discord;
|
||||||
|
using System;
|
||||||
|
using NadekoBot.Core.Services;
|
||||||
|
using NadekoBot.Extensions;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling
|
namespace NadekoBot.Modules.Gambling
|
||||||
{
|
{
|
||||||
@ -8,13 +12,34 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
{
|
{
|
||||||
public class CurrencyRaffleCommands : NadekoSubmodule<CurrencyRaffleService>
|
public class CurrencyRaffleCommands : NadekoSubmodule<CurrencyRaffleService>
|
||||||
{
|
{
|
||||||
|
private readonly IBotConfigProvider _bc;
|
||||||
|
|
||||||
|
public CurrencyRaffleCommands(IBotConfigProvider bc)
|
||||||
|
{
|
||||||
|
_bc = bc;
|
||||||
|
}
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
public async Task RaffleCur(int amount)
|
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 System.Threading.Tasks;
|
||||||
using NadekoBot.Core.Services;
|
using NadekoBot.Core.Services;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using NadekoBot.Core.Modules.Gambling.Common;
|
using NadekoBot.Core.Modules.Gambling.Common;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Linq;
|
||||||
|
using NadekoBot.Common;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Discord;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace NadekoBot.Core.Modules.Gambling.Services
|
namespace NadekoBot.Core.Modules.Gambling.Services
|
||||||
{
|
{
|
||||||
public class CurrencyRaffleService : INService
|
public class CurrencyRaffleService : INService
|
||||||
{
|
{
|
||||||
|
public enum JoinErrorType {
|
||||||
|
NotEnoughCurrency,
|
||||||
|
AlreadyJoined
|
||||||
|
}
|
||||||
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
||||||
private readonly DbService _db;
|
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;
|
_db = db;
|
||||||
|
_cs = cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task JoinOrCreateGame(ulong channelId, string username,
|
public async Task<(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, Func<IUser, int, Task> onEnded)
|
||||||
ulong userId)
|
|
||||||
{
|
{
|
||||||
await _locker.WaitAsync().ConfigureAwait(false);
|
await _locker.WaitAsync().ConfigureAwait(false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var newGame = false;
|
||||||
|
if (!Games.TryGetValue(channelId, out var crg))
|
||||||
|
{
|
||||||
|
newGame = true;
|
||||||
|
crg = new CurrencyRaffleGame(amount);
|
||||||
|
}
|
||||||
using (var uow = _db.UnitOfWork)
|
using (var uow = _db.UnitOfWork)
|
||||||
{
|
{
|
||||||
//remove money
|
//remove money, and stop the game if this
|
||||||
if (!await _cs.RemoveAsync(userId, "Currency Raffle Join", _amount).ConfigureAwait(false))
|
// user created it and doesn't have the money
|
||||||
return false;
|
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 (!crg.AddUser(user))
|
||||||
if (_users.Add((username, userId)))
|
{
|
||||||
return false;
|
await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false);
|
||||||
return true;
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
@ -884,5 +884,8 @@
|
|||||||
"administration_restarting": "Restarting.",
|
"administration_restarting": "Restarting.",
|
||||||
"customreactions_edit_fail": "Custom reaction with that ID does not exist.",
|
"customreactions_edit_fail": "Custom reaction with that ID does not exist.",
|
||||||
"searches_streaming": "Streaming",
|
"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": [
|
"usage": [
|
||||||
"{0}execsql UPDATE Currency SET Amount=Amount+1234"
|
"{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