mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-05-02 04:22:04 -04:00
some sloppa fixes (#69)
* update update * service service * Optimize message retrieval in MinesCommand Refactor message handling in MinesCommand to use last message directly. * Replace LastMessageId with LastMessage object
This commit is contained in:
@@ -13,17 +13,19 @@ public class MinesCommand : ICommand
|
|||||||
{
|
{
|
||||||
public List<Regex> Patterns => [
|
public List<Regex> Patterns => [
|
||||||
//cashout
|
//cashout
|
||||||
new Regex(@"^mines(?<cashout> cashout)$", RegexOptions.IgnoreCase),
|
new Regex(@"^mines\s+cashout$", RegexOptions.IgnoreCase),
|
||||||
//refresh
|
//refresh
|
||||||
new Regex(@"^mines(?<refresh> refresh)$", RegexOptions.IgnoreCase),
|
new Regex(@"^mines\s+refresh$", RegexOptions.IgnoreCase),
|
||||||
//attempting to start a game below here
|
//start game with number of picks
|
||||||
new Regex(@"^mines (?<bet>\d+(?:\.\d+)?) (?<size>\d+) (?<mines>\d+) (?<picks>\d+)(?<cashout> cashout|)$", RegexOptions.IgnoreCase),
|
new Regex(@"^mines\s+(?<bet>\d+(?:\.\d+)?)\s+(?<size>\d+)\s+(?<mines>\d+)\s+(?<picks>\d+)(?:\s+(?<cashout>cashout))?$", RegexOptions.IgnoreCase),
|
||||||
new Regex(@"^mines (?<bet>\d+(?:\.\d+)?) (?<size>\d+) (?<mines>\d+) (?<betString>.+)(?<cashout> cashout|)$", RegexOptions.IgnoreCase),
|
//start game with coordinate string (must contain comma)
|
||||||
//attempting to continue a game below here
|
new Regex(@"^mines\s+(?<bet>\d+(?:\.\d+)?)\s+(?<size>\d+)\s+(?<mines>\d+)\s+(?<betString>\d+,\d+(?:\s+\d+,\d+)*)(?:\s+(?<cashout>cashout))?$", RegexOptions.IgnoreCase),
|
||||||
new Regex(@"^mines (?<picks>\d+)(?<cashout> cashout|)$", RegexOptions.IgnoreCase),
|
//continue game with number of picks
|
||||||
new Regex(@"^mines (?<betString>.+)(?<cashout> cashout|)$", RegexOptions.IgnoreCase),
|
new Regex(@"^mines\s+(?<picks>\d+)(?:\s+(?<cashout>cashout))?$", RegexOptions.IgnoreCase),
|
||||||
|
//continue game with coordinate string (must contain comma)
|
||||||
|
new Regex(@"^mines\s+(?<betString>\d+,\d+(?:\s+\d+,\d+)*)(?:\s+(?<cashout>cashout))?$", RegexOptions.IgnoreCase),
|
||||||
//get info
|
//get info
|
||||||
new Regex("^mines$")
|
new Regex(@"^mines$", RegexOptions.IgnoreCase)
|
||||||
];
|
];
|
||||||
public string? HelpText => "!mines <bet> <board size> <number of mines> <picks> to play simple mines. !mines <bet> <board size> <number of mines> <betString> for advanced mines. Tool: https://i.ddos.lgbt/raw/UJ9Dty.html";
|
public string? HelpText => "!mines <bet> <board size> <number of mines> <picks> to play simple mines. !mines <bet> <board size> <number of mines> <betString> for advanced mines. Tool: https://i.ddos.lgbt/raw/UJ9Dty.html";
|
||||||
public UserRight RequiredRight => UserRight.Loser;
|
public UserRight RequiredRight => UserRight.Loser;
|
||||||
@@ -63,7 +65,22 @@ public class MinesCommand : ICommand
|
|||||||
throw new InvalidOperationException($"Caught a null when retrieving gambler for {user.KfUsername}");
|
throw new InvalidOperationException($"Caught a null when retrieving gambler for {user.KfUsername}");
|
||||||
KasinoMines = new KasinoMines(botInstance, gambler.Id);
|
KasinoMines = new KasinoMines(botInstance, gambler.Id);
|
||||||
bool cashout = false;
|
bool cashout = false;
|
||||||
if (message.Message.Contains("cashout")) cashout = true;
|
if (arguments.TryGetValue("cashout", out var cashOut)||message.Message.Contains("cashout")) cashout = true;
|
||||||
|
|
||||||
|
if (!Regex.IsMatch(message.Message, @"\d") && cashout) //if the message has no ints its a cashout attempt
|
||||||
|
{
|
||||||
|
if (KasinoMines.ActiveGames.ContainsKey(gambler.Id))
|
||||||
|
{
|
||||||
|
await KasinoMines.Cashout(KasinoMines.ActiveGames[gambler.Id]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, you don't have a game running to cash out.", true, autoDeleteAfter: cleanupDelay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//check if user has an existing game already
|
//check if user has an existing game already
|
||||||
if (!KasinoMines.ActiveGames.ContainsKey(gambler.Id))
|
if (!KasinoMines.ActiveGames.ContainsKey(gambler.Id))
|
||||||
{
|
{
|
||||||
@@ -86,15 +103,7 @@ public class MinesCommand : ICommand
|
|||||||
if (gambler.Balance < wager)
|
if (gambler.Balance < wager)
|
||||||
{
|
{
|
||||||
await botInstance.SendChatMessageAsync(
|
await botInstance.SendChatMessageAsync(
|
||||||
$"{user.FormatUsername()}, your balance is too low. Balance: {await gambler.Balance.FormatKasinoCurrencyAsync()}", true, autoDeleteAfter: cleanupDelay);
|
$"{user.FormatUsername()}, your balance is too low. Balance: {gambler.Balance.FormatKasinoCurrencyAsync()}", true, autoDeleteAfter: cleanupDelay);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wager == 0)
|
|
||||||
{
|
|
||||||
await botInstance.SendChatMessageAsync(
|
|
||||||
$"{user.FormatUsername()}, you have to wager more than {await wager.FormatKasinoCurrencyAsync()}", true,
|
|
||||||
autoDeleteAfter: cleanupDelay);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +115,13 @@ public class MinesCommand : ICommand
|
|||||||
true, autoDeleteAfter: TimeSpan.FromSeconds(10));
|
true, autoDeleteAfter: TimeSpan.FromSeconds(10));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wager <= 0)
|
||||||
|
{
|
||||||
|
await botInstance.SendChatMessageAsync(
|
||||||
|
$"{user.FormatUsername()}, you have to bet something to play mines.", true, autoDeleteAfter: cleanupDelay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!arguments.TryGetValue("size", out var size) || !arguments.TryGetValue("mines", out var mines))
|
if (!arguments.TryGetValue("size", out var size) || !arguments.TryGetValue("mines", out var mines))
|
||||||
{
|
{
|
||||||
await botInstance.SendChatMessageAsync(
|
await botInstance.SendChatMessageAsync(
|
||||||
@@ -164,7 +180,7 @@ public class MinesCommand : ICommand
|
|||||||
var game = KasinoMines.ActiveGames[gambler.Id];
|
var game = KasinoMines.ActiveGames[gambler.Id];
|
||||||
foreach (var coord in precisePicks)
|
foreach (var coord in precisePicks)
|
||||||
{
|
{
|
||||||
if (game.BetsPlaced.Contains(coord) || coord.r <= 0 || coord.r > game.Size || coord.c <= 0 || coord.c > game.Size)
|
if (game.BetsPlaced.Contains(coord) || coord.r < 0 || coord.r > game.Size || coord.c < 0 || coord.c > game.Size)
|
||||||
{
|
{
|
||||||
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, you can't place duplicate or invalid bets. Use the tool: {ToolUrl}", true, autoDeleteAfter: cleanupDelay);
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, you can't place duplicate or invalid bets. Use the tool: {ToolUrl}", true, autoDeleteAfter: cleanupDelay);
|
||||||
return;
|
return;
|
||||||
@@ -222,10 +238,8 @@ public class MinesCommand : ICommand
|
|||||||
true, autoDeleteAfter: cleanupDelay);
|
true, autoDeleteAfter: cleanupDelay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var msg = await botInstance.SendChatMessageAsync(
|
|
||||||
$"{KasinoMines.ActiveGames[gambler.Id].ToString()}", true);
|
var msg = KasinoMines.ActiveGames[gambler.Id].LastMessage;
|
||||||
var msgSuccess = await botInstance.WaitForChatMessageAsync(msg, ct: ctx);
|
|
||||||
if (!msgSuccess) throw new InvalidOperationException("Timed out waiting for the message");
|
|
||||||
if (pick == 0) //if using coordinates
|
if (pick == 0) //if using coordinates
|
||||||
{
|
{
|
||||||
var game = KasinoMines.ActiveGames[gambler.Id];
|
var game = KasinoMines.ActiveGames[gambler.Id];
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ public class KasinoMines
|
|||||||
public decimal Wager { get; set; }
|
public decimal Wager { get; set; }
|
||||||
public int Size { get; set; }
|
public int Size { get; set; }
|
||||||
public int Mines { get; set; }
|
public int Mines { get; set; }
|
||||||
public List<(int r, int c)> BetsPlaced = new();
|
public List<(int r, int c)> BetsPlaced;
|
||||||
public int LastMessageId;
|
public SentMessageTrackerModel LastMessage;
|
||||||
|
|
||||||
|
|
||||||
public KasinoMinesGame(GamblerDbModel creator, decimal wager, int size, int mines)
|
public KasinoMinesGame(GamblerDbModel creator, decimal wager, int size, int mines)
|
||||||
@@ -34,30 +34,38 @@ public class KasinoMines
|
|||||||
Mines = mines;
|
Mines = mines;
|
||||||
Wager = wager;
|
Wager = wager;
|
||||||
MinesBoard = CreateBoard();
|
MinesBoard = CreateBoard();
|
||||||
|
BetsPlaced = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ResetMessage(SentMessageTrackerModel msg)
|
public async Task ResetMessage(SentMessageTrackerModel msg)
|
||||||
{
|
{
|
||||||
_logger.Info("Resetting message");
|
_logger.Info("Resetting message");
|
||||||
// 0 is the default for int
|
// 0 is the default for int
|
||||||
if (LastMessageId != 0)
|
if (LastMessage.ChatMessageId.Value != 0)
|
||||||
{
|
{
|
||||||
await _kfChatBot.KfClient.DeleteMessageAsync(LastMessageId);
|
await _kfChatBot.KfClient.DeleteMessageAsync(LastMessage.ChatMessageId.Value);
|
||||||
}
|
}
|
||||||
if (msg.ChatMessageId == null) throw new InvalidOperationException($"ChatMessageId was null for {msg.Reference}");
|
if (msg.ChatMessageId == null) throw new InvalidOperationException($"ChatMessageId was null for {msg.Reference}");
|
||||||
LastMessageId = msg.ChatMessageId.Value;
|
LastMessage = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RigBoard((int r, int c) coord) //moves one of the mines to a specified coordinate for house edge rigging
|
public async Task RigBoard((int r, int c) coord) //moves one of the mines to a specified coordinate for house edge rigging
|
||||||
{
|
{
|
||||||
//find the first mine
|
//find the first mine
|
||||||
(int r, int c) originalMine = (11, 11);
|
(int r, int c) originalMine = (11, 11);
|
||||||
|
bool brek = false;
|
||||||
for (int r = 0; r < Size; r++)
|
for (int r = 0; r < Size; r++)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < Size; c++)
|
for (int c = 0; c < Size; c++)
|
||||||
{
|
{
|
||||||
if (MinesBoard[r, c] == 'M') originalMine = (r, c);
|
if (MinesBoard[r, c] == 'M')
|
||||||
|
{
|
||||||
|
originalMine = (r, c);
|
||||||
|
brek = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (brek) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MinesBoard[coord.r, coord.c] = 'M';
|
MinesBoard[coord.r, coord.c] = 'M';
|
||||||
@@ -71,7 +79,7 @@ public class KasinoMines
|
|||||||
}
|
}
|
||||||
public async Task Explode((int r, int c) mineLocation, SentMessageTrackerModel msg)
|
public async Task Explode((int r, int c) mineLocation, SentMessageTrackerModel msg)
|
||||||
{
|
{
|
||||||
if (LastMessageId != msg.ChatMessageId!.Value)
|
if (LastMessage.ChatMessageId.Value != msg.ChatMessageId!.Value)
|
||||||
{
|
{
|
||||||
await ResetMessage(msg);
|
await ResetMessage(msg);
|
||||||
}
|
}
|
||||||
@@ -133,7 +141,7 @@ public class KasinoMines
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
await _kfChatBot.KfClient.EditMessageAsync(LastMessageId, $"{str}[br]{Creator.User.FormatUsername()}");
|
await _kfChatBot.KfClient.EditMessageAsync(LastMessage.ChatMessageId.Value, $"{str}[br]{Creator.User.FormatUsername()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(10));
|
await Task.Delay(TimeSpan.FromSeconds(10));
|
||||||
@@ -278,11 +286,11 @@ public class KasinoMines
|
|||||||
public async Task Cashout(KasinoMinesGame game)
|
public async Task Cashout(KasinoMinesGame game)
|
||||||
{
|
{
|
||||||
decimal payout = 0;
|
decimal payout = 0;
|
||||||
decimal possiblePicks = game.Size * game.Size - game.Mines;
|
decimal numGems = game.Size * game.Size - game.Mines;
|
||||||
for (int i = 0; i < game.BetsPlaced.Count; i++)
|
for (int i = 0; i < game.BetsPlaced.Count; i++)
|
||||||
{
|
{
|
||||||
payout += game.Wager * (possiblePicks / game.BetsPlaced.Count);
|
payout += game.Wager * (game.Size * game.Size / numGems);
|
||||||
possiblePicks--;
|
numGems--;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newBalance = await Money.NewWagerAsync(game.Creator.Id, game.Wager, payout, WagerGame.Mines);
|
var newBalance = await Money.NewWagerAsync(game.Creator.Id, game.Wager, payout, WagerGame.Mines);
|
||||||
@@ -297,7 +305,7 @@ public class KasinoMines
|
|||||||
await GetSavedGames(gamblerId);
|
await GetSavedGames(gamblerId);
|
||||||
var game = ActiveGames[gamblerId];
|
var game = ActiveGames[gamblerId];
|
||||||
game.LastInteracted = DateTimeOffset.UtcNow;
|
game.LastInteracted = DateTimeOffset.UtcNow;
|
||||||
if (game.LastMessageId != msg.ChatMessageId!.Value)
|
if (game.LastMessage.ChatMessageId.Value != msg.ChatMessageId!.Value)
|
||||||
{
|
{
|
||||||
await game.ResetMessage(msg);
|
await game.ResetMessage(msg);
|
||||||
}
|
}
|
||||||
@@ -316,6 +324,12 @@ public class KasinoMines
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (validBets.Count == 0)
|
||||||
|
{
|
||||||
|
await _kfChatBot.SendChatMessageAsync($"{game.Creator.User.FormatUsername()}, unable to generate valid betting positions, game closed.", true, autoDeleteAfter: TimeSpan.FromSeconds(5));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (count > numGems)
|
if (count > numGems)
|
||||||
{
|
{
|
||||||
count = numGems;
|
count = numGems;
|
||||||
@@ -329,13 +343,14 @@ public class KasinoMines
|
|||||||
await _kfChatBot.SendChatMessageAsync($"{game.Creator.User.FormatUsername()}, you bet on all gems, so you will automatically cash out if you win.", true, autoDeleteAfter: TimeSpan.FromSeconds(5));
|
await _kfChatBot.SendChatMessageAsync($"{game.Creator.User.FormatUsername()}, you bet on all gems, so you will automatically cash out if you win.", true, autoDeleteAfter: TimeSpan.FromSeconds(5));
|
||||||
cashOut = true;
|
cashOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//randomly pull from that list to add coordinates to bet on
|
//randomly pull from that list to add coordinates to bet on
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
int rand = Money.GetRandomNumber(game.Creator, 0, validBets.Count - 1);
|
int rand = Money.GetRandomNumber(game.Creator, 0, validBets.Count - 1);
|
||||||
betCoords.Add(validBets[rand]);
|
betCoords.Add(validBets[rand]);
|
||||||
validBets.Remove(betCoords[rand]);
|
validBets.RemoveAt(rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Bet(gamblerId, betCoords, msg, cashOut, true);
|
return await Bet(gamblerId, betCoords, msg, cashOut, true);
|
||||||
@@ -347,7 +362,7 @@ public class KasinoMines
|
|||||||
await GetSavedGames(gamblerId);
|
await GetSavedGames(gamblerId);
|
||||||
var game = ActiveGames[gamblerId];
|
var game = ActiveGames[gamblerId];
|
||||||
game.LastInteracted = DateTimeOffset.UtcNow;
|
game.LastInteracted = DateTimeOffset.UtcNow;
|
||||||
if (game.LastMessageId != msg.ChatMessageId!.Value)
|
if (game.LastMessage.ChatMessageId.Value != msg.ChatMessageId!.Value)
|
||||||
{
|
{
|
||||||
await game.ResetMessage(msg);
|
await game.ResetMessage(msg);
|
||||||
}
|
}
|
||||||
@@ -370,18 +385,19 @@ public class KasinoMines
|
|||||||
}
|
}
|
||||||
|
|
||||||
var invalidBetMsg = await _kfChatBot.SendChatMessageAsync($"{game.Creator.User.FormatUsername()}, checking bets...", true);
|
var invalidBetMsg = await _kfChatBot.SendChatMessageAsync($"{game.Creator.User.FormatUsername()}, checking bets...", true);
|
||||||
await _kfChatBot.WaitForChatMessageAsync(invalidBetMsg);
|
await Task.Delay(3);
|
||||||
foreach (var bet in coords)
|
foreach (var bet in coords)
|
||||||
{
|
{
|
||||||
if (!validBets.Contains(bet) || game.BetsPlaced.Contains(bet) || bets.Contains(bet))
|
if (!validBets.Contains(bet) || game.BetsPlaced.Contains(bet) || bets.Contains(bet))
|
||||||
{
|
{
|
||||||
await _kfChatBot.KfClient.EditMessageAsync(invalidBetMsg.ChatMessageId!.Value,
|
await _kfChatBot.KfClient.EditMessageAsync(invalidBetMsg.ChatMessageId!.Value,
|
||||||
$"{game.Creator.User.FormatUsername()}, invalid bet of {bet.r},{bet.c} removed (already placed, duplicate, or invalid coordinate)");
|
$"{game.Creator.User.FormatUsername()}, invalid bet of {bet.r},{bet.c} removed (already placed, duplicate, or invalid coordinate)");
|
||||||
|
await Task.Delay(3);
|
||||||
}
|
}
|
||||||
else bets.Add(bet);
|
else bets.Add(bet);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _kfChatBot.KfClient.DeleteMessageAsync(invalidBetMsg.ChatMessageId!.Value);
|
|
||||||
if (bets.Count > numGems)
|
if (bets.Count > numGems)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -397,6 +413,7 @@ public class KasinoMines
|
|||||||
cashOut = true;
|
cashOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Task.Delay(5);
|
||||||
_ = _kfChatBot.KfClient.DeleteMessageAsync(invalidBetMsg.ChatMessageId.Value);
|
_ = _kfChatBot.KfClient.DeleteMessageAsync(invalidBetMsg.ChatMessageId.Value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user