Games module file, poll command converted
This commit is contained in:
parent
a219717456
commit
c954861baa
132
src/NadekoBot/Modules/Games/Commands/PollCommand.cs
Normal file
132
src/NadekoBot/Modules/Games/Commands/PollCommand.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Attributes;
|
||||||
|
using NadekoBot.Classes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules.Games.Commands
|
||||||
|
{
|
||||||
|
public partial class GamesModule
|
||||||
|
{
|
||||||
|
|
||||||
|
//todo DB in the future
|
||||||
|
public static ConcurrentDictionary<IGuild, Poll> ActivePolls = new ConcurrentDictionary<IGuild, Poll>();
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task Poll(IMessage imsg, [Remainder] string arg)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
|
||||||
|
if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels)
|
||||||
|
return;
|
||||||
|
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";"))
|
||||||
|
return;
|
||||||
|
var data = arg.Split(';');
|
||||||
|
if (data.Length < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var poll = new Poll(imsg, data[0], data.Skip(1));
|
||||||
|
if (ActivePolls.TryAdd(channel.Guild, poll))
|
||||||
|
{
|
||||||
|
await poll.StartPoll().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task Pollend(IMessage imsg)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
|
||||||
|
if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels)
|
||||||
|
return;
|
||||||
|
Poll poll;
|
||||||
|
ActivePolls.TryGetValue(channel.Guild, out poll);
|
||||||
|
await poll.StopPoll(channel).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Poll
|
||||||
|
{
|
||||||
|
private readonly IMessage imsg;
|
||||||
|
private readonly string[] answers;
|
||||||
|
private ConcurrentDictionary<IUser, int> participants = new ConcurrentDictionary<IUser, int>();
|
||||||
|
private readonly string question;
|
||||||
|
private DateTime started;
|
||||||
|
private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
public Poll(IMessage imsg, string question, IEnumerable<string> enumerable)
|
||||||
|
{
|
||||||
|
this.imsg = imsg;
|
||||||
|
this.question = question;
|
||||||
|
this.answers = enumerable as string[] ?? enumerable.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartPoll()
|
||||||
|
{
|
||||||
|
started = DateTime.Now;
|
||||||
|
NadekoBot.Client.MessageReceived += Vote;
|
||||||
|
var msgToSend = $@"📃**{imsg.Author.Username}** has created a poll which requires your attention:
|
||||||
|
|
||||||
|
**{question}**\n";
|
||||||
|
var num = 1;
|
||||||
|
msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
|
||||||
|
msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
|
||||||
|
await imsg.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopPoll(IGuildChannel ch)
|
||||||
|
{
|
||||||
|
NadekoBot.Client.MessageReceived -= Vote;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var results = participants.GroupBy(kvp => kvp.Value)
|
||||||
|
.ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
|
||||||
|
.OrderBy(kvp => kvp.Value);
|
||||||
|
|
||||||
|
var totalVotesCast = results.Sum(kvp => kvp.Value);
|
||||||
|
if (totalVotesCast == 0)
|
||||||
|
{
|
||||||
|
await imsg.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var closeMessage = $"--------------**POLL CLOSED**--------------\n" +
|
||||||
|
$"📄 , here are the results:\n";
|
||||||
|
closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" +
|
||||||
|
$" has {kvp.Value} votes." +
|
||||||
|
$"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n");
|
||||||
|
|
||||||
|
await imsg.Channel.SendMessageAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error in poll game {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Vote(IMessage msg)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IPrivateChannel ch;
|
||||||
|
if ((ch = msg.Channel as IPrivateChannel) == null)
|
||||||
|
return;
|
||||||
|
int vote;
|
||||||
|
if (!int.TryParse(msg.Content, out vote)) return;
|
||||||
|
if (vote < 1 || vote > answers.Length)
|
||||||
|
return;
|
||||||
|
if (participants.TryAdd(msg.Author, vote))
|
||||||
|
{
|
||||||
|
await (ch as ITextChannel).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
197
src/NadekoBot/Modules/Games/Commands/SpeedTyping.cs
Normal file
197
src/NadekoBot/Modules/Games/Commands/SpeedTyping.cs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
//using Discord;
|
||||||
|
//using Discord.Commands;
|
||||||
|
//using NadekoBot.Classes;
|
||||||
|
//using NadekoBot.DataModels;
|
||||||
|
//using NadekoBot.Extensions;
|
||||||
|
//using System;
|
||||||
|
//using System.Collections.Concurrent;
|
||||||
|
//using System.Collections.Generic;
|
||||||
|
//using System.Diagnostics;
|
||||||
|
//using System.Linq;
|
||||||
|
//using System.Threading.Tasks;
|
||||||
|
|
||||||
|
////todo DB
|
||||||
|
////todo rewrite?
|
||||||
|
//namespace NadekoBot.Modules.Games.Commands
|
||||||
|
//{
|
||||||
|
|
||||||
|
// public static class SentencesProvider
|
||||||
|
// {
|
||||||
|
// internal static string GetRandomSentence()
|
||||||
|
// {
|
||||||
|
// var data = DbHandler.Instance.GetAllRows<TypingArticle>();
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// return data.ToList()[new Random().Next(0, data.Count())].Text;
|
||||||
|
// }
|
||||||
|
// catch
|
||||||
|
// {
|
||||||
|
// return "Failed retrieving data from parse. Owner didn't add any articles to type using `typeadd`.";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public class TypingGame
|
||||||
|
// {
|
||||||
|
// public const float WORD_VALUE = 4.5f;
|
||||||
|
// private readonly Channel channel;
|
||||||
|
// public string CurrentSentence;
|
||||||
|
// public bool IsActive;
|
||||||
|
// private readonly Stopwatch sw;
|
||||||
|
// private readonly List<ulong> finishedUserIds;
|
||||||
|
|
||||||
|
// public TypingGame(Channel channel)
|
||||||
|
// {
|
||||||
|
// this.channel = channel;
|
||||||
|
// IsActive = false;
|
||||||
|
// sw = new Stopwatch();
|
||||||
|
// finishedUserIds = new List<ulong>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Channel Channell { get; internal set; }
|
||||||
|
|
||||||
|
// internal async Task<bool> Stop()
|
||||||
|
// {
|
||||||
|
// if (!IsActive) return false;
|
||||||
|
// NadekoBot.Client.MessageReceived -= AnswerReceived;
|
||||||
|
// finishedUserIds.Clear();
|
||||||
|
// IsActive = false;
|
||||||
|
// sw.Stop();
|
||||||
|
// sw.Reset();
|
||||||
|
// await channel.Send("Typing contest stopped").ConfigureAwait(false);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// internal async Task Start()
|
||||||
|
// {
|
||||||
|
// while (true)
|
||||||
|
// {
|
||||||
|
// if (IsActive) return; // can't start running game
|
||||||
|
// IsActive = true;
|
||||||
|
// CurrentSentence = SentencesProvider.GetRandomSentence();
|
||||||
|
// var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
|
||||||
|
// await channel.SendMessage($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
|
// var msg = await channel.SendMessage("Starting new typing contest in **3**...").ConfigureAwait(false);
|
||||||
|
// await Task.Delay(1000).ConfigureAwait(false);
|
||||||
|
// await msg.Edit("Starting new typing contest in **2**...").ConfigureAwait(false);
|
||||||
|
// await Task.Delay(1000).ConfigureAwait(false);
|
||||||
|
// await msg.Edit("Starting new typing contest in **1**...").ConfigureAwait(false);
|
||||||
|
// await Task.Delay(1000).ConfigureAwait(false);
|
||||||
|
// await msg.Edit($":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false);
|
||||||
|
// sw.Start();
|
||||||
|
// HandleAnswers();
|
||||||
|
|
||||||
|
// while (i > 0)
|
||||||
|
// {
|
||||||
|
// await Task.Delay(1000).ConfigureAwait(false);
|
||||||
|
// i--;
|
||||||
|
// if (!IsActive)
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await Stop().ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void HandleAnswers()
|
||||||
|
// {
|
||||||
|
// NadekoBot.Client.MessageReceived += AnswerReceived;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private async void AnswerReceived(object sender, MessageEventArgs e)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (e.Channel == null || e.Channel.Id != channel.Id || e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||||
|
|
||||||
|
// var guess = e.Message.RawText;
|
||||||
|
|
||||||
|
// var distance = CurrentSentence.LevenshteinDistance(guess);
|
||||||
|
// var decision = Judge(distance, guess.Length);
|
||||||
|
// if (decision && !finishedUserIds.Contains(e.User.Id))
|
||||||
|
// {
|
||||||
|
// finishedUserIds.Add(e.User.Id);
|
||||||
|
// await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
|
||||||
|
// if (finishedUserIds.Count % 2 == 0)
|
||||||
|
// {
|
||||||
|
// await imsg.Channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch { }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private bool Judge(int errors, int textLength) => errors <= textLength / 25;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// internal class SpeedTyping : DiscordCommand
|
||||||
|
// {
|
||||||
|
|
||||||
|
// public static ConcurrentDictionary<ulong, TypingGame> RunningContests;
|
||||||
|
|
||||||
|
// public SpeedTyping(DiscordModule module) : base(module)
|
||||||
|
// {
|
||||||
|
// RunningContests = new ConcurrentDictionary<ulong, TypingGame>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Func<CommandEventArgs, Task> DoFunc() =>
|
||||||
|
// async e =>
|
||||||
|
// {
|
||||||
|
// var game = RunningContests.GetOrAdd(e.User.Server.Id, id => new TypingGame(e.Channel));
|
||||||
|
|
||||||
|
// if (game.IsActive)
|
||||||
|
// {
|
||||||
|
// await imsg.Channel.SendMessageAsync(
|
||||||
|
// $"Contest already running in " +
|
||||||
|
// $"{game.Channell.Mention} channel.")
|
||||||
|
// .ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// await game.Start().ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// private Func<CommandEventArgs, Task> QuitFunc() =>
|
||||||
|
// async e =>
|
||||||
|
// {
|
||||||
|
// TypingGame game;
|
||||||
|
// if (RunningContests.TryRemove(e.User.Server.Id, out game))
|
||||||
|
// {
|
||||||
|
// await game.Stop().ConfigureAwait(false);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// await imsg.Channel.SendMessageAsync("No contest to stop on this channel.").ConfigureAwait(false);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
// {
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "typestart")
|
||||||
|
// .Description($"Starts a typing contest. | `{Prefix}typestart`")
|
||||||
|
// .Do(DoFunc());
|
||||||
|
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "typestop")
|
||||||
|
// .Description($"Stops a typing contest on the current channel. | `{Prefix}typestop`")
|
||||||
|
// .Do(QuitFunc());
|
||||||
|
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "typeadd")
|
||||||
|
// .Description($"Adds a new article to the typing contest. Owner only. | `{Prefix}typeadd wordswords`")
|
||||||
|
// .Parameter("text", ParameterType.Unparsed)
|
||||||
|
// .Do(async e =>
|
||||||
|
// {
|
||||||
|
// if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
||||||
|
|
||||||
|
// DbHandler.Instance.Connection.Insert(new TypingArticle
|
||||||
|
// {
|
||||||
|
// Text = e.GetArg("text"),
|
||||||
|
// DateAdded = DateTime.Now
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await imsg.Channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
76
src/NadekoBot/Modules/Games/Commands/TriviaCommand.cs
Normal file
76
src/NadekoBot/Modules/Games/Commands/TriviaCommand.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//using Discord.Commands;
|
||||||
|
//using NadekoBot.Classes;
|
||||||
|
//using NadekoBot.Modules.Games.Commands.Trivia;
|
||||||
|
//using System;
|
||||||
|
//using System.Collections.Concurrent;
|
||||||
|
//using System.Linq;
|
||||||
|
|
||||||
|
////todo DB
|
||||||
|
////todo Rewrite?
|
||||||
|
|
||||||
|
//namespace NadekoBot.Modules.Games.Commands
|
||||||
|
//{
|
||||||
|
// internal class TriviaCommands : DiscordCommand
|
||||||
|
// {
|
||||||
|
// public static ConcurrentDictionary<ulong, TriviaGame> RunningTrivias = new ConcurrentDictionary<ulong, TriviaGame>();
|
||||||
|
|
||||||
|
// public TriviaCommands(DiscordModule module) : base(module)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
// {
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "t")
|
||||||
|
// .Description($"Starts a game of trivia. You can add nohint to prevent hints." +
|
||||||
|
// "First player to get to 10 points wins by default. You can specify a different number. 30 seconds per question." +
|
||||||
|
// $" |`{Module.Prefix}t nohint` or `{Module.Prefix}t 5 nohint`")
|
||||||
|
// .Parameter("args", ParameterType.Multiple)
|
||||||
|
// .Do(async e =>
|
||||||
|
// {
|
||||||
|
// TriviaGame trivia;
|
||||||
|
// if (!RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
||||||
|
// {
|
||||||
|
// var showHints = !e.Args.Contains("nohint");
|
||||||
|
// var number = e.Args.Select(s =>
|
||||||
|
// {
|
||||||
|
// int num;
|
||||||
|
// return new Tuple<bool, int>(int.TryParse(s, out num), num);
|
||||||
|
// }).Where(t => t.Item1).Select(t => t.Item2).FirstOrDefault();
|
||||||
|
// if (number < 0)
|
||||||
|
// return;
|
||||||
|
// var triviaGame = new TriviaGame(e, showHints, number == 0 ? 10 : number);
|
||||||
|
// if (RunningTrivias.TryAdd(e.Server.Id, triviaGame))
|
||||||
|
// await imsg.Channel.SendMessageAsync($"**Trivia game started! {triviaGame.WinRequirement} points needed to win.**").ConfigureAwait(false);
|
||||||
|
// else
|
||||||
|
// await triviaGame.StopGame().ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// await imsg.Channel.SendMessageAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "tl")
|
||||||
|
// .Description($"Shows a current trivia leaderboard. | `{Prefix}tl`")
|
||||||
|
// .Do(async e =>
|
||||||
|
// {
|
||||||
|
// TriviaGame trivia;
|
||||||
|
// if (RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
||||||
|
// await imsg.Channel.SendMessageAsync(trivia.GetLeaderboard()).ConfigureAwait(false);
|
||||||
|
// else
|
||||||
|
// await imsg.Channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// cgb.CreateCommand(Module.Prefix + "tq")
|
||||||
|
// .Description($"Quits current trivia after current question. | `{Prefix}tq`")
|
||||||
|
// .Do(async e =>
|
||||||
|
// {
|
||||||
|
// TriviaGame trivia;
|
||||||
|
// if (RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
||||||
|
// {
|
||||||
|
// await trivia.StopGame().ConfigureAwait(false);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// await imsg.Channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
114
src/NadekoBot/Modules/Games/GamesModule.cs
Normal file
114
src/NadekoBot/Modules/Games/GamesModule.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using Discord.Commands;
|
||||||
|
using Discord;
|
||||||
|
using NadekoBot.Services;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NadekoBot.Attributes;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NadekoBot.Extensions;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules.Games
|
||||||
|
{
|
||||||
|
[Module(">", AppendSpace = false)]
|
||||||
|
public partial class GamesModule : DiscordModule
|
||||||
|
{
|
||||||
|
//todo DB
|
||||||
|
private IEnumerable<string> _8BallResponses;
|
||||||
|
public GamesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task Choose(IMessage imsg, [Remainder] string list)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
if (string.IsNullOrWhiteSpace(list))
|
||||||
|
return;
|
||||||
|
var listArr = list.Split(';');
|
||||||
|
if (listArr.Count() < 2)
|
||||||
|
return;
|
||||||
|
var rng = new Random();
|
||||||
|
await imsg.Channel.SendMessageAsync(listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task _8Ball(IMessage imsg, [Remainder] string question)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(question))
|
||||||
|
return;
|
||||||
|
var rng = new Random();
|
||||||
|
await imsg.Channel.SendMessageAsync($@":question: `Question` __**{question}**__
|
||||||
|
🎱 `8Ball Answers` __**{_8BallResponses.Shuffle().FirstOrDefault()}**__").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task Rps(IMessage imsg, string input)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
|
||||||
|
Func<int,string> GetRPSPick = (p) =>
|
||||||
|
{
|
||||||
|
if (p == 0)
|
||||||
|
return "rocket";
|
||||||
|
else if (p == 1)
|
||||||
|
return "paperclip";
|
||||||
|
else
|
||||||
|
return "scissors";
|
||||||
|
};
|
||||||
|
|
||||||
|
int pick;
|
||||||
|
switch (input)
|
||||||
|
{
|
||||||
|
case "r":
|
||||||
|
case "rock":
|
||||||
|
case "rocket":
|
||||||
|
pick = 0;
|
||||||
|
break;
|
||||||
|
case "p":
|
||||||
|
case "paper":
|
||||||
|
case "paperclip":
|
||||||
|
pick = 1;
|
||||||
|
break;
|
||||||
|
case "scissors":
|
||||||
|
case "s":
|
||||||
|
pick = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var nadekoPick = new Random().Next(0, 3);
|
||||||
|
var msg = "";
|
||||||
|
if (pick == nadekoPick)
|
||||||
|
msg = $"It's a draw! Both picked :{GetRPSPick(pick)}:";
|
||||||
|
else if ((pick == 0 && nadekoPick == 1) ||
|
||||||
|
(pick == 1 && nadekoPick == 2) ||
|
||||||
|
(pick == 2 && nadekoPick == 0))
|
||||||
|
msg = $"{(await NadekoBot.Client.GetCurrentUserAsync()).Mention} won! :{GetRPSPick(nadekoPick)}: beats :{GetRPSPick(pick)}:";
|
||||||
|
else
|
||||||
|
msg = $"{imsg.Author.Mention} won! :{GetRPSPick(pick)}: beats :{GetRPSPick(nadekoPick)}:";
|
||||||
|
|
||||||
|
await imsg.Channel.SendMessageAsync(msg).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task Linux(IMessage imsg, string guhnoo, string loonix)
|
||||||
|
{
|
||||||
|
var channel = imsg.Channel as IGuildChannel;
|
||||||
|
|
||||||
|
await imsg.Channel.SendMessageAsync(
|
||||||
|
$@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
|
||||||
|
|
||||||
|
Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project.
|
||||||
|
|
||||||
|
There really is a {loonix}, and these people are using it, but it is just a part of the system they use. {loonix} is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. {loonix} is normally used in combination with the {guhnoo} operating system: the whole system is basically {guhnoo} with {loonix} added, or {guhnoo}/{loonix}. All the so-called {loonix} distributions are really distributions of {guhnoo}/{loonix}."
|
||||||
|
).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ using NadekoBot.Services;
|
|||||||
|
|
||||||
namespace NadekoBot.Modules.Translator
|
namespace NadekoBot.Modules.Translator
|
||||||
{
|
{
|
||||||
|
[Module("~", AppendSpace = false)]
|
||||||
public class TranslatorModule : DiscordModule
|
public class TranslatorModule : DiscordModule
|
||||||
{
|
{
|
||||||
public TranslatorModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
|
public TranslatorModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Modules.Translator.Helpers;
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Translator
|
|
||||||
{
|
|
||||||
class ValidLanguagesCommand : DiscordCommand
|
|
||||||
{
|
|
||||||
public ValidLanguagesCommand(DiscordModule module) : base(module) { }
|
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb)
|
|
||||||
{
|
|
||||||
cgb.CreateCommand(Module.Prefix + "translangs")
|
|
||||||
.Description($"List the valid languages for translation. | `{Prefix}translangs` or `{Prefix}translangs language`")
|
|
||||||
.Parameter("search", ParameterType.Optional)
|
|
||||||
.Do(ListLanguagesFunc());
|
|
||||||
}
|
|
||||||
private Func<CommandEventArgs, Task> ListLanguagesFunc() => async e =>
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -128,6 +128,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo maybe split into 3/4 different commands with the same name
|
||||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task Prune(IMessage msg, [Remainder] string target = null)
|
public async Task Prune(IMessage msg, [Remainder] string target = null)
|
||||||
|
@ -8,6 +8,8 @@ namespace NadekoBot.Services.Impl
|
|||||||
{
|
{
|
||||||
public class BotConfiguration : IBotConfiguration
|
public class BotConfiguration : IBotConfiguration
|
||||||
{
|
{
|
||||||
|
internal Task _8BallResponses;
|
||||||
|
|
||||||
public HashSet<ulong> BlacklistedChannels { get; set; } = new HashSet<ulong>();
|
public HashSet<ulong> BlacklistedChannels { get; set; } = new HashSet<ulong>();
|
||||||
|
|
||||||
public HashSet<ulong> BlacklistedServers { get; set; } = new HashSet<ulong>();
|
public HashSet<ulong> BlacklistedServers { get; set; } = new HashSet<ulong>();
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
using Discord;
|
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Games.Commands
|
|
||||||
{
|
|
||||||
internal class PollCommand : DiscordCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
public static ConcurrentDictionary<Server, Poll> ActivePolls = new ConcurrentDictionary<Server, Poll>();
|
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb)
|
|
||||||
{
|
|
||||||
cgb.CreateCommand(Module.Prefix + "poll")
|
|
||||||
.Description($"Creates a poll, only person who has manage server permission can do it. | `{Prefix}poll Question?;Answer1;Answ 2;A_3`")
|
|
||||||
.Parameter("allargs", ParameterType.Unparsed)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
await Task.Run(async () =>
|
|
||||||
{
|
|
||||||
if (!e.User.ServerPermissions.ManageChannels)
|
|
||||||
return;
|
|
||||||
if (ActivePolls.ContainsKey(e.Server))
|
|
||||||
return;
|
|
||||||
var arg = e.GetArg("allargs");
|
|
||||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";"))
|
|
||||||
return;
|
|
||||||
var data = arg.Split(';');
|
|
||||||
if (data.Length < 3)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var poll = new Poll(e, data[0], data.Skip(1));
|
|
||||||
if (PollCommand.ActivePolls.TryAdd(e.Server, poll))
|
|
||||||
{
|
|
||||||
await poll.StartPoll().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
cgb.CreateCommand(Module.Prefix + "pollend")
|
|
||||||
.Description($"Stops active poll on this server and prints the results in this channel. | `{Prefix}pollend`")
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
if (!e.User.ServerPermissions.ManageChannels)
|
|
||||||
return;
|
|
||||||
if (!ActivePolls.ContainsKey(e.Server))
|
|
||||||
return;
|
|
||||||
await ActivePolls[e.Server].StopPoll(e.Channel).ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public PollCommand(DiscordModule module) : base(module) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class Poll
|
|
||||||
{
|
|
||||||
private readonly CommandEventArgs e;
|
|
||||||
private readonly string[] answers;
|
|
||||||
private ConcurrentDictionary<User, int> participants = new ConcurrentDictionary<User, int>();
|
|
||||||
private readonly string question;
|
|
||||||
private DateTime started;
|
|
||||||
private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
|
|
||||||
|
|
||||||
public Poll(CommandEventArgs e, string question, IEnumerable<string> enumerable)
|
|
||||||
{
|
|
||||||
this.e = e;
|
|
||||||
this.question = question;
|
|
||||||
this.answers = enumerable as string[] ?? enumerable.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task StartPoll()
|
|
||||||
{
|
|
||||||
started = DateTime.Now;
|
|
||||||
NadekoBot.Client.MessageReceived += Vote;
|
|
||||||
var msgToSend =
|
|
||||||
$"📃**{e.User.Name}** from **{e.Server.Name}** server has created a poll which requires your attention:\n\n" +
|
|
||||||
$"**{question}**\n";
|
|
||||||
var num = 1;
|
|
||||||
msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
|
|
||||||
msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
|
|
||||||
await imsg.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task StopPoll(Channel ch)
|
|
||||||
{
|
|
||||||
NadekoBot.Client.MessageReceived -= Vote;
|
|
||||||
Poll throwaway;
|
|
||||||
PollCommand.ActivePolls.TryRemove(e.Server, out throwaway);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var results = participants.GroupBy(kvp => kvp.Value)
|
|
||||||
.ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
|
|
||||||
.OrderBy(kvp => kvp.Value);
|
|
||||||
|
|
||||||
var totalVotesCast = results.Sum(kvp => kvp.Value);
|
|
||||||
if (totalVotesCast == 0)
|
|
||||||
{
|
|
||||||
await ch.SendMessage("📄 **No votes have been cast.**").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var closeMessage = $"--------------**POLL CLOSED**--------------\n" +
|
|
||||||
$"📄 , here are the results:\n";
|
|
||||||
closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" +
|
|
||||||
$" has {kvp.Value} votes." +
|
|
||||||
$"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n");
|
|
||||||
|
|
||||||
await ch.SendMessage($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error in poll game {ex}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Vote(object sender, MessageEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!e.Channel.IsPrivate)
|
|
||||||
return;
|
|
||||||
if (participants.ContainsKey(e.User))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int vote;
|
|
||||||
if (!int.TryParse(e.Message.Text, out vote)) return;
|
|
||||||
if (vote < 1 || vote > answers.Length)
|
|
||||||
return;
|
|
||||||
if (participants.TryAdd(e.User, vote))
|
|
||||||
{
|
|
||||||
await e.User.SendMessage($"Thanks for voting **{e.User.Name}**.").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,195 +0,0 @@
|
|||||||
using Discord;
|
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.DataModels;
|
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Games.Commands
|
|
||||||
{
|
|
||||||
|
|
||||||
public static class SentencesProvider
|
|
||||||
{
|
|
||||||
internal static string GetRandomSentence()
|
|
||||||
{
|
|
||||||
var data = DbHandler.Instance.GetAllRows<TypingArticle>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return data.ToList()[new Random().Next(0, data.Count())].Text;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return "Failed retrieving data from parse. Owner didn't add any articles to type using `typeadd`.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypingGame
|
|
||||||
{
|
|
||||||
public const float WORD_VALUE = 4.5f;
|
|
||||||
private readonly Channel channel;
|
|
||||||
public string CurrentSentence;
|
|
||||||
public bool IsActive;
|
|
||||||
private readonly Stopwatch sw;
|
|
||||||
private readonly List<ulong> finishedUserIds;
|
|
||||||
|
|
||||||
public TypingGame(Channel channel)
|
|
||||||
{
|
|
||||||
this.channel = channel;
|
|
||||||
IsActive = false;
|
|
||||||
sw = new Stopwatch();
|
|
||||||
finishedUserIds = new List<ulong>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Channel Channell { get; internal set; }
|
|
||||||
|
|
||||||
internal async Task<bool> Stop()
|
|
||||||
{
|
|
||||||
if (!IsActive) return false;
|
|
||||||
NadekoBot.Client.MessageReceived -= AnswerReceived;
|
|
||||||
finishedUserIds.Clear();
|
|
||||||
IsActive = false;
|
|
||||||
sw.Stop();
|
|
||||||
sw.Reset();
|
|
||||||
await channel.Send("Typing contest stopped").ConfigureAwait(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task Start()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (IsActive) return; // can't start running game
|
|
||||||
IsActive = true;
|
|
||||||
CurrentSentence = SentencesProvider.GetRandomSentence();
|
|
||||||
var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
|
|
||||||
await channel.SendMessage($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
|
|
||||||
|
|
||||||
|
|
||||||
var msg = await channel.SendMessage("Starting new typing contest in **3**...").ConfigureAwait(false);
|
|
||||||
await Task.Delay(1000).ConfigureAwait(false);
|
|
||||||
await msg.Edit("Starting new typing contest in **2**...").ConfigureAwait(false);
|
|
||||||
await Task.Delay(1000).ConfigureAwait(false);
|
|
||||||
await msg.Edit("Starting new typing contest in **1**...").ConfigureAwait(false);
|
|
||||||
await Task.Delay(1000).ConfigureAwait(false);
|
|
||||||
await msg.Edit($":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false);
|
|
||||||
sw.Start();
|
|
||||||
HandleAnswers();
|
|
||||||
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
await Task.Delay(1000).ConfigureAwait(false);
|
|
||||||
i--;
|
|
||||||
if (!IsActive)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Stop().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleAnswers()
|
|
||||||
{
|
|
||||||
NadekoBot.Client.MessageReceived += AnswerReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void AnswerReceived(object sender, MessageEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (e.Channel == null || e.Channel.Id != channel.Id || e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
|
||||||
|
|
||||||
var guess = e.Message.RawText;
|
|
||||||
|
|
||||||
var distance = CurrentSentence.LevenshteinDistance(guess);
|
|
||||||
var decision = Judge(distance, guess.Length);
|
|
||||||
if (decision && !finishedUserIds.Contains(e.User.Id))
|
|
||||||
{
|
|
||||||
finishedUserIds.Add(e.User.Id);
|
|
||||||
await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
|
|
||||||
if (finishedUserIds.Count % 2 == 0)
|
|
||||||
{
|
|
||||||
await imsg.Channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Judge(int errors, int textLength) => errors <= textLength / 25;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class SpeedTyping : DiscordCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
public static ConcurrentDictionary<ulong, TypingGame> RunningContests;
|
|
||||||
|
|
||||||
public SpeedTyping(DiscordModule module) : base(module)
|
|
||||||
{
|
|
||||||
RunningContests = new ConcurrentDictionary<ulong, TypingGame>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Func<CommandEventArgs, Task> DoFunc() =>
|
|
||||||
async e =>
|
|
||||||
{
|
|
||||||
var game = RunningContests.GetOrAdd(e.User.Server.Id, id => new TypingGame(e.Channel));
|
|
||||||
|
|
||||||
if (game.IsActive)
|
|
||||||
{
|
|
||||||
await imsg.Channel.SendMessageAsync(
|
|
||||||
$"Contest already running in " +
|
|
||||||
$"{game.Channell.Mention} channel.")
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await game.Start().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private Func<CommandEventArgs, Task> QuitFunc() =>
|
|
||||||
async e =>
|
|
||||||
{
|
|
||||||
TypingGame game;
|
|
||||||
if (RunningContests.TryRemove(e.User.Server.Id, out game))
|
|
||||||
{
|
|
||||||
await game.Stop().ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await imsg.Channel.SendMessageAsync("No contest to stop on this channel.").ConfigureAwait(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb)
|
|
||||||
{
|
|
||||||
cgb.CreateCommand(Module.Prefix + "typestart")
|
|
||||||
.Description($"Starts a typing contest. | `{Prefix}typestart`")
|
|
||||||
.Do(DoFunc());
|
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "typestop")
|
|
||||||
.Description($"Stops a typing contest on the current channel. | `{Prefix}typestop`")
|
|
||||||
.Do(QuitFunc());
|
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "typeadd")
|
|
||||||
.Description($"Adds a new article to the typing contest. Owner only. | `{Prefix}typeadd wordswords`")
|
|
||||||
.Parameter("text", ParameterType.Unparsed)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
|
||||||
|
|
||||||
DbHandler.Instance.Connection.Insert(new TypingArticle
|
|
||||||
{
|
|
||||||
Text = e.GetArg("text"),
|
|
||||||
DateAdded = DateTime.Now
|
|
||||||
});
|
|
||||||
|
|
||||||
await imsg.Channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Modules.Games.Commands.Trivia;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Games.Commands
|
|
||||||
{
|
|
||||||
internal class TriviaCommands : DiscordCommand
|
|
||||||
{
|
|
||||||
public static ConcurrentDictionary<ulong, TriviaGame> RunningTrivias = new ConcurrentDictionary<ulong, TriviaGame>();
|
|
||||||
|
|
||||||
public TriviaCommands(DiscordModule module) : base(module)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb)
|
|
||||||
{
|
|
||||||
cgb.CreateCommand(Module.Prefix + "t")
|
|
||||||
.Description($"Starts a game of trivia. You can add nohint to prevent hints." +
|
|
||||||
"First player to get to 10 points wins by default. You can specify a different number. 30 seconds per question." +
|
|
||||||
$" |`{Module.Prefix}t nohint` or `{Module.Prefix}t 5 nohint`")
|
|
||||||
.Parameter("args", ParameterType.Multiple)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
TriviaGame trivia;
|
|
||||||
if (!RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
|
||||||
{
|
|
||||||
var showHints = !e.Args.Contains("nohint");
|
|
||||||
var number = e.Args.Select(s =>
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
return new Tuple<bool, int>(int.TryParse(s, out num), num);
|
|
||||||
}).Where(t => t.Item1).Select(t => t.Item2).FirstOrDefault();
|
|
||||||
if (number < 0)
|
|
||||||
return;
|
|
||||||
var triviaGame = new TriviaGame(e, showHints, number == 0 ? 10 : number);
|
|
||||||
if (RunningTrivias.TryAdd(e.Server.Id, triviaGame))
|
|
||||||
await imsg.Channel.SendMessageAsync($"**Trivia game started! {triviaGame.WinRequirement} points needed to win.**").ConfigureAwait(false);
|
|
||||||
else
|
|
||||||
await triviaGame.StopGame().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
await imsg.Channel.SendMessageAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "tl")
|
|
||||||
.Description($"Shows a current trivia leaderboard. | `{Prefix}tl`")
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
TriviaGame trivia;
|
|
||||||
if (RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
|
||||||
await imsg.Channel.SendMessageAsync(trivia.GetLeaderboard()).ConfigureAwait(false);
|
|
||||||
else
|
|
||||||
await imsg.Channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "tq")
|
|
||||||
.Description($"Quits current trivia after current question. | `{Prefix}tq`")
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
TriviaGame trivia;
|
|
||||||
if (RunningTrivias.TryGetValue(e.Server.Id, out trivia))
|
|
||||||
{
|
|
||||||
await trivia.StopGame().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
await imsg.Channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
using Discord.Commands;
|
|
||||||
using Discord.Modules;
|
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using NadekoBot.Modules.Games.Commands;
|
|
||||||
using NadekoBot.Modules.Permissions.Classes;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Games
|
|
||||||
{
|
|
||||||
internal class GamesModule : DiscordModule
|
|
||||||
{
|
|
||||||
private readonly Random rng = new Random();
|
|
||||||
|
|
||||||
public GamesModule()
|
|
||||||
{
|
|
||||||
commands.Add(new TriviaCommands(this));
|
|
||||||
commands.Add(new SpeedTyping(this));
|
|
||||||
commands.Add(new PollCommand(this));
|
|
||||||
commands.Add(new PlantPick(this));
|
|
||||||
commands.Add(new Bomberman(this));
|
|
||||||
commands.Add(new Leet(this));
|
|
||||||
//commands.Add(new BetrayGame(this));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Games;
|
|
||||||
|
|
||||||
public override void Install(ModuleManager manager)
|
|
||||||
{
|
|
||||||
manager.CreateCommands("", cgb =>
|
|
||||||
{
|
|
||||||
|
|
||||||
cgb.AddCheck(PermissionChecker.Instance);
|
|
||||||
|
|
||||||
commands.ForEach(cmd => cmd.Init(cgb));
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "choose")
|
|
||||||
.Description($"Chooses a thing from a list of things | `{Prefix}choose Get up;Sleep;Sleep more`")
|
|
||||||
.Parameter("list", ParameterType.Unparsed)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var arg = e.GetArg("list");
|
|
||||||
if (string.IsNullOrWhiteSpace(arg))
|
|
||||||
return;
|
|
||||||
var list = arg.Split(';');
|
|
||||||
if (list.Count() < 2)
|
|
||||||
return;
|
|
||||||
await imsg.Channel.SendMessageAsync(list[rng.Next(0, list.Length)]).ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "8ball")
|
|
||||||
.Description($"Ask the 8ball a yes/no question. | `{Prefix}8ball should i do something`")
|
|
||||||
.Parameter("question", ParameterType.Unparsed)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var question = e.GetArg("question");
|
|
||||||
if (string.IsNullOrWhiteSpace(question))
|
|
||||||
return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await imsg.Channel.SendMessageAsync(
|
|
||||||
$":question: `Question` __**{question}**__ \n🎱 `8Ball Answers` __**{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}**__")
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "rps")
|
|
||||||
.Description($"Play a game of rocket paperclip scissors with Nadeko. | `{Prefix}rps scissors`")
|
|
||||||
.Parameter("input", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var input = e.GetArg("input").Trim();
|
|
||||||
int pick;
|
|
||||||
switch (input)
|
|
||||||
{
|
|
||||||
case "r":
|
|
||||||
case "rock":
|
|
||||||
case "rocket":
|
|
||||||
pick = 0;
|
|
||||||
break;
|
|
||||||
case "p":
|
|
||||||
case "paper":
|
|
||||||
case "paperclip":
|
|
||||||
pick = 1;
|
|
||||||
break;
|
|
||||||
case "scissors":
|
|
||||||
case "s":
|
|
||||||
pick = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var nadekoPick = new Random().Next(0, 3);
|
|
||||||
var msg = "";
|
|
||||||
if (pick == nadekoPick)
|
|
||||||
msg = $"It's a draw! Both picked :{GetRPSPick(pick)}:";
|
|
||||||
else if ((pick == 0 && nadekoPick == 1) ||
|
|
||||||
(pick == 1 && nadekoPick == 2) ||
|
|
||||||
(pick == 2 && nadekoPick == 0))
|
|
||||||
msg = $"{NadekoBot.BotMention} won! :{GetRPSPick(nadekoPick)}: beats :{GetRPSPick(pick)}:";
|
|
||||||
else
|
|
||||||
msg = $"{e.User.Mention} won! :{GetRPSPick(pick)}: beats :{GetRPSPick(nadekoPick)}:";
|
|
||||||
|
|
||||||
await imsg.Channel.SendMessageAsync(msg).ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "linux")
|
|
||||||
.Description($"Prints a customizable Linux interjection | `{Prefix}linux Spyware Windows`")
|
|
||||||
.Parameter("gnu", ParameterType.Required)
|
|
||||||
.Parameter("linux", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var guhnoo = e.Args[0];
|
|
||||||
var loonix = e.Args[1];
|
|
||||||
|
|
||||||
await imsg.Channel.SendMessageAsync(
|
|
||||||
$@"
|
|
||||||
I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
|
|
||||||
|
|
||||||
Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project.
|
|
||||||
|
|
||||||
There really is a {loonix}, and these people are using it, but it is just a part of the system they use. {loonix} is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. {loonix} is normally used in combination with the {guhnoo} operating system: the whole system is basically {guhnoo} with {loonix} added, or {guhnoo}/{loonix}. All the so-called {loonix} distributions are really distributions of {guhnoo}/{loonix}.
|
|
||||||
").ConfigureAwait(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetRPSPick(int i)
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
return "rocket";
|
|
||||||
else if (i == 1)
|
|
||||||
return "paperclip";
|
|
||||||
else
|
|
||||||
return "scissors";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user