mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
More common refactorings like renaming variables, removing empty statements and unused variables, etc
This commit is contained in:
@@ -38,8 +38,8 @@ public sealed class AcrophobiaGame : IDisposable
|
||||
public ImmutableArray<char> StartingLetters { get; private set; }
|
||||
public Options Opts { get; }
|
||||
|
||||
private readonly Dictionary<AcrophobiaUser, int> submissions = new();
|
||||
private readonly SemaphoreSlim locker = new(1, 1);
|
||||
private readonly Dictionary<AcrophobiaUser, int> _submissions = new();
|
||||
private readonly SemaphoreSlim _locker = new(1, 1);
|
||||
private readonly NadekoRandom _rng;
|
||||
|
||||
private readonly HashSet<ulong> _usersWhoVoted = new();
|
||||
@@ -55,37 +55,37 @@ public sealed class AcrophobiaGame : IDisposable
|
||||
{
|
||||
await OnStarted(this);
|
||||
await Task.Delay(Opts.SubmissionTime * 1000);
|
||||
await locker.WaitAsync();
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (submissions.Count == 0)
|
||||
if (_submissions.Count == 0)
|
||||
{
|
||||
CurrentPhase = Phase.Ended;
|
||||
await OnVotingStarted(this, ImmutableArray.Create<KeyValuePair<AcrophobiaUser, int>>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (submissions.Count == 1)
|
||||
if (_submissions.Count == 1)
|
||||
{
|
||||
CurrentPhase = Phase.Ended;
|
||||
await OnVotingStarted(this, submissions.ToArray().ToImmutableArray());
|
||||
await OnVotingStarted(this, _submissions.ToArray().ToImmutableArray());
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentPhase = Phase.Voting;
|
||||
|
||||
await OnVotingStarted(this, submissions.ToArray().ToImmutableArray());
|
||||
await OnVotingStarted(this, _submissions.ToArray().ToImmutableArray());
|
||||
}
|
||||
finally { locker.Release(); }
|
||||
finally { _locker.Release(); }
|
||||
|
||||
await Task.Delay(Opts.VoteTime * 1000);
|
||||
await locker.WaitAsync();
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
CurrentPhase = Phase.Ended;
|
||||
await OnEnded(this, submissions.ToArray().ToImmutableArray());
|
||||
await OnEnded(this, _submissions.ToArray().ToImmutableArray());
|
||||
}
|
||||
finally { locker.Release(); }
|
||||
finally { _locker.Release(); }
|
||||
}
|
||||
|
||||
private void InitializeStartingLetters()
|
||||
@@ -107,26 +107,26 @@ public sealed class AcrophobiaGame : IDisposable
|
||||
{
|
||||
var user = new AcrophobiaUser(userId, userName, input.ToLowerInvariant().ToTitleCase());
|
||||
|
||||
await locker.WaitAsync();
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
switch (CurrentPhase)
|
||||
{
|
||||
case Phase.Submission:
|
||||
if (submissions.ContainsKey(user) || !IsValidAnswer(input))
|
||||
if (_submissions.ContainsKey(user) || !IsValidAnswer(input))
|
||||
break;
|
||||
|
||||
submissions.Add(user, 0);
|
||||
_submissions.Add(user, 0);
|
||||
return true;
|
||||
case Phase.Voting:
|
||||
AcrophobiaUser toVoteFor;
|
||||
if (!int.TryParse(input, out var index)
|
||||
|| --index < 0
|
||||
|| index >= submissions.Count
|
||||
|| (toVoteFor = submissions.ToArray()[index].Key).UserId == user.UserId
|
||||
|| index >= _submissions.Count
|
||||
|| (toVoteFor = _submissions.ToArray()[index].Key).UserId == user.UserId
|
||||
|| !_usersWhoVoted.Add(userId))
|
||||
break;
|
||||
++submissions[toVoteFor];
|
||||
++_submissions[toVoteFor];
|
||||
_= Task.Run(() => OnUserVoted(userName));
|
||||
return true;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public sealed class AcrophobiaGame : IDisposable
|
||||
}
|
||||
finally
|
||||
{
|
||||
locker.Release();
|
||||
_locker.Release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,8 +169,8 @@ public sealed class AcrophobiaGame : IDisposable
|
||||
OnUserVoted = null;
|
||||
OnVotingStarted = null;
|
||||
_usersWhoVoted.Clear();
|
||||
submissions.Clear();
|
||||
locker.Dispose();
|
||||
_submissions.Clear();
|
||||
_locker.Dispose();
|
||||
}
|
||||
|
||||
public class Options : INadekoCommandOptions
|
||||
|
@@ -31,19 +31,19 @@ public partial class Games
|
||||
game.OnEnded += Game_OnEnded;
|
||||
game.OnVotingStarted += Game_OnVotingStarted;
|
||||
game.OnUserVoted += Game_OnUserVoted;
|
||||
_client.MessageReceived += _client_MessageReceived;
|
||||
_client.MessageReceived += ClientMessageReceived;
|
||||
await game.Run();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_client.MessageReceived -= _client_MessageReceived;
|
||||
_client.MessageReceived -= ClientMessageReceived;
|
||||
_service.AcrophobiaGames.TryRemove(channel.Id, out game);
|
||||
game.Dispose();
|
||||
game?.Dispose();
|
||||
}
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.acro_running);
|
||||
|
||||
Task _client_MessageReceived(SocketMessage msg)
|
||||
Task ClientMessageReceived(SocketMessage msg)
|
||||
{
|
||||
if (msg.Channel.Id != ctx.Channel.Id)
|
||||
return Task.CompletedTask;
|
||||
|
@@ -48,7 +48,7 @@ public class ChatterBotService : IEarlyBehavior
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
|
||||
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
|
||||
return new CleverbotIOSession("GAh3wUfzDCpDpdpT", "RStKgqn7tcO9blbrv4KbXM8NDlb7H37C", _httpFactory);
|
||||
return new CleverbotIoSession("GAh3wUfzDCpDpdpT", "RStKgqn7tcO9blbrv4KbXM8NDlb7H37C", _httpFactory);
|
||||
}
|
||||
|
||||
public string PrepareMessage(IUserMessage msg, out IChatterBotSession cleverbot)
|
||||
|
@@ -7,13 +7,13 @@ public class CleverbotResponse
|
||||
public string Output { get; set; }
|
||||
}
|
||||
|
||||
public class CleverbotIOCreateResponse
|
||||
public class CleverbotIoCreateResponse
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public string Nick { get; set; }
|
||||
}
|
||||
|
||||
public class CleverbotIOAskResponse
|
||||
public class CleverbotIoAskResponse
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public string Response { get; set; }
|
||||
|
@@ -10,7 +10,7 @@ public class OfficialCleverbotSession : IChatterBotSession
|
||||
|
||||
private readonly string _apiKey;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private string _cs;
|
||||
private string cs;
|
||||
|
||||
public OfficialCleverbotSession(string apiKey, IHttpClientFactory factory)
|
||||
{
|
||||
@@ -21,12 +21,12 @@ public class OfficialCleverbotSession : IChatterBotSession
|
||||
public async Task<string> Think(string input)
|
||||
{
|
||||
using var http = _httpFactory.CreateClient();
|
||||
var dataString = await http.GetStringAsync(string.Format(QueryString, input, _cs ?? ""));
|
||||
var dataString = await http.GetStringAsync(string.Format(QueryString, input, cs ?? ""));
|
||||
try
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<CleverbotResponse>(dataString);
|
||||
|
||||
_cs = data?.Cs;
|
||||
cs = data?.Cs;
|
||||
return data?.Output;
|
||||
}
|
||||
catch
|
||||
@@ -37,7 +37,7 @@ public class OfficialCleverbotSession : IChatterBotSession
|
||||
}
|
||||
}
|
||||
|
||||
public class CleverbotIOSession : IChatterBotSession
|
||||
public class CleverbotIoSession : IChatterBotSession
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly string _user;
|
||||
@@ -47,7 +47,7 @@ public class CleverbotIOSession : IChatterBotSession
|
||||
private readonly string _createEndpoint = "https://cleverbot.io/1.0/create";
|
||||
private readonly string _askEndpoint = "https://cleverbot.io/1.0/ask";
|
||||
|
||||
public CleverbotIOSession(string user, string key, IHttpClientFactory factory)
|
||||
public CleverbotIoSession(string user, string key, IHttpClientFactory factory)
|
||||
{
|
||||
_key = key;
|
||||
_user = user;
|
||||
@@ -58,14 +58,14 @@ public class CleverbotIOSession : IChatterBotSession
|
||||
|
||||
private async Task<string> GetNick()
|
||||
{
|
||||
using var _http = _httpFactory.CreateClient();
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var msg = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("user", _user), new KeyValuePair<string, string>("key", _key)
|
||||
});
|
||||
using var data = await _http.PostAsync(_createEndpoint, msg);
|
||||
using var data = await http.PostAsync(_createEndpoint, msg);
|
||||
var str = await data.Content.ReadAsStringAsync();
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIOCreateResponse>(str);
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIoCreateResponse>(str);
|
||||
if (obj.Status != "success")
|
||||
throw new OperationCanceledException(obj.Status);
|
||||
|
||||
@@ -74,15 +74,15 @@ public class CleverbotIOSession : IChatterBotSession
|
||||
|
||||
public async Task<string> Think(string input)
|
||||
{
|
||||
using var _http = _httpFactory.CreateClient();
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var msg = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("user", _user), new KeyValuePair<string, string>("key", _key),
|
||||
new KeyValuePair<string, string>("nick", await _nick), new KeyValuePair<string, string>("text", input)
|
||||
});
|
||||
using var data = await _http.PostAsync(_askEndpoint, msg);
|
||||
using var data = await http.PostAsync(_askEndpoint, msg);
|
||||
var str = await data.Content.ReadAsStringAsync();
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIOAskResponse>(str);
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIoAskResponse>(str);
|
||||
if (obj.Status != "success")
|
||||
throw new OperationCanceledException(obj.Status);
|
||||
|
||||
|
@@ -6,12 +6,12 @@ namespace NadekoBot.Modules.Games.Services;
|
||||
|
||||
public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
|
||||
{
|
||||
private const string FilePath = "data/games.yml";
|
||||
private static readonly TypedKey<GamesConfig> changeKey = new("config.games.updated");
|
||||
private const string FILE_PATH = "data/games.yml";
|
||||
private static readonly TypedKey<GamesConfig> _changeKey = new("config.games.updated");
|
||||
public override string Name { get; } = "games";
|
||||
|
||||
public GamesConfigService(IConfigSeria serializer, IPubSub pubSub)
|
||||
: base(FilePath, serializer, pubSub, changeKey)
|
||||
: base(FILE_PATH, serializer, pubSub, _changeKey)
|
||||
{
|
||||
AddParsedProp("trivia.min_win_req",
|
||||
gs => gs.Trivia.MinimumWinReq,
|
||||
|
@@ -10,7 +10,7 @@ namespace NadekoBot.Modules.Games.Services;
|
||||
|
||||
public class GamesService : INService
|
||||
{
|
||||
private const string TypingArticlesPath = "data/typing_articles3.json";
|
||||
private const string TYPING_ARTICLES_PATH = "data/typing_articles3.json";
|
||||
|
||||
public ConcurrentDictionary<ulong, GirlRating> GirlRatings { get; } = new();
|
||||
|
||||
@@ -54,11 +54,11 @@ public class GamesService : INService
|
||||
|
||||
try
|
||||
{
|
||||
TypingArticles = JsonConvert.DeserializeObject<List<TypingArticle>>(File.ReadAllText(TypingArticlesPath));
|
||||
TypingArticles = JsonConvert.DeserializeObject<List<TypingArticle>>(File.ReadAllText(TYPING_ARTICLES_PATH));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning("Error while loading typing articles {0}", ex.ToString());
|
||||
Log.Warning(ex, "Error while loading typing articles: {ErrorMessage}", ex.Message);
|
||||
TypingArticles = new();
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ public class GamesService : INService
|
||||
Text = text.SanitizeMentions(true)
|
||||
});
|
||||
|
||||
File.WriteAllText(TypingArticlesPath, JsonConvert.SerializeObject(TypingArticles));
|
||||
File.WriteAllText(TYPING_ARTICLES_PATH, JsonConvert.SerializeObject(TypingArticles));
|
||||
}
|
||||
|
||||
public string GetEightballResponse(ulong userId, string question)
|
||||
@@ -90,7 +90,6 @@ public class GamesService : INService
|
||||
e.Size = question.Length;
|
||||
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
|
||||
return EightBallResponses[_rng.Next(0, EightBallResponses.Count)];
|
||||
;
|
||||
});
|
||||
|
||||
public TypingArticle RemoveTypingArticle(int index)
|
||||
@@ -102,7 +101,7 @@ public class GamesService : INService
|
||||
var removed = articles[index];
|
||||
TypingArticles.RemoveAt(index);
|
||||
|
||||
File.WriteAllText(TypingArticlesPath, JsonConvert.SerializeObject(articles));
|
||||
File.WriteAllText(TYPING_ARTICLES_PATH, JsonConvert.SerializeObject(articles));
|
||||
return removed;
|
||||
}
|
||||
|
||||
|
@@ -15,11 +15,8 @@ public class GirlRating
|
||||
public AsyncLazy<Stream> Stream { get; }
|
||||
private readonly IImageCache _images;
|
||||
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
|
||||
public GirlRating(
|
||||
IImageCache images,
|
||||
IHttpClientFactory factory,
|
||||
double crazy,
|
||||
double hot,
|
||||
int roll,
|
||||
@@ -30,7 +27,6 @@ public class GirlRating
|
||||
Hot = hot;
|
||||
Roll = roll;
|
||||
Advice = advice; // convenient to have it here, even though atm there are only few different ones.
|
||||
_httpFactory = factory;
|
||||
|
||||
Stream = new(() =>
|
||||
{
|
||||
|
@@ -5,7 +5,7 @@ namespace NadekoBot.Modules.Games.Hangman;
|
||||
|
||||
public sealed class DefaultHangmanSource : IHangmanSource
|
||||
{
|
||||
private IReadOnlyDictionary<string, HangmanTerm[]> _terms = new Dictionary<string, HangmanTerm[]>();
|
||||
private IReadOnlyDictionary<string, HangmanTerm[]> termsDict = new Dictionary<string, HangmanTerm[]>();
|
||||
private readonly Random _rng;
|
||||
|
||||
public DefaultHangmanSource()
|
||||
@@ -18,7 +18,7 @@ public sealed class DefaultHangmanSource : IHangmanSource
|
||||
{
|
||||
if (!Directory.Exists("data/hangman"))
|
||||
{
|
||||
Log.Error("Hangman game won't work. Folder 'data/hangman' is missing.");
|
||||
Log.Error("Hangman game won't work. Folder 'data/hangman' is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,16 +31,16 @@ public sealed class DefaultHangmanSource : IHangmanSource
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Loading {HangmanFile} failed.", file);
|
||||
Log.Error(ex, "Loading {HangmanFile} failed", file);
|
||||
}
|
||||
|
||||
_terms = qs;
|
||||
termsDict = qs;
|
||||
|
||||
Log.Information("Loaded {HangmanCategoryCount} hangman categories.", qs.Count);
|
||||
Log.Information("Loaded {HangmanCategoryCount} hangman categories", qs.Count);
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<string> GetCategories()
|
||||
=> _terms.Keys.ToList();
|
||||
=> termsDict.Keys.ToList();
|
||||
|
||||
public bool GetTerm(string? category, [NotNullWhen(true)] out HangmanTerm? term)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public sealed class DefaultHangmanSource : IHangmanSource
|
||||
category = cats.ElementAt(_rng.Next(0, cats.Count));
|
||||
}
|
||||
|
||||
if (_terms.TryGetValue(category, out var terms))
|
||||
if (termsDict.TryGetValue(category, out var terms))
|
||||
{
|
||||
term = terms[_rng.Next(0, terms.Length)];
|
||||
return true;
|
||||
|
@@ -28,19 +28,19 @@ public partial class Games
|
||||
.WithOkColor()
|
||||
.AddField("Hangman", Draw(state))
|
||||
.AddField("Guess", Format.Code(state.Word))
|
||||
.WithFooter(state.missedLetters.Join(' '));
|
||||
.WithFooter(state.MissedLetters.Join(' '));
|
||||
|
||||
if (state.Phase == HangmanGame.Phase.Ended && state.Failed)
|
||||
return eb.Create()
|
||||
.WithErrorColor()
|
||||
.AddField("Hangman", Draw(state))
|
||||
.AddField("Guess", Format.Code(state.Word))
|
||||
.WithFooter(state.missedLetters.Join(' '));
|
||||
.WithFooter(state.MissedLetters.Join(' '));
|
||||
return eb.Create()
|
||||
.WithOkColor()
|
||||
.AddField("Hangman", Draw(state))
|
||||
.AddField("Guess", Format.Code(state.Word))
|
||||
.WithFooter(state.missedLetters.Join(' '));
|
||||
.WithFooter(state.MissedLetters.Join(' '));
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@@ -104,7 +104,7 @@ public sealed class HangmanGame
|
||||
Phase Phase,
|
||||
string Word,
|
||||
GuessResult GuessResult,
|
||||
List<char> missedLetters,
|
||||
List<char> MissedLetters,
|
||||
string ImageUrl)
|
||||
{
|
||||
public bool Failed
|
||||
|
@@ -54,7 +54,7 @@ public sealed class HangmanService : IHangmanService, ILateExecutor
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
if (_hangmanGames.TryRemove(channelId, out var game)) return new(true);
|
||||
if (_hangmanGames.TryRemove(channelId, out _)) return new(true);
|
||||
}
|
||||
|
||||
return new(false);
|
||||
|
@@ -13,8 +13,8 @@ public sealed class NunchiGame : IDisposable
|
||||
Ended
|
||||
}
|
||||
|
||||
private const int _killTimeout = 20 * 1000;
|
||||
private const int _nextRoundTimeout = 5 * 1000;
|
||||
private const int KILL_TIMEOUT = 20 * 1000;
|
||||
private const int NEXT_ROUND_TIMEOUT = 5 * 1000;
|
||||
|
||||
public event Func<NunchiGame, Task> OnGameStarted;
|
||||
public event Func<NunchiGame, int, Task> OnRoundStarted;
|
||||
@@ -26,19 +26,19 @@ public sealed class NunchiGame : IDisposable
|
||||
public Phase CurrentPhase { get; private set; } = Phase.Joining;
|
||||
|
||||
public ImmutableArray<(ulong Id, string Name)> Participants
|
||||
=> _participants.ToImmutableArray();
|
||||
=> participants.ToImmutableArray();
|
||||
|
||||
public int ParticipantCount
|
||||
=> _participants.Count;
|
||||
=> participants.Count;
|
||||
|
||||
private readonly SemaphoreSlim _locker = new(1, 1);
|
||||
|
||||
private HashSet<(ulong Id, string Name)> _participants = new();
|
||||
private HashSet<(ulong Id, string Name)> participants = new();
|
||||
private readonly HashSet<(ulong Id, string Name)> _passed = new();
|
||||
private Timer _killTimer;
|
||||
private Timer killTimer;
|
||||
|
||||
public NunchiGame(ulong creatorId, string creatorName)
|
||||
=> _participants.Add((creatorId, creatorName));
|
||||
=> participants.Add((creatorId, creatorName));
|
||||
|
||||
public async Task<bool> Join(ulong userId, string userName)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ public sealed class NunchiGame : IDisposable
|
||||
if (CurrentPhase != Phase.Joining)
|
||||
return false;
|
||||
|
||||
return _participants.Add((userId, userName));
|
||||
return participants.Add((userId, userName));
|
||||
}
|
||||
finally { _locker.Release(); }
|
||||
}
|
||||
@@ -60,13 +60,13 @@ public sealed class NunchiGame : IDisposable
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_participants.Count < 3)
|
||||
if (participants.Count < 3)
|
||||
{
|
||||
CurrentPhase = Phase.Ended;
|
||||
return false;
|
||||
}
|
||||
|
||||
_killTimer = new(async _ =>
|
||||
killTimer = new(async _ =>
|
||||
{
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
@@ -75,14 +75,14 @@ public sealed class NunchiGame : IDisposable
|
||||
return;
|
||||
|
||||
//if some players took too long to type a number, boot them all out and start a new round
|
||||
_participants = new HashSet<(ulong, string)>(_passed);
|
||||
participants = new HashSet<(ulong, string)>(_passed);
|
||||
EndRound();
|
||||
}
|
||||
finally { _locker.Release(); }
|
||||
},
|
||||
null,
|
||||
_killTimeout,
|
||||
_killTimeout);
|
||||
KILL_TIMEOUT,
|
||||
KILL_TIMEOUT);
|
||||
|
||||
CurrentPhase = Phase.Playing;
|
||||
_= OnGameStarted?.Invoke(this);
|
||||
@@ -105,7 +105,7 @@ public sealed class NunchiGame : IDisposable
|
||||
// if the user is not a member of the race,
|
||||
// or he already successfully typed the number
|
||||
// ignore the input
|
||||
if (!_participants.Contains(userTuple) || !_passed.Add(userTuple))
|
||||
if (!participants.Contains(userTuple) || !_passed.Add(userTuple))
|
||||
return;
|
||||
|
||||
//if the number is correct
|
||||
@@ -113,20 +113,20 @@ public sealed class NunchiGame : IDisposable
|
||||
{
|
||||
//increment current number
|
||||
++CurrentNumber;
|
||||
if (_passed.Count == _participants.Count - 1)
|
||||
if (_passed.Count == participants.Count - 1)
|
||||
{
|
||||
// if only n players are left, and n - 1 type the correct number, round is over
|
||||
|
||||
// if only 2 players are left, game is over
|
||||
if (_participants.Count == 2)
|
||||
if (participants.Count == 2)
|
||||
{
|
||||
_killTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
killTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
CurrentPhase = Phase.Ended;
|
||||
_= OnGameEnded?.Invoke(this, userTuple.Name);
|
||||
}
|
||||
else // else just start the new round without the user who was the last
|
||||
{
|
||||
var failure = _participants.Except(_passed).First();
|
||||
var failure = participants.Except(_passed).First();
|
||||
|
||||
OnUserGuessed?.Invoke(this);
|
||||
EndRound(failure);
|
||||
@@ -148,25 +148,25 @@ public sealed class NunchiGame : IDisposable
|
||||
|
||||
private void EndRound((ulong, string)? failure = null)
|
||||
{
|
||||
_killTimer.Change(_killTimeout, _killTimeout);
|
||||
killTimer.Change(KILL_TIMEOUT, KILL_TIMEOUT);
|
||||
CurrentNumber = new NadekoRandom().Next(0, 100); // reset the counter
|
||||
_passed.Clear(); // reset all users who passed (new round starts)
|
||||
if (failure is not null)
|
||||
_participants.Remove(failure.Value); // remove the dude who failed from the list of players
|
||||
participants.Remove(failure.Value); // remove the dude who failed from the list of players
|
||||
|
||||
var __ = OnRoundEnded?.Invoke(this, failure);
|
||||
if (_participants.Count <= 1) // means we have a winner or everyone was booted out
|
||||
if (participants.Count <= 1) // means we have a winner or everyone was booted out
|
||||
{
|
||||
_killTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
killTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
CurrentPhase = Phase.Ended;
|
||||
_= OnGameEnded?.Invoke(this, _participants.Count > 0 ? _participants.First().Name : null);
|
||||
_= OnGameEnded?.Invoke(this, participants.Count > 0 ? participants.First().Name : null);
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentPhase = Phase.WaitingForNextRound;
|
||||
var throwawayDelay = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(_nextRoundTimeout);
|
||||
await Task.Delay(NEXT_ROUND_TIMEOUT);
|
||||
CurrentPhase = Phase.Playing;
|
||||
var ___ = OnRoundStarted?.Invoke(this, CurrentNumber);
|
||||
});
|
||||
|
@@ -38,12 +38,12 @@ public partial class Games
|
||||
try { await ConfirmLocalizedAsync(strs.nunchi_created); }
|
||||
catch { }
|
||||
|
||||
nunchi.OnGameEnded += Nunchi_OnGameEnded;
|
||||
nunchi.OnGameEnded += NunchiOnGameEnded;
|
||||
//nunchi.OnGameStarted += Nunchi_OnGameStarted;
|
||||
nunchi.OnRoundEnded += Nunchi_OnRoundEnded;
|
||||
nunchi.OnUserGuessed += Nunchi_OnUserGuessed;
|
||||
nunchi.OnRoundStarted += Nunchi_OnRoundStarted;
|
||||
_client.MessageReceived += _client_MessageReceived;
|
||||
_client.MessageReceived += ClientMessageReceived;
|
||||
|
||||
var success = await nunchi.Initialize();
|
||||
if (!success)
|
||||
@@ -53,7 +53,7 @@ public partial class Games
|
||||
await ConfirmLocalizedAsync(strs.nunchi_failed_to_start);
|
||||
}
|
||||
|
||||
Task _client_MessageReceived(SocketMessage arg)
|
||||
Task ClientMessageReceived(SocketMessage arg)
|
||||
{
|
||||
_= Task.Run(async () =>
|
||||
{
|
||||
@@ -73,11 +73,11 @@ public partial class Games
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task Nunchi_OnGameEnded(NunchiGame arg1, string arg2)
|
||||
Task NunchiOnGameEnded(NunchiGame arg1, string arg2)
|
||||
{
|
||||
if (_service.NunchiGames.TryRemove(ctx.Guild.Id, out var game))
|
||||
{
|
||||
_client.MessageReceived -= _client_MessageReceived;
|
||||
_client.MessageReceived -= ClientMessageReceived;
|
||||
game.Dispose();
|
||||
}
|
||||
|
||||
|
@@ -90,8 +90,8 @@ public partial class Games
|
||||
|
||||
for (var i = 0; i < stats.Length; i++)
|
||||
{
|
||||
var (Index, votes, Text) = stats[i];
|
||||
sb.AppendLine(GetText(strs.poll_result(Index + 1, Format.Bold(Text), Format.Bold(votes.ToString()))));
|
||||
var (index, votes, text) = stats[i];
|
||||
sb.AppendLine(GetText(strs.poll_result(index + 1, Format.Bold(text), Format.Bold(votes.ToString()))));
|
||||
}
|
||||
|
||||
return eb.WithDescription(sb.ToString())
|
||||
|
@@ -10,19 +10,19 @@ public class TicTacToe
|
||||
private readonly ITextChannel _channel;
|
||||
private readonly IGuildUser[] _users;
|
||||
private readonly int?[,] _state;
|
||||
private Phase _phase;
|
||||
private int _curUserIndex;
|
||||
private Phase phase;
|
||||
private int curUserIndex;
|
||||
private readonly SemaphoreSlim _moveLock;
|
||||
|
||||
private IGuildUser _winner;
|
||||
private IGuildUser winner;
|
||||
|
||||
private readonly string[] _numbers =
|
||||
{
|
||||
":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:"
|
||||
};
|
||||
|
||||
private IUserMessage _previousMessage;
|
||||
private Timer _timeoutTimer;
|
||||
private IUserMessage previousMessage;
|
||||
private Timer timeoutTimer;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly Options _options;
|
||||
@@ -45,7 +45,7 @@ public class TicTacToe
|
||||
_users = new[] { firstUser, null };
|
||||
_state = new int?[,] { { null, null, null }, { null, null, null }, { null, null, null } };
|
||||
|
||||
_phase = Phase.Starting;
|
||||
phase = Phase.Starting;
|
||||
_moveLock = new(1, 1);
|
||||
}
|
||||
|
||||
@@ -81,16 +81,16 @@ public class TicTacToe
|
||||
if (!string.IsNullOrWhiteSpace(title))
|
||||
embed.WithTitle(title);
|
||||
|
||||
if (_winner is null)
|
||||
if (winner is null)
|
||||
{
|
||||
if (_phase == Phase.Ended)
|
||||
if (phase == Phase.Ended)
|
||||
embed.WithFooter(GetText(strs.ttt_no_moves));
|
||||
else
|
||||
embed.WithFooter(GetText(strs.ttt_users_move(_users[_curUserIndex])));
|
||||
embed.WithFooter(GetText(strs.ttt_users_move(_users[curUserIndex])));
|
||||
}
|
||||
else
|
||||
{
|
||||
embed.WithFooter(GetText(strs.ttt_has_won(_winner)));
|
||||
embed.WithFooter(GetText(strs.ttt_has_won(winner)));
|
||||
}
|
||||
|
||||
return embed;
|
||||
@@ -115,7 +115,7 @@ public class TicTacToe
|
||||
|
||||
public async Task Start(IGuildUser user)
|
||||
{
|
||||
if (_phase is Phase.Started or Phase.Ended)
|
||||
if (phase is Phase.Started or Phase.Ended)
|
||||
{
|
||||
await _channel.SendErrorAsync(_eb, user.Mention + GetText(strs.ttt_already_running));
|
||||
return;
|
||||
@@ -129,21 +129,21 @@ public class TicTacToe
|
||||
|
||||
_users[1] = user;
|
||||
|
||||
_phase = Phase.Started;
|
||||
phase = Phase.Started;
|
||||
|
||||
_timeoutTimer = new(async _ =>
|
||||
timeoutTimer = new(async _ =>
|
||||
{
|
||||
await _moveLock.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_phase == Phase.Ended)
|
||||
if (phase == Phase.Ended)
|
||||
return;
|
||||
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
if (_users[1] is not null)
|
||||
{
|
||||
_winner = _users[_curUserIndex ^= 1];
|
||||
var del = _previousMessage?.DeleteAsync();
|
||||
winner = _users[curUserIndex ^= 1];
|
||||
var del = previousMessage?.DeleteAsync();
|
||||
try
|
||||
{
|
||||
await _channel.EmbedAsync(GetEmbed(GetText(strs.ttt_time_expired)));
|
||||
@@ -168,7 +168,7 @@ public class TicTacToe
|
||||
_client.MessageReceived += Client_MessageReceived;
|
||||
|
||||
|
||||
_previousMessage = await _channel.EmbedAsync(GetEmbed(GetText(strs.game_started)));
|
||||
previousMessage = await _channel.EmbedAsync(GetEmbed(GetText(strs.game_started)));
|
||||
}
|
||||
|
||||
private bool IsDraw()
|
||||
@@ -187,8 +187,8 @@ public class TicTacToe
|
||||
await _moveLock.WaitAsync();
|
||||
try
|
||||
{
|
||||
var curUser = _users[_curUserIndex];
|
||||
if (_phase == Phase.Ended || msg.Author?.Id != curUser.Id)
|
||||
var curUser = _users[curUserIndex];
|
||||
if (phase == Phase.Ended || msg.Author?.Id != curUser.Id)
|
||||
return;
|
||||
|
||||
if (int.TryParse(msg.Content, out var index)
|
||||
@@ -196,69 +196,69 @@ public class TicTacToe
|
||||
&& index <= 9
|
||||
&& _state[index / 3, index % 3] is null)
|
||||
{
|
||||
_state[index / 3, index % 3] = _curUserIndex;
|
||||
_state[index / 3, index % 3] = curUserIndex;
|
||||
|
||||
// i'm lazy
|
||||
if (_state[index / 3, 0] == _state[index / 3, 1] && _state[index / 3, 1] == _state[index / 3, 2])
|
||||
{
|
||||
_state[index / 3, 0] = _curUserIndex + 2;
|
||||
_state[index / 3, 1] = _curUserIndex + 2;
|
||||
_state[index / 3, 2] = _curUserIndex + 2;
|
||||
_state[index / 3, 0] = curUserIndex + 2;
|
||||
_state[index / 3, 1] = curUserIndex + 2;
|
||||
_state[index / 3, 2] = curUserIndex + 2;
|
||||
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
}
|
||||
else if (_state[0, index % 3] == _state[1, index % 3]
|
||||
&& _state[1, index % 3] == _state[2, index % 3])
|
||||
{
|
||||
_state[0, index % 3] = _curUserIndex + 2;
|
||||
_state[1, index % 3] = _curUserIndex + 2;
|
||||
_state[2, index % 3] = _curUserIndex + 2;
|
||||
_state[0, index % 3] = curUserIndex + 2;
|
||||
_state[1, index % 3] = curUserIndex + 2;
|
||||
_state[2, index % 3] = curUserIndex + 2;
|
||||
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
}
|
||||
else if (_curUserIndex == _state[0, 0]
|
||||
else if (curUserIndex == _state[0, 0]
|
||||
&& _state[0, 0] == _state[1, 1]
|
||||
&& _state[1, 1] == _state[2, 2])
|
||||
{
|
||||
_state[0, 0] = _curUserIndex + 2;
|
||||
_state[1, 1] = _curUserIndex + 2;
|
||||
_state[2, 2] = _curUserIndex + 2;
|
||||
_state[0, 0] = curUserIndex + 2;
|
||||
_state[1, 1] = curUserIndex + 2;
|
||||
_state[2, 2] = curUserIndex + 2;
|
||||
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
}
|
||||
else if (_curUserIndex == _state[0, 2]
|
||||
else if (curUserIndex == _state[0, 2]
|
||||
&& _state[0, 2] == _state[1, 1]
|
||||
&& _state[1, 1] == _state[2, 0])
|
||||
{
|
||||
_state[0, 2] = _curUserIndex + 2;
|
||||
_state[1, 1] = _curUserIndex + 2;
|
||||
_state[2, 0] = _curUserIndex + 2;
|
||||
_state[0, 2] = curUserIndex + 2;
|
||||
_state[1, 1] = curUserIndex + 2;
|
||||
_state[2, 0] = curUserIndex + 2;
|
||||
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
}
|
||||
|
||||
var reason = string.Empty;
|
||||
|
||||
if (_phase == Phase.Ended) // if user won, stop receiving moves
|
||||
if (phase == Phase.Ended) // if user won, stop receiving moves
|
||||
{
|
||||
reason = GetText(strs.ttt_matched_three);
|
||||
_winner = _users[_curUserIndex];
|
||||
winner = _users[curUserIndex];
|
||||
_client.MessageReceived -= Client_MessageReceived;
|
||||
OnEnded?.Invoke(this);
|
||||
}
|
||||
else if (IsDraw())
|
||||
{
|
||||
reason = GetText(strs.ttt_a_draw);
|
||||
_phase = Phase.Ended;
|
||||
phase = Phase.Ended;
|
||||
_client.MessageReceived -= Client_MessageReceived;
|
||||
OnEnded?.Invoke(this);
|
||||
}
|
||||
|
||||
var sendstate = Task.Run(async () =>
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var del1 = msg.DeleteAsync();
|
||||
var del2 = _previousMessage?.DeleteAsync();
|
||||
try { _previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); }
|
||||
var del2 = previousMessage?.DeleteAsync();
|
||||
try { previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); }
|
||||
catch { }
|
||||
|
||||
try { await del1; }
|
||||
@@ -270,9 +270,9 @@ public class TicTacToe
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
_curUserIndex ^= 1;
|
||||
curUserIndex ^= 1;
|
||||
|
||||
_timeoutTimer.Change(_options.TurnTimer * 1000, Timeout.Infinite);
|
||||
timeoutTimer.Change(_options.TurnTimer * 1000, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@@ -6,10 +6,10 @@ namespace NadekoBot.Modules.Games.Common.Trivia;
|
||||
|
||||
public class TriviaQuestion
|
||||
{
|
||||
public const int maxStringLength = 22;
|
||||
public const int MAX_STRING_LENGTH = 22;
|
||||
|
||||
//represents the min size to judge levDistance with
|
||||
private static readonly HashSet<Tuple<int, int>> strictness = new()
|
||||
private static readonly HashSet<Tuple<int, int>> _strictness = new()
|
||||
{
|
||||
new(9, 0), new(14, 1), new(19, 2), new(22, 3)
|
||||
};
|
||||
@@ -56,7 +56,7 @@ public class TriviaQuestion
|
||||
|
||||
private static bool JudgeGuess(int guessLength, int answerLength, int levDistance)
|
||||
{
|
||||
foreach (var level in strictness)
|
||||
foreach (var level in _strictness)
|
||||
if (guessLength <= level.Item1 || answerLength <= level.Item1)
|
||||
{
|
||||
if (levDistance <= level.Item2)
|
||||
@@ -78,7 +78,7 @@ public class TriviaQuestion
|
||||
str = Regex.Replace(str, "^\\s+", "");
|
||||
str = Regex.Replace(str, "\\s+$", "");
|
||||
//Trim the really long answers
|
||||
str = str.Length <= maxStringLength ? str : str[..maxStringLength];
|
||||
str = str.Length <= MAX_STRING_LENGTH ? str : str[..MAX_STRING_LENGTH];
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@@ -10,14 +10,14 @@ public class TriviaQuestionPool
|
||||
=> _cache.LocalData.PokemonMap;
|
||||
|
||||
private readonly IDataCache _cache;
|
||||
private readonly int maxPokemonId;
|
||||
private readonly int _maxPokemonId;
|
||||
|
||||
private readonly NadekoRandom _rng = new();
|
||||
|
||||
public TriviaQuestionPool(IDataCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
maxPokemonId = 721; //xd
|
||||
_maxPokemonId = 721; //xd
|
||||
}
|
||||
|
||||
public TriviaQuestion GetRandomQuestion(HashSet<TriviaQuestion> exclude, bool isPokemon)
|
||||
@@ -27,7 +27,7 @@ public class TriviaQuestionPool
|
||||
|
||||
if (isPokemon)
|
||||
{
|
||||
var num = _rng.Next(1, maxPokemonId + 1);
|
||||
var num = _rng.Next(1, _maxPokemonId + 1);
|
||||
return new("Who's That Pokémon?",
|
||||
Map[num].ToTitleCase(),
|
||||
"Pokemon",
|
||||
@@ -36,7 +36,15 @@ public class TriviaQuestionPool
|
||||
}
|
||||
|
||||
TriviaQuestion randomQuestion;
|
||||
while (exclude.Contains(randomQuestion = Pool[_rng.Next(0, Pool.Length)])) ;
|
||||
while (exclude.Contains(randomQuestion = Pool[_rng.Next(0, Pool.Length)]))
|
||||
{
|
||||
// if too many questions are excluded, clear the exclusion list and start over
|
||||
if (exclude.Count > Pool.Length / 10 * 9)
|
||||
{
|
||||
exclude.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return randomQuestion;
|
||||
}
|
||||
|
Reference in New Issue
Block a user